Commit 8bcd65d2653092efcaa23a059fd5307e8f198f63

Authored by YunaiV
1 parent b8d340c7

✨ feat(task): 添加质检标志字段及相关查询功能

在生产任务和工艺路线工序中新增质检标志字段 `checkFlag`,并更新相关查询逻辑以支持根据该字段进行过滤。此变更旨在增强任务管理的灵活性和准确性。
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/task/MesProTaskController.java
@@ -39,12 +39,13 @@ import org.springframework.security.access.prepost.PreAuthorize; @@ -39,12 +39,13 @@ import org.springframework.security.access.prepost.PreAuthorize;
39 import org.springframework.validation.annotation.Validated; 39 import org.springframework.validation.annotation.Validated;
40 import org.springframework.web.bind.annotation.*; 40 import org.springframework.web.bind.annotation.*;
41 41
  42 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO;
  43 +import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService;
  44 +
42 import java.io.IOException; 45 import java.io.IOException;
43 import java.math.BigDecimal; 46 import java.math.BigDecimal;
44 import java.math.RoundingMode; 47 import java.math.RoundingMode;
45 -import java.util.Collections;  
46 -import java.util.List;  
47 -import java.util.Map; 48 +import java.util.*;
48 49
49 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; 50 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
50 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 51 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -59,24 +60,20 @@ public class MesProTaskController { @@ -59,24 +60,20 @@ public class MesProTaskController {
59 60
60 @Resource 61 @Resource
61 private MesProTaskService taskService; 62 private MesProTaskService taskService;
62 -  
63 @Resource 63 @Resource
64 private MesProWorkOrderService workOrderService; 64 private MesProWorkOrderService workOrderService;
65 -  
66 @Resource 65 @Resource
67 private MesMdWorkstationService workstationService; 66 private MesMdWorkstationService workstationService;
68 -  
69 @Resource 67 @Resource
70 private MesProProcessService processService; 68 private MesProProcessService processService;
71 -  
72 @Resource 69 @Resource
73 private MesMdItemService itemService; 70 private MesMdItemService itemService;
74 -  
75 @Resource 71 @Resource
76 private MesMdClientService clientService; 72 private MesMdClientService clientService;
77 -  
78 @Resource 73 @Resource
79 private MesMdUnitMeasureService unitMeasureService; 74 private MesMdUnitMeasureService unitMeasureService;
  75 + @Resource
  76 + private MesProRouteProcessService routeProcessService;
80 77
81 @PostMapping("/create") 78 @PostMapping("/create")
82 @Operation(summary = "创建生产任务") 79 @Operation(summary = "创建生产任务")
@@ -217,11 +214,22 @@ public class MesProTaskController { @@ -217,11 +214,22 @@ public class MesProTaskController {
217 Map<Long, MesMdWorkstationDO> workstationMap = workstationService.getWorkstationMap( 214 Map<Long, MesMdWorkstationDO> workstationMap = workstationService.getWorkstationMap(
218 convertSet(list, MesProTaskDO::getWorkstationId)); 215 convertSet(list, MesProTaskDO::getWorkstationId));
219 Map<Long, MesProProcessDO> processMap = processService.getProcessMap( 216 Map<Long, MesProProcessDO> processMap = processService.getProcessMap(
220 - new java.util.ArrayList<>(convertSet(list, MesProTaskDO::getProcessId))); 217 + new ArrayList<>(convertSet(list, MesProTaskDO::getProcessId)));
221 Map<Long, MesMdItemDO> itemMap = itemService.getItemMap( 218 Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
222 convertSet(list, MesProTaskDO::getItemId)); 219 convertSet(list, MesProTaskDO::getItemId));
223 Map<Long, MesMdClientDO> clientMap = clientService.getClientMap( 220 Map<Long, MesMdClientDO> clientMap = clientService.getClientMap(
224 convertSet(list, MesProTaskDO::getClientId)); 221 convertSet(list, MesProTaskDO::getClientId));
  222 + // 工序的 checkFlag:批量查询后构建 routeId -> processId -> checkFlag 的双层 Map
  223 + Set<Long> routeIds = convertSet(list, MesProTaskDO::getRouteId);
  224 + Map<Long, Map<Long, Boolean>> routeProcessCheckFlagMap = new HashMap<>();
  225 + if (CollUtil.isNotEmpty(routeIds)) {
  226 + List<MesProRouteProcessDO> allRouteProcesses = routeProcessService.getRouteProcessListByRouteIds(routeIds);
  227 + for (MesProRouteProcessDO rp : allRouteProcesses) {
  228 + routeProcessCheckFlagMap
  229 + .computeIfAbsent(rp.getRouteId(), k -> new HashMap<>())
  230 + .put(rp.getProcessId(), Boolean.TRUE.equals(rp.getCheckFlag()));
  231 + }
  232 + }
225 // 拼接 VO 233 // 拼接 VO
226 return convertList(list, task -> { 234 return convertList(list, task -> {
227 MesProTaskRespVO vo = BeanUtils.toBean(task, MesProTaskRespVO.class); 235 MesProTaskRespVO vo = BeanUtils.toBean(task, MesProTaskRespVO.class);
@@ -235,6 +243,8 @@ public class MesProTaskController { @@ -235,6 +243,8 @@ public class MesProTaskController {
235 vo.setItemCode(item.getCode()).setItemName(item.getName()).setItemSpec(item.getSpecification())); 243 vo.setItemCode(item.getCode()).setItemName(item.getName()).setItemSpec(item.getSpecification()));
236 findAndThen(clientMap, task.getClientId(), c -> 244 findAndThen(clientMap, task.getClientId(), c ->
237 vo.setClientName(c.getName())); 245 vo.setClientName(c.getName()));
  246 + findAndThen(routeProcessCheckFlagMap, task.getRouteId(), processCheckMap ->
  247 + findAndThen(processCheckMap, task.getProcessId(), vo::setCheckFlag));
238 return vo; 248 return vo;
239 }); 249 });
240 } 250 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/task/vo/MesProTaskPageReqVO.java
@@ -42,6 +42,9 @@ public class MesProTaskPageReqVO extends PageParam { @@ -42,6 +42,9 @@ public class MesProTaskPageReqVO extends PageParam {
42 @Schema(description = "任务状态列表(IN 查询)", example = "[0, 1, 2]") 42 @Schema(description = "任务状态列表(IN 查询)", example = "[0, 1, 2]")
43 private List<Integer> statuses; 43 private List<Integer> statuses;
44 44
  45 + @Schema(description = "是否质检(关联工艺路线工序)", example = "true")
  46 + private Boolean checkFlag;
  47 +
45 @Schema(description = "创建时间") 48 @Schema(description = "创建时间")
46 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 49 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
47 private LocalDateTime[] createTime; 50 private LocalDateTime[] createTime;
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/task/vo/MesProTaskRespVO.java
@@ -103,6 +103,9 @@ public class MesProTaskRespVO { @@ -103,6 +103,9 @@ public class MesProTaskRespVO {
103 @Schema(description = "任务状态", example = "0") 103 @Schema(description = "任务状态", example = "0")
104 private Integer status; 104 private Integer status;
105 105
  106 + @Schema(description = "是否质检(派生自工艺路线工序 checkFlag)", example = "true")
  107 + private Boolean checkFlag;
  108 +
106 @Schema(description = "备注", example = "备注") 109 @Schema(description = "备注", example = "备注")
107 private String remark; 110 private String remark;
108 111
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/task/MesProTaskMapper.java
@@ -3,7 +3,9 @@ package cn.iocoder.yudao.module.mes.dal.mysql.pro.task; @@ -3,7 +3,9 @@ package cn.iocoder.yudao.module.mes.dal.mysql.pro.task;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
6 import cn.iocoder.yudao.module.mes.controller.admin.pro.task.vo.MesProTaskPageReqVO; 7 import cn.iocoder.yudao.module.mes.controller.admin.pro.task.vo.MesProTaskPageReqVO;
  8 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO;
7 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO; 9 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
8 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; 10 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
9 import org.apache.ibatis.annotations.Mapper; 11 import org.apache.ibatis.annotations.Mapper;
@@ -20,8 +22,16 @@ import java.util.List; @@ -20,8 +22,16 @@ import java.util.List;
20 public interface MesProTaskMapper extends BaseMapperX<MesProTaskDO> { 22 public interface MesProTaskMapper extends BaseMapperX<MesProTaskDO> {
21 23
22 default PageResult<MesProTaskDO> selectPage(MesProTaskPageReqVO reqVO) { 24 default PageResult<MesProTaskDO> selectPage(MesProTaskPageReqVO reqVO) {
23 - return selectPage(reqVO, new LambdaQueryWrapperX<MesProTaskDO>()  
24 - .likeIfPresent(MesProTaskDO::getCode, reqVO.getCode()) 25 + MPJLambdaWrapperX<MesProTaskDO> query = new MPJLambdaWrapperX<>();
  26 + query.selectAll(MesProTaskDO.class);
  27 + // 当需要按 checkFlag 过滤时,LEFT JOIN pro_route_process
  28 + if (reqVO.getCheckFlag() != null) {
  29 + query.leftJoin(MesProRouteProcessDO.class, on -> on
  30 + .eq(MesProRouteProcessDO::getRouteId, MesProTaskDO::getRouteId)
  31 + .eq(MesProRouteProcessDO::getProcessId, MesProTaskDO::getProcessId));
  32 + query.eq(MesProRouteProcessDO::getCheckFlag, reqVO.getCheckFlag());
  33 + }
  34 + query.likeIfPresent(MesProTaskDO::getCode, reqVO.getCode())
25 .likeIfPresent(MesProTaskDO::getName, reqVO.getName()) 35 .likeIfPresent(MesProTaskDO::getName, reqVO.getName())
26 .eqIfPresent(MesProTaskDO::getWorkOrderId, reqVO.getWorkOrderId()) 36 .eqIfPresent(MesProTaskDO::getWorkOrderId, reqVO.getWorkOrderId())
27 .eqIfPresent(MesProTaskDO::getRouteId, reqVO.getRouteId()) 37 .eqIfPresent(MesProTaskDO::getRouteId, reqVO.getRouteId())
@@ -30,7 +40,8 @@ public interface MesProTaskMapper extends BaseMapperX&lt;MesProTaskDO&gt; { @@ -30,7 +40,8 @@ public interface MesProTaskMapper extends BaseMapperX&lt;MesProTaskDO&gt; {
30 .eqIfPresent(MesProTaskDO::getStatus, reqVO.getStatus()) 40 .eqIfPresent(MesProTaskDO::getStatus, reqVO.getStatus())
31 .inIfPresent(MesProTaskDO::getStatus, reqVO.getStatuses()) 41 .inIfPresent(MesProTaskDO::getStatus, reqVO.getStatuses())
32 .betweenIfPresent(MesProTaskDO::getCreateTime, reqVO.getCreateTime()) 42 .betweenIfPresent(MesProTaskDO::getCreateTime, reqVO.getCreateTime())
33 - .orderByDesc(MesProTaskDO::getId)); 43 + .orderByDesc(MesProTaskDO::getId);
  44 + return selectPage(reqVO, query);
34 } 45 }
35 46
36 default List<MesProTaskDO> selectListByWorkOrderId(Long workOrderId) { 47 default List<MesProTaskDO> selectListByWorkOrderId(Long workOrderId) {
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/task/MesProTaskMapperTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.mysql.pro.task;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  5 +import cn.iocoder.yudao.module.mes.controller.admin.pro.task.vo.MesProTaskPageReqVO;
  6 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
  8 +import cn.iocoder.yudao.module.mes.dal.mysql.pro.route.MesProRouteProcessMapper;
  9 +import jakarta.annotation.Resource;
  10 +import org.junit.jupiter.api.Test;
  11 +
  12 +import java.math.BigDecimal;
  13 +import java.util.List;
  14 +import java.util.function.Consumer;
  15 +
  16 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
  17 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
  18 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  19 +import static org.junit.jupiter.api.Assertions.assertEquals;
  20 +
  21 +/**
  22 + * {@link MesProTaskMapper#selectPage(MesProTaskPageReqVO)} 的单元测试
  23 + *
  24 + * @author 芋道源码
  25 + */
  26 +public class MesProTaskMapperTest extends BaseDbUnitTest {
  27 +
  28 + @Resource
  29 + private MesProTaskMapper taskMapper;
  30 +
  31 + @Resource
  32 + private MesProRouteProcessMapper routeProcessMapper;
  33 +
  34 + /**
  35 + * 创建 Task 时统一设置 BigDecimal 字段为 2 位小数,避免 H2 decimal(14,2) 精度不匹配
  36 + */
  37 + private MesProTaskDO createTaskPojo(Consumer<MesProTaskDO> consumer) {
  38 + return randomPojo(MesProTaskDO.class, o -> {
  39 + o.setQuantity(new BigDecimal("10.00"));
  40 + o.setProducedQuantity(new BigDecimal("5.00"));
  41 + o.setQualifyQuantity(new BigDecimal("4.00"));
  42 + o.setUnqualifyQuantity(new BigDecimal("1.00"));
  43 + o.setChangedQuantity(new BigDecimal("0.00"));
  44 + consumer.accept(o);
  45 + });
  46 + }
  47 +
  48 + // ==================== selectPage 基础过滤 ====================
  49 +
  50 + @Test
  51 + public void testSelectPage_byCode() {
  52 + MesProTaskDO matchTask = createTaskPojo(o -> {
  53 + o.setCode("PT202501010001");
  54 + o.setStatus(0);
  55 + });
  56 + taskMapper.insert(matchTask);
  57 + taskMapper.insert(cloneIgnoreId(matchTask, o -> o.setCode("OTHER_CODE")));
  58 +
  59 + MesProTaskPageReqVO reqVO = new MesProTaskPageReqVO();
  60 + reqVO.setCode("PT2025");
  61 + PageResult<MesProTaskDO> result = taskMapper.selectPage(reqVO);
  62 +
  63 + assertEquals(1, result.getTotal());
  64 + assertPojoEquals(matchTask, result.getList().get(0));
  65 + }
  66 +
  67 + @Test
  68 + public void testSelectPage_byName() {
  69 + MesProTaskDO matchTask = createTaskPojo(o -> {
  70 + o.setName("注塑任务-A");
  71 + o.setStatus(0);
  72 + });
  73 + taskMapper.insert(matchTask);
  74 + taskMapper.insert(cloneIgnoreId(matchTask, o -> o.setName("OTHER_NAME")));
  75 +
  76 + MesProTaskPageReqVO reqVO = new MesProTaskPageReqVO();
  77 + reqVO.setName("注塑");
  78 + PageResult<MesProTaskDO> result = taskMapper.selectPage(reqVO);
  79 +
  80 + assertEquals(1, result.getTotal());
  81 + assertPojoEquals(matchTask, result.getList().get(0));
  82 + }
  83 +
  84 + @Test
  85 + public void testSelectPage_byWorkOrderId() {
  86 + MesProTaskDO matchTask = createTaskPojo(o -> {
  87 + o.setWorkOrderId(100L);
  88 + o.setStatus(0);
  89 + });
  90 + taskMapper.insert(matchTask);
  91 + taskMapper.insert(cloneIgnoreId(matchTask, o -> o.setWorkOrderId(999L)));
  92 +
  93 + MesProTaskPageReqVO reqVO = new MesProTaskPageReqVO();
  94 + reqVO.setWorkOrderId(100L);
  95 + PageResult<MesProTaskDO> result = taskMapper.selectPage(reqVO);
  96 +
  97 + assertEquals(1, result.getTotal());
  98 + assertPojoEquals(matchTask, result.getList().get(0));
  99 + }
  100 +
  101 + @Test
  102 + public void testSelectPage_byStatus() {
  103 + MesProTaskDO matchTask = createTaskPojo(o -> o.setStatus(1));
  104 + taskMapper.insert(matchTask);
  105 + taskMapper.insert(cloneIgnoreId(matchTask, o -> o.setStatus(2)));
  106 +
  107 + MesProTaskPageReqVO reqVO = new MesProTaskPageReqVO();
  108 + reqVO.setStatus(1);
  109 + PageResult<MesProTaskDO> result = taskMapper.selectPage(reqVO);
  110 +
  111 + assertEquals(1, result.getTotal());
  112 + assertPojoEquals(matchTask, result.getList().get(0));
  113 + }
  114 +
  115 + @Test
  116 + public void testSelectPage_byStatuses() {
  117 + MesProTaskDO task1 = createTaskPojo(o -> o.setStatus(1));
  118 + MesProTaskDO task2 = createTaskPojo(o -> o.setStatus(2));
  119 + MesProTaskDO task3 = createTaskPojo(o -> o.setStatus(3));
  120 + taskMapper.insert(task1);
  121 + taskMapper.insert(task2);
  122 + taskMapper.insert(task3);
  123 +
  124 + MesProTaskPageReqVO reqVO = new MesProTaskPageReqVO();
  125 + reqVO.setStatuses(List.of(1, 2));
  126 + PageResult<MesProTaskDO> result = taskMapper.selectPage(reqVO);
  127 +
  128 + assertEquals(2, result.getTotal());
  129 + }
  130 +
  131 + @Test
  132 + public void testSelectPage_noFilter() {
  133 + MesProTaskDO task1 = createTaskPojo(o -> o.setStatus(0));
  134 + MesProTaskDO task2 = createTaskPojo(o -> o.setStatus(1));
  135 + taskMapper.insert(task1);
  136 + taskMapper.insert(task2);
  137 +
  138 + MesProTaskPageReqVO reqVO = new MesProTaskPageReqVO();
  139 + PageResult<MesProTaskDO> result = taskMapper.selectPage(reqVO);
  140 +
  141 + assertEquals(2, result.getTotal());
  142 + }
  143 +
  144 + // ==================== selectPage + checkFlag (MPJ LEFT JOIN) ====================
  145 +
  146 + @Test
  147 + public void testSelectPage_checkFlagTrue() {
  148 + Long routeId = 10L;
  149 + Long processId1 = 100L;
  150 + Long processId2 = 200L;
  151 +
  152 + MesProTaskDO task1 = createTaskPojo(o -> {
  153 + o.setRouteId(routeId);
  154 + o.setProcessId(processId1);
  155 + o.setStatus(0);
  156 + });
  157 + MesProTaskDO task2 = createTaskPojo(o -> {
  158 + o.setRouteId(routeId);
  159 + o.setProcessId(processId2);
  160 + o.setStatus(0);
  161 + });
  162 + taskMapper.insert(task1);
  163 + taskMapper.insert(task2);
  164 +
  165 + routeProcessMapper.insert(randomPojo(MesProRouteProcessDO.class, o -> {
  166 + o.setRouteId(routeId);
  167 + o.setProcessId(processId1);
  168 + o.setCheckFlag(true);
  169 + }));
  170 + routeProcessMapper.insert(randomPojo(MesProRouteProcessDO.class, o -> {
  171 + o.setRouteId(routeId);
  172 + o.setProcessId(processId2);
  173 + o.setCheckFlag(false);
  174 + }));
  175 +
  176 + // 查询:checkFlag = true,只返回 task1
  177 + MesProTaskPageReqVO reqVO = new MesProTaskPageReqVO();
  178 + reqVO.setCheckFlag(true);
  179 + PageResult<MesProTaskDO> result = taskMapper.selectPage(reqVO);
  180 +
  181 + assertEquals(1, result.getTotal());
  182 + assertPojoEquals(task1, result.getList().get(0));
  183 + }
  184 +
  185 + @Test
  186 + public void testSelectPage_checkFlagFalse() {
  187 + Long routeId = 20L;
  188 + Long processId1 = 300L;
  189 + Long processId2 = 400L;
  190 +
  191 + MesProTaskDO task1 = createTaskPojo(o -> {
  192 + o.setRouteId(routeId);
  193 + o.setProcessId(processId1);
  194 + o.setStatus(0);
  195 + });
  196 + MesProTaskDO task2 = createTaskPojo(o -> {
  197 + o.setRouteId(routeId);
  198 + o.setProcessId(processId2);
  199 + o.setStatus(0);
  200 + });
  201 + taskMapper.insert(task1);
  202 + taskMapper.insert(task2);
  203 +
  204 + routeProcessMapper.insert(randomPojo(MesProRouteProcessDO.class, o -> {
  205 + o.setRouteId(routeId);
  206 + o.setProcessId(processId1);
  207 + o.setCheckFlag(true);
  208 + }));
  209 + routeProcessMapper.insert(randomPojo(MesProRouteProcessDO.class, o -> {
  210 + o.setRouteId(routeId);
  211 + o.setProcessId(processId2);
  212 + o.setCheckFlag(false);
  213 + }));
  214 +
  215 + // 查询:checkFlag = false,只返回 task2
  216 + MesProTaskPageReqVO reqVO = new MesProTaskPageReqVO();
  217 + reqVO.setCheckFlag(false);
  218 + PageResult<MesProTaskDO> result = taskMapper.selectPage(reqVO);
  219 +
  220 + assertEquals(1, result.getTotal());
  221 + assertPojoEquals(task2, result.getList().get(0));
  222 + }
  223 +
  224 + @Test
  225 + public void testSelectPage_checkFlagWithOtherFilter() {
  226 + Long routeId = 30L;
  227 + Long processId = 500L;
  228 +
  229 + MesProTaskDO taskMatch = createTaskPojo(o -> {
  230 + o.setRouteId(routeId);
  231 + o.setProcessId(processId);
  232 + o.setCode("PT-MATCH-001");
  233 + o.setStatus(0);
  234 + });
  235 + MesProTaskDO taskNoMatch = createTaskPojo(o -> {
  236 + o.setRouteId(routeId);
  237 + o.setProcessId(processId);
  238 + o.setCode("OTHER-CODE");
  239 + o.setStatus(0);
  240 + });
  241 + taskMapper.insert(taskMatch);
  242 + taskMapper.insert(taskNoMatch);
  243 +
  244 + routeProcessMapper.insert(randomPojo(MesProRouteProcessDO.class, o -> {
  245 + o.setRouteId(routeId);
  246 + o.setProcessId(processId);
  247 + o.setCheckFlag(true);
  248 + }));
  249 +
  250 + // 查询:checkFlag=true 且 code like 'PT-MATCH'
  251 + MesProTaskPageReqVO reqVO = new MesProTaskPageReqVO();
  252 + reqVO.setCheckFlag(true);
  253 + reqVO.setCode("PT-MATCH");
  254 + PageResult<MesProTaskDO> result = taskMapper.selectPage(reqVO);
  255 +
  256 + assertEquals(1, result.getTotal());
  257 + assertPojoEquals(taskMatch, result.getList().get(0));
  258 + }
  259 +
  260 + @Test
  261 + public void testSelectPage_checkFlagNull_noJoin() {
  262 + Long routeId = 40L;
  263 + Long processId = 600L;
  264 +
  265 + MesProTaskDO task = createTaskPojo(o -> {
  266 + o.setRouteId(routeId);
  267 + o.setProcessId(processId);
  268 + o.setStatus(0);
  269 + });
  270 + taskMapper.insert(task);
  271 +
  272 + MesProTaskPageReqVO reqVO = new MesProTaskPageReqVO();
  273 + PageResult<MesProTaskDO> result = taskMapper.selectPage(reqVO);
  274 +
  275 + assertEquals(1, result.getTotal());
  276 + assertPojoEquals(task, result.getList().get(0));
  277 + }
  278 +
  279 +}
yudao-module-mes/src/test/resources/sql/clean.sql
@@ -13,3 +13,5 @@ DELETE FROM &quot;mes_wm_item_receipt&quot;; @@ -13,3 +13,5 @@ DELETE FROM &quot;mes_wm_item_receipt&quot;;
13 DELETE FROM "mes_wm_item_receipt_line"; 13 DELETE FROM "mes_wm_item_receipt_line";
14 DELETE FROM "mes_wm_item_receipt_detail"; 14 DELETE FROM "mes_wm_item_receipt_detail";
15 DELETE FROM "mes_wm_batch"; 15 DELETE FROM "mes_wm_batch";
  16 +DELETE FROM "mes_pro_task";
  17 +DELETE FROM "mes_pro_route_process";
yudao-module-mes/src/test/resources/sql/create_tables.sql
@@ -618,3 +618,63 @@ CREATE TABLE IF NOT EXISTS &quot;mes_wm_batch&quot; ( @@ -618,3 +618,63 @@ CREATE TABLE IF NOT EXISTS &quot;mes_wm_batch&quot; (
618 "tenant_id" bigint NOT NULL DEFAULT 0, 618 "tenant_id" bigint NOT NULL DEFAULT 0,
619 PRIMARY KEY ("id") 619 PRIMARY KEY ("id")
620 ); 620 );
  621 +
  622 +-- ----------------------------
  623 +-- MES 生产任务
  624 +-- ----------------------------
  625 +CREATE TABLE IF NOT EXISTS "mes_pro_task" (
  626 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  627 + "code" varchar(64) DEFAULT NULL,
  628 + "name" varchar(255) DEFAULT NULL,
  629 + "work_order_id" bigint DEFAULT NULL,
  630 + "workstation_id" bigint DEFAULT NULL,
  631 + "route_id" bigint DEFAULT NULL,
  632 + "process_id" bigint DEFAULT NULL,
  633 + "item_id" bigint DEFAULT NULL,
  634 + "quantity" decimal(14,2) DEFAULT NULL,
  635 + "produced_quantity" decimal(14,2) DEFAULT NULL,
  636 + "qualify_quantity" decimal(14,2) DEFAULT NULL,
  637 + "unqualify_quantity" decimal(14,2) DEFAULT NULL,
  638 + "changed_quantity" decimal(14,2) DEFAULT NULL,
  639 + "client_id" bigint DEFAULT NULL,
  640 + "start_time" timestamp DEFAULT NULL,
  641 + "duration" int DEFAULT NULL,
  642 + "end_time" timestamp DEFAULT NULL,
  643 + "color_code" varchar(20) DEFAULT NULL,
  644 + "finish_date" timestamp DEFAULT NULL,
  645 + "cancel_date" timestamp DEFAULT NULL,
  646 + "status" int DEFAULT NULL,
  647 + "remark" varchar(500) DEFAULT NULL,
  648 + "creator" varchar(64) DEFAULT '',
  649 + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  650 + "updater" varchar(64) DEFAULT '',
  651 + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  652 + "deleted" bit NOT NULL DEFAULT FALSE,
  653 + "tenant_id" bigint NOT NULL DEFAULT 0,
  654 + PRIMARY KEY ("id")
  655 +);
  656 +
  657 +-- ----------------------------
  658 +-- MES 工艺路线工序
  659 +-- ----------------------------
  660 +CREATE TABLE IF NOT EXISTS "mes_pro_route_process" (
  661 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  662 + "route_id" bigint DEFAULT NULL,
  663 + "process_id" bigint DEFAULT NULL,
  664 + "sort" int DEFAULT NULL,
  665 + "next_process_id" bigint DEFAULT NULL,
  666 + "link_type" int DEFAULT NULL,
  667 + "prepare_time" int DEFAULT NULL,
  668 + "wait_time" int DEFAULT NULL,
  669 + "color_code" varchar(20) DEFAULT NULL,
  670 + "key_flag" bit DEFAULT FALSE,
  671 + "check_flag" bit DEFAULT FALSE,
  672 + "remark" varchar(500) DEFAULT NULL,
  673 + "creator" varchar(64) DEFAULT '',
  674 + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  675 + "updater" varchar(64) DEFAULT '',
  676 + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  677 + "deleted" bit NOT NULL DEFAULT FALSE,
  678 + "tenant_id" bigint NOT NULL DEFAULT 0,
  679 + PRIMARY KEY ("id")
  680 +);