diff --git a/klp-admin/src/main/java/com/klp/web/controller/system/SysDictDataController.java b/klp-admin/src/main/java/com/klp/web/controller/system/SysDictDataController.java index a010b339..5c9cf14f 100644 --- a/klp-admin/src/main/java/com/klp/web/controller/system/SysDictDataController.java +++ b/klp-admin/src/main/java/com/klp/web/controller/system/SysDictDataController.java @@ -61,7 +61,7 @@ public class SysDictDataController extends BaseController { */ @SaCheckPermission("system:dict:query") @GetMapping(value = "/{dictCode}") - public R getInfo(@PathVariable Long dictCode) { + public R getInfo(@PathVariable("dictCode") Long dictCode) { return R.ok(dictDataService.selectDictDataById(dictCode)); } @@ -71,7 +71,7 @@ public class SysDictDataController extends BaseController { * @param dictType 字典类型 */ @GetMapping(value = "/type/{dictType}") - public R> dictType(@PathVariable String dictType) { + public R> dictType(@PathVariable("dictType") String dictType) { List data = dictTypeService.selectDictDataByType(dictType); if (ObjectUtil.isNull(data)) { data = new ArrayList<>(); @@ -109,7 +109,7 @@ public class SysDictDataController extends BaseController { @SaCheckPermission("system:dict:remove") @Log(title = "字典类型", businessType = BusinessType.DELETE) @DeleteMapping("/{dictCodes}") - public R remove(@PathVariable Long[] dictCodes) { + public R remove(@PathVariable("dictCodes") Long[] dictCodes) { dictDataService.deleteDictDataByIds(dictCodes); return R.ok(); } diff --git a/klp-ui/src/views/wms/coil/merge.vue b/klp-ui/src/views/wms/coil/merge.vue index f40c39bc..6fc10513 100644 --- a/klp-ui/src/views/wms/coil/merge.vue +++ b/klp-ui/src/views/wms/coil/merge.vue @@ -44,13 +44,32 @@ {{ item.enterCoilNo || '—' }}
- 当前库区: - {{ item.warehouseName || '未分配' }} + 逻辑库区: + {{ item.warehouseName || '—' }}
-
+
+ 真实库区: + {{ item.actualWarehouseName || '—' }} +
+
物料名称: {{ item.materialName || item.productName || '—' }}
+
+ 物料规格: + {{ item.specification }} +
+ + + @@ -128,8 +147,31 @@ - - + + + + + + + + + + + - - + + ({ id: item.rawMaterialId, - name: item.rawMaterialName + name: this.formatItemName(item) })); } else if (this.targetCoil.itemType === 'product') { return this.productList.map(item => ({ id: item.productId, - name: item.productName + name: this.formatItemName(item) })); } return []; @@ -309,8 +349,11 @@ export default { itemType: null, itemId: null, warehouseName: '', + actualWarehouseName: '', materialName: '', - productName: '' + productName: '', + specification: '', + bomItems: [] }, { coilId: null, @@ -319,8 +362,11 @@ export default { itemType: null, itemId: null, warehouseName: '', + actualWarehouseName: '', materialName: '', - productName: '' + productName: '', + specification: '', + bomItems: [] } ]; } @@ -343,8 +389,11 @@ export default { itemType: data.itemType, itemId: data.itemId, warehouseName: data.warehouseName || (data.warehouse ? data.warehouse.warehouseName : ''), + actualWarehouseName: data.actualWarehouseName || (data.actualWarehouse ? data.actualWarehouse.warehouseName : ''), materialName: data.materialName || (data.rawMaterial ? data.rawMaterial.rawMaterialName : ''), - productName: data.productName || (data.product ? data.product.productName : '') + productName: data.productName || (data.product ? data.product.productName : ''), + specification: data.rawMaterial?.specification || data.product?.specification || '', + bomItems: data.bomItemList || [] }, { coilId: null, @@ -353,8 +402,11 @@ export default { itemType: null, itemId: null, warehouseName: '', + actualWarehouseName: '', materialName: '', - productName: '' + productName: '', + specification: '', + bomItems: [] } ]; @@ -377,22 +429,47 @@ export default { } }, - // 加载待合卷列表 + // 加载待合卷列表(查询待处理和处理中的记录) async loadPendingMergeList() { try { this.pendingLoading = true; - const response = await listPendingAction({ - actionType: 1, // 1=合卷 - actionStatus: 0, // 0=待处理 - pageNum: 1, - pageSize: 50 - }); - - if (response.code === 200) { - // 排除当前钢卷 - const currentCoilId = this.sourceCoils[0].coilId; - this.pendingMergeList = (response.rows || []).filter(item => item.coilId !== currentCoilId); - } + console.log('=== 开始加载待合卷列表 ==='); + + // 分别查询待处理和处理中的记录 + const responses = await Promise.all([ + listPendingAction({ + actionType: 1, // 1=合卷 + actionStatus: 0, // 0=待处理 + pageNum: 1, + pageSize: 50 + }), + listPendingAction({ + actionType: 1, // 1=合卷 + actionStatus: 1, // 1=处理中 + pageNum: 1, + pageSize: 50 + }) + ]); + + console.log('待处理响应:', responses[0]); + console.log('处理中响应:', responses[1]); + + // 合并两个列表 + const allPending = [ + ...(responses[0].rows || []), + ...(responses[1].rows || []) + ]; + + console.log('所有待合卷记录数量:', allPending.length); + console.log('所有待合卷记录:', allPending); + + // 排除当前钢卷 + const currentCoilId = this.sourceCoils[0] ? this.sourceCoils[0].coilId : null; + console.log('当前钢卷ID:', currentCoilId); + + this.pendingMergeList = allPending.filter(item => item.coilId !== currentCoilId); + console.log('过滤后的待合卷列表数量:', this.pendingMergeList.length); + console.log('过滤后的待合卷列表:', this.pendingMergeList); } catch (error) { console.error('加载待合卷列表失败', error); } finally { @@ -414,8 +491,11 @@ export default { itemType: data.itemType, itemId: data.itemId, warehouseName: data.warehouseName || (data.warehouse ? data.warehouse.warehouseName : ''), + actualWarehouseName: data.actualWarehouseName || (data.actualWarehouse ? data.actualWarehouse.warehouseName : ''), materialName: data.materialName || (data.rawMaterial ? data.rawMaterial.rawMaterialName : ''), productName: data.productName || (data.product ? data.product.productName : ''), + specification: data.rawMaterial?.specification || data.product?.specification || '', + bomItems: data.bomItemList || [], actionId: pending.actionId // 保存待操作ID,用于后续完成操作 }); @@ -440,6 +520,41 @@ export default { return `${month}-${day} ${hour}:${minute}`; }, + // 格式化物品名称(添加规格和BOM信息) + formatItemName(item) { + if (!item) return ''; + + // 获取名称(原材料或产品) + const name = item.rawMaterialName || item.productName || ''; + if (!name) return ''; + + let displayName = name; + const specs = []; + + // 1. 优先显示规格(从对象的specification字段) + if (item.specification) { + specs.push(item.specification); + } + + // 2. 添加BOM参数(最多2个) + if (item.bomItems && item.bomItems.length > 0) { + const bomParams = item.bomItems + .filter(bomItem => bomItem.attrKey && bomItem.attrValue) + .slice(0, 2); // 最多2个BOM参数 + + bomParams.forEach(param => { + specs.push(`${param.attrKey}:${param.attrValue}`); + }); + } + + // 3. 拼接成最终格式 + if (specs.length > 0) { + displayName += `(${specs.join(' ')})`; + } + + return displayName; + }, + // 加载库区列表 async loadWarehouses() { try { @@ -455,16 +570,24 @@ export default { // 加载物品列表(根据类型) async loadItemList(itemType) { if (!itemType) return; - + try { this.itemSearchLoading = true; if (itemType === 'raw_material') { - const response = await listRawMaterial({ pageNum: 1, pageSize: 100 }); + const response = await listRawMaterial({ + pageNum: 1, + pageSize: 100, + withBom: true + }); if (response.code === 200) { this.rawMaterialList = response.rows || []; } } else if (itemType === 'product') { - const response = await listProduct({ pageNum: 1, pageSize: 100 }); + const response = await listProduct({ + pageNum: 1, + pageSize: 100, + withBom: true + }); if (response.code === 200) { this.productList = response.rows || []; } @@ -482,23 +605,30 @@ export default { this.$message.warning('请先选择物品类型'); return; } - + + if (!query || query.trim() === '') { + this.loadItemList(this.targetCoil.itemType); + return; + } + try { this.itemSearchLoading = true; if (this.targetCoil.itemType === 'raw_material') { - const response = await listRawMaterial({ + const response = await listRawMaterial({ rawMaterialName: query, - pageNum: 1, - pageSize: 50 + pageNum: 1, + pageSize: 50, + withBom: true }); if (response.code === 200) { this.rawMaterialList = response.rows || []; } } else if (this.targetCoil.itemType === 'product') { - const response = await listProduct({ + const response = await listProduct({ productName: query, - pageNum: 1, - pageSize: 50 + pageNum: 1, + pageSize: 50, + withBom: true }); if (response.code === 200) { this.productList = response.rows || []; @@ -520,8 +650,11 @@ export default { itemType: null, itemId: null, warehouseName: '', + actualWarehouseName: '', materialName: '', - productName: '' + productName: '', + specification: '', + bomItems: [] }); }, @@ -550,8 +683,11 @@ export default { itemType: coil.itemType, itemId: coil.itemId, warehouseName: coil.warehouseName || '', + actualWarehouseName: coil.actualWarehouseName || '', materialName: coil.materialName || '', - productName: coil.productName || '' + productName: coil.productName || '', + specification: coil.rawMaterial?.specification || coil.product?.specification || '', + bomItems: coil.bomItemList || [] }); // 如果是第一个源卷,自动填充目标卷信息 @@ -915,17 +1051,17 @@ export default { align-items: flex-start; margin-bottom: 8px; font-size: 13px; - + &:last-child { margin-bottom: 0; } - + .detail-label { color: #909399; min-width: 90px; flex-shrink: 0; } - + .detail-value { color: #303133; flex: 1; @@ -933,6 +1069,36 @@ export default { } } +.source-detail-divider { + margin: 10px 0 8px; + padding: 5px 0; + font-size: 12px; + font-weight: 500; + color: #606266; + border-bottom: 1px solid #e4e7ed; +} + +.source-bom-params { + margin-top: 8px; +} + +.source-bom-item { + display: flex; + align-items: center; + margin-bottom: 6px; + font-size: 12px; + + .bom-key { + color: #909399; + min-width: 60px; + } + + .bom-value { + color: #303133; + flex: 1; + } +} + .btn-remove { color: #f56c6c; padding: 0; diff --git a/klp-ui/src/views/wms/coil/split.vue b/klp-ui/src/views/wms/coil/split.vue index 857aaff5..c9831132 100644 --- a/klp-ui/src/views/wms/coil/split.vue +++ b/klp-ui/src/views/wms/coil/split.vue @@ -139,10 +139,10 @@ - + - + ({ id: item.rawMaterialId, - name: item.rawMaterialName + name: this.formatItemName(item) })); } else if (itemType === 'product') { return this.productList.map(item => ({ id: item.productId, - name: item.productName + name: this.formatItemName(item) })); } return []; }, + // 格式化物品名称(添加规格和BOM信息) + formatItemName(item) { + if (!item) return ''; + + // 获取名称(原材料或产品) + const name = item.rawMaterialName || item.productName || ''; + if (!name) return ''; + + let displayName = name; + const specs = []; + + // 1. 优先显示规格(从对象的specification字段) + if (item.specification) { + specs.push(item.specification); + } + + // 2. 添加BOM参数(最多2个) + if (item.bomItems && item.bomItems.length > 0) { + const bomParams = item.bomItems + .filter(bomItem => bomItem.attrKey && bomItem.attrValue) + .slice(0, 2); // 最多2个BOM参数 + + bomParams.forEach(param => { + specs.push(`${param.attrKey}:${param.attrValue}`); + }); + } + + // 3. 拼接成最终格式 + if (specs.length > 0) { + displayName += `(${specs.join(' ')})`; + } + + return displayName; + }, + // 物品类型变化 handleItemTypeChange(index) { this.splitList[index].itemId = null; @@ -296,23 +340,30 @@ export default { this.$message.warning('请先选择物品类型'); return; } - + + if (!query || query.trim() === '') { + this.loadItemListForSplit(itemType); + return; + } + try { this.itemSearchLoading = true; if (itemType === 'raw_material') { - const response = await listRawMaterial({ + const response = await listRawMaterial({ rawMaterialName: query, - pageNum: 1, - pageSize: 50 + pageNum: 1, + pageSize: 50, + withBom: true }); if (response.code === 200) { this.rawMaterialList = response.rows || []; } } else if (itemType === 'product') { - const response = await listProduct({ + const response = await listProduct({ productName: query, - pageNum: 1, - pageSize: 50 + pageNum: 1, + pageSize: 50, + withBom: true }); if (response.code === 200) { this.productList = response.rows || []; @@ -328,16 +379,24 @@ export default { // 加载子卷物品列表 async loadItemListForSplit(itemType) { if (!itemType) return; - + try { this.itemSearchLoading = true; if (itemType === 'raw_material') { - const response = await listRawMaterial({ pageNum: 1, pageSize: 100 }); + const response = await listRawMaterial({ + pageNum: 1, + pageSize: 100, + withBom: true + }); if (response.code === 200) { this.rawMaterialList = response.rows || []; } } else if (itemType === 'product') { - const response = await listProduct({ pageNum: 1, pageSize: 100 }); + const response = await listProduct({ + pageNum: 1, + pageSize: 100, + withBom: true + }); if (response.code === 200) { this.productList = response.rows || []; } @@ -522,6 +581,12 @@ export default { const response = await splitMaterialCoil(splitData); if (response.code === 200) { this.$message.success('分卷保存成功'); + + // 如果是从待操作列表进来的,标记操作为完成 + if (this.actionId) { + await completeAction(this.actionId); + } + // 延迟返回,让用户看到成功提示 setTimeout(() => { this.$router.back(); diff --git a/klp-ui/src/views/wms/coil/typing.vue b/klp-ui/src/views/wms/coil/typing.vue index 919ea723..8d27640b 100644 --- a/klp-ui/src/views/wms/coil/typing.vue +++ b/klp-ui/src/views/wms/coil/typing.vue @@ -55,7 +55,7 @@ {{ currentInfo.netWeight ? currentInfo.netWeight + ' t' : '—' }}
- 目标库区: + 逻辑库区: {{ currentInfo.nextWarehouseName || '—' }}
@@ -122,8 +122,8 @@ - - + @@ -256,7 +256,7 @@ export default { { type: 'number', message: '净重必须为数字', trigger: 'blur' } ], warehouseId: [ - { required: true, message: '请选择目标库区', trigger: 'change' } + { required: true, message: '请选择逻辑库区', trigger: 'change' } ], actualWarehouseId: [ { required: true, message: '请选择真实库区', trigger: 'change' } @@ -279,12 +279,12 @@ export default { if (this.updateForm.itemType === 'raw_material') { return this.rawMaterialList.map(item => ({ id: item.rawMaterialId, - name: item.rawMaterialName + name: this.formatItemName(item) })); } else if (this.updateForm.itemType === 'product') { return this.productList.map(item => ({ id: item.productId, - name: item.productName + name: this.formatItemName(item) })); } return []; @@ -395,6 +395,49 @@ export default { return warehouse ? warehouse.warehouseName : ''; }, + // 格式化物品名称(添加规格和BOM信息) + formatItemName(name, bomItems) { + if (!name) return ''; + + let displayName = name; + + // 如果有BOM参数,添加到名称后面 + if (bomItems && bomItems.length > 0) { + const specs = []; + + // 查找规格参数 + const specItem = bomItems.find(item => + item.attrKey === '规格' || + item.attrKey === 'spec' || + item.attrKey === '型号' + ); + if (specItem && specItem.attrValue) { + specs.push(specItem.attrValue); + } + + // 添加其他关键参数(最多3个) + const otherParams = bomItems + .filter(item => + item.attrKey !== '规格' && + item.attrKey !== 'spec' && + item.attrKey !== '型号' + ) + .slice(0, 2); // 最多2个其他参数 + + otherParams.forEach(param => { + if (param.attrValue) { + specs.push(`${param.attrKey}:${param.attrValue}`); + } + }); + + if (specs.length > 0) { + displayName += `(${specs.join(' ')})`; + } + } + + return displayName; + }, + // 加载库区列表 async loadWarehouses() { try { @@ -411,16 +454,26 @@ export default { // 加载物品列表(根据类型) async loadItemList(itemType) { if (!itemType) return; - + try { this.itemSearchLoading = true; if (itemType === 'raw_material') { - const response = await listRawMaterial({ pageNum: 1, pageSize: 100 }); + // 使用带BOM的接口 + const response = await listRawMaterial({ + pageNum: 1, + pageSize: 100, + withBom: true // 请求包含BOM信息 + }); if (response.code === 200) { this.rawMaterialList = response.rows || []; } } else if (itemType === 'product') { - const response = await listProduct({ pageNum: 1, pageSize: 100 }); + // 使用带BOM的接口 + const response = await listProduct({ + pageNum: 1, + pageSize: 100, + withBom: true // 请求包含BOM信息 + }); if (response.code === 200) { this.productList = response.rows || []; } @@ -432,29 +485,37 @@ export default { } }, - // 搜索物品 + // 搜索物品(支持名称和规格搜索) async searchItems(query) { if (!this.updateForm.itemType) { this.$message.warning('请先选择物品类型'); return; } - + + if (!query || query.trim() === '') { + // 如果搜索为空,加载默认列表 + this.loadItemList(this.updateForm.itemType); + return; + } + try { this.itemSearchLoading = true; if (this.updateForm.itemType === 'raw_material') { - const response = await listRawMaterial({ - rawMaterialName: query, - pageNum: 1, - pageSize: 50 + const response = await listRawMaterial({ + rawMaterialName: query, // 按名称搜索 + pageNum: 1, + pageSize: 50, + withBom: true }); if (response.code === 200) { this.rawMaterialList = response.rows || []; } } else if (this.updateForm.itemType === 'product') { - const response = await listProduct({ - productName: query, - pageNum: 1, - pageSize: 50 + const response = await listProduct({ + productName: query, // 按名称搜索 + pageNum: 1, + pageSize: 50, + withBom: true }); if (response.code === 200) { this.productList = response.rows || []; @@ -534,24 +595,26 @@ export default { try { this.loading = true; - // 构造更新数据(使用标准update接口,会创建历史版本) + // 构造更新数据(使用标准update接口,直接更新原记录) const updateData = { coilId: this.currentInfo.coilId, - enterCoilNo: this.currentInfo.enterCoilNo, // 入场钢卷号,从当前信息获取(必填) - supplierCoilNo: this.currentInfo.supplierCoilNo, // 厂家原料卷号(保持不变) + enterCoilNo: this.currentInfo.enterCoilNo, + supplierCoilNo: this.currentInfo.supplierCoilNo, currentCoilNo: this.updateForm.currentCoilNo, team: this.updateForm.team, itemType: this.updateForm.itemType, itemId: this.updateForm.itemId, grossWeight: this.updateForm.grossWeight, netWeight: this.updateForm.netWeight, - // warehouseId: this.currentInfo.warehouseId, // 当前库区ID(保持不变) - actualWarehouseId: this.updateForm.actualWarehouseId, // 真实库区ID - warehouseId: this.updateForm.warehouseId, // 目标库区ID + warehouseId: this.updateForm.warehouseId, + actualWarehouseId: this.updateForm.actualWarehouseId, remark: this.updateForm.remark + // 注意:不要传newCoils,否则会走批量更新逻辑 }; - + + console.log('=== 正常更新操作 ==='); console.log('提交的更新数据:', updateData); + console.log('是否有newCoils:', updateData.newCoils); const response = await updateMaterialCoil(updateData); diff --git a/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java b/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java index 54681662..2f927da3 100644 --- a/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java +++ b/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java @@ -62,7 +62,7 @@ public class WmsMaterialCoilController extends BaseController { */ @GetMapping("/{coilId}") public R getInfo(@NotNull(message = "主键不能为空") - @PathVariable Long coilId) { + @PathVariable("coilId") Long coilId) { return R.ok(iWmsMaterialCoilService.queryById(coilId)); } @@ -105,7 +105,7 @@ public class WmsMaterialCoilController extends BaseController { @Log(title = "钢卷物料表", businessType = BusinessType.DELETE) @DeleteMapping("/{coilIds}") public R remove(@NotEmpty(message = "主键不能为空") - @PathVariable Long[] coilIds) { + @PathVariable("coilIds") Long[] coilIds) { return toAjax(iWmsMaterialCoilService.deleteWithValidByIds(Arrays.asList(coilIds), true)); } diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java index 043c09ac..2c15faa1 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java @@ -22,7 +22,6 @@ import com.klp.domain.vo.WmsRawMaterialVo; import com.klp.domain.vo.WmsBomItemVo; import com.klp.domain.bo.WmsBomItemBo; import com.klp.domain.WmsMaterialCoil; -import com.klp.domain.WmsStock; import com.klp.domain.bo.WmsStockBo; import com.klp.domain.vo.WmsStockVo; import com.klp.mapper.WmsMaterialCoilMapper; @@ -31,9 +30,11 @@ import com.klp.service.IWmsMaterialCoilService; import com.klp.service.IWmsStockService; import com.klp.service.IWmsGenerateRecordService; import com.klp.service.IWmsWarehouseService; +import com.klp.service.IWmsActualWarehouseService; import com.klp.service.IWmsRawMaterialService; import com.klp.service.IWmsProductBomService; import com.klp.service.IWmsBomItemService; +import com.klp.domain.vo.WmsActualWarehouseVo; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.List; @@ -61,6 +62,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { private final IWmsStockService stockService; private final IWmsGenerateRecordService generateRecordService; private final IWmsWarehouseService warehouseService; + private final IWmsActualWarehouseService actualWarehouseService; private final IWmsRawMaterialService rawMaterialService; private final IWmsProductBomService productBomService; private final IWmsBomItemService bomItemService; @@ -97,6 +99,14 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { vo.setNextWarehouse(nextWarehouse); } + // 查询实际库区信息 + if (vo.getActualWarehouseId() != null) { + WmsActualWarehouseVo actualWarehouse = actualWarehouseService.queryById(vo.getActualWarehouseId()); + if (actualWarehouse != null) { + vo.setActualWarehouseName(actualWarehouse.getActualWarehouseName()); + } + } + // 查询二维码信息 if (vo.getQrcodeRecordId() != null) { WmsGenerateRecordVo qrcodeRecord = generateRecordService.queryById(vo.getQrcodeRecordId()); @@ -354,7 +364,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { } /** - * 单个更新 + * 单个更新(正常更新,不产生新记录,二维码不变) */ private Boolean updateBySingle(WmsMaterialCoilBo bo) { // 查询原钢卷 @@ -363,56 +373,36 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { throw new RuntimeException("原钢卷不存在"); } - // 判断warehouseId是否发生变化 - boolean warehouseChanged = bo.getWarehouseId() != null && - !bo.getWarehouseId().equals(oldCoil.getWarehouseId()); - - Long qrcodeRecordId; - if (warehouseChanged) { - // 如果库区发生变化,生成新的二维码 - qrcodeRecordId = generateQrcodeForUpdate(oldCoil, bo); - } else { - // 如果库区未变化,更新原二维码内容 - updateQrcodeContent(oldCoil.getQrcodeRecordId(), bo); - qrcodeRecordId = oldCoil.getQrcodeRecordId(); + // 直接更新原记录(不产生新记录,不修改dataType) + WmsMaterialCoil updateCoil = BeanUtil.toBean(bo, WmsMaterialCoil.class); + + // 确保关键字段不丢失 + if (updateCoil.getEnterCoilNo() == null) { + updateCoil.setEnterCoilNo(oldCoil.getEnterCoilNo()); } - - // 2. 将原数据更新为历史数据(data_type=0) - LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); - updateWrapper.eq(WmsMaterialCoil::getCoilId, bo.getCoilId()) - .set(WmsMaterialCoil::getDataType, 0); // 设置为历史数据 - baseMapper.update(null, updateWrapper); - - // 3. 插入一条新的当前数据(data_type=1) - WmsMaterialCoil newCoil = BeanUtil.toBean(bo, WmsMaterialCoil.class); - newCoil.setCoilId(null); // 清空ID,让数据库自动生成新的ID - newCoil.setDataType(1); // 设置为当前数据 - newCoil.setQrcodeRecordId(qrcodeRecordId); // 使用新的或原有的二维码ID - - // 确保关键字段不丢失(入场钢卷号始终不变) - newCoil.setEnterCoilNo(oldCoil.getEnterCoilNo()); // 入场钢卷号始终不变 - if (newCoil.getSupplierCoilNo() == null) { - newCoil.setSupplierCoilNo(oldCoil.getSupplierCoilNo()); // 保留厂家原料卷号 + if (updateCoil.getSupplierCoilNo() == null) { + updateCoil.setSupplierCoilNo(oldCoil.getSupplierCoilNo()); } - if (newCoil.getItemType() == null) { - newCoil.setItemType(oldCoil.getItemType()); + if (updateCoil.getQrcodeRecordId() == null) { + updateCoil.setQrcodeRecordId(oldCoil.getQrcodeRecordId()); } - if (newCoil.getItemId() == null) { - newCoil.setItemId(oldCoil.getItemId()); + if (updateCoil.getWarehouseId() == null) { + updateCoil.setWarehouseId(oldCoil.getWarehouseId()); } - // 确保warehouseId有值(如果前端没传,使用原值) - if (newCoil.getWarehouseId() == null) { - newCoil.setWarehouseId(oldCoil.getWarehouseId()); - newCoil.setActualWarehouseId(oldCoil.getActualWarehouseId()); + if (updateCoil.getActualWarehouseId() == null) { + updateCoil.setActualWarehouseId(oldCoil.getActualWarehouseId()); } - - validEntityBeforeSave(newCoil); - boolean flag = baseMapper.insert(newCoil) > 0; + + validEntityBeforeSave(updateCoil); + + // 直接更新记录(coilId不变) + boolean flag = baseMapper.updateById(updateCoil) > 0; + if (flag) { - bo.setCoilId(newCoil.getCoilId()); - // 无论库区是否变化,都需要更新二维码中的current_coil_id - updateQrcodeCoilId(qrcodeRecordId, newCoil.getCoilId()); + // 更新二维码内容(添加新的step) + updateQrcodeContentForNormalUpdate(oldCoil, bo); } + return flag; } @@ -543,9 +533,17 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { throw new RuntimeException("分卷操作需要原钢卷信息"); } - // 1. 将原始钢卷更新为历史数据(已在上面完成) + // 1. 将原始钢卷的二维码标记为失效(status=0) + if (oldCoil.getQrcodeRecordId() != null) { + WmsGenerateRecordBo oldQrBo = new WmsGenerateRecordBo(); + oldQrBo.setRecordId(oldCoil.getQrcodeRecordId()); + oldQrBo.setStatus(0); // 0=失效 + generateRecordService.updateByBo(oldQrBo); + } + + // 2. 将原始钢卷标记为历史数据(已在上面完成) - // 2. 为每个分卷后的子钢卷生成独立的二维码并插入数据库 + // 3. 为每个分卷后的子钢卷生成独立的二维码并插入数据库 for (WmsMaterialCoilBo newCoilBo : bo.getNewCoils()) { WmsMaterialCoil newCoil = BeanUtil.toBean(newCoilBo, WmsMaterialCoil.class); newCoil.setCoilId(null); @@ -578,13 +576,25 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { } } else if (isMerge) { // 合卷:将bo作为合卷后的新钢卷,newCoils中的对象作为参与合卷的原始钢卷 - // 1. 将参与合卷的原始钢卷更新为历史数据 + // 1. 将参与合卷的原始钢卷的二维码标记为失效,并将钢卷标记为历史数据 for (WmsMaterialCoilBo originalCoilBo : bo.getNewCoils()) { if (originalCoilBo.getCoilId() != null) { - LambdaUpdateWrapper originalUpdateWrapper = new LambdaUpdateWrapper<>(); - originalUpdateWrapper.eq(WmsMaterialCoil::getCoilId, originalCoilBo.getCoilId()) - .set(WmsMaterialCoil::getDataType, 0); // 设置为历史数据 - baseMapper.update(null, originalUpdateWrapper); + WmsMaterialCoil originalCoil = baseMapper.selectById(originalCoilBo.getCoilId()); + if (originalCoil != null) { + // 标记二维码为失效 + if (originalCoil.getQrcodeRecordId() != null) { + WmsGenerateRecordBo oldQrBo = new WmsGenerateRecordBo(); + oldQrBo.setRecordId(originalCoil.getQrcodeRecordId()); + oldQrBo.setStatus(0); // 0=失效 + generateRecordService.updateByBo(oldQrBo); + } + + // 标记钢卷为历史数据 + LambdaUpdateWrapper originalUpdateWrapper = new LambdaUpdateWrapper<>(); + originalUpdateWrapper.eq(WmsMaterialCoil::getCoilId, originalCoilBo.getCoilId()) + .set(WmsMaterialCoil::getDataType, 0); // 设置为历史数据 + baseMapper.update(null, originalUpdateWrapper); + } } } @@ -821,21 +831,19 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { } /** - * 更新二维码内容(单个更新) + * 更新二维码内容(正常更新,添加step) */ - private void updateQrcodeContent(Long qrcodeRecordId, WmsMaterialCoilBo bo) { + private void updateQrcodeContentForNormalUpdate(WmsMaterialCoil oldCoil, WmsMaterialCoilBo bo) { try { - // 获取原钢卷信息 - WmsMaterialCoil oldCoil = baseMapper.selectById(bo.getCoilId()); - // 获取原二维码记录 - WmsGenerateRecordVo oldRecord = generateRecordService.queryById(qrcodeRecordId); + WmsGenerateRecordVo oldRecord = generateRecordService.queryById(oldCoil.getQrcodeRecordId()); if (oldRecord == null) { throw new RuntimeException("二维码记录不存在"); } // 解析现有content ObjectMapper objectMapper = new ObjectMapper(); + @SuppressWarnings("unchecked") Map contentMap = objectMapper.readValue(oldRecord.getContent(), Map.class); // 获取现有steps @@ -845,39 +853,29 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { steps = new ArrayList<>(); } - // 添加新的step,记录钢卷号的变化 + // 添加新的step,记录更新信息 Map newStep = new HashMap<>(); newStep.put("step", steps.size() + 1); newStep.put("action", "更新"); - newStep.put("old_current_coil_no", oldCoil.getCurrentCoilNo()); // 原当前钢卷号 - newStep.put("new_current_coil_no", bo.getCurrentCoilNo()); // 新当前钢卷号 - newStep.put("coil_id", String.valueOf(bo.getCoilId())); // 钢卷ID - newStep.put("operator", LoginHelper.getUsername()); // 操作者 - - // 判断操作类型 - if (bo.getHasMergeSplit() != null && bo.getHasMergeSplit() == 2) { - newStep.put("operation", "合卷"); - newStep.put("parent_coil_nos", bo.getParentCoilNos()); - } else if (bo.getHasMergeSplit() != null && bo.getHasMergeSplit() == 1) { - newStep.put("operation", "分卷"); - newStep.put("new_current_coil_nos", bo.getCurrentCoilNo()); - } else { - newStep.put("operation", "更新"); - } + newStep.put("operation", "更新"); + newStep.put("old_current_coil_no", oldCoil.getCurrentCoilNo()); + newStep.put("new_current_coil_no", bo.getCurrentCoilNo()); + newStep.put("coil_id", String.valueOf(bo.getCoilId())); + newStep.put("operator", LoginHelper.getUsername()); + newStep.put("update_time", new java.util.Date()); steps.add(newStep); contentMap.put("steps", steps); - // 更新当前钢卷号到最外层(方便快速查看) + + // 更新当前钢卷号 contentMap.put("current_coil_no", bo.getCurrentCoilNo()); - - // 更新当前钢卷ID(注意:这里需要获取新插入的钢卷ID,但在这个方法中还没有新ID) - // 所以这个方法只在库区不变化时调用,此时钢卷ID不变 - // contentMap.put("current_coil_id", String.valueOf(bo.getCoilId())); // 保持当前ID不变 + + // current_coil_id保持不变(因为coilId没有变化) // 更新二维码记录 String newContentJson = objectMapper.writeValueAsString(contentMap); WmsGenerateRecordBo updateBo = new WmsGenerateRecordBo(); - updateBo.setRecordId(qrcodeRecordId); + updateBo.setRecordId(oldCoil.getQrcodeRecordId()); updateBo.setContent(newContentJson); generateRecordService.updateByBo(updateBo); } catch (Exception e) {