Commit 40a6786a4a1e4f435bdb44835cd68e720e111092

Authored by YunaiV
1 parent 0b8834cd

✨ feat(mes): 添加工单、工作站、任务和客户信息字段

yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/pendinginspect/MesQcPendingInspectController.java
... ... @@ -5,12 +5,18 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 6 import cn.iocoder.yudao.module.mes.controller.admin.qc.pendinginspect.vo.MesQcPendingInspectPageReqVO;
7 7 import cn.iocoder.yudao.module.mes.controller.admin.qc.pendinginspect.vo.MesQcPendingInspectRespVO;
  8 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.client.MesMdClientDO;
8 9 import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
9 10 import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
10 11 import cn.iocoder.yudao.module.mes.dal.dataobject.md.vendor.MesMdVendorDO;
  12 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO;
  13 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
  14 +import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService;
11 15 import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
12 16 import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
13 17 import cn.iocoder.yudao.module.mes.service.md.vendor.MesMdVendorService;
  18 +import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
  19 +import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
14 20 import cn.iocoder.yudao.module.mes.service.qc.pendinginspect.MesQcPendingInspectService;
15 21 import io.swagger.v3.oas.annotations.Operation;
16 22 import io.swagger.v3.oas.annotations.tags.Tag;
... ... @@ -42,6 +48,12 @@ public class MesQcPendingInspectController {
42 48 private MesMdUnitMeasureService unitMeasureService;
43 49 @Resource
44 50 private MesMdVendorService vendorService;
  51 + @Resource
  52 + private MesMdClientService clientService;
  53 + @Resource
  54 + private MesMdWorkstationService workstationService;
  55 + @Resource
  56 + private MesProTaskService taskService;
45 57  
46 58 @GetMapping("/page")
47 59 @Operation(summary = "获得待检任务分页")
... ... @@ -49,7 +61,7 @@ public class MesQcPendingInspectController {
49 61 public CommonResult<PageResult<MesQcPendingInspectRespVO>> getPendingInspectPage(
50 62 @Valid MesQcPendingInspectPageReqVO pageReqVO) {
51 63 PageResult<MesQcPendingInspectRespVO> pageResult = pendingInspectService.getPendingInspectPage(pageReqVO);
52   - // 拼接 VO:物料、供应商、计量单位
  64 + // 拼接 VO:物料、供应商、客户、工作站、任务等
53 65 buildPendingInspectRespVOList(pageResult.getList());
54 66 return success(pageResult);
55 67 }
... ... @@ -66,9 +78,18 @@ public class MesQcPendingInspectController {
66 78 // 批量查询计量单位(通过物料的 unitMeasureId)
67 79 Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
68 80 convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
69   - // 批量查询供应商
  81 + // 批量查询供应商(IQC 场景)
70 82 Map<Long, MesMdVendorDO> vendorMap = vendorService.getVendorMap(
71 83 convertSet(list, MesQcPendingInspectRespVO::getVendorId));
  84 + // 批量查询客户(OQC/RQC 场景)
  85 + Map<Long, MesMdClientDO> clientMap = clientService.getClientMap(
  86 + convertSet(list, MesQcPendingInspectRespVO::getClientId));
  87 + // 批量查询工作站(IPQC/RQC 场景)
  88 + Map<Long, MesMdWorkstationDO> workstationMap = workstationService.getWorkstationMap(
  89 + convertSet(list, MesQcPendingInspectRespVO::getWorkstationId));
  90 + // 批量查询任务(IPQC 场景)
  91 + Map<Long, MesProTaskDO> taskMap = taskService.getTaskMap(
  92 + convertSet(list, MesQcPendingInspectRespVO::getTaskId));
72 93 // 拼装
73 94 list.forEach(vo -> {
74 95 findAndThen(itemMap, vo.getItemId(), item -> {
... ... @@ -76,8 +97,11 @@ public class MesQcPendingInspectController {
76 97 findAndThen(unitMeasureMap, item.getUnitMeasureId(),
77 98 unit -> vo.setUnitName(unit.getName()));
78 99 });
79   - findAndThen(vendorMap, vo.getVendorId(),
80   - vendor -> vo.setVendorName(vendor.getName()));
  100 + findAndThen(vendorMap, vo.getVendorId(), vendor -> vo.setVendorName(vendor.getName()));
  101 + findAndThen(clientMap, vo.getClientId(), client -> vo.setClientName(client.getName()));
  102 + findAndThen(workstationMap, vo.getWorkstationId(),
  103 + workstation -> vo.setWorkstationName(workstation.getName()));
  104 + findAndThen(taskMap, vo.getTaskId(), task -> vo.setTaskCode(task.getCode()));
81 105 });
82 106 }
83 107  
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/pendinginspect/vo/MesQcPendingInspectRespVO.java
... ... @@ -55,9 +55,34 @@ public class MesQcPendingInspectRespVO {
55 55 @Schema(description = "供应商名称", example = "供应商A")
56 56 private String vendorName;
57 57  
  58 + // ========== 工单/工作站/任务(IPQC/RQC 场景) ==========
  59 +
  60 + @Schema(description = "生产工单 ID", example = "10")
  61 + private Long workOrderId;
  62 +
  63 + @Schema(description = "工作站 ID", example = "20")
  64 + private Long workstationId;
  65 +
  66 + @Schema(description = "工作站名称", example = "工作站A")
  67 + private String workstationName;
  68 +
  69 + @Schema(description = "生产任务 ID", example = "30")
  70 + private Long taskId;
  71 +
  72 + @Schema(description = "生产任务编码", example = "TASK2025001")
  73 + private String taskCode;
  74 +
  75 + // ========== 客户(OQC/RQC 场景) ==========
  76 +
  77 + @Schema(description = "客户 ID", example = "40")
  78 + private Long clientId;
  79 +
  80 + @Schema(description = "客户名称", example = "客户A")
  81 + private String clientName;
  82 +
58 83 // ========== 时间 ==========
59 84  
60 85 @Schema(description = "记录时间")
61 86 private LocalDateTime recordTime;
62 87  
63 88 -}
  89 +}
64 90 \ No newline at end of file
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
... ... @@ -282,7 +282,7 @@ public interface ErrorCodeConstants {
282 282 ErrorCode QC_IQC_CODE_DUPLICATE = new ErrorCode(1_040_603_001, "来料检验单编号已存在");
283 283 ErrorCode QC_IQC_NOT_PREPARE = new ErrorCode(1_040_603_002, "只有草稿状态的检验单才可操作");
284 284 ErrorCode QC_IQC_QUANTITY_MISMATCH = new ErrorCode(1_040_603_004, "合格品与不合格品数量之和须等于检测数量");
285   - ErrorCode QC_IQC_NO_TEMPLATE = new ErrorCode(1_040_603_005, "当前产品未配置 IQC 检测模板");
  285 + ErrorCode QC_NO_TEMPLATE = new ErrorCode(1_040_603_005, "当前产品未配置检测模板");
286 286 ErrorCode QC_IQC_SOURCE_DOC_PARAMS_MISSING = new ErrorCode(1_040_603_006, "来源单据类型非空时,来源单据 ID 和来源单据行 ID 不能为空");
287 287 ErrorCode QC_IQC_CHECK_RESULT_EMPTY = new ErrorCode(1_040_603_007, "完成检验单前,检测结果必须填写");
288 288 // ========== MES 质量管理-来料检验行(1-040-603-100) ==========
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java
... ... @@ -163,6 +163,9 @@ public class MesProTaskServiceImpl implements MesProTaskService {
163 163  
164 164 @Override
165 165 public List<MesProTaskDO> getTaskList(Collection<Long> ids) {
  166 + if (CollUtil.isEmpty(ids)) {
  167 + return Collections.emptyList();
  168 + }
166 169 return taskMapper.selectByIds(ids);
167 170 }
168 171  
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateDetailServiceImpl.java
... ... @@ -163,7 +163,7 @@ public class MesQcTemplateDetailServiceImpl implements MesQcTemplateDetailServic
163 163 // 1. 查出 itemId 关联的所有 templateId
164 164 List<MesQcTemplateItemDO> templateItems = templateItemMapper.selectListByItemId(itemId);
165 165 if (CollUtil.isEmpty(templateItems)) {
166   - throw exception(QC_IQC_NO_TEMPLATE);
  166 + throw exception(QC_NO_TEMPLATE);
167 167 }
168 168 // 2. 筛选 types 包含 qcType 的模板
169 169 List<MesQcTemplateDO> templates = templateMapper.selectByIds(
... ... @@ -171,7 +171,7 @@ public class MesQcTemplateDetailServiceImpl implements MesQcTemplateDetailServic
171 171 MesQcTemplateDO matchedTemplate = findFirst(templates,
172 172 t -> CollUtil.contains(t.getTypes(), qcType));
173 173 if (matchedTemplate == null) {
174   - throw exception(QC_IQC_NO_TEMPLATE);
  174 + throw exception(QC_NO_TEMPLATE);
175 175 }
176 176 // 3. 返回对应的 templateItem
177 177 return findFirst(templateItems,
... ...
yudao-module-mes/src/main/resources/mapper/qc/pendinginspect/MesQcPendingInspectMapper.xml
... ... @@ -9,6 +9,7 @@
9 9 3. 生产报工(IPQC):状态=待检验(3)
10 10 4. 销售出库单(OQC):行的 oqc_check=1 且 oqc_id IS NULL
11 11 5. 生产退料单(RQC):状态=待检验(5),行的 qc_flag=1 且 quality_status=0(待检)
  12 + 6. 销售退货单(RQC):状态=待执行(10),行的 quality_status=0(待检)
12 13 -->
13 14 <select id="selectQcPendingPage" resultType="cn.iocoder.yudao.module.mes.controller.admin.qc.pendinginspect.vo.MesQcPendingInspectRespVO">
14 15 SELECT * FROM (
... ... @@ -22,7 +23,11 @@
22 23 ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@IQC.type} AS qcType,
23 24 l.item_id AS itemId,
24 25 l.arrival_quantity AS quantity,
25   - n.vendor_id AS vendorId
  26 + n.vendor_id AS vendorId,
  27 + NULL AS workOrderId,
  28 + NULL AS workstationId,
  29 + NULL AS taskId,
  30 + NULL AS clientId
26 31 FROM mes_wm_arrival_notice n
27 32 JOIN mes_wm_arrival_notice_line l ON n.id = l.notice_id
28 33 WHERE n.status = ${@cn.iocoder.yudao.module.mes.enums.wm.MesWmArrivalNoticeStatusEnum@PENDING_QC.status}
... ... @@ -43,7 +48,11 @@
43 48 ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@IQC.type} AS qcType,
44 49 rl.item_id AS itemId,
45 50 rl.quantity AS quantity,
46   - r.vendor_id AS vendorId
  51 + r.vendor_id AS vendorId,
  52 + NULL AS workOrderId,
  53 + NULL AS workstationId,
  54 + NULL AS taskId,
  55 + NULL AS clientId
47 56 FROM mes_wm_outsource_receipt r
48 57 JOIN mes_wm_outsource_receipt_line rl ON r.id = rl.receipt_id
49 58 WHERE r.status = ${@cn.iocoder.yudao.module.mes.enums.wm.MesWmOutsourceReceiptStatusEnum@CONFIRMED.status}
... ... @@ -64,7 +73,11 @@
64 73 ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@IPQC.type} AS qcType,
65 74 f.item_id AS itemId,
66 75 f.uncheck_quantity AS quantity,
67   - NULL AS vendorId
  76 + NULL AS vendorId,
  77 + f.work_order_id AS workOrderId,
  78 + f.workstation_id AS workstationId,
  79 + f.task_id AS taskId,
  80 + NULL AS clientId
68 81 FROM mes_pro_feedback f
69 82 WHERE f.status = ${@cn.iocoder.yudao.module.mes.enums.pro.MesProFeedbackStatusEnum@UNCHECK.status}
70 83 AND f.deleted = 0
... ... @@ -81,7 +94,11 @@
81 94 ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@OQC.type} AS qcType,
82 95 sl.item_id AS itemId,
83 96 sl.quantity AS quantity,
84   - NULL AS vendorId
  97 + NULL AS vendorId,
  98 + NULL AS workOrderId,
  99 + NULL AS workstationId,
  100 + NULL AS taskId,
  101 + s.client_id AS clientId
85 102 FROM mes_wm_product_sales s
86 103 JOIN mes_wm_product_sales_line sl ON s.id = sl.sales_id
87 104 WHERE sl.oqc_check = 1
... ... @@ -101,7 +118,11 @@
101 118 ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@RQC.type} AS qcType,
102 119 ril.item_id AS itemId,
103 120 ril.quantity AS quantity,
104   - NULL AS vendorId
  121 + NULL AS vendorId,
  122 + ri.work_order_id AS workOrderId,
  123 + ri.workstation_id AS workstationId,
  124 + NULL AS taskId,
  125 + NULL AS clientId
105 126 FROM mes_wm_return_issue ri
106 127 JOIN mes_wm_return_issue_line ril ON ri.id = ril.issue_id
107 128 WHERE ri.status = ${@cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnIssueStatusEnum@CONFIRMED.status}
... ... @@ -109,6 +130,30 @@
109 130 AND ril.quality_status = ${@cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum@PENDING.status}
110 131 AND ri.deleted = 0
111 132 AND ril.deleted = 0
  133 +
  134 + UNION ALL
  135 +
  136 + <!-- 6. RQC 来源:销售退货单(待执行(APPROVING),行的 quality_status=0) -->
  137 + SELECT
  138 + r.id AS sourceDocId,
  139 + ${@cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants@WM_RETURN_SALES} AS sourceDocType,
  140 + r.code AS sourceDocCode,
  141 + rl.id AS sourceLineId,
  142 + r.return_date AS recordTime,
  143 + ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@RQC.type} AS qcType,
  144 + rl.item_id AS itemId,
  145 + rl.quantity AS quantity,
  146 + NULL AS vendorId,
  147 + NULL AS workOrderId,
  148 + NULL AS workstationId,
  149 + NULL AS taskId,
  150 + r.client_id AS clientId
  151 + FROM mes_wm_return_sales r
  152 + JOIN mes_wm_return_sales_line rl ON r.id = rl.return_id
  153 + WHERE r.status = ${@cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnSalesStatusEnum@APPROVING.status}
  154 + AND rl.quality_status = ${@cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum@PENDING.status}
  155 + AND r.deleted = 0
  156 + AND rl.deleted = 0
112 157 ) t
113 158 <where>
114 159 <if test="sourceDocCode != null and sourceDocCode != ''">
... ...
yudao-module-mes/src/test/resources/sql/create_tables.sql
... ... @@ -350,7 +350,6 @@ CREATE TABLE IF NOT EXISTS &quot;mes_qc_rqc&quot; (
350 350 "template_id" bigint NOT NULL,
351 351 "source_doc_id" bigint DEFAULT NULL,
352 352 "source_doc_type" int DEFAULT NULL,
353   - "source_doc_code" varchar(64) DEFAULT NULL,
354 353 "source_line_id" bigint DEFAULT NULL,
355 354 "type" int DEFAULT NULL,
356 355 "item_id" bigint NOT NULL,
... ...