半成品/成品入库:BOM 编号下拉按父件规格联动过滤(前后端双端改造)
- 后端 /inbound/{semi,product}/search-bom 增加 parent_spec 可选参数,Service 层在 MaterialBase.spec_model 上加等值过滤
This commit is contained in:
@ -60,7 +60,8 @@ def search_base():
|
|||||||
def search_bom():
|
def search_bom():
|
||||||
try:
|
try:
|
||||||
keyword = request.args.get('keyword', '')
|
keyword = request.args.get('keyword', '')
|
||||||
data = ProductInboundService.search_bom_options(keyword)
|
parent_spec = request.args.get('parent_spec', None)
|
||||||
|
data = ProductInboundService.search_bom_options(keyword, parent_spec=parent_spec)
|
||||||
return jsonify({"code": 200, "msg": "success", "data": data})
|
return jsonify({"code": 200, "msg": "success", "data": data})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|||||||
@ -60,7 +60,8 @@ def search_base():
|
|||||||
def search_bom():
|
def search_bom():
|
||||||
try:
|
try:
|
||||||
keyword = request.args.get('keyword', '')
|
keyword = request.args.get('keyword', '')
|
||||||
data = SemiInboundService.search_bom_options(keyword)
|
parent_spec = request.args.get('parent_spec', None)
|
||||||
|
data = SemiInboundService.search_bom_options(keyword, parent_spec=parent_spec)
|
||||||
return jsonify({"code": 200, "msg": "success", "data": data})
|
return jsonify({"code": 200, "msg": "success", "data": data})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|||||||
@ -66,7 +66,7 @@ class ProductInboundService:
|
|||||||
return {"items": [], "total": 0, "page": 1, "has_next": False}
|
return {"items": [], "total": 0, "page": 1, "has_next": False}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def search_bom_options(keyword):
|
def search_bom_options(keyword, parent_spec=None):
|
||||||
from app.models.bom import BomTable
|
from app.models.bom import BomTable
|
||||||
try:
|
try:
|
||||||
query = db.session.query(
|
query = db.session.query(
|
||||||
@ -79,6 +79,9 @@ class ProductInboundService:
|
|||||||
if hasattr(BomTable, 'is_enabled'):
|
if hasattr(BomTable, 'is_enabled'):
|
||||||
query = query.filter(BomTable.is_enabled == True)
|
query = query.filter(BomTable.is_enabled == True)
|
||||||
|
|
||||||
|
if parent_spec:
|
||||||
|
query = query.filter(MaterialBase.spec_model == parent_spec)
|
||||||
|
|
||||||
if keyword:
|
if keyword:
|
||||||
kw = f'%{keyword}%'
|
kw = f'%{keyword}%'
|
||||||
query = query.filter(
|
query = query.filter(
|
||||||
|
|||||||
@ -71,7 +71,7 @@ class SemiInboundService:
|
|||||||
return {"items": [], "total": 0, "page": 1, "has_next": False}
|
return {"items": [], "total": 0, "page": 1, "has_next": False}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def search_bom_options(keyword):
|
def search_bom_options(keyword, parent_spec=None):
|
||||||
from app.models.bom import BomTable
|
from app.models.bom import BomTable
|
||||||
try:
|
try:
|
||||||
query = db.session.query(
|
query = db.session.query(
|
||||||
@ -84,6 +84,9 @@ class SemiInboundService:
|
|||||||
if hasattr(BomTable, 'is_enabled'):
|
if hasattr(BomTable, 'is_enabled'):
|
||||||
query = query.filter(BomTable.is_enabled == True)
|
query = query.filter(BomTable.is_enabled == True)
|
||||||
|
|
||||||
|
if parent_spec:
|
||||||
|
query = query.filter(MaterialBase.spec_model == parent_spec)
|
||||||
|
|
||||||
if keyword:
|
if keyword:
|
||||||
kw = f'%{keyword}%'
|
kw = f'%{keyword}%'
|
||||||
query = query.filter(
|
query = query.filter(
|
||||||
|
|||||||
@ -43,11 +43,11 @@ export function searchMaterialBase(keyword: string, page: number = 1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 搜索BOM
|
// 搜索BOM
|
||||||
export function searchBom(keyword: string) {
|
export function searchBom(keyword: string, parent_spec?: string) {
|
||||||
return request({
|
return request({
|
||||||
url: '/inbound/product/search-bom',
|
url: '/inbound/product/search-bom',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: { keyword }
|
params: { keyword, parent_spec }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -45,11 +45,11 @@ export function searchMaterialBase(keyword: string, page: number = 1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 5.5 搜索BOM (新增)
|
// 5.5 搜索BOM (新增)
|
||||||
export function searchBom(keyword: string) {
|
export function searchBom(keyword: string, parent_spec?: string) {
|
||||||
return request({
|
return request({
|
||||||
url: '/inbound/semi/search-bom',
|
url: '/inbound/semi/search-bom',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: { keyword }
|
params: { keyword, parent_spec }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -461,7 +461,8 @@
|
|||||||
filterable
|
filterable
|
||||||
remote
|
remote
|
||||||
clearable
|
clearable
|
||||||
placeholder="搜规格/编号"
|
:disabled="!form.spec_model"
|
||||||
|
:placeholder="!form.spec_model ? '请先在上方选择入库物料' : '搜规格/编号'"
|
||||||
:remote-method="handleSearchBom"
|
:remote-method="handleSearchBom"
|
||||||
:loading="bomSearchLoading"
|
:loading="bomSearchLoading"
|
||||||
@change="handleBomSelect"
|
@change="handleBomSelect"
|
||||||
@ -544,10 +545,10 @@
|
|||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
|
||||||
<el-dialog v-model="dialogVisibleImage" append-to-body width="50%">
|
<el-dialog v-model="dialogVisibleImage" append-to-body width="50%" :close-on-click-modal="false" :close-on-press-escape="false">
|
||||||
<img style="width: 100%" :src="dialogImageUrl" alt="Preview Image" />
|
<img style="width: 100%" :src="dialogImageUrl" alt="Preview Image" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<el-dialog v-model="cameraDialogVisible" title="拍照上传" width="500px" append-to-body destroy-on-close :close-on-click-modal="false">
|
<el-dialog v-model="cameraDialogVisible" title="拍照上传" width="500px" append-to-body destroy-on-close :close-on-click-modal="false" :close-on-press-escape="false">
|
||||||
<WebRtcCamera
|
<WebRtcCamera
|
||||||
ref="cameraRef"
|
ref="cameraRef"
|
||||||
@photo-submit="handleCameraConfirm"
|
@photo-submit="handleCameraConfirm"
|
||||||
@ -555,7 +556,7 @@
|
|||||||
/>
|
/>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<el-dialog v-model="printVisible" title="标签打印预览" width="400px" destroy-on-close append-to-body>
|
<el-dialog v-model="printVisible" title="标签打印预览" width="400px" destroy-on-close append-to-body :close-on-click-modal="false" :close-on-press-escape="false">
|
||||||
<div style="text-align: center;">
|
<div style="text-align: center;">
|
||||||
<div v-loading="printLoading" class="preview-box">
|
<div v-loading="printLoading" class="preview-box">
|
||||||
<img v-if="previewUrl" :src="previewUrl" alt="Label Preview" style="width: 100%; border: 1px solid #ccc;"/>
|
<img v-if="previewUrl" :src="previewUrl" alt="Label Preview" style="width: 100%; border: 1px solid #ccc;"/>
|
||||||
@ -957,7 +958,7 @@ const form = reactive({
|
|||||||
const handleSearchBom = async (query: string) => {
|
const handleSearchBom = async (query: string) => {
|
||||||
bomSearchLoading.value = true
|
bomSearchLoading.value = true
|
||||||
try {
|
try {
|
||||||
const res: any = await searchBom(query)
|
const res: any = await searchBom(query, form.spec_model)
|
||||||
bomOptions.value = res.data || []
|
bomOptions.value = res.data || []
|
||||||
} finally { bomSearchLoading.value = false }
|
} finally { bomSearchLoading.value = false }
|
||||||
}
|
}
|
||||||
@ -1108,6 +1109,10 @@ const onMaterialSelected = async (val: number) => {
|
|||||||
form.material_type = item.type
|
form.material_type = item.type
|
||||||
form.category = item.category
|
form.category = item.category
|
||||||
form.unit = item.unit
|
form.unit = item.unit
|
||||||
|
// 切换物料时清空已选 BOM,防止脏数据
|
||||||
|
form.bom_code = ''
|
||||||
|
form.bom_version = ''
|
||||||
|
bomOptions.value = []
|
||||||
|
|
||||||
// 获取该物料历史入库库位(新增独立接口)
|
// 获取该物料历史入库库位(新增独立接口)
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -526,7 +526,8 @@
|
|||||||
filterable
|
filterable
|
||||||
remote
|
remote
|
||||||
clearable
|
clearable
|
||||||
placeholder="搜规格/编号"
|
:disabled="!form.spec_model"
|
||||||
|
:placeholder="!form.spec_model ? '请先在上方选择入库物料' : '搜规格/编号'"
|
||||||
:remote-method="handleSearchBom"
|
:remote-method="handleSearchBom"
|
||||||
:loading="bomSearchLoading"
|
:loading="bomSearchLoading"
|
||||||
@change="handleBomSelect"
|
@change="handleBomSelect"
|
||||||
@ -603,15 +604,15 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<el-dialog v-model="dialogVisibleImage" append-to-body width="50%"><img style="width: 100%" :src="dialogImageUrl" alt="Preview Image" /></el-dialog>
|
<el-dialog v-model="dialogVisibleImage" append-to-body width="50%" :close-on-click-modal="false" :close-on-press-escape="false"><img style="width: 100%" :src="dialogImageUrl" alt="Preview Image" /></el-dialog>
|
||||||
<el-dialog v-model="cameraDialogVisible" title="拍照上传" width="500px" append-to-body destroy-on-close :close-on-click-modal="false">
|
<el-dialog v-model="cameraDialogVisible" title="拍照上传" width="500px" append-to-body destroy-on-close :close-on-click-modal="false" :close-on-press-escape="false">
|
||||||
<WebRtcCamera
|
<WebRtcCamera
|
||||||
ref="cameraRef"
|
ref="cameraRef"
|
||||||
@photo-submit="handleCameraConfirm"
|
@photo-submit="handleCameraConfirm"
|
||||||
@cancel="cameraDialogVisible = false"
|
@cancel="cameraDialogVisible = false"
|
||||||
/>
|
/>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<el-dialog v-model="printVisible" title="标签打印预览" width="400px" destroy-on-close append-to-body>
|
<el-dialog v-model="printVisible" title="标签打印预览" width="400px" destroy-on-close append-to-body :close-on-click-modal="false" :close-on-press-escape="false">
|
||||||
<div style="text-align: center;">
|
<div style="text-align: center;">
|
||||||
<div v-loading="printLoading" class="preview-box">
|
<div v-loading="printLoading" class="preview-box">
|
||||||
<img v-if="previewUrl" :src="previewUrl" alt="Label Preview" style="width: 100%; border: 1px solid #ccc;"/>
|
<img v-if="previewUrl" :src="previewUrl" alt="Label Preview" style="width: 100%; border: 1px solid #ccc;"/>
|
||||||
@ -1004,7 +1005,7 @@ watch(
|
|||||||
const handleSearchBom = async (query: string) => {
|
const handleSearchBom = async (query: string) => {
|
||||||
bomSearchLoading.value = true
|
bomSearchLoading.value = true
|
||||||
try {
|
try {
|
||||||
const res: any = await searchBom(query)
|
const res: any = await searchBom(query, form.spec_model)
|
||||||
bomOptions.value = res.data || []
|
bomOptions.value = res.data || []
|
||||||
} finally { bomSearchLoading.value = false }
|
} finally { bomSearchLoading.value = false }
|
||||||
}
|
}
|
||||||
@ -1102,6 +1103,10 @@ const onMaterialSelected = async (val: number) => {
|
|||||||
form.category = item.category
|
form.category = item.category
|
||||||
form.unit = item.unit
|
form.unit = item.unit
|
||||||
form.material_type = item.type
|
form.material_type = item.type
|
||||||
|
// 切换物料时清空已选 BOM,防止脏数据
|
||||||
|
form.bom_code = ''
|
||||||
|
form.bom_version = ''
|
||||||
|
bomOptions.value = []
|
||||||
checkHistoryAndSetMode(item.id)
|
checkHistoryAndSetMode(item.id)
|
||||||
|
|
||||||
// 获取该物料历史入库库位(新增独立接口)
|
// 获取该物料历史入库库位(新增独立接口)
|
||||||
|
|||||||
Reference in New Issue
Block a user