From c922856a0814917b8e429d4f0ab461620ee54287 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, 4 Jul 2026 11:49:04 +0800 Subject: [PATCH 01/23] feat(qc): add auto warehouse update logic for regraded coils MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根据改判后的钢卷质量等级自动将C/D级钢卷移动到技术部逻辑库区 --- .../impl/QcQualityReviewServiceImpl.java | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/klp-mes/src/main/java/com/klp/mes/qc/service/impl/QcQualityReviewServiceImpl.java b/klp-mes/src/main/java/com/klp/mes/qc/service/impl/QcQualityReviewServiceImpl.java index bdb9fa99e..1325fc981 100644 --- a/klp-mes/src/main/java/com/klp/mes/qc/service/impl/QcQualityReviewServiceImpl.java +++ b/klp-mes/src/main/java/com/klp/mes/qc/service/impl/QcQualityReviewServiceImpl.java @@ -45,6 +45,9 @@ import java.util.stream.Collectors; @Service public class QcQualityReviewServiceImpl implements IQcQualityReviewService { + /** 技术部逻辑库ID(C/D级改判后移入此库区) */ + private static final Long TECH_WAREHOUSE_ID = 2019583656787259393L; + private final QcQualityReviewMapper baseMapper; private final QcQualityReviewCoilMapper coilMapper; private final QcQualityReviewLogMapper logMapper; @@ -319,7 +322,15 @@ public class QcQualityReviewServiceImpl implements IQcQualityReviewService { coil.getCoilId(), coil.getRegradeQuality(), reason); } - // 2. 更新明细执行状态 + // 2. 根据改判后质量等级自动更新钢卷所在逻辑库区 + Long targetWarehouseId = determineTargetWarehouse(coil.getRegradeQuality()); + if (targetWarehouseId != null && coil.getCoilId() != null) { + wmsMaterialCoilMapper.update(null, Wrappers.lambdaUpdate() + .eq(WmsMaterialCoil::getCoilId, coil.getCoilId()) + .set(WmsMaterialCoil::getWarehouseId, targetWarehouseId)); + } + + // 3. 更新明细执行状态 coilMapper.update(null, Wrappers.lambdaUpdate() .eq(QcQualityReviewCoil::getDetailId, coil.getDetailId()) .set(QcQualityReviewCoil::getExecuteStatus, 1L) @@ -400,6 +411,23 @@ public class QcQualityReviewServiceImpl implements IQcQualityReviewService { return "QR-" + dateStr + "-" + String.format("%04d", count + 1); } + /** + * 根据改判后质量等级确定目标逻辑库区 + * O/A/B → 不移动,C+/C/C- → 技术部逻辑库,D+/D/D- → 技术部逻辑库 + */ + private Long determineTargetWarehouse(String regradeQuality) { + if (regradeQuality == null) return null; + // O/A/B 级不移动 + if ("O".equals(regradeQuality) || "A".equals(regradeQuality) || "B".equals(regradeQuality)) { + return null; + } + // C/D 级 → 技术部逻辑库 + if (regradeQuality.startsWith("C") || regradeQuality.startsWith("D")) { + return TECH_WAREHOUSE_ID; + } + return null; + } + private void validEntityBeforeSave(QcQualityReview entity) { if (StringUtils.isBlank(entity.getProductName())) { throw new RuntimeException("产品名称不能为空"); From 85751acc46cea86cedc6264a6d119a61bf8f7870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= <2178503051@qq.com> Date: Sat, 4 Jul 2026 13:19:32 +0800 Subject: [PATCH 02/23] =?UTF-8?q?feat(cost/comprehensive):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=B1=87=E6=80=BB=E8=A1=8C=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=A1=A8=E6=A0=BC=E6=95=B0=E6=8D=AE=E6=B1=82?= =?UTF-8?q?=E5=92=8C=E4=B8=8E=E5=B9=B3=E5=9D=87=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增summaryRows计算属性,生成总和与平均两行汇总数据 2. 新增tableData计算属性,将汇总行合并到原表格数据中 3. 为汇总行添加专属样式,高亮显示并加粗文字 4. 优化表格列渲染逻辑,普通行保留编辑能力,汇总行仅展示静态数据 5. 调整删除按钮逻辑,仅对非汇总行生效并修复删除索引问题 6. 新增rowClassName方法为汇总行添加专属CSS类 --- klp-ui/src/views/cost/comprehensive.vue | 98 ++++++++++++++++++++----- 1 file changed, 79 insertions(+), 19 deletions(-) diff --git a/klp-ui/src/views/cost/comprehensive.vue b/klp-ui/src/views/cost/comprehensive.vue index 4afc366f3..845b899a0 100644 --- a/klp-ui/src/views/cost/comprehensive.vue +++ b/klp-ui/src/views/cost/comprehensive.vue @@ -30,9 +30,9 @@ - + - + - + @@ -82,7 +95,7 @@ - 删除 + 删除 @@ -494,6 +507,45 @@ export default { }) return col && col.color ? { background: col.color, color: '#fff' } : {} } + }, + summaryRows() { + const rows = this.gridRows.filter(r => r.detailDate) + if (!rows.length) return [] + const detailCols = this.allCols.filter(c => c.$type === 'detail') + const metricCols = this.allCols.filter(c => c.$type === 'metric') + const calc = (type) => { + const row = { detailDate: type === 'sum' ? '总和' : '平均', $isSummary: true, $summaryType: type } + const n = rows.length || 1 + detailCols.forEach(col => { + if (col.isShift) { + const s1 = rows.reduce((a, r) => a + (parseFloat(r['q' + col.itemId + '_1']) || 0), 0) + const s2 = rows.reduce((a, r) => a + (parseFloat(r['q' + col.itemId + '_2']) || 0), 0) + row['q' + col.itemId + '_1'] = type === 'sum' ? s1.toFixed(2) : (s1 / n).toFixed(2) + row['q' + col.itemId + '_2'] = type === 'sum' ? s2.toFixed(2) : (s2 / n).toFixed(2) + row['q' + col.itemId] = type === 'sum' ? (s1 + s2).toFixed(2) : ((s1 + s2) / n).toFixed(2) + } else { + const s = rows.reduce((a, r) => a + (parseFloat(r['q' + col.itemId]) || 0), 0) + row['q' + col.itemId] = type === 'sum' ? s.toFixed(2) : (s / n).toFixed(2) + } + }) + metricCols.forEach(col => { + if (col.isShift) { + const s1 = rows.reduce((a, r) => a + (parseFloat(r['mv' + col.mIdx + '_1']) || 0), 0) + const s2 = rows.reduce((a, r) => a + (parseFloat(r['mv' + col.mIdx + '_2']) || 0), 0) + row['mv' + col.mIdx + '_1'] = type === 'sum' ? s1.toFixed(2) : (s1 / n).toFixed(2) + row['mv' + col.mIdx + '_2'] = type === 'sum' ? s2.toFixed(2) : (s2 / n).toFixed(2) + row['mv' + col.mIdx] = type === 'sum' ? (s1 + s2).toFixed(2) : ((s1 + s2) / n).toFixed(2) + } else { + const s = rows.reduce((a, r) => a + (parseFloat(r['mv' + col.mIdx]) || 0), 0) + row['mv' + col.mIdx] = type === 'sum' ? s.toFixed(2) : (s / n).toFixed(2) + } + }) + return row + } + return [calc('sum'), calc('avg')] + }, + tableData() { + return [...this.summaryRows, ...this.gridRows] } }, watch: { configOpen(v) { if (!v) this.rpOpen = false } }, @@ -509,6 +561,10 @@ export default { } }, methods: { + rowClassName({ row }) { + if (row.$isSummary) return 'summary-row' + return '' + }, /* report */ getList() { this.loading = true @@ -1142,4 +1198,8 @@ export default { .ica-backfill { color: #67c23a; margin-right: 1px; } .ica:hover { opacity: 0.7; } /deep/ .anomaly-input .el-input__inner { background: #fef0f0 !important; border-color: #f56c6c !important; } +/deep/ .summary-row td { background: #f0f7ff !important; font-weight: bold; } +/deep/ .summary-row td .cell { color: #303133; } +.summary-label { font-weight: bold; color: #303133; padding: 0 5px; } +.summary-val { font-weight: bold; color: #303133; } From eecb7fcae665bd4c199d446715fd08925d732192 Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Sat, 4 Jul 2026 13:38:23 +0800 Subject: [PATCH 03/23] =?UTF-8?q?feat(erp):=20=E8=A1=A5=E5=85=85=E5=90=88?= =?UTF-8?q?=E5=90=8C=E4=BF=A1=E6=81=AF=E5=AD=97=E6=AE=B5=E5=B9=B6=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E9=87=87=E8=B4=AD=E8=AE=A1=E5=88=92=E5=85=B3=E8=81=94?= =?UTF-8?q?=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在ErpContractOptionVo中添加crm_order全量字段包括订单类型、交货日期、订单状态等 - 添加@JsonFormat注解支持日期格式化 - 新增selectContractsByOrderCodes方法支持按合同编号批量查询 - 更新SQL映射文件中的selectContractPage和新增selectContractsByOrderCodes查询 - 在采购计划服务实现中查询时刷新进度并关联合同详情 - 在前端界面中新增关联合同标签页显示合同详细信息表格 - 重构采购到货界面将采购要求和到货明细合并显示 - 添加合同状态文本转换方法和相关样式定义 --- .../erp/domain/vo/ErpContractOptionVo.java | 99 +++++++++++++++++ .../klp/erp/domain/vo/ErpPurchasePlanVo.java | 3 + .../klp/erp/mapper/ErpPurchasePlanMapper.java | 5 + .../impl/ErpPurchasePlanServiceImpl.java | 9 ++ .../mapper/erp/ErpPurchasePlanMapper.xml | 100 ++++++++++++++++-- .../src/views/erp/purchaseDelivery/index.vue | 49 +++++++-- klp-ui/src/views/erp/purchasePlan/index.vue | 28 +++++ 7 files changed, 276 insertions(+), 17 deletions(-) diff --git a/klp-erp/src/main/java/com/klp/erp/domain/vo/ErpContractOptionVo.java b/klp-erp/src/main/java/com/klp/erp/domain/vo/ErpContractOptionVo.java index 1e9f0eaad..3043ceb48 100644 --- a/klp-erp/src/main/java/com/klp/erp/domain/vo/ErpContractOptionVo.java +++ b/klp-erp/src/main/java/com/klp/erp/domain/vo/ErpContractOptionVo.java @@ -1,9 +1,11 @@ package com.klp.erp.domain.vo; +import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import java.io.Serializable; import java.math.BigDecimal; +import java.util.Date; /** * 采购计划左侧「合同列表」视图对象:crm_order + 该合同已有的采购计划数。 @@ -42,4 +44,101 @@ public class ErpContractOptionVo implements Serializable { /** 该合同已挂接的采购计划数 */ private Integer planCount; + + // ====== 以下为 crm_order 全量补充字段 ====== + + /** 订单类型:pre-预订单,formal-正式订单 */ + private Long orderType; + + /** 交货日期 */ + @JsonFormat(pattern = "yyyy-MM-dd") + private Date deliveryDate; + + /** 订单状态 */ + private Long orderStatus; + + /** 财务状态 */ + private Long financeStatus; + + /** 未结款数额 */ + private BigDecimal unpaidAmount; + + /** 签订时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + private Date signTime; + + /** 签订地点 */ + private String signLocation; + + /** 产品内容 */ + private String productContent; + + /** 合同内容 */ + private String contractContent; + + /** 供方地址 */ + private String supplierAddress; + + /** 供方电话 */ + private String supplierPhone; + + /** 供方开户行 */ + private String supplierBank; + + /** 供方账号 */ + private String supplierAccount; + + /** 供方税号 */ + private String supplierTaxNo; + + /** 需方地址 */ + private String customerAddress; + + /** 需方电话 */ + private String customerPhone; + + /** 需方开户行 */ + private String customerBank; + + /** 需方账号 */ + private String customerAccount; + + /** 需方税号 */ + private String customerTaxNo; + + /** 技术附件 */ + private String techAnnex; + + /** 商务附件 */ + private String businessAnnex; + + /** 排产函 */ + private String productionSchedule; + + /** 算单价备注 */ + private String unitPriceRemark; + + /** 应付定金(万元) */ + private BigDecimal depositPayable; + + /** 已付定金(万元) */ + private BigDecimal depositPaid; + + /** 定金比例(%) */ + private BigDecimal depositRatio; + + /** 合同状态 0=草稿 1=生效 2=作废 3=已完成 */ + private Long status; + + /** 关联合同ID */ + private Long contractId; + + /** 附件 */ + private String annexFiles; + + /** 备注 */ + private String remark; + + /** 是否置顶 */ + private Integer isTop; } diff --git a/klp-erp/src/main/java/com/klp/erp/domain/vo/ErpPurchasePlanVo.java b/klp-erp/src/main/java/com/klp/erp/domain/vo/ErpPurchasePlanVo.java index 3700fb25e..c3aecdd64 100644 --- a/klp-erp/src/main/java/com/klp/erp/domain/vo/ErpPurchasePlanVo.java +++ b/klp-erp/src/main/java/com/klp/erp/domain/vo/ErpPurchasePlanVo.java @@ -86,6 +86,9 @@ public class ErpPurchasePlanVo implements Serializable { /** 关联销售合同编号(展示用) */ private List contractCodes; + /** 关联销售合同信息(来自 crm_order,含客户、金额、销售员等) */ + private List contractInfos; + /** 审核历史(每次审核/驳回留痕) */ private List auditLogs; } diff --git a/klp-erp/src/main/java/com/klp/erp/mapper/ErpPurchasePlanMapper.java b/klp-erp/src/main/java/com/klp/erp/mapper/ErpPurchasePlanMapper.java index 00c2cb581..c49b3a72b 100644 --- a/klp-erp/src/main/java/com/klp/erp/mapper/ErpPurchasePlanMapper.java +++ b/klp-erp/src/main/java/com/klp/erp/mapper/ErpPurchasePlanMapper.java @@ -61,4 +61,9 @@ public interface ErpPurchasePlanMapper extends BaseMapperPlus selectDistinctManufacturers(@Param("kw") String kw); + + /** + * 根据合同编号(order_code)批量查询 crm_order 合同信息。 + */ + List selectContractsByOrderCodes(@Param("codes") List codes); } diff --git a/klp-erp/src/main/java/com/klp/erp/service/impl/ErpPurchasePlanServiceImpl.java b/klp-erp/src/main/java/com/klp/erp/service/impl/ErpPurchasePlanServiceImpl.java index 6f7e5d341..b2967a137 100644 --- a/klp-erp/src/main/java/com/klp/erp/service/impl/ErpPurchasePlanServiceImpl.java +++ b/klp-erp/src/main/java/com/klp/erp/service/impl/ErpPurchasePlanServiceImpl.java @@ -73,6 +73,8 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService { @Override public ErpPurchasePlanVo queryById(Long planId) { + // 刷新到货进度(含在途统计),确保每次查看都是最新数据 + refreshProgress(planId); ErpPurchasePlanVo vo = baseMapper.selectVoById(planId); if (vo == null) { return null; @@ -88,6 +90,10 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService { if (!orderIds.isEmpty()) { vo.setContractCodes(baseMapper.selectOrderCodes(orderIds)); } + // 关联合同详情(从 crm_order 按 contractCodes 批量查) + if (vo.getContractCodes() != null && !vo.getContractCodes().isEmpty()) { + vo.setContractInfos(baseMapper.selectContractsByOrderCodes(vo.getContractCodes())); + } fillProgress(vo); // 审核历史(含每次驳回理由) vo.setAuditLogs(queryAuditLogs(planId)); @@ -484,6 +490,9 @@ public class ErpPurchasePlanServiceImpl implements IErpPurchasePlanService { if (!orderIds.isEmpty()) { v.setContractCodes(baseMapper.selectOrderCodes(orderIds)); } + if (v.getContractCodes() != null && !v.getContractCodes().isEmpty()) { + v.setContractInfos(baseMapper.selectContractsByOrderCodes(v.getContractCodes())); + } } return TableDataInfo.build(result); } diff --git a/klp-erp/src/main/resources/mapper/erp/ErpPurchasePlanMapper.xml b/klp-erp/src/main/resources/mapper/erp/ErpPurchasePlanMapper.xml index 9bc505264..f4713426f 100644 --- a/klp-erp/src/main/resources/mapper/erp/ErpPurchasePlanMapper.xml +++ b/klp-erp/src/main/resources/mapper/erp/ErpPurchasePlanMapper.xml @@ -32,17 +32,48 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ORDER BY order_id, item_id - + + + +