From d982efc866d9befa33ec1da2799f2558134a7066 Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Thu, 21 May 2026 14:29:14 +0800 Subject: [PATCH 01/40] =?UTF-8?q?feat(wms):=20=E6=96=B0=E5=A2=9E=E9=92=A2?= =?UTF-8?q?=E5=8D=B7=E5=AF=B9=E6=AF=94=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=90=8C=E6=AD=A5=E7=8A=B6=E6=80=81=E7=9B=91?= =?UTF-8?q?=E6=8E=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 SqlServerApiBusinessService 中新增按时间段查询出口卷实绩方法 - 在 SqlServerApiClient 中实现 queryExcoilByTimeRange 数据查询接口 - 在 SqlServerApiController 中添加 /excoil/by-time 时间段查询端点 - 新增 CoilComparisonController 实现钢卷数据对比和匹配状态逻辑 - 创建前端 coilComparison API 接口文件并导出 getExcoilStatus 方法 - 开发钢卷对比页面界面,包含产线切换标签页和时间范围筛选功能 - 实现钢卷加工状态、入库状态和匹配状态的数据展示和标记功能 --- .../framework/client/SqlServerApiClient.java | 15 +++ .../controller/CoilComparisonController.java | 120 ++++++++++++++++++ .../service/SqlServerApiBusinessService.java | 7 + .../sqlserver/SqlServerApiController.java | 11 ++ klp-ui/src/api/wms/coilComparison.js | 9 ++ klp-ui/src/views/wms/coilComparison/index.vue | 94 ++++++++++++++ 6 files changed, 256 insertions(+) create mode 100644 klp-admin/src/main/java/com/klp/framework/controller/CoilComparisonController.java create mode 100644 klp-ui/src/api/wms/coilComparison.js create mode 100644 klp-ui/src/views/wms/coilComparison/index.vue diff --git a/klp-admin/src/main/java/com/klp/framework/client/SqlServerApiClient.java b/klp-admin/src/main/java/com/klp/framework/client/SqlServerApiClient.java index 1bdfd602..405aec7d 100644 --- a/klp-admin/src/main/java/com/klp/framework/client/SqlServerApiClient.java +++ b/klp-admin/src/main/java/com/klp/framework/client/SqlServerApiClient.java @@ -413,6 +413,21 @@ public class SqlServerApiClient { return executeSql("oracle", sql.toString(), params); } + public ExecuteSqlResponse queryExcoilByTimeRange(String startTime, String endTime) { + Map params = new java.util.HashMap<>(); + StringBuilder sql = new StringBuilder("SELECT * FROM JXPLTCM.PLTCM_PDO_EXCOIL WHERE 1=1"); + if (startTime != null && !startTime.trim().isEmpty()) { + sql.append(" AND END_DATE >= TO_DATE(:startTime, 'YYYY-MM-DD HH24:MI:SS')"); + params.put("startTime", startTime.trim()); + } + if (endTime != null && !endTime.trim().isEmpty()) { + sql.append(" AND END_DATE <= TO_DATE(:endTime, 'YYYY-MM-DD HH24:MI:SS')"); + params.put("endTime", endTime.trim()); + } + sql.append(" ORDER BY END_DATE DESC"); + return executeSql("oracle", sql.toString(), params); + } + public ExecuteSqlResponse queryExcoilList(int page, int pageSize) { int endRow = page * pageSize; int startRow = endRow - pageSize; diff --git a/klp-admin/src/main/java/com/klp/framework/controller/CoilComparisonController.java b/klp-admin/src/main/java/com/klp/framework/controller/CoilComparisonController.java new file mode 100644 index 00000000..fb26c9dc --- /dev/null +++ b/klp-admin/src/main/java/com/klp/framework/controller/CoilComparisonController.java @@ -0,0 +1,120 @@ +package com.klp.framework.controller; + +import com.klp.common.core.domain.R; +import com.klp.domain.bo.WmsMaterialCoilBo; +import com.klp.domain.vo.WmsMaterialCoilVo; +import com.klp.framework.service.SqlServerApiBusinessService; +import com.klp.service.IWmsMaterialCoilService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@RequiredArgsConstructor +@RestController +@RequestMapping("/wms/coil-comparison") +public class CoilComparisonController { + + private final SqlServerApiBusinessService sqlServerService; + private final IWmsMaterialCoilService wmsMaterialCoilService; + + @GetMapping("/excoil-status") + public R>> getExcoilStatus( + @RequestParam(required = false) String startTime, + @RequestParam(required = false) String endTime, + @RequestParam(required = false) String lineType) { + + List> excoilRows = sqlServerService.getExcoilByTimeRange(startTime, endTime); + + WmsMaterialCoilBo bo = new WmsMaterialCoilBo(); + bo.setItemType("raw_material"); + bo.setMaterialType("原料"); + bo.setItemName("热轧卷板"); + bo.setSelectType("raw_material"); + List localCoils = wmsMaterialCoilService.queryList(bo); + + Map localMap = new HashMap<>(); + for (WmsMaterialCoilVo coil : localCoils) { + if (coil.getEnterCoilNo() != null) { + localMap.put(coil.getEnterCoilNo(), coil); + } + } + + List> result = new ArrayList<>(); + for (Map excoil : excoilRows) { + String hotCoilId = excoil.get("HOT_COILID") != null ? String.valueOf(excoil.get("HOT_COILID")) : null; + Map item = new LinkedHashMap<>(); + item.put("excoilId", excoil.get("EXCOILID")); + item.put("coilId", excoil.get("COILID")); + item.put("hotCoilId", hotCoilId); + item.put("endDate", excoil.get("END_DATE")); + item.put("startDate", excoil.get("START_DATE")); + item.put("actualThick", excoil.get("ACTUAL_THICK")); + item.put("actualWidth", excoil.get("ACTUAL_WIDTH")); + item.put("actualWeight", excoil.get("ACTUAL_WEIGHT")); + item.put("processCode", excoil.get("PROCESS_CODE")); + + if (hotCoilId != null) { + WmsMaterialCoilVo matched = localMap.get(hotCoilId); + if (matched != null) { + item.put("enterCoilNo", matched.getEnterCoilNo()); + item.put("currentCoilNo", matched.getCurrentCoilNo()); + item.put("supplierCoilNo", matched.getSupplierCoilNo()); + item.put("dataType", matched.getDataType()); + item.put("itemName", matched.getItemName()); + item.put("itemCode", matched.getItemCode()); + item.put("specification", matched.getSpecification()); + item.put("material", matched.getMaterial()); + item.put("manufacturer", matched.getManufacturer()); + item.put("coilStatus", matched.getStatus()); + item.put("warehouseName", matched.getWarehouseName()); + if (matched.getDataType() != null && matched.getDataType() == 0) { + item.put("matchStatus", 0); + item.put("matchStatusDesc", "已加工"); + } else { + item.put("matchStatus", 1); + item.put("matchStatusDesc", "未加工"); + } + } else { + item.put("enterCoilNo", null); + item.put("currentCoilNo", null); + item.put("supplierCoilNo", null); + item.put("dataType", null); + item.put("itemName", null); + item.put("itemCode", null); + item.put("specification", null); + item.put("material", null); + item.put("manufacturer", null); + item.put("coilStatus", null); + item.put("warehouseName", null); + item.put("matchStatus", 2); + item.put("matchStatusDesc", "未入库"); + } + } else { + item.put("enterCoilNo", null); + item.put("currentCoilNo", null); + item.put("supplierCoilNo", null); + item.put("dataType", null); + item.put("itemName", null); + item.put("itemCode", null); + item.put("specification", null); + item.put("material", null); + item.put("manufacturer", null); + item.put("coilStatus", null); + item.put("warehouseName", null); + item.put("matchStatus", 2); + item.put("matchStatusDesc", "未入库"); + } + result.add(item); + } + + return R.ok(result); + } +} diff --git a/klp-admin/src/main/java/com/klp/framework/service/SqlServerApiBusinessService.java b/klp-admin/src/main/java/com/klp/framework/service/SqlServerApiBusinessService.java index 416eb7ce..bf39a5c6 100644 --- a/klp-admin/src/main/java/com/klp/framework/service/SqlServerApiBusinessService.java +++ b/klp-admin/src/main/java/com/klp/framework/service/SqlServerApiBusinessService.java @@ -154,6 +154,13 @@ public class SqlServerApiBusinessService { public List> getExitTrace() { return exitTrace; } } + /** + * 出口卷实绩列表(按时间段),来自 PLTCM_PDO_EXCOIL。 + */ + public List> getExcoilByTimeRange(String startTime, String endTime) { + return asRowList(client.queryExcoilByTimeRange(startTime, endTime)); + } + /** * 出口卷实绩列表(分页),来自 PLTCM_PDO_EXCOIL。 */ diff --git a/klp-admin/src/main/java/com/klp/framework/sqlserver/SqlServerApiController.java b/klp-admin/src/main/java/com/klp/framework/sqlserver/SqlServerApiController.java index 52a2e5e3..b4b972b5 100644 --- a/klp-admin/src/main/java/com/klp/framework/sqlserver/SqlServerApiController.java +++ b/klp-admin/src/main/java/com/klp/framework/sqlserver/SqlServerApiController.java @@ -155,6 +155,17 @@ public class SqlServerApiController { return R.ok(businessService.getRollHistoryList(page, pageSize, rollId, standId)); } + /** + * 出口卷实绩列表(按时间段),来自 PLTCM_PDO_EXCOIL。 + * startTime / endTime 格式:yyyy-MM-dd HH:mm:ss + */ + @GetMapping("/excoil/by-time") + public R>> excoilByTime( + @RequestParam(required = false) String startTime, + @RequestParam(required = false) String endTime) { + return R.ok(businessService.getExcoilByTimeRange(startTime, endTime)); + } + /** * 出口卷实绩列表(分页),来自 PLTCM_PDO_EXCOIL。 */ diff --git a/klp-ui/src/api/wms/coilComparison.js b/klp-ui/src/api/wms/coilComparison.js new file mode 100644 index 00000000..716514d3 --- /dev/null +++ b/klp-ui/src/api/wms/coilComparison.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +export function getExcoilStatus(query) { + return request({ + url: '/wms/coil-comparison/excoil-status', + method: 'get', + params: query + }) +} diff --git a/klp-ui/src/views/wms/coilComparison/index.vue b/klp-ui/src/views/wms/coilComparison/index.vue new file mode 100644 index 00000000..46b1c218 --- /dev/null +++ b/klp-ui/src/views/wms/coilComparison/index.vue @@ -0,0 +1,94 @@ + + + From ddc1caa06512e102ebac8bcfd006dc2a968e7717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= <2178503051@qq.com> Date: Thu, 21 May 2026 15:16:44 +0800 Subject: [PATCH 02/40] =?UTF-8?q?feat(wms):=20=E6=96=B0=E5=A2=9E=E8=B0=83?= =?UTF-8?q?=E6=8B=A8=E6=89=B9=E9=87=8F=E7=A1=AE=E8=AE=A4=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=8C=96=E8=B0=83=E6=8B=A8=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E4=B8=8E=E8=A1=A8=E6=A0=BC=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增批量确认调拨单接口及前端实现 2. 调整调拨单号查询为模糊匹配 3. 新增调拨单号远程搜索功能 4. 优化调拨表格列宽与操作栏展示 5. 新增调拨记录删除功能 6. 新增调拨执行页面do.vue 7. 优化调拨管理页面代码格式 --- klp-ui/src/api/wms/transferOrderItem.js | 15 + klp-ui/src/views/wms/move/batch.vue | 258 +++++++----------- .../wms/move/components/tranferItemTable.vue | 80 +++++- klp-ui/src/views/wms/move/do.vue | 201 ++++++++++++++ klp-ui/src/views/wms/move/record.vue | 29 +- .../impl/WmsTransferOrderServiceImpl.java | 2 +- 6 files changed, 408 insertions(+), 177 deletions(-) create mode 100644 klp-ui/src/views/wms/move/do.vue diff --git a/klp-ui/src/api/wms/transferOrderItem.js b/klp-ui/src/api/wms/transferOrderItem.js index b1c812e7..0ff3a191 100644 --- a/klp-ui/src/api/wms/transferOrderItem.js +++ b/klp-ui/src/api/wms/transferOrderItem.js @@ -126,6 +126,21 @@ export function confirmTransferOrderItem(item) { }) } +/** + * 批量确认调拨 + */ +export function batchConfirmTransferOrderItem(list) { + if (!list || list.length === 0) { + return Promise.reject('参数错误') + } + + return request({ + url: '/wms/transferOrderItem/batchConfirm', + method: 'post', + data: list + }) +} + /** * 取消调拨 */ diff --git a/klp-ui/src/views/wms/move/batch.vue b/klp-ui/src/views/wms/move/batch.vue index 20a87476..3150d790 100644 --- a/klp-ui/src/views/wms/move/batch.vue +++ b/klp-ui/src/views/wms/move/batch.vue @@ -2,26 +2,14 @@
- + - + - @@ -45,42 +33,18 @@ - 新增 + 新增 - 修改 + 修改 - 删除 + 删除 - 导出 + 导出 @@ -96,7 +60,7 @@ - + - + @@ -317,20 +231,34 @@ export default { }); }, handleResolve(row) { - approveTransferOrder(row.orderId, '2').then(response => { + updateTransferOrder({ + ...row, + approveStatus: '2', + }).then(_ => { this.$modal.msgSuccess('审批成功'); this.getList(); - }).finally(() => { - this.loading = false; - }); + }) + // approveTransferOrder(row.orderId, '2').then(response => { + // this.$modal.msgSuccess('审批成功'); + // this.getList(); + // }).finally(() => { + // this.loading = false; + // }); }, handleReject(row) { - approveTransferOrder(row.orderId, '3').then(response => { - this.$modal.msgSuccess('审批成功'); + updateTransferOrder({ + ...row, + approveStatus: '3', + }).then(_ => { + this.$modal.msgSuccess('已驳回调拨单'); this.getList(); - }).finally(() => { - this.loading = false; - }); + }) + // approveTransferOrder(row.orderId, '3').then(response => { + // this.$modal.msgSuccess('已驳回调拨单'); + // this.getList(); + // }).finally(() => { + // this.loading = false; + // }); }, /** 获取审批状态文本 */ getapproveStatusText(status) { @@ -468,7 +396,7 @@ export default { 'coil_supplierCoilNo': '厂家卷号', // 'coil_warehouseName': '逻辑库区', 'coil_netWeight': '净重', - + // 'coil_itemName': '物品名称', // 'coil_materialType': '物料类型', 'coil_qualityStatus': '质量状态', @@ -484,7 +412,7 @@ export default { // 准备导出数据 const exportData = this.transferOrderItems.map(item => { const flatItem = {}; - + // 处理Before和After字段 exportFields.forEach(field => { if (field.startsWith('coil_')) { @@ -494,7 +422,7 @@ export default { flatItem[field] = item[field] !== null && item[field] !== undefined ? item[field] : ''; } }); - + return flatItem; }); @@ -525,7 +453,7 @@ export default { document.body.appendChild(link); link.click(); document.body.removeChild(link); - }, + }, /** 钢卷选择器改变 */ handleCoilChange(coils) { console.log(coils); @@ -550,25 +478,25 @@ export default { this.reset(); }, // 表单重置 - reset() { - this.form = { - orderId: undefined, - transferNo: undefined, - transferName: undefined, - transferStatus: undefined, - transferTime: undefined, - remark: undefined, - delFlag: undefined, - createBy: undefined, - updateBy: undefined, - createTime: undefined, - updateTime: undefined, - approveStatus: '0', - approver: undefined, - approveTime: undefined - }; - this.resetForm("form"); - }, + reset() { + this.form = { + orderId: undefined, + transferNo: undefined, + transferName: undefined, + transferStatus: undefined, + transferTime: undefined, + remark: undefined, + delFlag: undefined, + createBy: undefined, + updateBy: undefined, + createTime: undefined, + updateTime: undefined, + approveStatus: '0', + approver: undefined, + approveTime: undefined + }; + this.resetForm("form"); + }, getDetailList() { this.handleView({ orderId: this.currentOrderId, approveStatus: this.currentOrderStatus }); }, @@ -601,7 +529,7 @@ export default { // 多选框选中数据 handleSelectionChange(selection) { this.ids = selection.map(item => item.orderId) - this.single = selection.length!==1 + this.single = selection.length !== 1 this.multiple = !selection.length }, /** 新增按钮操作 */ @@ -610,18 +538,18 @@ export default { // 生成当前时间 const currentDate = new Date(); // 生成调拨单号:TR + 年月日时分秒 - const transferNo = 'TR' + currentDate.getFullYear() + - String(currentDate.getMonth() + 1).padStart(2, '0') + - String(currentDate.getDate()).padStart(2, '0') + - String(currentDate.getHours()).padStart(2, '0') + - String(currentDate.getMinutes()).padStart(2, '0') + + const transferNo = 'TR' + currentDate.getFullYear() + + String(currentDate.getMonth() + 1).padStart(2, '0') + + String(currentDate.getDate()).padStart(2, '0') + + String(currentDate.getHours()).padStart(2, '0') + + String(currentDate.getMinutes()).padStart(2, '0') + String(currentDate.getSeconds()).padStart(2, '0'); // 生成调拨时间:YYYY-MM-DD HH:mm:ss - const transferTime = currentDate.getFullYear() + '-' + - String(currentDate.getMonth() + 1).padStart(2, '0') + '-' + - String(currentDate.getDate()).padStart(2, '0') + ' ' + - String(currentDate.getHours()).padStart(2, '0') + ':' + - String(currentDate.getMinutes()).padStart(2, '0') + ':' + + const transferTime = currentDate.getFullYear() + '-' + + String(currentDate.getMonth() + 1).padStart(2, '0') + '-' + + String(currentDate.getDate()).padStart(2, '0') + ' ' + + String(currentDate.getHours()).padStart(2, '0') + ':' + + String(currentDate.getMinutes()).padStart(2, '0') + ':' + String(currentDate.getSeconds()).padStart(2, '0'); // 填充表单 this.form.transferNo = transferNo; diff --git a/klp-ui/src/views/wms/move/components/tranferItemTable.vue b/klp-ui/src/views/wms/move/components/tranferItemTable.vue index e18158d8..684e9483 100644 --- a/klp-ui/src/views/wms/move/components/tranferItemTable.vue +++ b/klp-ui/src/views/wms/move/components/tranferItemTable.vue @@ -1,5 +1,6 @@ + + \ No newline at end of file diff --git a/klp-ui/src/views/wms/move/record.vue b/klp-ui/src/views/wms/move/record.vue index bdff37d7..068b2c1d 100644 --- a/klp-ui/src/views/wms/move/record.vue +++ b/klp-ui/src/views/wms/move/record.vue @@ -23,8 +23,16 @@ + + + + + - + @@ -71,6 +79,7 @@ import TransferItemTable from "@/views/wms/move/components/tranferItemTable.vue"; import WarehouseSelect from "@/components/KLPService/WarehouseSelect"; import { listTransferOrderItem } from "@/api/wms/transferOrderItem"; +import { listTransferOrder } from "@/api/wms/transferOrder"; import { listMaterialCoil } from "@/api/wms/coil"; export default { @@ -87,6 +96,7 @@ export default { queryParams: { warehouseIdBefore: '', warehouseIdAfter: '', + transferNo: '', isTransferred: '', pageSize: 20, pageNum: 1, @@ -94,12 +104,27 @@ export default { transferList: [], tracedCoils: [], warehouseList: [], + transferOrderOptions: [], + transferOrderLoading: false, loading: false, total: 0, dialogVisible: false, }; }, methods: { + async remoteSearchTransferOrder(query) { + this.transferOrderLoading = true + try { + const params = { pageSize: 50, pageNum: 1 } + if (query) params.transferNo = query + const res = await listTransferOrder(params) + this.transferOrderOptions = res.rows || [] + } catch (_) { + this.transferOrderOptions = [] + } finally { + this.transferOrderLoading = false + } + }, async handleTraceSearch() { if (!this.traceParams.currentCoilNo && !this.traceParams.enterCoilNo) { this.$message.warning('请输入当前卷号或入库卷号'); @@ -148,7 +173,7 @@ export default { }, }, mounted() { - + this.remoteSearchTransferOrder('') this.handleRegularSearch(); }, }; diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsTransferOrderServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsTransferOrderServiceImpl.java index c0b78438..0e3be7ee 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsTransferOrderServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsTransferOrderServiceImpl.java @@ -77,7 +77,7 @@ public class WmsTransferOrderServiceImpl implements IWmsTransferOrderService { private LambdaQueryWrapper buildQueryWrapper(WmsTransferOrderBo bo) { Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.eq(StringUtils.isNotBlank(bo.getTransferNo()), WmsTransferOrder::getTransferNo, bo.getTransferNo()); + lqw.like(StringUtils.isNotBlank(bo.getTransferNo()), WmsTransferOrder::getTransferNo, bo.getTransferNo()); lqw.like(StringUtils.isNotBlank(bo.getTransferName()), WmsTransferOrder::getTransferName, bo.getTransferName()); lqw.eq(bo.getTransferStatus() != null, WmsTransferOrder::getTransferStatus, bo.getTransferStatus()); lqw.eq(bo.getTransferTime() != null, WmsTransferOrder::getTransferTime, bo.getTransferTime()); From baed852ff4f37c42bf143ccbddac241b23e6b8c6 Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Thu, 21 May 2026 15:26:46 +0800 Subject: [PATCH 03/40] =?UTF-8?q?feat(excoil):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=87=BA=E5=8F=A3=E5=8D=B7=E6=95=B0=E6=8D=AE=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 MesExCoil 实体类定义数据库表结构 - 创建 MesExCoilBo 业务对象用于数据传输 - 实现 IMesExCoilService 接口及 MesExCoilServiceImpl 服务类 - 添加 MesExCoilController 控制器提供 REST API 接口 - 集成 MyBatis Plus 持久层框架实现数据库操作 - 实现出入口厚度、宽度、重量等完整字段映射 - 添加同步 L2 系统出口卷实绩数据功能 - 支持首次全量同步和后续增量同步模式 - 实现数据校验、分页查询、导出等功能 - 配置数据写入时间和同步时间字段处理 --- .../framework/client/SqlServerApiClient.java | 15 + .../service/SqlServerApiBusinessService.java | 7 + .../sqlserver/SqlServerApiController.java | 13 +- .../controller/MesExCoilController.java | 112 +++++++ .../com/klp/mes/excoil/domain/MesExCoil.java | 196 +++++++++++ .../klp/mes/excoil/domain/bo/MesExCoilBo.java | 229 +++++++++++++ .../klp/mes/excoil/domain/vo/MesExCoilVo.java | 272 ++++++++++++++++ .../mes/excoil/mapper/MesExCoilMapper.java | 17 + .../mes/excoil/service/IMesExCoilService.java | 55 ++++ .../service/impl/MesExCoilServiceImpl.java | 303 ++++++++++++++++++ .../mapper/excoil/MesExCoilMapper.xml | 61 ++++ 11 files changed, 1279 insertions(+), 1 deletion(-) create mode 100644 klp-mes/src/main/java/com/klp/mes/excoil/controller/MesExCoilController.java create mode 100644 klp-mes/src/main/java/com/klp/mes/excoil/domain/MesExCoil.java create mode 100644 klp-mes/src/main/java/com/klp/mes/excoil/domain/bo/MesExCoilBo.java create mode 100644 klp-mes/src/main/java/com/klp/mes/excoil/domain/vo/MesExCoilVo.java create mode 100644 klp-mes/src/main/java/com/klp/mes/excoil/mapper/MesExCoilMapper.java create mode 100644 klp-mes/src/main/java/com/klp/mes/excoil/service/IMesExCoilService.java create mode 100644 klp-mes/src/main/java/com/klp/mes/excoil/service/impl/MesExCoilServiceImpl.java create mode 100644 klp-mes/src/main/resources/mapper/excoil/MesExCoilMapper.xml diff --git a/klp-admin/src/main/java/com/klp/framework/client/SqlServerApiClient.java b/klp-admin/src/main/java/com/klp/framework/client/SqlServerApiClient.java index 405aec7d..d817f335 100644 --- a/klp-admin/src/main/java/com/klp/framework/client/SqlServerApiClient.java +++ b/klp-admin/src/main/java/com/klp/framework/client/SqlServerApiClient.java @@ -428,6 +428,21 @@ public class SqlServerApiClient { return executeSql("oracle", sql.toString(), params); } + public ExecuteSqlResponse queryExcoilByInsdateRange(String startTime, String endTime) { + Map params = new java.util.HashMap<>(); + StringBuilder sql = new StringBuilder("SELECT * FROM JXPLTCM.PLTCM_PDO_EXCOIL WHERE 1=1"); + if (startTime != null && !startTime.trim().isEmpty()) { + sql.append(" AND INSDATE > TO_DATE(:startTime, 'YYYY-MM-DD HH24:MI:SS')"); + params.put("startTime", startTime.trim()); + } + if (endTime != null && !endTime.trim().isEmpty()) { + sql.append(" AND INSDATE <= TO_DATE(:endTime, 'YYYY-MM-DD HH24:MI:SS')"); + params.put("endTime", endTime.trim()); + } + sql.append(" ORDER BY INSDATE ASC"); + return executeSql("oracle", sql.toString(), params); + } + public ExecuteSqlResponse queryExcoilList(int page, int pageSize) { int endRow = page * pageSize; int startRow = endRow - pageSize; diff --git a/klp-admin/src/main/java/com/klp/framework/service/SqlServerApiBusinessService.java b/klp-admin/src/main/java/com/klp/framework/service/SqlServerApiBusinessService.java index bf39a5c6..e5845d22 100644 --- a/klp-admin/src/main/java/com/klp/framework/service/SqlServerApiBusinessService.java +++ b/klp-admin/src/main/java/com/klp/framework/service/SqlServerApiBusinessService.java @@ -161,6 +161,13 @@ public class SqlServerApiBusinessService { return asRowList(client.queryExcoilByTimeRange(startTime, endTime)); } + /** + * 出口卷实绩列表(按数据写入时间),用于增量同步。 + */ + public List> getExcoilByInsdateRange(String startTime, String endTime) { + return asRowList(client.queryExcoilByInsdateRange(startTime, endTime)); + } + /** * 出口卷实绩列表(分页),来自 PLTCM_PDO_EXCOIL。 */ diff --git a/klp-admin/src/main/java/com/klp/framework/sqlserver/SqlServerApiController.java b/klp-admin/src/main/java/com/klp/framework/sqlserver/SqlServerApiController.java index b4b972b5..d2a73c6f 100644 --- a/klp-admin/src/main/java/com/klp/framework/sqlserver/SqlServerApiController.java +++ b/klp-admin/src/main/java/com/klp/framework/sqlserver/SqlServerApiController.java @@ -156,7 +156,7 @@ public class SqlServerApiController { } /** - * 出口卷实绩列表(按时间段),来自 PLTCM_PDO_EXCOIL。 + * 出口卷实绩列表(按下线时间),来自 PLTCM_PDO_EXCOIL。 * startTime / endTime 格式:yyyy-MM-dd HH:mm:ss */ @GetMapping("/excoil/by-time") @@ -166,6 +166,17 @@ public class SqlServerApiController { return R.ok(businessService.getExcoilByTimeRange(startTime, endTime)); } + /** + * 出口卷实绩列表(按数据写入时间),用于增量同步。 + * startTime(exclusive)/ endTime(inclusive),格式:yyyy-MM-dd HH:mm:ss + */ + @GetMapping("/excoil/by-insdate") + public R>> excoilByInsdate( + @RequestParam(required = false) String startTime, + @RequestParam(required = false) String endTime) { + return R.ok(businessService.getExcoilByInsdateRange(startTime, endTime)); + } + /** * 出口卷实绩列表(分页),来自 PLTCM_PDO_EXCOIL。 */ diff --git a/klp-mes/src/main/java/com/klp/mes/excoil/controller/MesExCoilController.java b/klp-mes/src/main/java/com/klp/mes/excoil/controller/MesExCoilController.java new file mode 100644 index 00000000..34493f41 --- /dev/null +++ b/klp-mes/src/main/java/com/klp/mes/excoil/controller/MesExCoilController.java @@ -0,0 +1,112 @@ +package com.klp.mes.excoil.controller; + +import java.util.List; +import java.util.Arrays; +import java.util.Map; + +import lombok.RequiredArgsConstructor; +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.*; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.klp.common.annotation.RepeatSubmit; +import com.klp.common.annotation.Log; +import com.klp.common.core.controller.BaseController; +import com.klp.common.core.domain.PageQuery; +import com.klp.common.core.domain.R; +import com.klp.common.core.validate.AddGroup; +import com.klp.common.core.validate.EditGroup; +import com.klp.common.enums.BusinessType; +import com.klp.common.utils.poi.ExcelUtil; +import com.klp.mes.excoil.domain.vo.MesExCoilVo; +import com.klp.mes.excoil.domain.bo.MesExCoilBo; +import com.klp.mes.excoil.service.IMesExCoilService; +import com.klp.common.core.page.TableDataInfo; + +/** + * 出口卷数据同步 + * + * @author klp + * @date 2026-05-21 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/excoil/exCoil") +public class MesExCoilController extends BaseController { + + private final IMesExCoilService iMesExCoilService; + + /** + * 查询出口卷数据同步列表 + */ + @GetMapping("/list") + public TableDataInfo list(MesExCoilBo bo, PageQuery pageQuery) { + return iMesExCoilService.queryPageList(bo, pageQuery); + } + + /** + * 导出出口卷数据同步列表 + */ + @Log(title = "出口卷数据同步", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(MesExCoilBo bo, HttpServletResponse response) { + List list = iMesExCoilService.queryList(bo); + ExcelUtil.exportExcel(list, "出口卷数据同步", MesExCoilVo.class, response); + } + + /** + * 获取出口卷数据同步详细信息 + * + * @param exId 主键 + */ + @GetMapping("/{exId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long exId) { + return R.ok(iMesExCoilService.queryById(exId)); + } + + /** + * 新增出口卷数据同步 + */ + @Log(title = "出口卷数据同步", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody MesExCoilBo bo) { + return toAjax(iMesExCoilService.insertByBo(bo)); + } + + /** + * 修改出口卷数据同步 + */ + @Log(title = "出口卷数据同步", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody MesExCoilBo bo) { + return toAjax(iMesExCoilService.updateByBo(bo)); + } + + /** + * 删除出口卷数据同步 + * + * @param exIds 主键串 + */ + @Log(title = "出口卷数据同步", businessType = BusinessType.DELETE) + @DeleteMapping("/{exIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] exIds) { + return toAjax(iMesExCoilService.deleteWithValidByIds(Arrays.asList(exIds), true)); + } + + /** + * 从 L2 系统同步出口卷实绩数据。 + * 首次全量同步,后续增量同步(以 insdate 为锚点)。 + */ + @Log(title = "出口卷数据同步", businessType = BusinessType.OTHER) + @RepeatSubmit(interval = 300000, message = "同步任务已提交,请勿重复操作") + @PostMapping("/sync") + public R> sync() { + Map result = iMesExCoilService.syncExCoilData(); + return R.ok(result); + } +} diff --git a/klp-mes/src/main/java/com/klp/mes/excoil/domain/MesExCoil.java b/klp-mes/src/main/java/com/klp/mes/excoil/domain/MesExCoil.java new file mode 100644 index 00000000..4a0764ad --- /dev/null +++ b/klp-mes/src/main/java/com/klp/mes/excoil/domain/MesExCoil.java @@ -0,0 +1,196 @@ +package com.klp.mes.excoil.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.klp.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * 出口卷数据同步对象 mes_ex_coil + * + * @author klp + * @date 2026-05-21 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("mes_ex_coil") +public class MesExCoil extends BaseEntity { + + private static final long serialVersionUID=1L; + + /** + * 主键ID + */ + @TableId(value = "ex_id") + private Long exId; + /** + * 出口卷号(唯一标识) + */ + private String excoilid; + /** + * 入口卷号 + */ + private String encoilid; + /** + * 热卷号 + */ + private String hotCoilid; + /** + * 钢种 + */ + private String grade; + /** + * 订单质量 + */ + private String orderQuality; + /** + * 产品类型 + */ + private String productType; + /** + * 状态 + */ + private String status; + /** + * 班次 + */ + private String shift; + /** + * 包装类型 + */ + private String parkType; + /** + * 切边类型 + */ + private String sideTrim; + /** + * 入口厚度 + */ + private BigDecimal entryThick; + /** + * 入口宽度 + */ + private BigDecimal entryWidth; + /** + * 入口重量 + */ + private BigDecimal entryWeight; + /** + * 使用入口重量 + */ + private BigDecimal usedEntryWeight; + /** + * 出口厚度 + */ + private BigDecimal exitThick; + /** + * 出口宽度 + */ + private BigDecimal exitWidth; + /** + * 出口长度 + */ + private BigDecimal exitLength; + /** + * 出口重量 + */ + private BigDecimal exitWeight; + /** + * 计算出口重量 + */ + private BigDecimal calcExitWeight; + /** + * 实测出口重量 + */ + private BigDecimal measExitWeight; + /** + * 出口正偏差 + */ + private BigDecimal exitPosDev; + /** + * 出口负偏差 + */ + private BigDecimal exitNegDev; + /** + * 内径 + */ + private BigDecimal innerDiameter; + /** + * 外径 + */ + private BigDecimal outerDiameter; + /** + * 头部位置 + */ + private BigDecimal headpos; + /** + * 尾部位置 + */ + private BigDecimal tailpos; + /** + * 质量 + */ + private BigDecimal quality; + /** + * 板形质量 + */ + private BigDecimal shapeQuality; + /** + * 机组 + */ + private String crew; + /** + * 报告标志 + */ + private Long reportFlag; + /** + * 子ID + */ + private Long subid; + /** + * 序号 + */ + private Long rn; + /** + * 上线时间 + */ + private Date onlineDate; + /** + * 开始时间 + */ + private Date startDate; + /** + * 结束时间 + */ + private Date endDate; + /** + * 焊接时间 + */ + private Date weldedDate; + /** + * 数据写入时间(来源系统) + */ + private Date insdate; + /** + * 同步时间 + */ + private Date syncTime; + /** + * 同步备注 + */ + private String comments; + /** + * 备注 + */ + private String remark; + /** + * 删除标识 0正常 2删除 + */ + @TableLogic + private Long delFlag; + +} diff --git a/klp-mes/src/main/java/com/klp/mes/excoil/domain/bo/MesExCoilBo.java b/klp-mes/src/main/java/com/klp/mes/excoil/domain/bo/MesExCoilBo.java new file mode 100644 index 00000000..41e8e205 --- /dev/null +++ b/klp-mes/src/main/java/com/klp/mes/excoil/domain/bo/MesExCoilBo.java @@ -0,0 +1,229 @@ +package com.klp.mes.excoil.domain.bo; + +import com.klp.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; +import javax.validation.constraints.*; + +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * 出口卷数据同步业务对象 mes_ex_coil + * + * @author klp + * @date 2026-05-21 + */ + +@Data +@EqualsAndHashCode(callSuper = true) +public class MesExCoilBo extends BaseEntity { + + /** + * 主键ID + */ + private Long exId; + + /** + * 出口卷号(唯一标识) + */ + private String excoilid; + + /** + * 入口卷号 + */ + private String encoilid; + + /** + * 热卷号 + */ + private String hotCoilid; + + /** + * 钢种 + */ + private String grade; + + /** + * 订单质量 + */ + private String orderQuality; + + /** + * 产品类型 + */ + private String productType; + + /** + * 状态 + */ + private String status; + + /** + * 班次 + */ + private String shift; + + /** + * 包装类型 + */ + private String parkType; + + /** + * 切边类型 + */ + private String sideTrim; + + /** + * 入口厚度 + */ + private BigDecimal entryThick; + + /** + * 入口宽度 + */ + private BigDecimal entryWidth; + + /** + * 入口重量 + */ + private BigDecimal entryWeight; + + /** + * 使用入口重量 + */ + private BigDecimal usedEntryWeight; + + /** + * 出口厚度 + */ + private BigDecimal exitThick; + + /** + * 出口宽度 + */ + private BigDecimal exitWidth; + + /** + * 出口长度 + */ + private BigDecimal exitLength; + + /** + * 出口重量 + */ + private BigDecimal exitWeight; + + /** + * 计算出口重量 + */ + private BigDecimal calcExitWeight; + + /** + * 实测出口重量 + */ + private BigDecimal measExitWeight; + + /** + * 出口正偏差 + */ + private BigDecimal exitPosDev; + + /** + * 出口负偏差 + */ + private BigDecimal exitNegDev; + + /** + * 内径 + */ + private BigDecimal innerDiameter; + + /** + * 外径 + */ + private BigDecimal outerDiameter; + + /** + * 头部位置 + */ + private BigDecimal headpos; + + /** + * 尾部位置 + */ + private BigDecimal tailpos; + + /** + * 质量 + */ + private BigDecimal quality; + + /** + * 板形质量 + */ + private BigDecimal shapeQuality; + + /** + * 机组 + */ + private String crew; + + /** + * 报告标志 + */ + private Long reportFlag; + + /** + * 子ID + */ + private Long subid; + + /** + * 序号 + */ + private Long rn; + + /** + * 上线时间 + */ + private Date onlineDate; + + /** + * 开始时间 + */ + private Date startDate; + + /** + * 结束时间 + */ + private Date endDate; + + /** + * 焊接时间 + */ + private Date weldedDate; + + /** + * 数据写入时间(来源系统) + */ + private Date insdate; + + /** + * 同步时间 + */ + private Date syncTime; + + /** + * 同步备注 + */ + private String comments; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/klp-mes/src/main/java/com/klp/mes/excoil/domain/vo/MesExCoilVo.java b/klp-mes/src/main/java/com/klp/mes/excoil/domain/vo/MesExCoilVo.java new file mode 100644 index 00000000..9f8b61c3 --- /dev/null +++ b/klp-mes/src/main/java/com/klp/mes/excoil/domain/vo/MesExCoilVo.java @@ -0,0 +1,272 @@ +package com.klp.mes.excoil.domain.vo; + +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import com.klp.common.annotation.ExcelDictFormat; +import com.klp.common.convert.ExcelDictConvert; +import lombok.Data; + + +/** + * 出口卷数据同步视图对象 mes_ex_coil + * + * @author klp + * @date 2026-05-21 + */ +@Data +@ExcelIgnoreUnannotated +public class MesExCoilVo { + + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty(value = "主键ID") + private Long exId; + + /** + * 出口卷号(唯一标识) + */ + @ExcelProperty(value = "出口卷号(唯一标识)") + private String excoilid; + + /** + * 入口卷号 + */ + @ExcelProperty(value = "入口卷号") + private String encoilid; + + /** + * 热卷号 + */ + @ExcelProperty(value = "热卷号") + private String hotCoilid; + + /** + * 钢种 + */ + @ExcelProperty(value = "钢种") + private String grade; + + /** + * 订单质量 + */ + @ExcelProperty(value = "订单质量") + private String orderQuality; + + /** + * 产品类型 + */ + @ExcelProperty(value = "产品类型") + private String productType; + + /** + * 状态 + */ + @ExcelProperty(value = "状态") + private String status; + + /** + * 班次 + */ + @ExcelProperty(value = "班次") + private String shift; + + /** + * 包装类型 + */ + @ExcelProperty(value = "包装类型") + private String parkType; + + /** + * 切边类型 + */ + @ExcelProperty(value = "切边类型") + private String sideTrim; + + /** + * 入口厚度 + */ + @ExcelProperty(value = "入口厚度") + private BigDecimal entryThick; + + /** + * 入口宽度 + */ + @ExcelProperty(value = "入口宽度") + private BigDecimal entryWidth; + + /** + * 入口重量 + */ + @ExcelProperty(value = "入口重量") + private BigDecimal entryWeight; + + /** + * 使用入口重量 + */ + @ExcelProperty(value = "使用入口重量") + private BigDecimal usedEntryWeight; + + /** + * 出口厚度 + */ + @ExcelProperty(value = "出口厚度") + private BigDecimal exitThick; + + /** + * 出口宽度 + */ + @ExcelProperty(value = "出口宽度") + private BigDecimal exitWidth; + + /** + * 出口长度 + */ + @ExcelProperty(value = "出口长度") + private BigDecimal exitLength; + + /** + * 出口重量 + */ + @ExcelProperty(value = "出口重量") + private BigDecimal exitWeight; + + /** + * 计算出口重量 + */ + @ExcelProperty(value = "计算出口重量") + private BigDecimal calcExitWeight; + + /** + * 实测出口重量 + */ + @ExcelProperty(value = "实测出口重量") + private BigDecimal measExitWeight; + + /** + * 出口正偏差 + */ + @ExcelProperty(value = "出口正偏差") + private BigDecimal exitPosDev; + + /** + * 出口负偏差 + */ + @ExcelProperty(value = "出口负偏差") + private BigDecimal exitNegDev; + + /** + * 内径 + */ + @ExcelProperty(value = "内径") + private BigDecimal innerDiameter; + + /** + * 外径 + */ + @ExcelProperty(value = "外径") + private BigDecimal outerDiameter; + + /** + * 头部位置 + */ + @ExcelProperty(value = "头部位置") + private BigDecimal headpos; + + /** + * 尾部位置 + */ + @ExcelProperty(value = "尾部位置") + private BigDecimal tailpos; + + /** + * 质量 + */ + @ExcelProperty(value = "质量") + private BigDecimal quality; + + /** + * 板形质量 + */ + @ExcelProperty(value = "板形质量") + private BigDecimal shapeQuality; + + /** + * 机组 + */ + @ExcelProperty(value = "机组") + private String crew; + + /** + * 报告标志 + */ + @ExcelProperty(value = "报告标志") + private Long reportFlag; + + /** + * 子ID + */ + @ExcelProperty(value = "子ID") + private Long subid; + + /** + * 序号 + */ + @ExcelProperty(value = "序号") + private Long rn; + + /** + * 上线时间 + */ + @ExcelProperty(value = "上线时间") + private Date onlineDate; + + /** + * 开始时间 + */ + @ExcelProperty(value = "开始时间") + private Date startDate; + + /** + * 结束时间 + */ + @ExcelProperty(value = "结束时间") + private Date endDate; + + /** + * 焊接时间 + */ + @ExcelProperty(value = "焊接时间") + private Date weldedDate; + + /** + * 数据写入时间(来源系统) + */ + @ExcelProperty(value = "数据写入时间(来源系统)") + private Date insdate; + + /** + * 同步时间 + */ + @ExcelProperty(value = "同步时间") + private Date syncTime; + + /** + * 同步备注 + */ + @ExcelProperty(value = "同步备注") + private String comments; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + +} diff --git a/klp-mes/src/main/java/com/klp/mes/excoil/mapper/MesExCoilMapper.java b/klp-mes/src/main/java/com/klp/mes/excoil/mapper/MesExCoilMapper.java new file mode 100644 index 00000000..640ce386 --- /dev/null +++ b/klp-mes/src/main/java/com/klp/mes/excoil/mapper/MesExCoilMapper.java @@ -0,0 +1,17 @@ +package com.klp.mes.excoil.mapper; + +import com.klp.mes.excoil.domain.MesExCoil; +import com.klp.mes.excoil.domain.vo.MesExCoilVo; +import com.klp.common.core.mapper.BaseMapperPlus; +import java.util.Date; + +/** + * 出口卷数据同步Mapper接口 + * + * @author klp + * @date 2026-05-21 + */ +public interface MesExCoilMapper extends BaseMapperPlus { + + Date getMaxInsdate(); +} diff --git a/klp-mes/src/main/java/com/klp/mes/excoil/service/IMesExCoilService.java b/klp-mes/src/main/java/com/klp/mes/excoil/service/IMesExCoilService.java new file mode 100644 index 00000000..348a4736 --- /dev/null +++ b/klp-mes/src/main/java/com/klp/mes/excoil/service/IMesExCoilService.java @@ -0,0 +1,55 @@ +package com.klp.mes.excoil.service; + +import com.klp.mes.excoil.domain.MesExCoil; +import com.klp.mes.excoil.domain.vo.MesExCoilVo; +import com.klp.mes.excoil.domain.bo.MesExCoilBo; +import com.klp.common.core.page.TableDataInfo; +import com.klp.common.core.domain.PageQuery; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 出口卷数据同步Service接口 + * + * @author klp + * @date 2026-05-21 + */ +public interface IMesExCoilService { + + /** + * 查询出口卷数据同步 + */ + MesExCoilVo queryById(Long exId); + + /** + * 查询出口卷数据同步列表 + */ + TableDataInfo queryPageList(MesExCoilBo bo, PageQuery pageQuery); + + /** + * 查询出口卷数据同步列表 + */ + List queryList(MesExCoilBo bo); + + /** + * 新增出口卷数据同步 + */ + Boolean insertByBo(MesExCoilBo bo); + + /** + * 修改出口卷数据同步 + */ + Boolean updateByBo(MesExCoilBo bo); + + /** + * 校验并批量删除出口卷数据同步信息 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 从 L2 系统同步出口卷实绩数据 + */ + Map syncExCoilData(); +} diff --git a/klp-mes/src/main/java/com/klp/mes/excoil/service/impl/MesExCoilServiceImpl.java b/klp-mes/src/main/java/com/klp/mes/excoil/service/impl/MesExCoilServiceImpl.java new file mode 100644 index 00000000..78a15f46 --- /dev/null +++ b/klp-mes/src/main/java/com/klp/mes/excoil/service/impl/MesExCoilServiceImpl.java @@ -0,0 +1,303 @@ +package com.klp.mes.excoil.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.klp.common.core.page.TableDataInfo; +import com.klp.common.core.domain.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.klp.common.utils.StringUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; +import com.klp.mes.excoil.domain.bo.MesExCoilBo; +import com.klp.mes.excoil.domain.vo.MesExCoilVo; +import com.klp.mes.excoil.domain.MesExCoil; +import com.klp.mes.excoil.mapper.MesExCoilMapper; +import com.klp.mes.excoil.service.IMesExCoilService; + +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@RequiredArgsConstructor +@Service +public class MesExCoilServiceImpl implements IMesExCoilService { + + private final MesExCoilMapper baseMapper; + + @Value("${server.port:8080}") + private int serverPort; + + private RestTemplate restTemplate; + + private RestTemplate getRestTemplate() { + if (restTemplate == null) { + SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); + factory.setConnectTimeout(5000); + factory.setReadTimeout(600000); + restTemplate = new RestTemplate(factory); + } + return restTemplate; + } + + private String getInternalApiBaseUrl() { + return "http://127.0.0.1:" + serverPort; + } + + @Override + public MesExCoilVo queryById(Long exId){ + return baseMapper.selectVoById(exId); + } + + @Override + public TableDataInfo queryPageList(MesExCoilBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + @Override + public List queryList(MesExCoilBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(MesExCoilBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(StringUtils.isNotBlank(bo.getExcoilid()), MesExCoil::getExcoilid, bo.getExcoilid()); + lqw.eq(StringUtils.isNotBlank(bo.getEncoilid()), MesExCoil::getEncoilid, bo.getEncoilid()); + lqw.eq(StringUtils.isNotBlank(bo.getHotCoilid()), MesExCoil::getHotCoilid, bo.getHotCoilid()); + lqw.eq(StringUtils.isNotBlank(bo.getGrade()), MesExCoil::getGrade, bo.getGrade()); + lqw.eq(StringUtils.isNotBlank(bo.getOrderQuality()), MesExCoil::getOrderQuality, bo.getOrderQuality()); + lqw.eq(StringUtils.isNotBlank(bo.getProductType()), MesExCoil::getProductType, bo.getProductType()); + lqw.eq(StringUtils.isNotBlank(bo.getStatus()), MesExCoil::getStatus, bo.getStatus()); + lqw.eq(StringUtils.isNotBlank(bo.getShift()), MesExCoil::getShift, bo.getShift()); + lqw.eq(StringUtils.isNotBlank(bo.getParkType()), MesExCoil::getParkType, bo.getParkType()); + lqw.eq(StringUtils.isNotBlank(bo.getSideTrim()), MesExCoil::getSideTrim, bo.getSideTrim()); + lqw.eq(bo.getEntryThick() != null, MesExCoil::getEntryThick, bo.getEntryThick()); + lqw.eq(bo.getEntryWidth() != null, MesExCoil::getEntryWidth, bo.getEntryWidth()); + lqw.eq(bo.getEntryWeight() != null, MesExCoil::getEntryWeight, bo.getEntryWeight()); + lqw.eq(bo.getUsedEntryWeight() != null, MesExCoil::getUsedEntryWeight, bo.getUsedEntryWeight()); + lqw.eq(bo.getExitThick() != null, MesExCoil::getExitThick, bo.getExitThick()); + lqw.eq(bo.getExitWidth() != null, MesExCoil::getExitWidth, bo.getExitWidth()); + lqw.eq(bo.getExitLength() != null, MesExCoil::getExitLength, bo.getExitLength()); + lqw.eq(bo.getExitWeight() != null, MesExCoil::getExitWeight, bo.getExitWeight()); + lqw.eq(bo.getCalcExitWeight() != null, MesExCoil::getCalcExitWeight, bo.getCalcExitWeight()); + lqw.eq(bo.getMeasExitWeight() != null, MesExCoil::getMeasExitWeight, bo.getMeasExitWeight()); + lqw.eq(bo.getExitPosDev() != null, MesExCoil::getExitPosDev, bo.getExitPosDev()); + lqw.eq(bo.getExitNegDev() != null, MesExCoil::getExitNegDev, bo.getExitNegDev()); + lqw.eq(bo.getInnerDiameter() != null, MesExCoil::getInnerDiameter, bo.getInnerDiameter()); + lqw.eq(bo.getOuterDiameter() != null, MesExCoil::getOuterDiameter, bo.getOuterDiameter()); + lqw.eq(bo.getHeadpos() != null, MesExCoil::getHeadpos, bo.getHeadpos()); + lqw.eq(bo.getTailpos() != null, MesExCoil::getTailpos, bo.getTailpos()); + lqw.eq(bo.getQuality() != null, MesExCoil::getQuality, bo.getQuality()); + lqw.eq(bo.getShapeQuality() != null, MesExCoil::getShapeQuality, bo.getShapeQuality()); + lqw.eq(StringUtils.isNotBlank(bo.getCrew()), MesExCoil::getCrew, bo.getCrew()); + lqw.eq(bo.getReportFlag() != null, MesExCoil::getReportFlag, bo.getReportFlag()); + lqw.eq(bo.getSubid() != null, MesExCoil::getSubid, bo.getSubid()); + lqw.eq(bo.getRn() != null, MesExCoil::getRn, bo.getRn()); + lqw.eq(bo.getOnlineDate() != null, MesExCoil::getOnlineDate, bo.getOnlineDate()); + lqw.eq(bo.getStartDate() != null, MesExCoil::getStartDate, bo.getStartDate()); + lqw.eq(bo.getEndDate() != null, MesExCoil::getEndDate, bo.getEndDate()); + lqw.eq(bo.getWeldedDate() != null, MesExCoil::getWeldedDate, bo.getWeldedDate()); + lqw.eq(bo.getInsdate() != null, MesExCoil::getInsdate, bo.getInsdate()); + lqw.eq(bo.getSyncTime() != null, MesExCoil::getSyncTime, bo.getSyncTime()); + lqw.eq(StringUtils.isNotBlank(bo.getComments()), MesExCoil::getComments, bo.getComments()); + return lqw; + } + + @Override + public Boolean insertByBo(MesExCoilBo bo) { + MesExCoil add = BeanUtil.toBean(bo, MesExCoil.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setExId(add.getExId()); + } + return flag; + } + + @Override + public Boolean updateByBo(MesExCoilBo bo) { + MesExCoil update = BeanUtil.toBean(bo, MesExCoil.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + private void validEntityBeforeSave(MesExCoil entity){ + } + + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + } + return baseMapper.deleteBatchIds(ids) > 0; + } + + @Override + public Map syncExCoilData() { + Date maxInsdate = baseMapper.getMaxInsdate(); + boolean isFullSync = (maxInsdate == null); + + List> apiRows; + if (isFullSync) { + apiRows = fetchAllFromApi(); + } else { + apiRows = fetchIncrementalFromApi(maxInsdate); + } + + int insertCount = 0; + int updateCount = 0; + Date now = new Date(); + + for (Map row : apiRows) { + MesExCoil entity = mapRowToEntity(row); + entity.setSyncTime(now); + + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.eq(MesExCoil::getExcoilid, entity.getExcoilid()); + MesExCoil existing = baseMapper.selectOne(wrapper); + + if (existing != null) { + entity.setExId(existing.getExId()); + baseMapper.updateById(entity); + updateCount++; + } else { + baseMapper.insert(entity); + insertCount++; + } + } + + Map result = new HashMap<>(); + result.put("totalFetched", apiRows.size()); + result.put("insertCount", insertCount); + result.put("updateCount", updateCount); + result.put("fullSync", isFullSync); + return result; + } + + @SuppressWarnings("unchecked") + private List> fetchAllFromApi() { + List> all = new ArrayList<>(); + int page = 1; + int pageSize = 500; + String baseUrl = getInternalApiBaseUrl(); + + while (true) { + String url = baseUrl + "/sql-server-api/excoil?page=" + page + "&pageSize=" + pageSize; + Map response = getRestTemplate().getForObject(url, Map.class); + if (response == null) break; + + Map data = (Map) response.get("data"); + if (data == null) break; + + List> rows = (List>) data.get("rows"); + if (rows == null || rows.isEmpty()) break; + + all.addAll(rows); + if (rows.size() < pageSize) break; + page++; + } + return all; + } + + @SuppressWarnings("unchecked") + private List> fetchIncrementalFromApi(Date since) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String startTime = sdf.format(since); + String baseUrl = getInternalApiBaseUrl(); + String url = baseUrl + "/sql-server-api/excoil/by-insdate?startTime=" + startTime; + + Map response = getRestTemplate().getForObject(url, Map.class); + if (response != null && response.get("data") instanceof List) { + return (List>) response.get("data"); + } + return new ArrayList<>(); + } + + private MesExCoil mapRowToEntity(Map row) { + MesExCoil entity = new MesExCoil(); + entity.setExcoilid(str(row.get("excoilid"))); + entity.setEncoilid(str(row.get("encoilid"))); + entity.setHotCoilid(str(row.get("hot_coilid"))); + entity.setGrade(str(row.get("grade"))); + entity.setOrderQuality(str(row.get("order_quality"))); + entity.setProductType(str(row.get("product_type"))); + entity.setStatus(str(row.get("status"))); + entity.setShift(str(row.get("shift"))); + entity.setParkType(str(row.get("park_type"))); + entity.setSideTrim(str(row.get("side_trim"))); + entity.setEntryThick(bd(row.get("entry_thick"))); + entity.setEntryWidth(bd(row.get("entry_width"))); + entity.setEntryWeight(bd(row.get("entry_weight"))); + entity.setUsedEntryWeight(bd(row.get("used_entry_weight"))); + entity.setExitThick(bd(row.get("exit_thick"))); + entity.setExitWidth(bd(row.get("exit_width"))); + entity.setExitLength(bd(row.get("exit_length"))); + entity.setExitWeight(bd(row.get("exit_weight"))); + entity.setCalcExitWeight(bd(row.get("calc_exit_weight"))); + entity.setMeasExitWeight(bd(row.get("meas_exit_weight"))); + entity.setExitPosDev(bd(row.get("exit_pos_dev"))); + entity.setExitNegDev(bd(row.get("exit_neg_dev"))); + entity.setInnerDiameter(bd(row.get("inner_diameter"))); + entity.setOuterDiameter(bd(row.get("outer_diameter"))); + entity.setHeadpos(bd(row.get("headpos"))); + entity.setTailpos(bd(row.get("tailpos"))); + entity.setQuality(bd(row.get("quality"))); + entity.setShapeQuality(bd(row.get("shape_quality"))); + entity.setCrew(str(row.get("crew"))); + entity.setReportFlag(longVal(row.get("report_flag"))); + entity.setSubid(longVal(row.get("subid"))); + entity.setRn(longVal(row.get("rn"))); + entity.setOnlineDate(parseDate(row.get("online_date"))); + entity.setStartDate(parseDate(row.get("start_date"))); + entity.setEndDate(parseDate(row.get("end_date"))); + entity.setWeldedDate(parseDate(row.get("welded_date"))); + entity.setInsdate(parseDate(row.get("insdate"))); + entity.setComments(str(row.get("comments"))); + entity.setRemark(str(row.get("remark"))); + return entity; + } + + private String str(Object value) { + return value == null ? null : String.valueOf(value); + } + + private BigDecimal bd(Object value) { + if (value == null) return null; + if (value instanceof BigDecimal) return (BigDecimal) value; + if (value instanceof Number) return BigDecimal.valueOf(((Number) value).doubleValue()); + try { return new BigDecimal(String.valueOf(value)); } catch (Exception e) { return null; } + } + + private Long longVal(Object value) { + if (value == null) return null; + if (value instanceof Number) return ((Number) value).longValue(); + try { return Long.parseLong(String.valueOf(value)); } catch (Exception e) { return null; } + } + + private Date parseDate(Object value) { + if (value == null) return null; + if (value instanceof Date) return (Date) value; + String s = String.valueOf(value); + if (s.isEmpty() || "null".equals(s)) return null; + try { + if (s.contains("T")) { + s = s.replace("T", " "); + if (s.length() > 19) s = s.substring(0, 19); + } + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(s); + } catch (Exception e) { + return null; + } + } +} diff --git a/klp-mes/src/main/resources/mapper/excoil/MesExCoilMapper.xml b/klp-mes/src/main/resources/mapper/excoil/MesExCoilMapper.xml new file mode 100644 index 00000000..d7abc93e --- /dev/null +++ b/klp-mes/src/main/resources/mapper/excoil/MesExCoilMapper.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From e531ce019d88b9f544b4235f92929ba0b1065305 Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Thu, 21 May 2026 15:35:15 +0800 Subject: [PATCH 04/40] =?UTF-8?q?refactor(mes-excoil):=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E5=A4=96=E9=83=A8=E5=8D=B7=E6=9D=90=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E6=80=A7=E8=83=BD(=E5=8F=AA=E6=8F=92?= =?UTF-8?q?=E5=85=A5=E4=B8=8D=E6=9B=B4=E6=96=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加空数据检查并返回默认结果 - 实现批量数据转换提升处理效率 - 采用批量查询替代逐条查询减少数据库访问 - 分离新增和更新操作支持批量处理 - 实现分批插入和更新避免大数据量问题 - 每批处理500条记录确保系统稳定性 --- .../service/impl/MesExCoilServiceImpl.java | 82 ++++++++++++++++--- 1 file changed, 69 insertions(+), 13 deletions(-) diff --git a/klp-mes/src/main/java/com/klp/mes/excoil/service/impl/MesExCoilServiceImpl.java b/klp-mes/src/main/java/com/klp/mes/excoil/service/impl/MesExCoilServiceImpl.java index 78a15f46..b5363752 100644 --- a/klp-mes/src/main/java/com/klp/mes/excoil/service/impl/MesExCoilServiceImpl.java +++ b/klp-mes/src/main/java/com/klp/mes/excoil/service/impl/MesExCoilServiceImpl.java @@ -155,28 +155,84 @@ public class MesExCoilServiceImpl implements IMesExCoilService { apiRows = fetchIncrementalFromApi(maxInsdate); } + if (apiRows == null || apiRows.isEmpty()) { + Map result = new HashMap<>(); + result.put("totalFetched", 0); + result.put("insertCount", 0); + result.put("updateCount", 0); + result.put("fullSync", isFullSync); + return result; + } + int insertCount = 0; int updateCount = 0; Date now = new Date(); + // 1. 批量转换所有数据 + List allEntities = new ArrayList<>(apiRows.size()); for (Map row : apiRows) { MesExCoil entity = mapRowToEntity(row); entity.setSyncTime(now); - - LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); - wrapper.eq(MesExCoil::getExcoilid, entity.getExcoilid()); - MesExCoil existing = baseMapper.selectOne(wrapper); - - if (existing != null) { - entity.setExId(existing.getExId()); - baseMapper.updateById(entity); - updateCount++; - } else { - baseMapper.insert(entity); - insertCount++; - } + allEntities.add(entity); } +// // 2. 收集所有 excoilid +// List excoilids = allEntities.stream() +// .map(MesExCoil::getExcoilid) +// .filter(StringUtils::isNotBlank) +// .distinct() +// .collect(java.util.stream.Collectors.toList()); + +// // 3. 批量查询已存在的记录 +// Map existingMap = new HashMap<>(); +// if (!excoilids.isEmpty()) { +// LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); +// wrapper.in(MesExCoil::getExcoilid, excoilids); +// List existingList = baseMapper.selectList(wrapper); +// existingMap = existingList.stream() +// .collect(java.util.stream.Collectors.toMap(MesExCoil::getExcoilid, v -> v, (a, b) -> a)); +// } + + // 4. 分离新增和更新的记录 + List toInsert = new ArrayList<>(); +// List toUpdate = new ArrayList<>(); + + for (MesExCoil entity : allEntities) { +// MesExCoil existing = existingMap.get(entity.getExcoilid()); +// if (existing != null) { +// // 更新:设置主键 +// entity.setExId(existing.getExId()); +// toUpdate.add(entity); +// } else { + // 新增 + toInsert.add(entity); +// } + } + + // 5. 批量插入 + if (!toInsert.isEmpty()) { + // 分批插入,每批500条 + int batchSize = 500; + for (int i = 0; i < toInsert.size(); i += batchSize) { + int end = Math.min(i + batchSize, toInsert.size()); + List batch = toInsert.subList(i, end); + baseMapper.insertBatch(batch); + } + insertCount = toInsert.size(); + } + +// // 6. 批量更新 +// if (!toUpdate.isEmpty()) { +// // 分批更新,每批500条 +// int batchSize = 500; +// for (int i = 0; i < toUpdate.size(); i += batchSize) { +// int end = Math.min(i + batchSize, toUpdate.size()); +// List batch = toUpdate.subList(i, end); +// baseMapper.updateBatchById(batch, batch.size()); +// } +// updateCount = toUpdate.size(); +// } + Map result = new HashMap<>(); result.put("totalFetched", apiRows.size()); result.put("insertCount", insertCount); From 67410af985c19b383cf87d13d3026ebd657b4e75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= <2178503051@qq.com> Date: Thu, 21 May 2026 16:35:03 +0800 Subject: [PATCH 05/40] =?UTF-8?q?feat(qc):=20=E6=96=B0=E5=A2=9E=E5=85=A5?= =?UTF-8?q?=E5=9C=BA=E9=92=A2=E5=8D=B7=E5=8F=B7=E5=AD=97=E6=AE=B5=E5=B9=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=B4=A8=E6=A3=80=E7=9B=B8=E5=85=B3=E6=B5=81?= =?UTF-8?q?=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 在质检任务相关BO、VO、实体类中新增enterCoilNos字段 2. 调整检验任务查询逻辑,支持按入场钢卷号筛选 3. 优化钢卷相关页面的字段展示和表单校验 4. 简化理化导入流程,移除钢卷匹配步骤 --- .../klp/mes/qc/domain/QcInspectionTask.java | 4 + .../mes/qc/domain/bo/QcInspectionTaskBo.java | 5 +- .../mes/qc/domain/vo/QcInspectionTaskVo.java | 5 + .../impl/QcInspectionTaskServiceImpl.java | 1 + .../mapper/qc/QcInspectionTaskMapper.xml | 1 + .../KLPService/SchemeSelect/index.vue | 12 +- .../views/mes/qc/certificate/chemistry.vue | 208 +++--------------- klp-ui/src/views/mes/qc/certificate/item.vue | 13 +- .../src/views/mes/qc/certificate/physics.vue | 204 +++-------------- klp-ui/src/views/mes/qc/inspection/task.vue | 26 ++- klp-ui/src/views/wms/coil/info.vue | 2 +- 11 files changed, 112 insertions(+), 369 deletions(-) diff --git a/klp-mes/src/main/java/com/klp/mes/qc/domain/QcInspectionTask.java b/klp-mes/src/main/java/com/klp/mes/qc/domain/QcInspectionTask.java index 5464c0ab..3f4d1092 100644 --- a/klp-mes/src/main/java/com/klp/mes/qc/domain/QcInspectionTask.java +++ b/klp-mes/src/main/java/com/klp/mes/qc/domain/QcInspectionTask.java @@ -86,6 +86,10 @@ public class QcInspectionTask extends BaseEntity { * 钢卷ID集合,多个使用英文逗号分隔 */ private String coilIds; + /** + * 钢卷号集合 + */ + private String enterCoilNos; /** * 删除标志(0=正常,1=已删除) */ diff --git a/klp-mes/src/main/java/com/klp/mes/qc/domain/bo/QcInspectionTaskBo.java b/klp-mes/src/main/java/com/klp/mes/qc/domain/bo/QcInspectionTaskBo.java index ac092ea1..cb8a45e2 100644 --- a/klp-mes/src/main/java/com/klp/mes/qc/domain/bo/QcInspectionTaskBo.java +++ b/klp-mes/src/main/java/com/klp/mes/qc/domain/bo/QcInspectionTaskBo.java @@ -99,5 +99,8 @@ public class QcInspectionTaskBo extends BaseEntity { */ private String coilIds; - + /** + * 钢卷号集合 + */ + private String enterCoilNos; } diff --git a/klp-mes/src/main/java/com/klp/mes/qc/domain/vo/QcInspectionTaskVo.java b/klp-mes/src/main/java/com/klp/mes/qc/domain/vo/QcInspectionTaskVo.java index 9ef1cd0e..898d2876 100644 --- a/klp-mes/src/main/java/com/klp/mes/qc/domain/vo/QcInspectionTaskVo.java +++ b/klp-mes/src/main/java/com/klp/mes/qc/domain/vo/QcInspectionTaskVo.java @@ -124,6 +124,11 @@ public class QcInspectionTaskVo { */ private String coilIds; + /** + * 钢卷号集合 + */ + private String enterCoilNos; + private List coilList; diff --git a/klp-mes/src/main/java/com/klp/mes/qc/service/impl/QcInspectionTaskServiceImpl.java b/klp-mes/src/main/java/com/klp/mes/qc/service/impl/QcInspectionTaskServiceImpl.java index c0aec3cb..71e0b94c 100644 --- a/klp-mes/src/main/java/com/klp/mes/qc/service/impl/QcInspectionTaskServiceImpl.java +++ b/klp-mes/src/main/java/com/klp/mes/qc/service/impl/QcInspectionTaskServiceImpl.java @@ -135,6 +135,7 @@ public class QcInspectionTaskServiceImpl implements IQcInspectionTaskService { lqw.eq(bo.getAuditTime() != null, QcInspectionTask::getAuditTime, bo.getAuditTime()); lqw.eq(StringUtils.isNotBlank(bo.getResult()), QcInspectionTask::getResult, bo.getResult()); lqw.like(StringUtils.isNotBlank(bo.getCoilIds()), QcInspectionTask::getCoilIds, bo.getCoilIds()); + lqw.like(StringUtils.isNotBlank(bo.getEnterCoilNos()), QcInspectionTask::getEnterCoilNos, bo.getEnterCoilNos()); return lqw; } diff --git a/klp-mes/src/main/resources/mapper/qc/QcInspectionTaskMapper.xml b/klp-mes/src/main/resources/mapper/qc/QcInspectionTaskMapper.xml index 860ab064..4c09a356 100644 --- a/klp-mes/src/main/resources/mapper/qc/QcInspectionTaskMapper.xml +++ b/klp-mes/src/main/resources/mapper/qc/QcInspectionTaskMapper.xml @@ -21,6 +21,7 @@ + diff --git a/klp-ui/src/components/KLPService/SchemeSelect/index.vue b/klp-ui/src/components/KLPService/SchemeSelect/index.vue index 57cf7838..b9c697c0 100644 --- a/klp-ui/src/components/KLPService/SchemeSelect/index.vue +++ b/klp-ui/src/components/KLPService/SchemeSelect/index.vue @@ -72,7 +72,12 @@ -
+ + + + + +
@@ -245,20 +246,22 @@ import { listDeliveryWaybillDetail } from "@/api/wms/deliveryWaybillDetail"; import { listOrder } from "@/api/crm/order"; import MemoInput from "@/components/MemoInput"; import DeliveryWaybillDetail from "../components/detailTable.vue"; -import WayBill from "../components/wayBill.vue"; +// import WayBill from "../components/wayBill.vue"; import PlanList from "../components/planList.vue"; -import WayBill2 from "../components/wayBill2.vue"; +// import WayBill2 from "../components/wayBill2.vue"; import PlanSelector from "../components/planSelector.vue"; import DragResizePanel from "@/components/DragResizePanel"; +import WayBillPrinter from "../components/WayBillPrinter.vue"; export default { name: "Exp-Waybill", components: { MemoInput, DeliveryWaybillDetail, - WayBill, + WayBillPrinter, + // WayBill, PlanList, - WayBill2, + // WayBill2, PlanSelector, DragResizePanel }, @@ -693,9 +696,14 @@ export default { }; this.currentWaybillDetails = this.currentWaybillDetails.map(item => { const actualWarehouseName = response.rows.find(detail => detail.coilId === item.coilId)?.actualWarehouseName || ''; + const zincLayer = response.rows.find(detail => detail.coilId === item.coilId)?.zincLayer || ''; + const temperGrade = response.rows.find(detail => detail.coilId === item.coilId)?.temperGrade || ''; + console.log(zincLayer, temperGrade, actualWahouseNames); return { ...item, actualWarehouseName: actualWarehouseName, + zincLayer: zincLayer || '', + temperGrade: temperGrade || '', }; }); }); From fe5188e8fc6d644b273c95076898781bfb2a20af Mon Sep 17 00:00:00 2001 From: jhd <1684074631@qq.com> Date: Fri, 22 May 2026 12:08:28 +0800 Subject: [PATCH 17/40] =?UTF-8?q?=E5=A4=9A=E9=80=89=E6=A1=86=E5=8F=B3?= =?UTF-8?q?=E4=BE=A7=E6=98=BE=E7=A4=BAbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/EmployeeSelector/index.vue | 94 +++++++++++-------- 1 file changed, 54 insertions(+), 40 deletions(-) diff --git a/klp-ui/src/components/EmployeeSelector/index.vue b/klp-ui/src/components/EmployeeSelector/index.vue index 999a879d..fa781335 100644 --- a/klp-ui/src/components/EmployeeSelector/index.vue +++ b/klp-ui/src/components/EmployeeSelector/index.vue @@ -220,25 +220,25 @@ export default { availableList() { const duplicates = this.duplicateNames return this.rawEmployeeList.map(employee => { - // 直接使用 infoId 作为唯一标识 - const employeeId = employee.infoId + // 使用 keyField 作为唯一标识 + const employeeId = employee[this.keyField] const idStr = String(employeeId) return { ...employee, disabled: this.disabledIdList.includes(idStr), isDuplicate: duplicates.includes(employee.name || ''), - isSelected: this.selectedIds.some(id => String(id) === idStr) + isSelected: this.selectedIds.includes(idStr) } }) }, // 已选列表 selectedList() { const duplicates = this.duplicateNames - // 使用 infoId 作为唯一标识,支持同名不同ID的员工 + // 使用 keyField 作为唯一标识,支持同名不同ID的员工 return this.selectedIds .map(id => { const idStr = String(id) - const matched = this.rawEmployeeList.filter(item => String(item.infoId) === idStr) + const matched = this.rawEmployeeList.filter(item => String(item[this.keyField]) === idStr) const employee = matched.length > 0 ? matched[0] : null if (employee) { // 创建新对象,避免修改原始数据 @@ -281,12 +281,11 @@ export default { handler(newVal) { if (this.multiple) { if (newVal) { - // 处理重名问题:确保ID是唯一标识,转换为正确类型 + // 统一使用字符串类型的ID this.selectedIds = newVal.split(',').map(id => { const trimmedId = id.trim() if (!trimmedId) return null - const numId = Number(trimmedId) - return isNaN(numId) ? trimmedId : numId + return String(trimmedId) }).filter(id => id !== null) } else { this.selectedIds = [] @@ -306,12 +305,37 @@ export default { methods: { toggleDialog() { if (!this.open) { - // 打开时清空选中状态 + // 清空临时勾选状态 this.leftSelectedKeys = [] this.rightSelectedKeys = [] - this.getEmployeeList() + + if (this.rawEmployeeList.length > 0) { + // 如果列表已加载,直接恢复选中状态 + this.restoreSelectedIds() + this.open = true + } else { + // 如果列表未加载,先加载再恢复 + this.getEmployeeList().then(() => { + this.restoreSelectedIds() + this.open = true + }) + } + } else { + this.open = false + } + }, + + // 恢复选中状态 + restoreSelectedIds() { + if (this.multiple && this.value) { + this.selectedIds = this.value.split(',').map(id => { + const trimmedId = id.trim() + if (!trimmedId) return null + return String(trimmedId) + }).filter(id => id !== null) + } else { + this.selectedIds = [] } - this.open = !this.open }, getEmployeeList() { @@ -335,11 +359,6 @@ export default { }) }) }, - // 判断员工是否已离职 - isEmployeeResigned(employee) { - // 支持多种可能的离职状态字段 - return employee.status === 1 || employee.isLeave === true || employee.resignStatus === 1 || employee.leaveStatus === 1 - }, handleSearch() { }, @@ -399,18 +418,18 @@ export default { // 判断左侧是否选中 isLeftSelected(item) { - return this.leftSelectedKeys.includes(item.infoId) + return this.leftSelectedKeys.includes(String(item[this.keyField])) }, // 判断右侧是否选中 isRightSelected(item) { - return this.rightSelectedKeys.includes(item.infoId) + return this.rightSelectedKeys.includes(String(item[this.keyField])) }, // 切换左侧选中状态 toggleItem(item) { if (item.disabled) return - const key = item.infoId + const key = String(item[this.keyField]) const index = this.leftSelectedKeys.indexOf(key) if (index > -1) { this.leftSelectedKeys.splice(index, 1) @@ -421,7 +440,7 @@ export default { // 切换右侧选中状态 toggleSelectedItem(item) { - const key = item.infoId + const key = String(item[this.keyField]) const index = this.rightSelectedKeys.indexOf(key) if (index > -1) { this.rightSelectedKeys.splice(index, 1) @@ -433,25 +452,20 @@ export default { // 添加单个到已选 addToSelected(item) { if (item.disabled) return - // 直接使用 infoId 作为唯一标识 - const key = item.infoId - const keyStr = String(key) - // 检查是否已存在(字符串比较) - const exists = this.selectedIds.some(id => String(id) === keyStr) + // 统一使用字符串类型的ID + const key = String(item[this.keyField]) + // 检查是否已存在 + const exists = this.selectedIds.includes(key) if (!exists) { this.selectedIds.push(key) - console.log('添加员工:', item.name, 'ID:', key, 'selectedIds:', this.selectedIds) - } else { - console.log('员工已存在:', item.name, 'ID:', key) } }, // 从已选移除单个 removeFromSelected(item) { - // 直接使用 infoId 作为唯一标识 - const key = item.infoId - const keyStr = String(key) - const index = this.selectedIds.findIndex(id => String(id) === keyStr) + // 统一使用字符串类型的ID + const key = String(item[this.keyField]) + const index = this.selectedIds.indexOf(key) if (index > -1) { this.selectedIds.splice(index, 1) } @@ -461,8 +475,8 @@ export default { addSelected() { this.leftSelectedKeys.forEach(key => { const keyStr = String(key) - if (!this.selectedIds.some(id => String(id) === keyStr)) { - this.selectedIds.push(key) + if (!this.selectedIds.includes(keyStr)) { + this.selectedIds.push(keyStr) } }) this.leftSelectedKeys = [] @@ -472,7 +486,7 @@ export default { removeSelected() { this.rightSelectedKeys.forEach(key => { const keyStr = String(key) - const index = this.selectedIds.findIndex(id => String(id) === keyStr) + const index = this.selectedIds.indexOf(keyStr) if (index > -1) { this.selectedIds.splice(index, 1) } @@ -484,9 +498,9 @@ export default { addAll() { this.availableList.forEach(item => { if (!item.disabled && !item.isSelected) { - const keyStr = String(item.infoId) - if (!this.selectedIds.some(id => String(id) === keyStr)) { - this.selectedIds.push(item.infoId) + const keyStr = String(item[this.keyField]) + if (!this.selectedIds.includes(keyStr)) { + this.selectedIds.push(keyStr) } } }) @@ -511,11 +525,11 @@ export default { cancelSelection() { if (this.multiple) { if (this.value) { + // 统一使用字符串类型 this.selectedIds = this.value.split(',').map(id => { const trimmedId = id.trim() if (!trimmedId) return null - const numId = Number(trimmedId) - return isNaN(numId) ? trimmedId : numId + return String(trimmedId) }).filter(id => id !== null) } else { this.selectedIds = [] From 903c354addb6e8f00de55564c577cbbf69044ad9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= <2178503051@qq.com> Date: Fri, 22 May 2026 13:02:53 +0800 Subject: [PATCH 18/40] =?UTF-8?q?feat(wms):=20=E6=96=B0=E5=A2=9E=E5=BA=94?= =?UTF-8?q?=E6=94=B6=E8=B4=A7=E7=89=A9=E8=AE=A1=E5=88=92=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=92=8C=E6=B8=85=E7=A9=BA=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=8C=96=E8=A1=A8=E6=A0=BC=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 后端添加批量删除应收计划接口 2. 前端新增批量删除、清空按钮和多选功能 3. 优化表格高度和字段文案,调整分页查询大小 --- klp-ui/src/api/wms/receivePlan.js | 11 ++++ klp-ui/src/views/wms/receive/plan/index.vue | 65 +++++++++++++++++-- .../controller/WmsReceivePlanController.java | 10 +++ 3 files changed, 80 insertions(+), 6 deletions(-) diff --git a/klp-ui/src/api/wms/receivePlan.js b/klp-ui/src/api/wms/receivePlan.js index 48ca3419..6670214f 100644 --- a/klp-ui/src/api/wms/receivePlan.js +++ b/klp-ui/src/api/wms/receivePlan.js @@ -51,3 +51,14 @@ export function checkReceivePlan(data) { data: data }) } + +/** + * 大批量删除应收货物计划明细 + */ +export function delReceivePlanBatch(receiveIdList) { + return request({ + url: '/wms/receivePlan/batchDelete', + method: 'delete', + data: receiveIdList || [] + }) +} diff --git a/klp-ui/src/views/wms/receive/plan/index.vue b/klp-ui/src/views/wms/receive/plan/index.vue index 74da08af..e6125d10 100644 --- a/klp-ui/src/views/wms/receive/plan/index.vue +++ b/klp-ui/src/views/wms/receive/plan/index.vue @@ -101,8 +101,20 @@ 新增 + + 批量删除 + + + 清空 + + + 刷新 + - + @@ -145,7 +157,7 @@ :limit.sync="detailQueryParams.pageSize" @pagination="getDetailList" /> - + @@ -153,7 +165,7 @@ - + @@ -389,7 +401,7 @@ From b14f4f69c783e14820f57996ec5b95df009a65f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= <2178503051@qq.com> Date: Fri, 22 May 2026 14:26:07 +0800 Subject: [PATCH 21/40] =?UTF-8?q?fix(grind):=20=E4=BF=AE=E6=AD=A3=E7=A3=A8?= =?UTF-8?q?=E5=89=8A=E6=AC=A1=E6=95=B0=E6=98=BE=E7=A4=BA=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E4=B8=BA=E8=A1=A8=E6=A0=BC=E6=95=B0=E6=8D=AE=E9=95=BF=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- klp-ui/src/views/mes/roll/grind/index.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/klp-ui/src/views/mes/roll/grind/index.vue b/klp-ui/src/views/mes/roll/grind/index.vue index 7a952ec0..2d76adcc 100644 --- a/klp-ui/src/views/mes/roll/grind/index.vue +++ b/klp-ui/src/views/mes/roll/grind/index.vue @@ -70,7 +70,7 @@
初始辊径{{ selectedRoll.initialDia != null ? selectedRoll.initialDia + ' mm' : '—' }}
当前辊径{{ selectedRoll.currentDia != null ? selectedRoll.currentDia + ' mm' : '—' }}
最小辊径{{ selectedRoll.minDia != null ? selectedRoll.minDia + ' mm' : '—' }}
-
磨削次数{{ selectedRoll.grindCount != null ? selectedRoll.grindCount + ' 次' : '0 次' }}
+
磨削次数{{ tableData.length ? tableData.length + ' 次' : '0 次' }}
粗糙度{{ selectedRoll.roughness != null ? selectedRoll.roughness + ' μm' : '—' }}
凸度{{ selectedRoll.crown != null ? selectedRoll.crown + ' mm' : '—' }}
状态 From 7b2881c45fa07ce4d9dddaed69b1d06941f352a4 Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Fri, 22 May 2026 14:56:10 +0800 Subject: [PATCH 22/40] =?UTF-8?q?refactor(eqp):=20=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E9=99=84=E5=B8=A6=E5=B7=A1=E6=A3=80=E9=83=A8?= =?UTF-8?q?=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mes/eqp/service/impl/EqpEquipmentPartServiceImpl.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/klp-mes/src/main/java/com/klp/mes/eqp/service/impl/EqpEquipmentPartServiceImpl.java b/klp-mes/src/main/java/com/klp/mes/eqp/service/impl/EqpEquipmentPartServiceImpl.java index b79232aa..c04f4a49 100644 --- a/klp-mes/src/main/java/com/klp/mes/eqp/service/impl/EqpEquipmentPartServiceImpl.java +++ b/klp-mes/src/main/java/com/klp/mes/eqp/service/impl/EqpEquipmentPartServiceImpl.java @@ -59,9 +59,11 @@ public class EqpEquipmentPartServiceImpl implements IEqpEquipmentPartService { List checklistList = checklistMapper.selectVoList(checklistLqw); Map> checklistMap = checklistList.stream() .collect(Collectors.groupingBy(EqpEquipmentChecklistVo::getPartId)); - result.getRecords().forEach(vo -> - vo.setChecklistList(checklistMap.getOrDefault(vo.getPartId(), Collections.emptyList())) - ); + result.getRecords().forEach(vo -> { + List items = checklistMap.getOrDefault(vo.getPartId(), Collections.emptyList()); + items.forEach(checklist -> checklist.setPartName(vo.getInspectPart())); + vo.setChecklistList(items); + }); } return TableDataInfo.build(result); } From 0a286023c77afa016ce91afb4c7e853148099c22 Mon Sep 17 00:00:00 2001 From: jhd <1684074631@qq.com> Date: Fri, 22 May 2026 15:28:48 +0800 Subject: [PATCH 23/40] =?UTF-8?q?=E6=8E=92=E7=8F=AD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- klp-ui/src/views/wms/hrm/attendance/drag.vue | 499 +++++++++++++++---- 1 file changed, 392 insertions(+), 107 deletions(-) diff --git a/klp-ui/src/views/wms/hrm/attendance/drag.vue b/klp-ui/src/views/wms/hrm/attendance/drag.vue index 01d5ceaf..40b1981f 100644 --- a/klp-ui/src/views/wms/hrm/attendance/drag.vue +++ b/klp-ui/src/views/wms/hrm/attendance/drag.vue @@ -53,45 +53,112 @@
- - - - - - - - - -
-
-
- - {{ item.employeeName || '员工' + (index + 1) }} -
- + +
+ + + + + +
+
+
+ 班次 {{ index + 1 }} + 添加班次 + 删除 +
+
+ + + + + {{ getShiftTime(item.shiftId) }} + + + + +
+
+
+
+
+ + +
+
+
+ {{ getShiftName(item.shiftId) || '未选择班次' }} + + 已分配 {{ item.employeeIds ? item.employeeIds.split(',').filter(id => id.trim()).length : 0 }} 人 + + 复制
- - + +
+
+ + 按部门自动分配 + +
+
+ + +
+ + + + + +
+ 共 {{ totalEmployeeCount }} 名员工,{{ totalScheduleCount }} 条排班记录 +
+
+ + @@ -152,11 +219,12 @@ export default { shiftRuleList: [], dialogVisible: false, editDialogVisible: false, - scheduleMode: 'single', // single: 普通排班, rotate: 倒班排班 + currentStep: 1, // 步骤:1-选择班次,2-分配人员,3-确认 form: { dateRange: [], - selectedEmployees: '', - shiftConfig: [] + shiftList: [ + { shiftId: '', ruleId: '', employeeIds: '' } + ] }, editForm: { shiftId: '' @@ -174,21 +242,52 @@ export default { } }, computed: { - canSubmit() { - if (!this.form.dateRange || this.form.dateRange.length === 0) { - return false - } - if (!this.form.selectedEmployees) { - return false - } - if (this.form.shiftConfig.length === 0) { - return false - } - if (this.scheduleMode === 'single') { - return this.form.shiftConfig.every(item => item.shiftId) - } else { - return this.form.shiftConfig.every(item => item.shiftRuleId) + // 检查是否可以进入下一步 + canProceed() { + if (this.currentStep === 1) { + // 步骤1:必须选择时间段和至少一个有效班次 + if (!this.form.dateRange || this.form.dateRange.length === 0) return false + return this.form.shiftList.some(item => item.shiftId) + } else if (this.currentStep === 2) { + // 步骤2:至少有一个班次分配了人员 + return this.form.shiftList.some(item => item.employeeIds && item.employeeIds.trim()) } + return true + }, + + // 预览数据 + previewData() { + return this.form.shiftList + .filter(item => item.shiftId && item.employeeIds) + .map(item => ({ + shiftName: this.getShiftName(item.shiftId), + employeeNames: this.getEmployeeNames(item.employeeIds), + count: item.employeeIds.split(',').filter(id => id.trim()).length + })) + }, + + // 总员工数 + totalEmployeeCount() { + const allIds = new Set() + this.form.shiftList.forEach(item => { + if (item.employeeIds) { + item.employeeIds.split(',').forEach(id => { + if (id.trim()) allIds.add(id.trim()) + }) + } + }) + return allIds.size + }, + + // 总排班记录数 + totalScheduleCount() { + let count = 0 + this.form.shiftList.forEach(item => { + if (item.employeeIds) { + count += item.employeeIds.split(',').filter(id => id.trim()).length + } + }) + return count }, currentShift() { if (!this.editForm.shiftId) { @@ -529,74 +628,113 @@ export default { // 重置表单 reset() { - this.scheduleMode = 'single' + this.currentStep = 1 this.form = { dateRange: [], - selectedEmployees: '', - shiftConfig: [] + shiftList: [ + { shiftId: '', ruleId: '', employeeIds: '' } + ] } - this.resetForm('form') - }, - - // 员工选择变化时自动生成配置项 - handleEmployeeSelect(employees) { - if (!employees || employees.length === 0) { - this.form.shiftConfig = [] - return - } - - // 为每个选中的员工生成配置项 - if (this.scheduleMode === 'single') { - this.form.shiftConfig = employees.map(employee => ({ - employeeId: employee.infoId, - employeeName: employee.name, - shiftId: null - })) - } else { - this.form.shiftConfig = employees.map(employee => ({ - employeeId: employee.infoId, - employeeName: employee.name, - shiftRuleId: null - })) + if (this.$refs['form']) { + this.$refs['form'].resetFields() } }, - // 排班模式切换 - handleScheduleModeChange() { - // 模式切换时重新生成配置项 - if (this.form.selectedEmployees && this.form.selectedEmployees.length > 0) { - this.handleEmployeeSelect(this.form.selectedEmployees) + // 添加班次配置项 + addShiftItem() { + this.form.shiftList.push({ shiftId: '', ruleId: '', employeeIds: '' }) + }, + + // 移除班次配置项 + removeShiftItem(index) { + this.form.shiftList.splice(index, 1) + }, + + // 复制班次配置(不复制人员) + copyShiftItem(index) { + const source = this.form.shiftList[index] + this.form.shiftList.push({ + shiftId: source.shiftId, + ruleId: source.ruleId, + employeeIds: '' + }) + }, + + // 获取排除的员工ID(避免重复分配) + getExcludedIds(currentIndex) { + const excluded = [] + this.form.shiftList.forEach((item, index) => { + if (index !== currentIndex && item.employeeIds) { + excluded.push(...item.employeeIds.split(',')) + } + }) + return excluded.join(',').trim() + }, + + // 获取班次名称 + getShiftName(shiftId) { + const shift = this.shiftList.find(s => s.shiftId === shiftId) + return shift ? shift.shiftName : '未知班次' + }, + + // 获取员工姓名(临时实现,实际应从API获取) + getEmployeeNames(employeeIds) { + if (!employeeIds) return '未分配' + return employeeIds.split(',').filter(id => id.trim()).length + ' 名员工' + }, + + // 下一步 + nextStep() { + if (this.currentStep < 3) { + this.currentStep++ } }, + // 上一步 + prevStep() { + if (this.currentStep > 1) { + this.currentStep-- + } + }, + + // 按部门自动分配 + quickAssignByDepartment() { + this.$message.info('按部门自动分配功能开发中...') + // 实际实现时可以调用API获取部门员工列表并分配 + }, + // 提交表单 submitForm() { - this.$refs['form'].validate(valid => { - if (valid) { - this.loading = true; - this.buttonLoading = true; - // 构建提交数据 - const list = [] - for (const item of this.form.shiftConfig) { - const payload = { - userId: item.employeeId, - shiftId: item.shiftId, - ruleId: item.shiftRuleId, - startDate: this.dateRangeParams.scheduleDateStart.split(' ')[0], - endDate: this.dateRangeParams.scheduleDateEnd.split(' ')[0] - } - list.push(payload) - } + this.buttonLoading = true - // 调用API - generateenerateSchedule(list).then(response => { - this.$modal.msgSuccess('生成成功') - this.dialogVisible = false - this.loading = false; - this.buttonLoading = false; - this.getScheduleList() + // 构建提交数据 + const list = [] + const startDate = this.form.dateRange[0] + const endDate = this.form.dateRange[1] + + this.form.shiftList.forEach(shiftItem => { + if (!shiftItem.shiftId || !shiftItem.employeeIds) return + + const employeeIds = shiftItem.employeeIds.split(',').filter(id => id.trim()) + employeeIds.forEach(employeeId => { + list.push({ + userId: employeeId, + shiftId: shiftItem.shiftId, + ruleId: shiftItem.ruleId, + startDate: startDate, + endDate: endDate }) - } + }) + }) + + // 调用API + generateenerateSchedule(list).then(response => { + this.$modal.msgSuccess('生成成功') + this.dialogVisible = false + this.buttonLoading = false + this.getScheduleList() + }).catch(() => { + this.buttonLoading = false }) }, @@ -716,4 +854,151 @@ export default { font-size: 12px; color: #606266; } + +/* ===== 优化后的排班弹窗样式 ===== */ + +/* 步骤指示器 */ +.steps { + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 24px; + padding-bottom: 20px; + border-bottom: 1px solid #e4e7ed; +} + +.step { + display: flex; + flex-direction: column; + align-items: center; + min-width: 80px; +} + +.step-number { + width: 32px; + height: 32px; + line-height: 32px; + border-radius: 50%; + background-color: #e4e7ed; + color: #909399; + font-size: 14px; + font-weight: bold; + text-align: center; + transition: all 0.3s; +} + +.step.active .step-number { + background-color: #409eff; + color: #fff; +} + +.step.done .step-number { + background-color: #67c23a; + color: #fff; +} + +.step-text { + margin-top: 8px; + font-size: 13px; + color: #909399; +} + +.step.active .step-text, +.step.done .step-text { + color: #606266; +} + +.step-arrow { + margin: 0 12px; + color: #c0c4cc; + font-size: 16px; +} + +/* 步骤内容 */ +.step-content { + min-height: 200px; +} + +/* 班次配置面板 */ +.shift-config-panel { + margin-top: 12px; +} + +.shift-config-row { + margin-bottom: 16px; + padding: 16px; + background-color: #fafafa; + border-radius: 4px; +} + +.shift-config-header { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 12px; +} + +.config-label { + font-weight: 600; + color: #606266; +} + +.shift-config-fields { + display: flex; + align-items: center; + gap: 16px; +} + +.shift-time-display { + font-size: 13px; + color: #67c23a; + padding: 4px 8px; + background-color: #f0f9eb; + border-radius: 4px; +} + +/* 班次分配区域 */ +.shift-assignment { + margin-bottom: 20px; + padding: 16px; + background-color: #fafafa; + border-radius: 4px; +} + +.assignment-header { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 12px; +} + +.assignment-count { + font-size: 13px; + color: #909399; +} + +/* 快速操作按钮 */ +.quick-actions { + margin-top: 16px; + padding-top: 16px; + border-top: 1px dashed #e4e7ed; +} + +/* 预览摘要 */ +.preview-summary { + margin-top: 16px; + padding: 12px; + background-color: #f0f9eb; + border-radius: 4px; + text-align: center; + color: #67c23a; + font-size: 14px; +} + +/* 对话框按钮 */ +.dialog-footer { + display: flex; + justify-content: flex-end; + gap: 12px; +} From b7016b35911f22d9ab7b3285c0a2e745bc124234 Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Fri, 22 May 2026 15:30:01 +0800 Subject: [PATCH 24/40] =?UTF-8?q?feat(eqp):=20=E6=B7=BB=E5=8A=A0=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E6=A3=80=E9=AA=8C=E6=B8=85=E5=8D=95=E9=83=A8=E4=BD=8D?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=E5=A1=AB=E5=85=85=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在EqpEquipmentChecklistBo中新增partIds字段用于批量查询 - 实现检验清单查询时自动填充检验部位名称的功能 - 重构设备部件服务中的检验清单列表获取逻辑 - 优化设备部件页面数据加载性能通过批量查询方式 - 移除手动设置部位名称的冗余代码实现自动关联 --- .../domain/bo/EqpEquipmentChecklistBo.java | 3 +++ .../EqpEquipmentChecklistServiceImpl.java | 25 ++++++++++++++++++- .../impl/EqpEquipmentPartServiceImpl.java | 17 +++++++------ 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/klp-mes/src/main/java/com/klp/mes/eqp/domain/bo/EqpEquipmentChecklistBo.java b/klp-mes/src/main/java/com/klp/mes/eqp/domain/bo/EqpEquipmentChecklistBo.java index 0d34d6b3..5b11e70b 100644 --- a/klp-mes/src/main/java/com/klp/mes/eqp/domain/bo/EqpEquipmentChecklistBo.java +++ b/klp-mes/src/main/java/com/klp/mes/eqp/domain/bo/EqpEquipmentChecklistBo.java @@ -4,6 +4,7 @@ import com.klp.common.core.domain.BaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; import javax.validation.constraints.*; +import java.util.List; /** @@ -62,5 +63,7 @@ public class EqpEquipmentChecklistBo extends BaseEntity { */ private String remark; + private List partIds; + } diff --git a/klp-mes/src/main/java/com/klp/mes/eqp/service/impl/EqpEquipmentChecklistServiceImpl.java b/klp-mes/src/main/java/com/klp/mes/eqp/service/impl/EqpEquipmentChecklistServiceImpl.java index 2535a45a..e5a164c1 100644 --- a/klp-mes/src/main/java/com/klp/mes/eqp/service/impl/EqpEquipmentChecklistServiceImpl.java +++ b/klp-mes/src/main/java/com/klp/mes/eqp/service/impl/EqpEquipmentChecklistServiceImpl.java @@ -12,7 +12,9 @@ import org.springframework.stereotype.Service; import com.klp.mes.eqp.domain.bo.EqpEquipmentChecklistBo; import com.klp.mes.eqp.domain.vo.EqpEquipmentChecklistVo; import com.klp.mes.eqp.domain.EqpEquipmentChecklist; +import com.klp.mes.eqp.domain.EqpEquipmentPart; import com.klp.mes.eqp.mapper.EqpEquipmentChecklistMapper; +import com.klp.mes.eqp.mapper.EqpEquipmentPartMapper; import com.klp.mes.eqp.service.IEqpEquipmentChecklistService; import java.util.List; @@ -30,6 +32,7 @@ import java.util.Collection; public class EqpEquipmentChecklistServiceImpl implements IEqpEquipmentChecklistService { private final EqpEquipmentChecklistMapper baseMapper; + private final EqpEquipmentPartMapper eqpEquipmentPartMapper; /** * 查询设备检验清单 @@ -46,6 +49,7 @@ public class EqpEquipmentChecklistServiceImpl implements IEqpEquipmentChecklistS public TableDataInfo queryPageList(EqpEquipmentChecklistBo bo, PageQuery pageQuery) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + fillPartName(result.getRecords()); return TableDataInfo.build(result); } @@ -55,7 +59,26 @@ public class EqpEquipmentChecklistServiceImpl implements IEqpEquipmentChecklistS @Override public List queryList(EqpEquipmentChecklistBo bo) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); - return baseMapper.selectVoList(lqw); + List list = baseMapper.selectVoList(lqw); + fillPartName(list); + return list; + } + + /** + * 填充检验清单的检验部位名称 + */ + private void fillPartName(List list) { + if (list == null || list.isEmpty()) { + return; + } + list.forEach(vo -> { + if (vo.getPartId() != null) { + EqpEquipmentPart part = eqpEquipmentPartMapper.selectById(vo.getPartId()); + if (part != null) { + vo.setPartName(part.getInspectPart()); + } + } + }); } private LambdaQueryWrapper buildQueryWrapper(EqpEquipmentChecklistBo bo) { diff --git a/klp-mes/src/main/java/com/klp/mes/eqp/service/impl/EqpEquipmentPartServiceImpl.java b/klp-mes/src/main/java/com/klp/mes/eqp/service/impl/EqpEquipmentPartServiceImpl.java index c04f4a49..36f90973 100644 --- a/klp-mes/src/main/java/com/klp/mes/eqp/service/impl/EqpEquipmentPartServiceImpl.java +++ b/klp-mes/src/main/java/com/klp/mes/eqp/service/impl/EqpEquipmentPartServiceImpl.java @@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.klp.common.utils.StringUtils; import com.klp.mes.eqp.domain.bo.EqpEquipmentChecklistBo; +import com.klp.mes.eqp.service.IEqpEquipmentChecklistService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import com.klp.mes.eqp.domain.bo.EqpEquipmentPartBo; @@ -21,6 +22,7 @@ import com.klp.mes.eqp.service.IEqpEquipmentPartService; import java.util.*; import java.util.stream.Collectors; + import org.springframework.transaction.annotation.Transactional; /** @@ -34,6 +36,7 @@ import org.springframework.transaction.annotation.Transactional; public class EqpEquipmentPartServiceImpl implements IEqpEquipmentPartService { private final EqpEquipmentPartMapper baseMapper; + private final IEqpEquipmentChecklistService checklistService; private final EqpEquipmentChecklistMapper checklistMapper; /** @@ -54,16 +57,14 @@ public class EqpEquipmentPartServiceImpl implements IEqpEquipmentPartService { List partIds = result.getRecords().stream() .map(EqpEquipmentPartVo::getPartId).collect(Collectors.toList()); if (!partIds.isEmpty()) { - LambdaQueryWrapper checklistLqw = Wrappers.lambdaQuery(); - checklistLqw.in(EqpEquipmentChecklist::getPartId, partIds); - List checklistList = checklistMapper.selectVoList(checklistLqw); + EqpEquipmentChecklistBo eqpEquipmentChecklistBo = new EqpEquipmentChecklistBo(); + eqpEquipmentChecklistBo.setPartIds(partIds); + List checklistList = checklistService.queryList(eqpEquipmentChecklistBo); Map> checklistMap = checklistList.stream() .collect(Collectors.groupingBy(EqpEquipmentChecklistVo::getPartId)); - result.getRecords().forEach(vo -> { - List items = checklistMap.getOrDefault(vo.getPartId(), Collections.emptyList()); - items.forEach(checklist -> checklist.setPartName(vo.getInspectPart())); - vo.setChecklistList(items); - }); + result.getRecords().forEach(vo -> + vo.setChecklistList(checklistMap.getOrDefault(vo.getPartId(), Collections.emptyList())) + ); } return TableDataInfo.build(result); } From e084576f1e0a9ae12b4334053a5c1fde084da15d Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Fri, 22 May 2026 16:03:24 +0800 Subject: [PATCH 25/40] =?UTF-8?q?perf(wms/attendance):=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=8E=92=E7=8F=AD=E7=94=9F=E6=88=90=E6=80=A7=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E6=89=B9=E9=87=8F=E6=9F=A5=E8=AF=A2=E5=B7=B2=E5=AD=98?= =?UTF-8?q?=E5=9C=A8=E6=97=A5=E6=9C=9F=E5=B9=B6=E9=87=8D=E6=9E=84=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将单日排班存在性检查改为批量查询整个日期范围内的已存在排班日期集合 - 移除冗余的日期检查逻辑,统一使用批量查询结果进行过滤 - 简化倒班日判断和班次切换逻辑,移除注释掉的复杂处理代码 - 优化导入语句,使用通配符和流式处理提高代码简洁性 --- .../WmsAttendanceScheduleServiceImpl.java | 58 +++++++------------ 1 file changed, 20 insertions(+), 38 deletions(-) diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsAttendanceScheduleServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsAttendanceScheduleServiceImpl.java index af1e48bf..9d2a2b7e 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsAttendanceScheduleServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsAttendanceScheduleServiceImpl.java @@ -25,12 +25,8 @@ import com.klp.service.IWmsAttendanceShiftService; import java.time.LocalDate; import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import java.util.Collection; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; /** * 排班(谁在哪天上班)Service业务层处理 @@ -157,18 +153,18 @@ public class WmsAttendanceScheduleServiceImpl implements IWmsAttendanceScheduleS * 生成正常排班 */ private void generateNormalSchedule(GenerateScheduleBo bo, LocalDate startDate, LocalDate endDate) { - List schedules = new ArrayList<>(); - - // 获取班次信息 WmsAttendanceShiftVo shift = shiftService.queryById(bo.getShiftId()); if (shift == null) { throw new RuntimeException("班次不存在"); } + // 一次查询整个日期范围内已存在的排班 + Set existingDates = getExistingScheduleDates(bo.getUserId(), startDate, endDate); + + List schedules = new ArrayList<>(); LocalDate currentDate = startDate; while (!currentDate.isAfter(endDate)) { - // 检查是否已存在排班 - if (!isScheduleExists(bo.getUserId(), currentDate)) { + if (!existingDates.contains(currentDate)) { WmsAttendanceSchedule schedule = new WmsAttendanceSchedule(); schedule.setUserId(bo.getUserId()); schedule.setWorkDate(java.sql.Date.valueOf(currentDate)); @@ -215,28 +211,27 @@ public class WmsAttendanceScheduleServiceImpl implements IWmsAttendanceScheduleS throw new RuntimeException("倒班规则中的班次不存在"); } + // 一次查询整个日期范围内已存在的排班 + Set existingDates = getExistingScheduleDates(bo.getUserId(), startDate, endDate); + List schedules = new ArrayList<>(); LocalDate currentDate = startDate; long daysFromStart = 0; // 确定初始班次 boolean isCurrentShiftA = bo.getShiftId().equals(rule.getShiftA()); + long cycleDays = rule.getCycleDays() != null ? rule.getCycleDays() : 10; while (!currentDate.isAfter(endDate)) { - if (!isScheduleExists(bo.getUserId(), currentDate)) { + if (!existingDates.contains(currentDate)) { WmsAttendanceSchedule schedule = new WmsAttendanceSchedule(); schedule.setUserId(bo.getUserId()); schedule.setWorkDate(java.sql.Date.valueOf(currentDate)); - // 判断是否为倒班日 - long cycleDays = rule.getCycleDays() != null ? rule.getCycleDays() : 10; - // boolean isChangeDay = (daysFromStart + 1) % cycleDays == 0; boolean isChangeDay = daysFromStart > 0 && daysFromStart % cycleDays == 0; if (isChangeDay) { - // 倒班日 if (isCurrentShiftA) { - // 白班转夜班 if (changeShiftB != null) { schedule.setShiftId(rule.getChangeShiftBId()); schedule.setShiftName(changeShiftB.getShiftName()); @@ -244,24 +239,7 @@ public class WmsAttendanceScheduleServiceImpl implements IWmsAttendanceScheduleS schedule.setShiftId(rule.getShiftB()); schedule.setShiftName(shiftB.getShiftName()); } -// // 下一天也使用倒班班次(工作18小时) -// LocalDate nextDay = currentDate.plusDays(1); -// if (!nextDay.isAfter(endDate) && !isScheduleExists(bo.getUserId(), nextDay)) { -// WmsAttendanceSchedule nextSchedule = new WmsAttendanceSchedule(); -// nextSchedule.setUserId(bo.getUserId()); -// nextSchedule.setWorkDate(java.sql.Date.valueOf(nextDay)); -// if (changeShiftB != null) { -// nextSchedule.setShiftId(rule.getChangeShiftBId()); -// nextSchedule.setShiftName(changeShiftB.getShiftName()); -// } else { -// nextSchedule.setShiftId(rule.getShiftB()); -// nextSchedule.setShiftName(shiftB.getShiftName()); -// } -// schedules.add(nextSchedule); -// } isCurrentShiftA = false; -// currentDate = currentDate.plusDays(1); // 跳过下一天,因为已经处理了 -// daysFromStart++; } else { // 夜班转白班 if (changeShiftA != null) { @@ -300,12 +278,16 @@ public class WmsAttendanceScheduleServiceImpl implements IWmsAttendanceScheduleS } /** - * 检查排班是否已存在 + * 批量查询指定用户日期范围内已存在的排班日期 */ - private boolean isScheduleExists(Long userId, LocalDate workDate) { + private Set getExistingScheduleDates(Long userId, LocalDate startDate, LocalDate endDate) { LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); wrapper.eq(WmsAttendanceSchedule::getUserId, userId) - .eq(WmsAttendanceSchedule::getWorkDate, java.sql.Date.valueOf(workDate)); - return baseMapper.selectCount(wrapper) > 0; + .between(WmsAttendanceSchedule::getWorkDate, java.sql.Date.valueOf(startDate), java.sql.Date.valueOf(endDate)) + .select(WmsAttendanceSchedule::getWorkDate); + List list = baseMapper.selectList(wrapper); + return list.stream() + .map(s -> new java.sql.Date(s.getWorkDate().getTime()).toLocalDate()) + .collect(Collectors.toSet()); } } From 749ae46490944f2bd7746f3736d759d3639e5c5c Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Fri, 22 May 2026 16:09:50 +0800 Subject: [PATCH 26/40] =?UTF-8?q?fix(wms/receivable):=20=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=E5=BA=94=E6=94=B6=E8=B4=A7=E7=89=A9=E8=AE=A1=E5=88=92=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E5=AE=A2=E6=88=B7=E4=BF=A1=E6=81=AF=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将客户名称查询字段从c.name调整为c.company_name以匹配CRM客户表结构 - 新增客户编号customerCode字段映射,补充客户信息完整性 - 调整关联表从wms_customer切换为crm_customer确保数据一致性 --- klp-wms/src/main/java/com/klp/domain/vo/WmsReceivableVo.java | 4 +++- .../src/main/resources/mapper/klp/WmsReceivableMapper.xml | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/klp-wms/src/main/java/com/klp/domain/vo/WmsReceivableVo.java b/klp-wms/src/main/java/com/klp/domain/vo/WmsReceivableVo.java index c6665b7b..d235638a 100644 --- a/klp-wms/src/main/java/com/klp/domain/vo/WmsReceivableVo.java +++ b/klp-wms/src/main/java/com/klp/domain/vo/WmsReceivableVo.java @@ -83,6 +83,8 @@ public class WmsReceivableVo { /** * 客户名称 */ - @ExcelProperty(value = "客户名称") private String customerName; + + // 客户编号 + private String customerCode; } diff --git a/klp-wms/src/main/resources/mapper/klp/WmsReceivableMapper.xml b/klp-wms/src/main/resources/mapper/klp/WmsReceivableMapper.xml index 2cc426b4..0218b8fa 100644 --- a/klp-wms/src/main/resources/mapper/klp/WmsReceivableMapper.xml +++ b/klp-wms/src/main/resources/mapper/klp/WmsReceivableMapper.xml @@ -36,9 +36,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" r.create_by, r.update_time, r.update_by, - c.name as customerName + c.company_name as customerName, + c.customer_code as customerCode from wms_receivable r - left join wms_customer c on r.customer_id = c.customer_id and c.del_flag = 0 + left join crm_customer c on r.customer_id = c.customer_id and c.del_flag = 0 ${ew.customSqlSegment} From d81773b1ab9e89800211e39e74ea37f15e11d729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= <2178503051@qq.com> Date: Fri, 22 May 2026 16:19:00 +0800 Subject: [PATCH 27/40] =?UTF-8?q?feat(attendance):=20=E4=B8=BA=E6=8E=92?= =?UTF-8?q?=E7=8F=AD=E8=A1=A8=E6=A0=BC=E6=B7=BB=E5=8A=A0=E9=AB=98=E5=BA=A6?= =?UTF-8?q?=E9=80=82=E9=85=8D=EF=BC=8C=E9=9A=90=E8=97=8F=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E6=8C=89=E9=92=AE=E5=B9=B6=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=8A=A0=E8=BD=BD=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- klp-ui/src/views/wms/hrm/attendance/drag.vue | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/klp-ui/src/views/wms/hrm/attendance/drag.vue b/klp-ui/src/views/wms/hrm/attendance/drag.vue index 40b1981f..3c1d1a51 100644 --- a/klp-ui/src/views/wms/hrm/attendance/drag.vue +++ b/klp-ui/src/views/wms/hrm/attendance/drag.vue @@ -17,7 +17,7 @@
- + @@ -116,8 +116,8 @@ 已分配 {{ item.employeeIds ? item.employeeIds.split(',').filter(id => id.trim()).length : 0 }} 人 - 复制 +
-
+
@@ -152,7 +152,7 @@ 上一步 From be75c1a4b82da1e8d101e3716d5e18eb2fc493e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= <2178503051@qq.com> Date: Fri, 22 May 2026 16:19:24 +0800 Subject: [PATCH 28/40] feat(wms): add transfer remark field and re-label function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增调拨备注字段transferRemark到调拨单itemBO 2. 新增执行后重贴标签的复选框和备注输入框 3. 调整调拨确认时传递调拨备注参数 4. 注释调旧的调拨类型获取逻辑,改用传入的调拨备注作为调拨类型 --- .../wms/move/components/tranferItemTable.vue | 36 +++++++++++++++++-- klp-ui/src/views/wms/move/do.vue | 26 +++++++++----- .../klp/domain/bo/WmsTransferOrderItemBo.java | 2 ++ .../impl/WmsTransferOrderItemServiceImpl.java | 13 ++++--- 4 files changed, 61 insertions(+), 16 deletions(-) diff --git a/klp-ui/src/views/wms/move/components/tranferItemTable.vue b/klp-ui/src/views/wms/move/components/tranferItemTable.vue index 684e9483..8dc60090 100644 --- a/klp-ui/src/views/wms/move/components/tranferItemTable.vue +++ b/klp-ui/src/views/wms/move/components/tranferItemTable.vue @@ -131,6 +131,14 @@ export default { type: Boolean, default: false }, + refreshLabel: { + type: Boolean, + default: false + }, + transferRemark: { + type: String, + default: '' + }, }, components: { // WarehouseSelect, @@ -235,7 +243,19 @@ export default { // 确认调拨 handleConfirm(item) { this.buttonLoading = true - confirmTransferOrderItem(item).then(res => { + let transferRemark = this.transferRemark + if (this.refreshLabel && !transferRemark) { + transferRemark = '调拨' + } + if (!this.refreshLabel) { + transferRemark = '' + } + // console.log(transferRemark, this.refreshLabel, this.transferRemark) + // return; + confirmTransferOrderItem({ + ...item, + transferRemark + }).then(res => { if (res.code === 200) { this.$message({ message: '确认调拨成功', @@ -260,8 +280,20 @@ export default { return; } + let transferRemark = this.transferRemark + if (this.refreshLabel && !transferRemark) { + transferRemark = '调拨' + } + if (!this.refreshLabel) { + transferRemark = '' + } + // console.log(transferRemark) + // return; this.buttonLoading = true; - batchConfirmTransferOrderItem(unconfirmedItems).then(res => { + batchConfirmTransferOrderItem(unconfirmedItems.map(item => ({ + ...item, + transferRemark + }))).then(res => { if (res.code === 200) { this.$message({ message: '确认调拨成功', diff --git a/klp-ui/src/views/wms/move/do.vue b/klp-ui/src/views/wms/move/do.vue index 68cae7a2..55418979 100644 --- a/klp-ui/src/views/wms/move/do.vue +++ b/klp-ui/src/views/wms/move/do.vue @@ -18,10 +18,10 @@ - + remote-method="remoteSearchTransferOrder" :remote-loading="transferOrderLoading" placeholder="请输入调拨单号搜索" + @change="handleRegularSearch" style="width:220px"> + @@ -36,9 +36,15 @@ +
+ 执行后重贴标签 + + 请填写重贴原因,不填则默认为:’调拨‘ +
+ - ({{ coil.enterCoilNo }}) - {{ coil.dataType === 1 ? '当前卷' : '历史卷' }} | + {{ coil.dataType === 1 ? '当前卷' : '历史卷' }} | {{ coil.status === 1 ? '已发货' : '未发货' }} @@ -65,7 +71,7 @@ {{ coil.material || '-' }} {{ coil.manufacturer || '-' }} - +
@@ -89,6 +95,8 @@ export default { currentCoilNo: '', enterCoilNo: '', }, + refreshLabel: false, + transferRemark: '', queryParams: { warehouseIdBefore: '', warehouseIdAfter: '', @@ -143,7 +151,7 @@ export default { }) ); this.tracedCoils = tracedCoilsData.filter(coil => coil.transferRecords.length > 0); - + } else { this.$message.info('未找到符合条件的钢卷'); } diff --git a/klp-wms/src/main/java/com/klp/domain/bo/WmsTransferOrderItemBo.java b/klp-wms/src/main/java/com/klp/domain/bo/WmsTransferOrderItemBo.java index 82e54384..40a70030 100644 --- a/klp-wms/src/main/java/com/klp/domain/bo/WmsTransferOrderItemBo.java +++ b/klp-wms/src/main/java/com/klp/domain/bo/WmsTransferOrderItemBo.java @@ -82,4 +82,6 @@ public class WmsTransferOrderItemBo extends BaseEntity { // 修改之后的itemType private String itemTypeAfter; + // 重贴标签的备注 + private String transferRemark; } diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsTransferOrderItemServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsTransferOrderItemServiceImpl.java index abbd2561..a97153a3 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsTransferOrderItemServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsTransferOrderItemServiceImpl.java @@ -589,11 +589,14 @@ public class WmsTransferOrderItemServiceImpl implements IWmsTransferOrderItemSer coil.setWarehouseId(finalWarehouseId); // 设置调拨类型 - if (item.getTransferId() != null) { - WmsTransferOrder wmsTransferOrder = wmsTransferOrderMapper.selectById(item.getTransferId()); - if (wmsTransferOrder != null) { - coil.setTransferType(wmsTransferOrder.getTransferType()); - } +// if (item.getTransferId() != null) { +// WmsTransferOrder wmsTransferOrder = wmsTransferOrderMapper.selectById(item.getTransferId()); +// if (wmsTransferOrder != null) { +// coil.setTransferType(wmsTransferOrder.getTransferType()); +// } +// } + if (bo.getTransferRemark() != null) { + coil.setTransferType(bo.getTransferRemark()); } coilMapper.updateById(coil); From 3718132a5952b259acb8e5614e9b6ec74217272f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E6=98=8A?= <15984991+wwh2328692301@user.noreply.gitee.com> Date: Fri, 22 May 2026 17:03:13 +0800 Subject: [PATCH 29/40] =?UTF-8?q?refactor(crm):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E6=98=8E=E7=BB=86=E6=9F=A5=E8=AF=A2=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=8C=E7=A7=BB=E9=99=A4=E5=86=85=E5=AD=98=E6=8E=92?= =?UTF-8?q?=E5=BA=8F=E5=B9=B6=E8=BF=81=E7=A7=BB=E5=88=B0SQL=E5=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增联表分页查询方法,在数据库层完成排序和分页 2. 移除前端页面冗余的合同信息缓存和内存排序逻辑 3. 新增钢卷导入组件,支持调拨单钢批量化导入 4. 补充订单明细VO类的联表查询字段 --- .../com/klp/crm/domain/vo/CrmOrderItemVo.java | 53 ++ .../klp/crm/mapper/CrmOrderItemMapper.java | 12 + .../service/impl/CrmOrderItemServiceImpl.java | 52 +- .../resources/mapper/CrmOrderItemMapper.xml | 171 ++++- klp-ui/src/views/crm/orderItem/index.vue | 57 +- klp-ui/src/views/wms/move/batch.vue | 7 + .../views/wms/move/components/ImportCoil.vue | 723 ++++++++++++++++++ 7 files changed, 975 insertions(+), 100 deletions(-) create mode 100644 klp-ui/src/views/wms/move/components/ImportCoil.vue diff --git a/klp-crm/src/main/java/com/klp/crm/domain/vo/CrmOrderItemVo.java b/klp-crm/src/main/java/com/klp/crm/domain/vo/CrmOrderItemVo.java index d8553f4b..d0a5da63 100644 --- a/klp-crm/src/main/java/com/klp/crm/domain/vo/CrmOrderItemVo.java +++ b/klp-crm/src/main/java/com/klp/crm/domain/vo/CrmOrderItemVo.java @@ -181,6 +181,59 @@ public class CrmOrderItemVo { @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; + /** + * 创建人 + */ + private String createBy; + + /** + * 更新时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + /** + * 更新人 + */ + private String updateBy; + + /** + * 删除标志 + */ + private Long delFlag; + + /** + * 合同号(联表查询直接映射) + */ + @ExcelProperty(value = "合同号") + private String contractCode; + + /** + * 供方(联表查询直接映射) + */ + @ExcelProperty(value = "供方") + private String supplier; + + /** + * 需方(联表查询直接映射) + */ + @ExcelProperty(value = "需方") + private String customer; + + /** + * 签订时间(联表查询直接映射) + */ + @JsonFormat(pattern = "yyyy-MM-dd") + @ExcelProperty(value = "签订时间") + private Date signTime; + + /** + * 交货日期(联表查询直接映射) + */ + @JsonFormat(pattern = "yyyy-MM-dd") + @ExcelProperty(value = "交货日期") + private Date deliveryDate; + /** * 订单信息 */ diff --git a/klp-crm/src/main/java/com/klp/crm/mapper/CrmOrderItemMapper.java b/klp-crm/src/main/java/com/klp/crm/mapper/CrmOrderItemMapper.java index 530c9a1f..946f6ff5 100644 --- a/klp-crm/src/main/java/com/klp/crm/mapper/CrmOrderItemMapper.java +++ b/klp-crm/src/main/java/com/klp/crm/mapper/CrmOrderItemMapper.java @@ -1,8 +1,10 @@ package com.klp.crm.mapper; import com.klp.crm.domain.CrmOrderItem; +import com.klp.crm.domain.bo.CrmOrderItemBo; import com.klp.crm.domain.vo.CrmOrderItemVo; import com.klp.common.core.mapper.BaseMapperPlus; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -22,4 +24,14 @@ public interface CrmOrderItemMapper extends BaseMapperPlus selectOrderItemsByOrderIds(@Param("orderIds") List orderIds); + + /** + * 联表查询订单明细(支持排序和分页) + * 排序规则:deliveryDate DESC -> orderId ASC -> createTime DESC + * + * @param page 分页对象 + * @param bo 查询条件 + * @return 分页结果 + */ + Page selectVoListWithOrder(Page page, @Param("bo") CrmOrderItemBo bo); } diff --git a/klp-crm/src/main/java/com/klp/crm/service/impl/CrmOrderItemServiceImpl.java b/klp-crm/src/main/java/com/klp/crm/service/impl/CrmOrderItemServiceImpl.java index d2210951..7d751054 100644 --- a/klp-crm/src/main/java/com/klp/crm/service/impl/CrmOrderItemServiceImpl.java +++ b/klp-crm/src/main/java/com/klp/crm/service/impl/CrmOrderItemServiceImpl.java @@ -69,51 +69,19 @@ public class CrmOrderItemServiceImpl implements ICrmOrderItemService { /** * 查询正式订单明细列表 - * 实现逻辑:查出全部匹配记录 → Java内存排序(交货日期倒序→订单ID升序→创建时间倒序)→ 手动分页 - * 排序跨页生效,同一合同明细连续排列 + * 实现逻辑:SQL联表查询 → 数据库层排序(交货日期倒序→订单ID升序→创建时间倒序)→ 物理分页 + * 排序跨页生效,同一合同明细连续排列,避免内存排序大数据量问题 */ @Override public TableDataInfo queryPageList(CrmOrderItemBo bo, PageQuery pageQuery) { - List orderIdScope = resolveOrderIdScope(bo); - if (orderIdScope != null && orderIdScope.isEmpty()) { - Page emptyPage = new Page<>(ObjectUtil.defaultIfNull(pageQuery.getPageNum(), 1), - ObjectUtil.defaultIfNull(pageQuery.getPageSize(), 10), 0); - emptyPage.setRecords(Collections.emptyList()); - return TableDataInfo.build(emptyPage); - } - LambdaQueryWrapper lqw = buildQueryWrapper(bo); - if (orderIdScope != null) { - lqw.in(CrmOrderItem::getOrderId, orderIdScope); - } - // 1. 查出全部匹配记录 - List allItems = baseMapper.selectVoList(lqw); - // 2. 填充订单信息(含 deliveryDate) - fillOrderInfoOnItems(allItems); - // 3. 三级排序:deliveryDate DESC → orderId ASC → createTime DESC - allItems.sort((a, b) -> { - // 同一合同组内:按创建时间倒序 - if (Objects.equals(a.getOrderId(), b.getOrderId())) { - return compareDate(a.getCreateTime(), b.getCreateTime(), true); - } - // 不同合同组:按交货日期倒序 - Date dateA = a.getOrderInfo() != null ? a.getOrderInfo().getDeliveryDate() : null; - Date dateB = b.getOrderInfo() != null ? b.getOrderInfo().getDeliveryDate() : null; - int cmp = compareDate(dateA, dateB, true); - if (cmp != 0) return cmp; - // 交货日期相同:按订单ID升序,保证同一合同组连续 - return Long.compare(a.getOrderId(), b.getOrderId()); - }); - // 4. 手动分页 - int total = allItems.size(); - int pageNum = ObjectUtil.defaultIfNull(pageQuery.getPageNum(), 1); - int pageSize = ObjectUtil.defaultIfNull(pageQuery.getPageSize(), 10); - int from = (pageNum - 1) * pageSize; - int to = Math.min(from + pageSize, total); - List pageItems = from >= total ? Collections.emptyList() : allItems.subList(from, to); - - Page page = new Page<>(pageNum, pageSize, total); - page.setRecords(pageItems); - return TableDataInfo.build(page); + // 使用MyBatis-Plus分页插件,SQL层完成联表查询、排序和分页 + Page page = new Page<>( + ObjectUtil.defaultIfNull(pageQuery.getPageNum(), 1), + ObjectUtil.defaultIfNull(pageQuery.getPageSize(), 10) + ); + // 联表查询:在SQL层完成排序,避免内存排序 + Page resultPage = baseMapper.selectVoListWithOrder(page, bo); + return TableDataInfo.build(resultPage); } /** diff --git a/klp-crm/src/main/resources/mapper/CrmOrderItemMapper.xml b/klp-crm/src/main/resources/mapper/CrmOrderItemMapper.xml index 1df4a74b..040882f6 100644 --- a/klp-crm/src/main/resources/mapper/CrmOrderItemMapper.xml +++ b/klp-crm/src/main/resources/mapper/CrmOrderItemMapper.xml @@ -1,7 +1,7 @@ + PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> @@ -36,6 +36,46 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/klp-ui/src/views/crm/orderItem/index.vue b/klp-ui/src/views/crm/orderItem/index.vue index d1f7be81..9c1b3090 100644 --- a/klp-ui/src/views/crm/orderItem/index.vue +++ b/klp-ui/src/views/crm/orderItem/index.vue @@ -314,7 +314,6 @@ + + From 26f285ec804e1d5cde38f3b0b6b83fa35dab9edc Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Fri, 22 May 2026 17:46:11 +0800 Subject: [PATCH 30/40] =?UTF-8?q?feat(wms/receivable):=20=E5=9C=A8?= =?UTF-8?q?=E5=BA=94=E6=94=B6=E8=B4=A7=E7=89=A9=E8=AE=A1=E5=88=92=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E4=B8=AD=E8=A1=A5=E5=85=85=E8=AE=A2=E5=8D=95=E7=BC=96?= =?UTF-8?q?=E5=8F=B7=E5=92=8C=E8=AE=A2=E5=8D=95=E5=90=8D=E7=A7=B0=E5=AD=97?= =?UTF-8?q?=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在应收货物计划查询SQL中新增订单编号orderCode和订单名称orderName字段映射 - 关联crm_order表以获取订单信息,确保数据完整性 - 在应收货物计划VO类中补充订单编号和订单名称字段定义 --- .../main/java/com/klp/domain/vo/WmsReceivableVo.java | 10 ++++++++++ .../main/resources/mapper/klp/WmsReceivableMapper.xml | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/klp-wms/src/main/java/com/klp/domain/vo/WmsReceivableVo.java b/klp-wms/src/main/java/com/klp/domain/vo/WmsReceivableVo.java index d235638a..a73bf774 100644 --- a/klp-wms/src/main/java/com/klp/domain/vo/WmsReceivableVo.java +++ b/klp-wms/src/main/java/com/klp/domain/vo/WmsReceivableVo.java @@ -87,4 +87,14 @@ public class WmsReceivableVo { // 客户编号 private String customerCode; + + /** + * 订单编号 + */ + private String orderCode; + + /** + * 订单名称 + */ + private String orderName; } diff --git a/klp-wms/src/main/resources/mapper/klp/WmsReceivableMapper.xml b/klp-wms/src/main/resources/mapper/klp/WmsReceivableMapper.xml index 0218b8fa..181b8020 100644 --- a/klp-wms/src/main/resources/mapper/klp/WmsReceivableMapper.xml +++ b/klp-wms/src/main/resources/mapper/klp/WmsReceivableMapper.xml @@ -37,9 +37,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" r.update_time, r.update_by, c.company_name as customerName, - c.customer_code as customerCode + c.customer_code as customerCode, + o.order_code as orderCode, + o.contract_name as orderName from wms_receivable r left join crm_customer c on r.customer_id = c.customer_id and c.del_flag = 0 + left join crm_order o on r.order_id = o.order_id and o.del_flag = 0 ${ew.customSqlSegment} From a5b1a19a2b21195dbad3b10238d64cc0c0749b80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= <2178503051@qq.com> Date: Sat, 23 May 2026 09:18:24 +0800 Subject: [PATCH 31/40] =?UTF-8?q?fix(mes/roll/grind):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=BD=93=E5=89=8D=E8=BE=8A=E5=BE=84=E6=98=BE=E7=A4=BA=E5=92=8C?= =?UTF-8?q?=E5=8F=96=E5=80=BC=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将当前辊径取值改为优先使用有效当前辊径计算逻辑,统一磨削前辊径取值 --- klp-ui/src/views/mes/roll/grind/index.vue | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/klp-ui/src/views/mes/roll/grind/index.vue b/klp-ui/src/views/mes/roll/grind/index.vue index 2d76adcc..788b06fe 100644 --- a/klp-ui/src/views/mes/roll/grind/index.vue +++ b/klp-ui/src/views/mes/roll/grind/index.vue @@ -68,7 +68,7 @@
辊型{{ selectedRoll.rollType === 'WR' ? '工作辊' : '支撑辊' }}
材质{{ selectedRoll.material || '—' }}
初始辊径{{ selectedRoll.initialDia != null ? selectedRoll.initialDia + ' mm' : '—' }}
-
当前辊径{{ selectedRoll.currentDia != null ? selectedRoll.currentDia + ' mm' : '—' }}
+
当前辊径{{ effectiveCurrentDia != null ? effectiveCurrentDia + ' mm' : '—' }}
最小辊径{{ selectedRoll.minDia != null ? selectedRoll.minDia + ' mm' : '—' }}
磨削次数{{ tableData.length ? tableData.length + ' 次' : '0 次' }}
粗糙度{{ selectedRoll.roughness != null ? selectedRoll.roughness + ' μm' : '—' }}
@@ -296,6 +296,22 @@ export default { }) }, + // 有效当前辊径:优先取 currentDia,无则取最新磨削记录的磨后径 + effectiveCurrentDia() { + if (this.selectedRoll && this.selectedRoll.currentDia != null) { + return parseFloat(this.selectedRoll.currentDia) + } + if (this.grindList.length > 0) { + const latest = [...this.grindList].sort((a, b) => { + const ta = a.grindTime ? new Date(a.grindTime).getTime() : 0 + const tb = b.grindTime ? new Date(b.grindTime).getTime() : 0 + return tb - ta + })[0] + if (latest && latest.diaAfter != null) return parseFloat(latest.diaAfter) + } + return null + }, + // 表格数据:新增时在顶部插入一个编辑行占位 tableData() { if (this.editRow && this.editRow.__isNew) { @@ -401,8 +417,7 @@ export default { rollId: this.selectedRollId, grindTime, team: undefined, - diaBefore: this.selectedRoll && this.selectedRoll.currentDia != null - ? parseFloat(this.selectedRoll.currentDia) : undefined, + diaBefore: this.effectiveCurrentDia != null ? this.effectiveCurrentDia : undefined, diaAfter: undefined, rollShape: '平', flawResult: '合格', From 6f5d09beefaecbca8d873dbdbc7ad3bb361463bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E6=98=8A?= <15984991+wwh2328692301@user.noreply.gitee.com> Date: Sat, 23 May 2026 10:03:19 +0800 Subject: [PATCH 32/40] =?UTF-8?q?feat=20(wms/move)=EF=BC=9A=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E9=92=A2=E5=8D=B7=E5=8C=B9=E9=85=8D=E8=BF=9B=E5=BA=A6?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=20=E4=B8=BA=E5=85=A5=E5=BA=93=E9=92=A2?= =?UTF-8?q?=E5=8D=B7=E5=8A=9F=E8=83=BD=E6=B7=BB=E5=8A=A0=E5=8C=B9=E9=85=8D?= =?UTF-8?q?=E8=BF=9B=E5=BA=A6=E7=95=8C=E9=9D=A2=E5=8F=8A=E5=AF=B9=E5=BA=94?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E3=80=81=E4=B8=9A=E5=8A=A1=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E6=97=B6=E5=B1=95=E7=A4=BA=E5=8C=B9=E9=85=8D?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E3=80=81=E8=BF=9B=E5=BA=A6=E5=8D=A0=E6=AF=94?= =?UTF-8?q?=E4=B8=8E=E5=BD=93=E5=89=8D=E5=8C=B9=E9=85=8D=E9=A1=B9=E7=BB=93?= =?UTF-8?q?=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/wms/move/components/ImportCoil.vue | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/klp-ui/src/views/wms/move/components/ImportCoil.vue b/klp-ui/src/views/wms/move/components/ImportCoil.vue index 8df49fa0..a008a614 100644 --- a/klp-ui/src/views/wms/move/components/ImportCoil.vue +++ b/klp-ui/src/views/wms/move/components/ImportCoil.vue @@ -98,6 +98,30 @@ + +
+
+ + 正在匹配钢卷... + {{ matchingPercentage }}% +
+ +
+ {{ matchingProgress }} / {{ matchingTotal }}条 + + 当前: {{ currentMatchingText }} + 已匹配 + 冲突 + 未匹配 + +
+
+
@@ -237,6 +261,11 @@ + + +