Commit 165cd78f174c562f00149edc124eb8381caa5914

Authored by YunaiV
1 parent be3709eb

feat(mes): 新增工艺路线模块,支持路线、工序链、产品及 BOM 管理

从 ktg-mes 迁移工艺路线(pro-route)模块,包含:
- 4 个 DO:MesProRoute / RouteProcess / RouteProduct / RouteProductBom
- 4 个 Mapper 及 9 个 VO(含工序链 findPre/findNext 查询)
- 4 对 Service 接口+实现(链表重建、启用校验、级联删除)
- 4 个 Controller(路线 CRUD+导出,子资源复用父权限)
Showing 30 changed files with 2052 additions and 3 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.pro.route;
  2 +
  3 +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  5 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  7 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  8 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  9 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  10 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.MesProRoutePageReqVO;
  11 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.MesProRouteRespVO;
  12 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.MesProRouteSaveReqVO;
  13 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteDO;
  14 +import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteService;
  15 +import io.swagger.v3.oas.annotations.Operation;
  16 +import io.swagger.v3.oas.annotations.Parameter;
  17 +import io.swagger.v3.oas.annotations.tags.Tag;
  18 +import jakarta.annotation.Resource;
  19 +import jakarta.servlet.http.HttpServletResponse;
  20 +import jakarta.validation.Valid;
  21 +import org.springframework.security.access.prepost.PreAuthorize;
  22 +import org.springframework.validation.annotation.Validated;
  23 +import org.springframework.web.bind.annotation.*;
  24 +
  25 +import java.io.IOException;
  26 +import java.util.List;
  27 +
  28 +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
  29 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  30 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  31 +
  32 +@Tag(name = "管理后台 - MES 工艺路线")
  33 +@RestController
  34 +@RequestMapping("/mes/pro/route")
  35 +@Validated
  36 +public class MesProRouteController {
  37 +
  38 + @Resource
  39 + private MesProRouteService routeService;
  40 +
  41 + @PostMapping("/create")
  42 + @Operation(summary = "创建工艺路线")
  43 + @PreAuthorize("@ss.hasPermission('mes:pro-route:create')")
  44 + public CommonResult<Long> createRoute(@Valid @RequestBody MesProRouteSaveReqVO createReqVO) {
  45 + return success(routeService.createRoute(createReqVO));
  46 + }
  47 +
  48 + @PutMapping("/update")
  49 + @Operation(summary = "更新工艺路线")
  50 + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')")
  51 + public CommonResult<Boolean> updateRoute(@Valid @RequestBody MesProRouteSaveReqVO updateReqVO) {
  52 + routeService.updateRoute(updateReqVO);
  53 + return success(true);
  54 + }
  55 +
  56 + @DeleteMapping("/delete")
  57 + @Operation(summary = "删除工艺路线")
  58 + @Parameter(name = "id", description = "编号", required = true)
  59 + @PreAuthorize("@ss.hasPermission('mes:pro-route:delete')")
  60 + public CommonResult<Boolean> deleteRoute(@RequestParam("id") Long id) {
  61 + routeService.deleteRoute(id);
  62 + return success(true);
  63 + }
  64 +
  65 + @GetMapping("/get")
  66 + @Operation(summary = "获得工艺路线")
  67 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  68 + @PreAuthorize("@ss.hasPermission('mes:pro-route:query')")
  69 + public CommonResult<MesProRouteRespVO> getRoute(@RequestParam("id") Long id) {
  70 + MesProRouteDO route = routeService.getRoute(id);
  71 + return success(BeanUtils.toBean(route, MesProRouteRespVO.class));
  72 + }
  73 +
  74 + @GetMapping("/page")
  75 + @Operation(summary = "获得工艺路线分页")
  76 + @PreAuthorize("@ss.hasPermission('mes:pro-route:query')")
  77 + public CommonResult<PageResult<MesProRouteRespVO>> getRoutePage(@Valid MesProRoutePageReqVO pageReqVO) {
  78 + PageResult<MesProRouteDO> pageResult = routeService.getRoutePage(pageReqVO);
  79 + return success(BeanUtils.toBean(pageResult, MesProRouteRespVO.class));
  80 + }
  81 +
  82 + @GetMapping("/simple-list")
  83 + @Operation(summary = "获得工艺路线精简列表", description = "只包含被开启的工艺路线,主要用于前端的下拉选项")
  84 + public CommonResult<List<MesProRouteRespVO>> getRouteSimpleList() {
  85 + List<MesProRouteDO> list = routeService.getRouteListByStatus(CommonStatusEnum.ENABLE.getStatus());
  86 + return success(convertList(list, route -> new MesProRouteRespVO()
  87 + .setId(route.getId()).setName(route.getName()).setCode(route.getCode())));
  88 + }
  89 +
  90 + @GetMapping("/export-excel")
  91 + @Operation(summary = "导出工艺路线 Excel")
  92 + @PreAuthorize("@ss.hasPermission('mes:pro-route:export')")
  93 + @ApiAccessLog(operateType = EXPORT)
  94 + public void exportRouteExcel(@Valid MesProRoutePageReqVO pageReqVO,
  95 + HttpServletResponse response) throws IOException {
  96 + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
  97 + List<MesProRouteDO> list = routeService.getRoutePage(pageReqVO).getList();
  98 + List<MesProRouteRespVO> data = BeanUtils.toBean(list, MesProRouteRespVO.class);
  99 + ExcelUtils.write(response, "工艺路线.xls", "数据", MesProRouteRespVO.class, data);
  100 + }
  101 +
  102 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProcessController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.pro.route;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process.MesProRouteProcessRespVO;
  6 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process.MesProRouteProcessSaveReqVO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.MesProProcessDO;
  8 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO;
  9 +import cn.iocoder.yudao.module.mes.service.pro.MesProProcessService;
  10 +import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService;
  11 +import io.swagger.v3.oas.annotations.Operation;
  12 +import io.swagger.v3.oas.annotations.Parameter;
  13 +import io.swagger.v3.oas.annotations.tags.Tag;
  14 +import jakarta.annotation.Resource;
  15 +import jakarta.validation.Valid;
  16 +import org.springframework.security.access.prepost.PreAuthorize;
  17 +import org.springframework.validation.annotation.Validated;
  18 +import org.springframework.web.bind.annotation.*;
  19 +
  20 +import java.util.ArrayList;
  21 +import java.util.List;
  22 +import java.util.Map;
  23 +
  24 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  25 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  26 +
  27 +@Tag(name = "管理后台 - MES 工艺路线工序")
  28 +@RestController
  29 +@RequestMapping("/mes/pro/route-process")
  30 +@Validated
  31 +public class MesProRouteProcessController {
  32 +
  33 + @Resource
  34 + private MesProRouteProcessService routeProcessService;
  35 +
  36 + @Resource
  37 + private MesProProcessService processService;
  38 +
  39 + @PostMapping("/create")
  40 + @Operation(summary = "创建工艺路线工序")
  41 + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')")
  42 + public CommonResult<Long> createRouteProcess(@Valid @RequestBody MesProRouteProcessSaveReqVO createReqVO) {
  43 + return success(routeProcessService.createRouteProcess(createReqVO));
  44 + }
  45 +
  46 + @PutMapping("/update")
  47 + @Operation(summary = "更新工艺路线工序")
  48 + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')")
  49 + public CommonResult<Boolean> updateRouteProcess(@Valid @RequestBody MesProRouteProcessSaveReqVO updateReqVO) {
  50 + routeProcessService.updateRouteProcess(updateReqVO);
  51 + return success(true);
  52 + }
  53 +
  54 + @DeleteMapping("/delete")
  55 + @Operation(summary = "删除工艺路线工序")
  56 + @Parameter(name = "id", description = "编号", required = true)
  57 + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')")
  58 + public CommonResult<Boolean> deleteRouteProcess(@RequestParam("id") Long id) {
  59 + routeProcessService.deleteRouteProcess(id);
  60 + return success(true);
  61 + }
  62 +
  63 + @GetMapping("/get")
  64 + @Operation(summary = "获得工艺路线工序")
  65 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  66 + @PreAuthorize("@ss.hasPermission('mes:pro-route:query')")
  67 + public CommonResult<MesProRouteProcessRespVO> getRouteProcess(@RequestParam("id") Long id) {
  68 + MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcess(id);
  69 + return success(buildRouteProcessRespVO(routeProcess));
  70 + }
  71 +
  72 + @GetMapping("/list-by-route")
  73 + @Operation(summary = "按工艺路线获得工序列表")
  74 + @Parameter(name = "routeId", description = "工艺路线编号", required = true, example = "1")
  75 + @PreAuthorize("@ss.hasPermission('mes:pro-route:query')")
  76 + public CommonResult<List<MesProRouteProcessRespVO>> getRouteProcessListByRoute(@RequestParam("routeId") Long routeId) {
  77 + List<MesProRouteProcessDO> list = routeProcessService.getRouteProcessListByRouteId(routeId);
  78 + return success(buildRouteProcessRespVOList(list));
  79 + }
  80 +
  81 + // ==================== 拼接 VO ====================
  82 +
  83 + private List<MesProRouteProcessRespVO> buildRouteProcessRespVOList(List<MesProRouteProcessDO> list) {
  84 + // TODO @AI:collutil 去判断空;
  85 + if (list.isEmpty()) {
  86 + return List.of();
  87 + }
  88 + // 批量查询工序信息
  89 + // TODO @AI:我记得有 CollUtil 可以搞多个的;
  90 + List<Long> processIds = new ArrayList<>();
  91 + for (MesProRouteProcessDO item : list) {
  92 + processIds.add(item.getProcessId());
  93 + if (item.getNextProcessId() != null) {
  94 + processIds.add(item.getNextProcessId());
  95 + }
  96 + }
  97 + // TODO @AI:processService.getProcessMap 直接返回 Map 就好了;
  98 + List<MesProProcessDO> processList = processService.getProcessList(processIds);
  99 + Map<Long, MesProProcessDO> processMap = convertMap(processList, MesProProcessDO::getId);
  100 + // 拼装
  101 + List<MesProRouteProcessRespVO> result = BeanUtils.toBean(list, MesProRouteProcessRespVO.class);
  102 + for (MesProRouteProcessRespVO vo : result) {
  103 + // TODO @AI:MapUtil findMap
  104 + MesProProcessDO process = processMap.get(vo.getProcessId());
  105 + if (process != null) {
  106 + vo.setProcessCode(process.getCode()).setProcessName(process.getName());
  107 + }
  108 + // TODO @AI:MapUtil findMap
  109 + if (vo.getNextProcessId() != null) {
  110 + MesProProcessDO nextProcess = processMap.get(vo.getNextProcessId());
  111 + if (nextProcess != null) {
  112 + vo.setNextProcessName(nextProcess.getName());
  113 + }
  114 + }
  115 + }
  116 + return result;
  117 + }
  118 +
  119 + // TODO @AI:需要的地方,直接调用 buildRouteProcessRespVOList;
  120 + private MesProRouteProcessRespVO buildRouteProcessRespVO(MesProRouteProcessDO routeProcess) {
  121 + if (routeProcess == null) {
  122 + return null;
  123 + }
  124 + return buildRouteProcessRespVOList(List.of(routeProcess)).get(0);
  125 + }
  126 +
  127 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProductBomController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.pro.route;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.productbom.MesProRouteProductBomRespVO;
  6 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.productbom.MesProRouteProductBomSaveReqVO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
  8 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
  9 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO;
  10 +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
  11 +import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
  12 +import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductBomService;
  13 +import io.swagger.v3.oas.annotations.Operation;
  14 +import io.swagger.v3.oas.annotations.Parameter;
  15 +import io.swagger.v3.oas.annotations.Parameters;
  16 +import io.swagger.v3.oas.annotations.tags.Tag;
  17 +import jakarta.annotation.Resource;
  18 +import jakarta.validation.Valid;
  19 +import org.springframework.security.access.prepost.PreAuthorize;
  20 +import org.springframework.validation.annotation.Validated;
  21 +import org.springframework.web.bind.annotation.*;
  22 +
  23 +import java.util.List;
  24 +import java.util.Map;
  25 +
  26 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  27 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  28 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  29 +
  30 +@Tag(name = "管理后台 - MES 工艺路线产品 BOM")
  31 +@RestController
  32 +@RequestMapping("/mes/pro/route-product-bom")
  33 +@Validated
  34 +public class MesProRouteProductBomController {
  35 +
  36 + @Resource
  37 + private MesProRouteProductBomService routeProductBomService;
  38 +
  39 + @Resource
  40 + private MesMdItemService itemService;
  41 +
  42 + @Resource
  43 + private MesMdUnitMeasureService unitMeasureService;
  44 +
  45 + @PostMapping("/create")
  46 + @Operation(summary = "创建工艺路线产品 BOM")
  47 + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')")
  48 + public CommonResult<Long> createRouteProductBom(@Valid @RequestBody MesProRouteProductBomSaveReqVO createReqVO) {
  49 + return success(routeProductBomService.createRouteProductBom(createReqVO));
  50 + }
  51 +
  52 + @PutMapping("/update")
  53 + @Operation(summary = "更新工艺路线产品 BOM")
  54 + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')")
  55 + public CommonResult<Boolean> updateRouteProductBom(@Valid @RequestBody MesProRouteProductBomSaveReqVO updateReqVO) {
  56 + routeProductBomService.updateRouteProductBom(updateReqVO);
  57 + return success(true);
  58 + }
  59 +
  60 + @DeleteMapping("/delete")
  61 + @Operation(summary = "删除工艺路线产品 BOM")
  62 + @Parameter(name = "id", description = "编号", required = true)
  63 + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')")
  64 + public CommonResult<Boolean> deleteRouteProductBom(@RequestParam("id") Long id) {
  65 + routeProductBomService.deleteRouteProductBom(id);
  66 + return success(true);
  67 + }
  68 +
  69 + @GetMapping("/get")
  70 + @Operation(summary = "获得工艺路线产品 BOM")
  71 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  72 + @PreAuthorize("@ss.hasPermission('mes:pro-route:query')")
  73 + public CommonResult<MesProRouteProductBomRespVO> getRouteProductBom(@RequestParam("id") Long id) {
  74 + MesProRouteProductBomDO routeProductBom = routeProductBomService.getRouteProductBom(id);
  75 + return success(buildRouteProductBomRespVO(routeProductBom));
  76 + }
  77 +
  78 + @GetMapping("/list")
  79 + @Operation(summary = "查询工艺路线产品 BOM 列表")
  80 + @Parameters({
  81 + @Parameter(name = "routeId", description = "工艺路线编号", required = true, example = "1"),
  82 + @Parameter(name = "processId", description = "工序编号", example = "1"),
  83 + @Parameter(name = "productId", description = "产品物料编号", example = "1")
  84 + })
  85 + @PreAuthorize("@ss.hasPermission('mes:pro-route:query')")
  86 + public CommonResult<List<MesProRouteProductBomRespVO>> getRouteProductBomList(
  87 + @RequestParam("routeId") Long routeId,
  88 + @RequestParam(value = "processId", required = false) Long processId,
  89 + @RequestParam(value = "productId", required = false) Long productId) {
  90 + List<MesProRouteProductBomDO> list = routeProductBomService.getRouteProductBomList(routeId, processId, productId);
  91 + return success(buildRouteProductBomRespVOList(list));
  92 + }
  93 +
  94 + // ==================== 拼接 VO ====================
  95 +
  96 + // TODO @AI:参考 /Users/yunai/Java/yudao-all-in-one/ruoyi-vue-pro/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProcessController.java 的 todo;
  97 +
  98 + private List<MesProRouteProductBomRespVO> buildRouteProductBomRespVOList(List<MesProRouteProductBomDO> list) {
  99 + if (list.isEmpty()) {
  100 + return List.of();
  101 + }
  102 + // 批量查询物料信息
  103 + List<Long> itemIds = convertList(list, MesProRouteProductBomDO::getItemId);
  104 + List<MesMdItemDO> itemList = itemService.getItemList(itemIds);
  105 + Map<Long, MesMdItemDO> itemMap = convertMap(itemList, MesMdItemDO::getId);
  106 + // 批量查询单位信息
  107 + List<Long> unitMeasureIds = convertList(itemList, MesMdItemDO::getUnitMeasureId);
  108 + Map<Long, MesMdUnitMeasureDO> unitMap = convertMap(
  109 + unitMeasureService.getUnitMeasureList(unitMeasureIds), MesMdUnitMeasureDO::getId);
  110 + // 拼装
  111 + List<MesProRouteProductBomRespVO> result = BeanUtils.toBean(list, MesProRouteProductBomRespVO.class);
  112 + for (MesProRouteProductBomRespVO vo : result) {
  113 + MesMdItemDO item = itemMap.get(vo.getItemId());
  114 + if (item != null) {
  115 + vo.setItemCode(item.getCode());
  116 + vo.setItemName(item.getName());
  117 + vo.setSpecification(item.getSpecification());
  118 + MesMdUnitMeasureDO unit = unitMap.get(item.getUnitMeasureId());
  119 + if (unit != null) {
  120 + vo.setUnitName(unit.getName());
  121 + }
  122 + }
  123 + }
  124 + return result;
  125 + }
  126 +
  127 + private MesProRouteProductBomRespVO buildRouteProductBomRespVO(MesProRouteProductBomDO routeProductBom) {
  128 + if (routeProductBom == null) {
  129 + return null;
  130 + }
  131 + return buildRouteProductBomRespVOList(List.of(routeProductBom)).get(0);
  132 + }
  133 +
  134 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProductController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.pro.route;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.product.MesProRouteProductRespVO;
  6 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.product.MesProRouteProductSaveReqVO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
  8 +import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
  9 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO;
  10 +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
  11 +import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
  12 +import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductService;
  13 +import io.swagger.v3.oas.annotations.Operation;
  14 +import io.swagger.v3.oas.annotations.Parameter;
  15 +import io.swagger.v3.oas.annotations.tags.Tag;
  16 +import jakarta.annotation.Resource;
  17 +import jakarta.validation.Valid;
  18 +import org.springframework.security.access.prepost.PreAuthorize;
  19 +import org.springframework.validation.annotation.Validated;
  20 +import org.springframework.web.bind.annotation.*;
  21 +
  22 +import java.util.List;
  23 +import java.util.Map;
  24 +
  25 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  26 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  27 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  28 +
  29 +@Tag(name = "管理后台 - MES 工艺路线产品")
  30 +@RestController
  31 +@RequestMapping("/mes/pro/route-product")
  32 +@Validated
  33 +public class MesProRouteProductController {
  34 +
  35 + @Resource
  36 + private MesProRouteProductService routeProductService;
  37 +
  38 + @Resource
  39 + private MesMdItemService itemService;
  40 +
  41 + @Resource
  42 + private MesMdUnitMeasureService unitMeasureService;
  43 +
  44 + @PostMapping("/create")
  45 + @Operation(summary = "创建工艺路线产品")
  46 + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')")
  47 + public CommonResult<Long> createRouteProduct(@Valid @RequestBody MesProRouteProductSaveReqVO createReqVO) {
  48 + return success(routeProductService.createRouteProduct(createReqVO));
  49 + }
  50 +
  51 + @PutMapping("/update")
  52 + @Operation(summary = "更新工艺路线产品")
  53 + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')")
  54 + public CommonResult<Boolean> updateRouteProduct(@Valid @RequestBody MesProRouteProductSaveReqVO updateReqVO) {
  55 + routeProductService.updateRouteProduct(updateReqVO);
  56 + return success(true);
  57 + }
  58 +
  59 + @DeleteMapping("/delete")
  60 + @Operation(summary = "删除工艺路线产品")
  61 + @Parameter(name = "id", description = "编号", required = true)
  62 + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')")
  63 + public CommonResult<Boolean> deleteRouteProduct(@RequestParam("id") Long id) {
  64 + routeProductService.deleteRouteProduct(id);
  65 + return success(true);
  66 + }
  67 +
  68 + @GetMapping("/get")
  69 + @Operation(summary = "获得工艺路线产品")
  70 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  71 + @PreAuthorize("@ss.hasPermission('mes:pro-route:query')")
  72 + public CommonResult<MesProRouteProductRespVO> getRouteProduct(@RequestParam("id") Long id) {
  73 + MesProRouteProductDO routeProduct = routeProductService.getRouteProduct(id);
  74 + return success(buildRouteProductRespVO(routeProduct));
  75 + }
  76 +
  77 + @GetMapping("/list-by-route")
  78 + @Operation(summary = "按工艺路线获得产品列表")
  79 + @Parameter(name = "routeId", description = "工艺路线编号", required = true, example = "1")
  80 + @PreAuthorize("@ss.hasPermission('mes:pro-route:query')")
  81 + public CommonResult<List<MesProRouteProductRespVO>> getRouteProductListByRoute(@RequestParam("routeId") Long routeId) {
  82 + List<MesProRouteProductDO> list = routeProductService.getRouteProductListByRouteId(routeId);
  83 + return success(buildRouteProductRespVOList(list));
  84 + }
  85 +
  86 + // ==================== 拼接 VO ====================
  87 + // TODO @AI:参考 /Users/yunai/Java/yudao-all-in-one/ruoyi-vue-pro/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProcessController.java 的 todo;
  88 +
  89 + private List<MesProRouteProductRespVO> buildRouteProductRespVOList(List<MesProRouteProductDO> list) {
  90 + if (list.isEmpty()) {
  91 + return List.of();
  92 + }
  93 + // 批量查询物料信息
  94 + List<Long> itemIds = convertList(list, MesProRouteProductDO::getItemId);
  95 + List<MesMdItemDO> itemList = itemService.getItemList(itemIds);
  96 + Map<Long, MesMdItemDO> itemMap = convertMap(itemList, MesMdItemDO::getId);
  97 + // 批量查询单位信息
  98 + List<Long> unitMeasureIds = convertList(itemList, MesMdItemDO::getUnitMeasureId);
  99 + Map<Long, MesMdUnitMeasureDO> unitMap = convertMap(
  100 + unitMeasureService.getUnitMeasureList(unitMeasureIds), MesMdUnitMeasureDO::getId);
  101 + // 拼装
  102 + List<MesProRouteProductRespVO> result = BeanUtils.toBean(list, MesProRouteProductRespVO.class);
  103 + for (MesProRouteProductRespVO vo : result) {
  104 + MesMdItemDO item = itemMap.get(vo.getItemId());
  105 + if (item != null) {
  106 + vo.setItemCode(item.getCode());
  107 + vo.setItemName(item.getName());
  108 + vo.setSpecification(item.getSpecification());
  109 + MesMdUnitMeasureDO unit = unitMap.get(item.getUnitMeasureId());
  110 + if (unit != null) {
  111 + vo.setUnitName(unit.getName());
  112 + }
  113 + }
  114 + }
  115 + return result;
  116 + }
  117 +
  118 + private MesProRouteProductRespVO buildRouteProductRespVO(MesProRouteProductDO routeProduct) {
  119 + if (routeProduct == null) {
  120 + return null;
  121 + }
  122 + return buildRouteProductRespVOList(List.of(routeProduct)).get(0);
  123 + }
  124 +
  125 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/MesProRoutePageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  13 +
  14 +@Schema(description = "管理后台 - MES 工艺路线分页 Request VO")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +public class MesProRoutePageReqVO extends PageParam {
  19 +
  20 + @Schema(description = "工艺路线编码", example = "ROUTE001")
  21 + private String code;
  22 +
  23 + @Schema(description = "工艺路线名称", example = "标准路线")
  24 + private String name;
  25 +
  26 + @Schema(description = "状态", example = "0")
  27 + private Integer status;
  28 +
  29 + @Schema(description = "创建时间")
  30 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  31 + private LocalDateTime[] createTime;
  32 +
  33 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/MesProRouteRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo;
  2 +
  3 +import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
  4 +import cn.idev.excel.annotation.ExcelProperty;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import lombok.Data;
  7 +
  8 +import java.time.LocalDateTime;
  9 +
  10 +@Schema(description = "管理后台 - MES 工艺路线 Response VO")
  11 +@Data
  12 +@ExcelIgnoreUnannotated
  13 +public class MesProRouteRespVO {
  14 +
  15 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  16 + @ExcelProperty("编号")
  17 + private Long id;
  18 +
  19 + @Schema(description = "工艺路线编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "ROUTE001")
  20 + @ExcelProperty("工艺路线编码")
  21 + private String code;
  22 +
  23 + @Schema(description = "工艺路线名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "标准路线")
  24 + @ExcelProperty("工艺路线名称")
  25 + private String name;
  26 +
  27 + @Schema(description = "工艺路线说明")
  28 + @ExcelProperty("工艺路线说明")
  29 + private String description;
  30 +
  31 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  32 + @ExcelProperty("状态")
  33 + private Integer status;
  34 +
  35 + @Schema(description = "备注")
  36 + @ExcelProperty("备注")
  37 + private String remark;
  38 +
  39 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  40 + @ExcelProperty("创建时间")
  41 + private LocalDateTime createTime;
  42 +
  43 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/MesProRouteSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotBlank;
  5 +import jakarta.validation.constraints.NotNull;
  6 +import lombok.Data;
  7 +
  8 +@Schema(description = "管理后台 - MES 工艺路线新增/修改 Request VO")
  9 +@Data
  10 +public class MesProRouteSaveReqVO {
  11 +
  12 + @Schema(description = "编号", example = "1")
  13 + private Long id;
  14 +
  15 + @Schema(description = "工艺路线编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "ROUTE001")
  16 + @NotBlank(message = "工艺路线编码不能为空")
  17 + private String code;
  18 +
  19 + @Schema(description = "工艺路线名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "标准路线")
  20 + @NotBlank(message = "工艺路线名称不能为空")
  21 + private String name;
  22 +
  23 + @Schema(description = "工艺路线说明")
  24 + private String description;
  25 +
  26 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  27 + @NotNull(message = "状态不能为空")
  28 + private Integer status;
  29 +
  30 + @Schema(description = "备注")
  31 + private String remark;
  32 +
  33 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/process/MesProRouteProcessRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +@Schema(description = "管理后台 - MES 工艺路线工序 Response VO")
  9 +@Data
  10 +public class MesProRouteProcessRespVO {
  11 +
  12 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  13 + private Long id;
  14 +
  15 + @Schema(description = "工艺路线编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  16 + private Long routeId;
  17 +
  18 + @Schema(description = "工序编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  19 + private Long processId;
  20 +
  21 + @Schema(description = "工序编码")
  22 + private String processCode;
  23 +
  24 + @Schema(description = "工序名称")
  25 + private String processName;
  26 +
  27 + @Schema(description = "序号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  28 + private Integer sort;
  29 +
  30 + @Schema(description = "下一道工序编号")
  31 + private Long nextProcessId;
  32 +
  33 + @Schema(description = "下一道工序名称")
  34 + private String nextProcessName;
  35 +
  36 + @Schema(description = "与下一道工序关系", example = "0")
  37 + private Integer linkType;
  38 +
  39 + @Schema(description = "准备时间(分钟)", example = "10")
  40 + private Integer prepareTime;
  41 +
  42 + @Schema(description = "等待时间(分钟)", example = "5")
  43 + private Integer waitTime;
  44 +
  45 + @Schema(description = "甘特图显示颜色", example = "#00AEF3")
  46 + private String colorCode;
  47 +
  48 + @Schema(description = "是否关键工序", example = "false")
  49 + private Boolean keyFlag;
  50 +
  51 + @Schema(description = "是否质检工序", example = "false")
  52 + private Boolean checkFlag;
  53 +
  54 + @Schema(description = "备注")
  55 + private String remark;
  56 +
  57 + @Schema(description = "创建时间")
  58 + private LocalDateTime createTime;
  59 +
  60 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/process/MesProRouteProcessSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotNull;
  5 +import lombok.Data;
  6 +
  7 +@Schema(description = "管理后台 - MES 工艺路线工序新增/修改 Request VO")
  8 +@Data
  9 +public class MesProRouteProcessSaveReqVO {
  10 +
  11 + @Schema(description = "编号", example = "1")
  12 + private Long id;
  13 +
  14 + @Schema(description = "工艺路线编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  15 + @NotNull(message = "工艺路线编号不能为空")
  16 + private Long routeId;
  17 +
  18 + @Schema(description = "工序编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  19 + @NotNull(message = "工序编号不能为空")
  20 + private Long processId;
  21 +
  22 + @Schema(description = "序号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  23 + @NotNull(message = "序号不能为空")
  24 + private Integer sort;
  25 +
  26 + @Schema(description = "与下一道工序关系", example = "0")
  27 + private Integer linkType;
  28 +
  29 + @Schema(description = "准备时间(分钟)", example = "10")
  30 + private Integer prepareTime;
  31 +
  32 + @Schema(description = "等待时间(分钟)", example = "5")
  33 + private Integer waitTime;
  34 +
  35 + @Schema(description = "甘特图显示颜色", example = "#00AEF3")
  36 + private String colorCode;
  37 +
  38 + @Schema(description = "是否关键工序", example = "false")
  39 + private Boolean keyFlag;
  40 +
  41 + @Schema(description = "是否质检工序", example = "false")
  42 + private Boolean checkFlag;
  43 +
  44 + @Schema(description = "备注")
  45 + private String remark;
  46 +
  47 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/product/MesProRouteProductRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.product;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +import java.time.LocalDateTime;
  8 +
  9 +@Schema(description = "管理后台 - MES 工艺路线产品 Response VO")
  10 +@Data
  11 +public class MesProRouteProductRespVO {
  12 +
  13 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  14 + private Long id;
  15 +
  16 + @Schema(description = "工艺路线编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  17 + private Long routeId;
  18 +
  19 + @Schema(description = "产品物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  20 + private Long itemId;
  21 +
  22 + @Schema(description = "产品物料编码")
  23 + private String itemCode;
  24 +
  25 + @Schema(description = "产品物料名称")
  26 + private String itemName;
  27 +
  28 + @Schema(description = "规格型号")
  29 + private String specification;
  30 +
  31 + @Schema(description = "单位名称")
  32 + private String unitName;
  33 +
  34 + @Schema(description = "生产数量", example = "100")
  35 + private Integer quantity;
  36 +
  37 + @Schema(description = "生产用时", example = "60.00")
  38 + private BigDecimal productionTime;
  39 +
  40 + @Schema(description = "时间单位", example = "MINUTE")
  41 + private String timeUnitType;
  42 +
  43 + @Schema(description = "备注")
  44 + private String remark;
  45 +
  46 + @Schema(description = "创建时间")
  47 + private LocalDateTime createTime;
  48 +
  49 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/product/MesProRouteProductSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.product;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotNull;
  5 +import lombok.Data;
  6 +
  7 +import java.math.BigDecimal;
  8 +
  9 +@Schema(description = "管理后台 - MES 工艺路线产品新增/修改 Request VO")
  10 +@Data
  11 +public class MesProRouteProductSaveReqVO {
  12 +
  13 + @Schema(description = "编号", example = "1")
  14 + private Long id;
  15 +
  16 + @Schema(description = "工艺路线编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  17 + @NotNull(message = "工艺路线编号不能为空")
  18 + private Long routeId;
  19 +
  20 + @Schema(description = "产品物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  21 + @NotNull(message = "产品物料编号不能为空")
  22 + private Long itemId;
  23 +
  24 + @Schema(description = "生产数量", example = "100")
  25 + private Integer quantity;
  26 +
  27 + @Schema(description = "生产用时", example = "60.00")
  28 + private BigDecimal productionTime;
  29 +
  30 + @Schema(description = "时间单位", example = "MINUTE")
  31 + private String timeUnitType;
  32 +
  33 + @Schema(description = "备注")
  34 + private String remark;
  35 +
  36 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/productbom/MesProRouteProductBomRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.productbom;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.math.BigDecimal;
  7 +import java.time.LocalDateTime;
  8 +
  9 +@Schema(description = "管理后台 - MES 工艺路线产品 BOM Response VO")
  10 +@Data
  11 +public class MesProRouteProductBomRespVO {
  12 +
  13 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  14 + private Long id;
  15 +
  16 + @Schema(description = "工艺路线编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  17 + private Long routeId;
  18 +
  19 + @Schema(description = "工序编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  20 + private Long processId;
  21 +
  22 + @Schema(description = "产品物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  23 + private Long productId;
  24 +
  25 + @Schema(description = "BOM 物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  26 + private Long itemId;
  27 +
  28 + @Schema(description = "BOM 物料编码")
  29 + private String itemCode;
  30 +
  31 + @Schema(description = "BOM 物料名称")
  32 + private String itemName;
  33 +
  34 + @Schema(description = "规格型号")
  35 + private String specification;
  36 +
  37 + @Schema(description = "单位名称")
  38 + private String unitName;
  39 +
  40 + @Schema(description = "用料比例", example = "1.50")
  41 + private BigDecimal quantity;
  42 +
  43 + @Schema(description = "备注")
  44 + private String remark;
  45 +
  46 + @Schema(description = "创建时间")
  47 + private LocalDateTime createTime;
  48 +
  49 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/productbom/MesProRouteProductBomSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.productbom;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotNull;
  5 +import lombok.Data;
  6 +
  7 +import java.math.BigDecimal;
  8 +
  9 +@Schema(description = "管理后台 - MES 工艺路线产品 BOM 新增/修改 Request VO")
  10 +@Data
  11 +public class MesProRouteProductBomSaveReqVO {
  12 +
  13 + @Schema(description = "编号", example = "1")
  14 + private Long id;
  15 +
  16 + @Schema(description = "工艺路线编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  17 + @NotNull(message = "工艺路线编号不能为空")
  18 + private Long routeId;
  19 +
  20 + @Schema(description = "工序编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  21 + @NotNull(message = "工序编号不能为空")
  22 + private Long processId;
  23 +
  24 + @Schema(description = "产品物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  25 + @NotNull(message = "产品物料编号不能为空")
  26 + private Long productId;
  27 +
  28 + @Schema(description = "BOM 物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  29 + @NotNull(message = "BOM 物料编号不能为空")
  30 + private Long itemId;
  31 +
  32 + @Schema(description = "用料比例", example = "1.50")
  33 + private BigDecimal quantity;
  34 +
  35 + @Schema(description = "备注")
  36 + private String remark;
  37 +
  38 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.dataobject.pro.route;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +/**
  10 + * MES 工艺路线 DO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@TableName("mes_pro_route")
  15 +@KeySequence("mes_pro_route_seq")
  16 +@Data
  17 +@EqualsAndHashCode(callSuper = true)
  18 +@ToString(callSuper = true)
  19 +@Builder
  20 +@NoArgsConstructor
  21 +@AllArgsConstructor
  22 +public class MesProRouteDO extends BaseDO {
  23 +
  24 + /**
  25 + * 编号
  26 + */
  27 + @TableId
  28 + private Long id;
  29 + /**
  30 + * 工艺路线编码
  31 + */
  32 + private String code;
  33 + /**
  34 + * 工艺路线名称
  35 + */
  36 + private String name;
  37 + /**
  38 + * 工艺路线说明
  39 + */
  40 + private String description;
  41 + /**
  42 + * 状态
  43 + *
  44 + * 枚举 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum}
  45 + */
  46 + private Integer status;
  47 + /**
  48 + * 备注
  49 + */
  50 + private String remark;
  51 + /**
  52 + * 预留字段1
  53 + */
  54 + private String attribute1;
  55 + /**
  56 + * 预留字段2
  57 + */
  58 + private String attribute2;
  59 + /**
  60 + * 预留字段3
  61 + */
  62 + private Integer attribute3;
  63 + /**
  64 + * 预留字段4
  65 + */
  66 + private Integer attribute4;
  67 +
  68 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteProcessDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.dataobject.pro.route;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +/**
  10 + * MES 工艺路线工序 DO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@TableName("mes_pro_route_process")
  15 +@KeySequence("mes_pro_route_process_seq")
  16 +@Data
  17 +@EqualsAndHashCode(callSuper = true)
  18 +@ToString(callSuper = true)
  19 +@Builder
  20 +@NoArgsConstructor
  21 +@AllArgsConstructor
  22 +public class MesProRouteProcessDO extends BaseDO {
  23 +
  24 + /**
  25 + * 编号
  26 + */
  27 + @TableId
  28 + private Long id;
  29 + // TODO @AI:外链 @ 加下,参考别的模块
  30 + /**
  31 + * 工艺路线编号
  32 + */
  33 + private Long routeId;
  34 + // TODO @AI:外链 @ 加下,参考别的模块
  35 + /**
  36 + * 工序编号
  37 + */
  38 + private Long processId;
  39 + /**
  40 + * 序号
  41 + */
  42 + private Integer sort;
  43 + // TODO @AI:外链 @ 加下,参考别的模块
  44 + /**
  45 + * 下一道工序编号
  46 + */
  47 + private Long nextProcessId;
  48 + /**
  49 + * 与下一道工序关系
  50 + *
  51 + * 枚举 {@link cn.iocoder.yudao.module.mes.enums.pro.MesProLinkTypeEnum}
  52 + */
  53 + private Integer linkType;
  54 + /**
  55 + * 准备时间(分钟)
  56 + */
  57 + private Integer prepareTime;
  58 + /**
  59 + * 等待时间(分钟)
  60 + */
  61 + private Integer waitTime;
  62 + /**
  63 + * 甘特图显示颜色
  64 + */
  65 + private String colorCode;
  66 + /**
  67 + * 是否关键工序
  68 + */
  69 + private Boolean keyFlag;
  70 + /**
  71 + * 是否质检工序
  72 + */
  73 + private Boolean checkFlag;
  74 + /**
  75 + * 备注
  76 + */
  77 + private String remark;
  78 + /**
  79 + * 预留字段1
  80 + */
  81 + private String attribute1;
  82 + /**
  83 + * 预留字段2
  84 + */
  85 + private String attribute2;
  86 + /**
  87 + * 预留字段3
  88 + */
  89 + private Integer attribute3;
  90 + /**
  91 + * 预留字段4
  92 + */
  93 + private Integer attribute4;
  94 +
  95 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteProductBomDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.dataobject.pro.route;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +import java.math.BigDecimal;
  10 +
  11 +/**
  12 + * MES 工艺路线产品 BOM DO
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +@TableName("mes_pro_route_product_bom")
  17 +@KeySequence("mes_pro_route_product_bom_seq")
  18 +@Data
  19 +@EqualsAndHashCode(callSuper = true)
  20 +@ToString(callSuper = true)
  21 +@Builder
  22 +@NoArgsConstructor
  23 +@AllArgsConstructor
  24 +public class MesProRouteProductBomDO extends BaseDO {
  25 +
  26 + /**
  27 + * 编号
  28 + */
  29 + @TableId
  30 + private Long id;
  31 + // TODO @AI:外链 @ 加下,参考别的模块
  32 + /**
  33 + * 工艺路线编号
  34 + */
  35 + private Long routeId;
  36 + // TODO @AI:外链 @ 加下,参考别的模块
  37 + /**
  38 + * 工序编号
  39 + */
  40 + private Long processId;
  41 + // TODO @AI:外链 @ 加下,参考别的模块
  42 + /**
  43 + * 产品物料编号
  44 + */
  45 + private Long productId;
  46 + // TODO @AI:外链 @ 加下,参考别的模块
  47 + /**
  48 + * BOM 物料编号
  49 + */
  50 + private Long itemId;
  51 + /**
  52 + * 用料比例
  53 + */
  54 + private BigDecimal quantity;
  55 + /**
  56 + * 备注
  57 + */
  58 + private String remark;
  59 + /**
  60 + * 预留字段1
  61 + */
  62 + private String attribute1;
  63 + /**
  64 + * 预留字段2
  65 + */
  66 + private String attribute2;
  67 + /**
  68 + * 预留字段3
  69 + */
  70 + private Integer attribute3;
  71 + /**
  72 + * 预留字段4
  73 + */
  74 + private Integer attribute4;
  75 +
  76 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteProductDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.dataobject.pro.route;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +import java.math.BigDecimal;
  10 +
  11 +/**
  12 + * MES 工艺路线产品 DO
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +@TableName("mes_pro_route_product")
  17 +@KeySequence("mes_pro_route_product_seq")
  18 +@Data
  19 +@EqualsAndHashCode(callSuper = true)
  20 +@ToString(callSuper = true)
  21 +@Builder
  22 +@NoArgsConstructor
  23 +@AllArgsConstructor
  24 +public class MesProRouteProductDO extends BaseDO {
  25 +
  26 + /**
  27 + * 编号
  28 + */
  29 + @TableId
  30 + private Long id;
  31 + // TODO @AI:外链 @ 加下,参考别的模块
  32 + /**
  33 + * 工艺路线编号
  34 + */
  35 + private Long routeId;
  36 + // TODO @AI:外链 @ 加下,参考别的模块
  37 + /**
  38 + * 产品物料编号
  39 + */
  40 + private Long itemId;
  41 + /**
  42 + * 生产数量
  43 + */
  44 + private Integer quantity;
  45 + /**
  46 + * 生产用时
  47 + */
  48 + private BigDecimal productionTime;
  49 + /**
  50 + * 时间单位
  51 + */
  52 + // TODO @AI:外链 @ 加下,字典 + 枚举类;
  53 + private String timeUnitType;
  54 + /**
  55 + * 备注
  56 + */
  57 + private String remark;
  58 + /**
  59 + * 预留字段1
  60 + */
  61 + private String attribute1;
  62 + /**
  63 + * 预留字段2
  64 + */
  65 + private String attribute2;
  66 + /**
  67 + * 预留字段3
  68 + */
  69 + private Integer attribute3;
  70 + /**
  71 + * 预留字段4
  72 + */
  73 + private Integer attribute4;
  74 +
  75 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/MesProRouteMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.mysql.pro;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.MesProRoutePageReqVO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * MES 工艺路线 Mapper
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@Mapper
  18 +public interface MesProRouteMapper extends BaseMapperX<MesProRouteDO> {
  19 +
  20 + default PageResult<MesProRouteDO> selectPage(MesProRoutePageReqVO reqVO) {
  21 + return selectPage(reqVO, new LambdaQueryWrapperX<MesProRouteDO>()
  22 + .likeIfPresent(MesProRouteDO::getCode, reqVO.getCode())
  23 + .likeIfPresent(MesProRouteDO::getName, reqVO.getName())
  24 + .eqIfPresent(MesProRouteDO::getStatus, reqVO.getStatus())
  25 + .betweenIfPresent(MesProRouteDO::getCreateTime, reqVO.getCreateTime())
  26 + .orderByDesc(MesProRouteDO::getId));
  27 + }
  28 +
  29 + default MesProRouteDO selectByCode(String code) {
  30 + return selectOne(MesProRouteDO::getCode, code);
  31 + }
  32 +
  33 + default List<MesProRouteDO> selectListByStatus(Integer status) {
  34 + return selectList(MesProRouteDO::getStatus, status);
  35 + }
  36 +
  37 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/MesProRouteProcessMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.mysql.pro;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  5 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO;
  6 +import org.apache.ibatis.annotations.Mapper;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * MES 工艺路线工序 Mapper
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Mapper
  16 +public interface MesProRouteProcessMapper extends BaseMapperX<MesProRouteProcessDO> {
  17 +
  18 + default List<MesProRouteProcessDO> selectListByRouteId(Long routeId) {
  19 + return selectList(new LambdaQueryWrapperX<MesProRouteProcessDO>()
  20 + .eq(MesProRouteProcessDO::getRouteId, routeId)
  21 + .orderByAsc(MesProRouteProcessDO::getSort));
  22 + }
  23 +
  24 + default MesProRouteProcessDO selectByRouteIdAndSort(Long routeId, Integer sort) {
  25 + return selectOne(new LambdaQueryWrapperX<MesProRouteProcessDO>()
  26 + .eq(MesProRouteProcessDO::getRouteId, routeId)
  27 + .eq(MesProRouteProcessDO::getSort, sort));
  28 + }
  29 +
  30 + default MesProRouteProcessDO selectByRouteIdAndProcessId(Long routeId, Long processId) {
  31 + return selectOne(new LambdaQueryWrapperX<MesProRouteProcessDO>()
  32 + .eq(MesProRouteProcessDO::getRouteId, routeId)
  33 + .eq(MesProRouteProcessDO::getProcessId, processId));
  34 + }
  35 +
  36 + default MesProRouteProcessDO selectKeyProcessByRouteId(Long routeId) {
  37 + return selectOne(new LambdaQueryWrapperX<MesProRouteProcessDO>()
  38 + .eq(MesProRouteProcessDO::getRouteId, routeId)
  39 + .eq(MesProRouteProcessDO::getKeyFlag, true));
  40 + }
  41 +
  42 + default void deleteByRouteId(Long routeId) {
  43 + delete(new LambdaQueryWrapperX<MesProRouteProcessDO>()
  44 + .eq(MesProRouteProcessDO::getRouteId, routeId));
  45 + }
  46 +
  47 + default List<MesProRouteProcessDO> selectListByProcessId(Long processId) {
  48 + return selectList(MesProRouteProcessDO::getProcessId, processId);
  49 + }
  50 +
  51 + default MesProRouteProcessDO findPreProcess(Long routeId, Integer sort) {
  52 + return selectOne(new LambdaQueryWrapperX<MesProRouteProcessDO>()
  53 + .eq(MesProRouteProcessDO::getRouteId, routeId)
  54 + .lt(MesProRouteProcessDO::getSort, sort)
  55 + .orderByDesc(MesProRouteProcessDO::getSort)
  56 + // TODO @AI:limit 1,使用 mybatis utils
  57 + .last("LIMIT 1"));
  58 + }
  59 +
  60 + default MesProRouteProcessDO findNextProcess(Long routeId, Integer sort) {
  61 + return selectOne(new LambdaQueryWrapperX<MesProRouteProcessDO>()
  62 + .eq(MesProRouteProcessDO::getRouteId, routeId)
  63 + .gt(MesProRouteProcessDO::getSort, sort)
  64 + .orderByAsc(MesProRouteProcessDO::getSort)
  65 + // TODO @AI:limit 1,使用 mybatis utils
  66 + .last("LIMIT 1"));
  67 + }
  68 +
  69 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/MesProRouteProductBomMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.mysql.pro;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  5 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO;
  6 +import org.apache.ibatis.annotations.Mapper;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * MES 工艺路线产品 BOM Mapper
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Mapper
  16 +public interface MesProRouteProductBomMapper extends BaseMapperX<MesProRouteProductBomDO> {
  17 +
  18 + default List<MesProRouteProductBomDO> selectList(Long routeId, Long processId, Long productId) {
  19 + return selectList(new LambdaQueryWrapperX<MesProRouteProductBomDO>()
  20 + .eqIfPresent(MesProRouteProductBomDO::getRouteId, routeId)
  21 + .eqIfPresent(MesProRouteProductBomDO::getProcessId, processId)
  22 + .eqIfPresent(MesProRouteProductBomDO::getProductId, productId));
  23 + }
  24 +
  25 + default MesProRouteProductBomDO selectByUnique(Long itemId, Long processId, Long productId) {
  26 + return selectOne(new LambdaQueryWrapperX<MesProRouteProductBomDO>()
  27 + .eq(MesProRouteProductBomDO::getItemId, itemId)
  28 + .eq(MesProRouteProductBomDO::getProcessId, processId)
  29 + .eq(MesProRouteProductBomDO::getProductId, productId));
  30 + }
  31 +
  32 + default void deleteByRouteId(Long routeId) {
  33 + delete(new LambdaQueryWrapperX<MesProRouteProductBomDO>()
  34 + .eq(MesProRouteProductBomDO::getRouteId, routeId));
  35 + }
  36 +
  37 + default void deleteByRouteIdAndProductId(Long routeId, Long productId) {
  38 + delete(new LambdaQueryWrapperX<MesProRouteProductBomDO>()
  39 + .eq(MesProRouteProductBomDO::getRouteId, routeId)
  40 + .eq(MesProRouteProductBomDO::getProductId, productId));
  41 + }
  42 +
  43 + default List<MesProRouteProductBomDO> selectListByRouteIdAndProductId(Long routeId, Long productId) {
  44 + return selectList(new LambdaQueryWrapperX<MesProRouteProductBomDO>()
  45 + .eq(MesProRouteProductBomDO::getRouteId, routeId)
  46 + .eq(MesProRouteProductBomDO::getProductId, productId));
  47 + }
  48 +
  49 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/MesProRouteProductMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.dal.mysql.pro;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  5 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO;
  6 +import org.apache.ibatis.annotations.Mapper;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * MES 工艺路线产品 Mapper
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Mapper
  16 +public interface MesProRouteProductMapper extends BaseMapperX<MesProRouteProductDO> {
  17 +
  18 + default List<MesProRouteProductDO> selectListByRouteId(Long routeId) {
  19 + return selectList(MesProRouteProductDO::getRouteId, routeId);
  20 + }
  21 +
  22 + default MesProRouteProductDO selectByItemId(Long itemId) {
  23 + return selectOne(MesProRouteProductDO::getItemId, itemId);
  24 + }
  25 +
  26 + default void deleteByRouteId(Long routeId) {
  27 + delete(new LambdaQueryWrapperX<MesProRouteProductDO>()
  28 + .eq(MesProRouteProductDO::getRouteId, routeId));
  29 + }
  30 +
  31 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/MesProProcessServiceImpl.java
... ... @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.pro.process.vo.MesProProcess
6 6 import cn.iocoder.yudao.module.mes.controller.admin.pro.process.vo.MesProProcessSaveReqVO;
7 7 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.MesProProcessDO;
8 8 import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProProcessMapper;
  9 +import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProRouteProcessMapper;
9 10 import jakarta.annotation.Resource;
10 11 import org.springframework.stereotype.Service;
11 12 import org.springframework.transaction.annotation.Transactional;
... ... @@ -31,6 +32,9 @@ public class MesProProcessServiceImpl implements MesProProcessService {
31 32 @Resource
32 33 private MesProProcessContentService processContentService;
33 34  
  35 + @Resource
  36 + private MesProRouteProcessMapper routeProcessMapper;
  37 +
34 38 @Override
35 39 public Long createProcess(MesProProcessSaveReqVO createReqVO) {
36 40 // 1. 校验工序编码唯一性
... ... @@ -61,10 +65,13 @@ public class MesProProcessServiceImpl implements MesProProcessService {
61 65 public void deleteProcess(Long id) {
62 66 // 1. 校验存在
63 67 validateProcessExists(id);
64   - // TODO @芋艿:校验是否被工艺路线引用(pro_route_process 表实现后)
65   - // 2. 删除工序
  68 + // 2. 校验是否被工艺路线引用
  69 + if (!routeProcessMapper.selectListByProcessId(id).isEmpty()) {
  70 + throw exception(PRO_PROCESS_USED_BY_ROUTE);
  71 + }
  72 + // 3. 删除工序
66 73 processMapper.deleteById(id);
67   - // 3. 级联删除工序内容
  74 + // 4. 级联删除工序内容
68 75 processContentService.deleteProcessContentByProcessId(id);
69 76 }
70 77  
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProcessService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.pro.route;
  2 +
  3 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process.MesProRouteProcessSaveReqVO;
  4 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO;
  5 +import jakarta.validation.Valid;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * MES 工艺路线工序 Service 接口
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +public interface MesProRouteProcessService {
  15 +
  16 + /**
  17 + * 创建工艺路线工序
  18 + */
  19 + Long createRouteProcess(@Valid MesProRouteProcessSaveReqVO createReqVO);
  20 +
  21 + /**
  22 + * 更新工艺路线工序
  23 + */
  24 + void updateRouteProcess(@Valid MesProRouteProcessSaveReqVO updateReqVO);
  25 +
  26 + /**
  27 + * 删除工艺路线工序
  28 + */
  29 + void deleteRouteProcess(Long id);
  30 +
  31 + /**
  32 + * 获得工艺路线工序
  33 + */
  34 + MesProRouteProcessDO getRouteProcess(Long id);
  35 +
  36 + /**
  37 + * 按工艺路线获得工序列表
  38 + */
  39 + List<MesProRouteProcessDO> getRouteProcessListByRouteId(Long routeId);
  40 +
  41 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProcessServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.pro.route;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  4 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process.MesProRouteProcessSaveReqVO;
  5 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.MesProProcessDO;
  6 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO;
  7 +import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProRouteProcessMapper;
  8 +import cn.iocoder.yudao.module.mes.service.pro.MesProProcessService;
  9 +import jakarta.annotation.Resource;
  10 +import org.springframework.context.annotation.Lazy;
  11 +import org.springframework.stereotype.Service;
  12 +import org.springframework.transaction.annotation.Transactional;
  13 +import org.springframework.validation.annotation.Validated;
  14 +
  15 +import java.util.Comparator;
  16 +import java.util.List;
  17 +
  18 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  19 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
  20 +
  21 +// TODO @AI:参考别的模块,需要校验下相关的工艺路线、工序是否存在;(别的 route 也是);最好对方 service 提供校验方法;
  22 +/**
  23 + * MES 工艺路线工序 Service 实现类
  24 + *
  25 + * @author 芋道源码
  26 + */
  27 +@Service
  28 +@Validated
  29 +public class MesProRouteProcessServiceImpl implements MesProRouteProcessService {
  30 +
  31 + @Resource
  32 + private MesProRouteProcessMapper routeProcessMapper;
  33 +
  34 + // TODO @AI:貌似没用到?是不是应该要用下哈?
  35 + @Resource
  36 + @Lazy
  37 + private MesProProcessService processService;
  38 +
  39 + @Override
  40 + @Transactional(rollbackFor = Exception.class)
  41 + public Long createRouteProcess(MesProRouteProcessSaveReqVO createReqVO) {
  42 + // 1. 校验
  43 + validateRouteProcessCreate(createReqVO);
  44 +
  45 + // 2. 插入
  46 + MesProRouteProcessDO routeProcess = BeanUtils.toBean(createReqVO, MesProRouteProcessDO.class);
  47 + routeProcessMapper.insert(routeProcess);
  48 +
  49 + // 3. 更新工序链
  50 + rebuildProcessChain(createReqVO.getRouteId());
  51 + return routeProcess.getId();
  52 + }
  53 +
  54 + @Override
  55 + @Transactional(rollbackFor = Exception.class)
  56 + public void updateRouteProcess(MesProRouteProcessSaveReqVO updateReqVO) {
  57 + // 1.1 校验存在
  58 + validateRouteProcessExists(updateReqVO.getId());
  59 + // 1.2 校验唯一性
  60 + validateRouteProcessUpdate(updateReqVO);
  61 +
  62 + // 2. 更新
  63 + MesProRouteProcessDO updateObj = BeanUtils.toBean(updateReqVO, MesProRouteProcessDO.class);
  64 + routeProcessMapper.updateById(updateObj);
  65 +
  66 + // 3. 重建工序链
  67 + rebuildProcessChain(updateReqVO.getRouteId());
  68 + }
  69 +
  70 + @Override
  71 + @Transactional(rollbackFor = Exception.class)
  72 + public void deleteRouteProcess(Long id) {
  73 + // 1. 校验存在
  74 + MesProRouteProcessDO routeProcess = routeProcessMapper.selectById(id);
  75 + if (routeProcess == null) {
  76 + throw exception(PRO_ROUTE_PROCESS_NOT_EXISTS);
  77 + }
  78 +
  79 + // 2. 删除
  80 + routeProcessMapper.deleteById(id);
  81 +
  82 + // 3. 重建工序链
  83 + rebuildProcessChain(routeProcess.getRouteId());
  84 + }
  85 +
  86 + /**
  87 + * 重建工序链(更新所有工序的 nextProcessId)
  88 + */
  89 + private void rebuildProcessChain(Long routeId) {
  90 + List<MesProRouteProcessDO> list = routeProcessMapper.selectListByRouteId(routeId);
  91 + // TODO @AI:CollUtil isEmpty;
  92 + if (list.isEmpty()) {
  93 + return;
  94 + }
  95 + // 按 sort 排序
  96 + list.sort(Comparator.comparing(MesProRouteProcessDO::getSort));
  97 + for (int i = 0; i < list.size(); i++) {
  98 + MesProRouteProcessDO item = list.get(i);
  99 + if (i + 1 < list.size()) {
  100 + item.setNextProcessId(list.get(i + 1).getProcessId());
  101 + } else {
  102 + item.setNextProcessId(null);
  103 + }
  104 + routeProcessMapper.updateById(item);
  105 + }
  106 + }
  107 +
  108 + private void validateRouteProcessExists(Long id) {
  109 + if (routeProcessMapper.selectById(id) == null) {
  110 + throw exception(PRO_ROUTE_PROCESS_NOT_EXISTS);
  111 + }
  112 + }
  113 +
  114 + // TODO @AI:参考别的模块,拆分为多个模块
  115 + private void validateRouteProcessCreate(MesProRouteProcessSaveReqVO reqVO) {
  116 + // 序号唯一
  117 + MesProRouteProcessDO existing = routeProcessMapper.selectByRouteIdAndSort(reqVO.getRouteId(), reqVO.getSort());
  118 + if (existing != null) {
  119 + throw exception(PRO_ROUTE_PROCESS_SORT_DUPLICATE);
  120 + }
  121 + // 工序不重复
  122 + existing = routeProcessMapper.selectByRouteIdAndProcessId(reqVO.getRouteId(), reqVO.getProcessId());
  123 + if (existing != null) {
  124 + throw exception(PRO_ROUTE_PROCESS_DUPLICATE);
  125 + }
  126 + // 关键工序唯一
  127 + if (Boolean.TRUE.equals(reqVO.getKeyFlag())) {
  128 + existing = routeProcessMapper.selectKeyProcessByRouteId(reqVO.getRouteId());
  129 + if (existing != null) {
  130 + throw exception(PRO_ROUTE_PROCESS_KEY_DUPLICATE);
  131 + }
  132 + }
  133 + }
  134 +
  135 + // TODO @AI:参考别的模块,拆分为多个模块
  136 + private void validateRouteProcessUpdate(MesProRouteProcessSaveReqVO reqVO) {
  137 + // 序号唯一(排除自身)
  138 + MesProRouteProcessDO existing = routeProcessMapper.selectByRouteIdAndSort(reqVO.getRouteId(), reqVO.getSort());
  139 + if (existing != null && !existing.getId().equals(reqVO.getId())) {
  140 + throw exception(PRO_ROUTE_PROCESS_SORT_DUPLICATE);
  141 + }
  142 + // 工序不重复(排除自身)
  143 + existing = routeProcessMapper.selectByRouteIdAndProcessId(reqVO.getRouteId(), reqVO.getProcessId());
  144 + if (existing != null && !existing.getId().equals(reqVO.getId())) {
  145 + throw exception(PRO_ROUTE_PROCESS_DUPLICATE);
  146 + }
  147 + // 关键工序唯一(排除自身)
  148 + if (Boolean.TRUE.equals(reqVO.getKeyFlag())) {
  149 + existing = routeProcessMapper.selectKeyProcessByRouteId(reqVO.getRouteId());
  150 + if (existing != null && !existing.getId().equals(reqVO.getId())) {
  151 + throw exception(PRO_ROUTE_PROCESS_KEY_DUPLICATE);
  152 + }
  153 + }
  154 + }
  155 +
  156 + @Override
  157 + public MesProRouteProcessDO getRouteProcess(Long id) {
  158 + return routeProcessMapper.selectById(id);
  159 + }
  160 +
  161 + @Override
  162 + public List<MesProRouteProcessDO> getRouteProcessListByRouteId(Long routeId) {
  163 + return routeProcessMapper.selectListByRouteId(routeId);
  164 + }
  165 +
  166 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProductBomService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.pro.route;
  2 +
  3 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.productbom.MesProRouteProductBomSaveReqVO;
  4 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO;
  5 +import jakarta.validation.Valid;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * MES 工艺路线产品 BOM Service 接口
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +public interface MesProRouteProductBomService {
  15 +
  16 + /**
  17 + * 创建工艺路线产品 BOM
  18 + */
  19 + Long createRouteProductBom(@Valid MesProRouteProductBomSaveReqVO createReqVO);
  20 +
  21 + /**
  22 + * 更新工艺路线产品 BOM
  23 + */
  24 + void updateRouteProductBom(@Valid MesProRouteProductBomSaveReqVO updateReqVO);
  25 +
  26 + /**
  27 + * 删除工艺路线产品 BOM
  28 + */
  29 + void deleteRouteProductBom(Long id);
  30 +
  31 + /**
  32 + * 获得工艺路线产品 BOM
  33 + */
  34 + MesProRouteProductBomDO getRouteProductBom(Long id);
  35 +
  36 + /**
  37 + * 按条件查询工艺路线产品 BOM 列表
  38 + */
  39 + List<MesProRouteProductBomDO> getRouteProductBomList(Long routeId, Long processId, Long productId);
  40 +
  41 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProductBomServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.pro.route;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  4 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.productbom.MesProRouteProductBomSaveReqVO;
  5 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO;
  6 +import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProRouteProductBomMapper;
  7 +import jakarta.annotation.Resource;
  8 +import org.springframework.stereotype.Service;
  9 +import org.springframework.validation.annotation.Validated;
  10 +
  11 +import java.util.List;
  12 +
  13 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  14 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
  15 +
  16 +/**
  17 + * MES 工艺路线产品 BOM Service 实现类
  18 + *
  19 + * @author 芋道源码
  20 + */
  21 +@Service
  22 +@Validated
  23 +public class MesProRouteProductBomServiceImpl implements MesProRouteProductBomService {
  24 +
  25 + @Resource
  26 + private MesProRouteProductBomMapper routeProductBomMapper;
  27 +
  28 + @Override
  29 + public Long createRouteProductBom(MesProRouteProductBomSaveReqVO createReqVO) {
  30 + // 1. 校验唯一性
  31 + validateBomUnique(null, createReqVO.getItemId(), createReqVO.getProcessId(), createReqVO.getProductId());
  32 + // 2. 插入
  33 + MesProRouteProductBomDO routeProductBom = BeanUtils.toBean(createReqVO, MesProRouteProductBomDO.class);
  34 + routeProductBomMapper.insert(routeProductBom);
  35 + return routeProductBom.getId();
  36 + }
  37 +
  38 + @Override
  39 + public void updateRouteProductBom(MesProRouteProductBomSaveReqVO updateReqVO) {
  40 + // 1. 校验存在
  41 + validateRouteProductBomExists(updateReqVO.getId());
  42 + // 2. 校验唯一性
  43 + validateBomUnique(updateReqVO.getId(), updateReqVO.getItemId(), updateReqVO.getProcessId(), updateReqVO.getProductId());
  44 + // 3. 更新
  45 + MesProRouteProductBomDO updateObj = BeanUtils.toBean(updateReqVO, MesProRouteProductBomDO.class);
  46 + routeProductBomMapper.updateById(updateObj);
  47 + }
  48 +
  49 + @Override
  50 + public void deleteRouteProductBom(Long id) {
  51 + // 1. 校验存在
  52 + validateRouteProductBomExists(id);
  53 + // 2. 删除
  54 + routeProductBomMapper.deleteById(id);
  55 + }
  56 +
  57 + private void validateRouteProductBomExists(Long id) {
  58 + if (routeProductBomMapper.selectById(id) == null) {
  59 + throw exception(PRO_ROUTE_PRODUCT_BOM_NOT_EXISTS);
  60 + }
  61 + }
  62 +
  63 + private void validateBomUnique(Long id, Long itemId, Long processId, Long productId) {
  64 + MesProRouteProductBomDO existing = routeProductBomMapper.selectByUnique(itemId, processId, productId);
  65 + if (existing == null) {
  66 + return;
  67 + }
  68 + if (id == null || !existing.getId().equals(id)) {
  69 + throw exception(PRO_ROUTE_PRODUCT_BOM_DUPLICATE);
  70 + }
  71 + }
  72 +
  73 + @Override
  74 + public MesProRouteProductBomDO getRouteProductBom(Long id) {
  75 + return routeProductBomMapper.selectById(id);
  76 + }
  77 +
  78 + @Override
  79 + public List<MesProRouteProductBomDO> getRouteProductBomList(Long routeId, Long processId, Long productId) {
  80 + return routeProductBomMapper.selectList(routeId, processId, productId);
  81 + }
  82 +
  83 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProductService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.pro.route;
  2 +
  3 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.product.MesProRouteProductSaveReqVO;
  4 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO;
  5 +import jakarta.validation.Valid;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * MES 工艺路线产品 Service 接口
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +public interface MesProRouteProductService {
  15 +
  16 + /**
  17 + * 创建工艺路线产品
  18 + */
  19 + Long createRouteProduct(@Valid MesProRouteProductSaveReqVO createReqVO);
  20 +
  21 + /**
  22 + * 更新工艺路线产品
  23 + */
  24 + void updateRouteProduct(@Valid MesProRouteProductSaveReqVO updateReqVO);
  25 +
  26 + /**
  27 + * 删除工艺路线产品
  28 + */
  29 + void deleteRouteProduct(Long id);
  30 +
  31 + /**
  32 + * 获得工艺路线产品
  33 + */
  34 + MesProRouteProductDO getRouteProduct(Long id);
  35 +
  36 + /**
  37 + * 按工艺路线获得产品列表
  38 + */
  39 + List<MesProRouteProductDO> getRouteProductListByRouteId(Long routeId);
  40 +
  41 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProductServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.pro.route;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  4 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.product.MesProRouteProductSaveReqVO;
  5 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO;
  6 +import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProRouteProductBomMapper;
  7 +import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProRouteProductMapper;
  8 +import jakarta.annotation.Resource;
  9 +import org.springframework.stereotype.Service;
  10 +import org.springframework.transaction.annotation.Transactional;
  11 +import org.springframework.validation.annotation.Validated;
  12 +
  13 +import java.util.List;
  14 +
  15 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  16 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
  17 +
  18 +/**
  19 + * MES 工艺路线产品 Service 实现类
  20 + *
  21 + * @author 芋道源码
  22 + */
  23 +@Service
  24 +@Validated
  25 +public class MesProRouteProductServiceImpl implements MesProRouteProductService {
  26 +
  27 + @Resource
  28 + private MesProRouteProductMapper routeProductMapper;
  29 +
  30 + // TODO @AI:别人模块的操作,需要通过 service;
  31 + @Resource
  32 + private MesProRouteProductBomMapper routeProductBomMapper;
  33 +
  34 + @Override
  35 + public Long createRouteProduct(MesProRouteProductSaveReqVO createReqVO) {
  36 + // 1. 校验产品唯一性(一个产品只能关联一条工艺路线)
  37 + validateItemUnique(null, createReqVO.getItemId());
  38 +
  39 + // 2. 插入
  40 + MesProRouteProductDO routeProduct = BeanUtils.toBean(createReqVO, MesProRouteProductDO.class);
  41 + routeProductMapper.insert(routeProduct);
  42 + return routeProduct.getId();
  43 + }
  44 +
  45 + @Override
  46 + public void updateRouteProduct(MesProRouteProductSaveReqVO updateReqVO) {
  47 + // 1.1 校验存在
  48 + validateRouteProductExists(updateReqVO.getId());
  49 + // 1.2 校验产品唯一性
  50 + validateItemUnique(updateReqVO.getId(), updateReqVO.getItemId());
  51 +
  52 + // 2. 更新
  53 + MesProRouteProductDO updateObj = BeanUtils.toBean(updateReqVO, MesProRouteProductDO.class);
  54 + routeProductMapper.updateById(updateObj);
  55 + }
  56 +
  57 + @Override
  58 + @Transactional(rollbackFor = Exception.class)
  59 + public void deleteRouteProduct(Long id) {
  60 + // 1. 校验存在
  61 + // TODO @AI:复用 validateRouteProductExists 方法;
  62 + MesProRouteProductDO routeProduct = routeProductMapper.selectById(id);
  63 + if (routeProduct == null) {
  64 + throw exception(PRO_ROUTE_PRODUCT_NOT_EXISTS);
  65 + }
  66 +
  67 + // 2.1 级联删除关联的 BOM
  68 + routeProductBomMapper.deleteByRouteIdAndProductId(routeProduct.getRouteId(), routeProduct.getItemId());
  69 + // 2.2 删除产品关联
  70 + routeProductMapper.deleteById(id);
  71 + }
  72 +
  73 + private void validateRouteProductExists(Long id) {
  74 + if (routeProductMapper.selectById(id) == null) {
  75 + throw exception(PRO_ROUTE_PRODUCT_NOT_EXISTS);
  76 + }
  77 + }
  78 +
  79 + private void validateItemUnique(Long id, Long itemId) {
  80 + MesProRouteProductDO existing = routeProductMapper.selectByItemId(itemId);
  81 + if (existing == null) {
  82 + return;
  83 + }
  84 + // TODO @AI:notEquals
  85 + if (id == null || !existing.getId().equals(id)) {
  86 + throw exception(PRO_ROUTE_PRODUCT_ITEM_DUPLICATE);
  87 + }
  88 + }
  89 +
  90 + @Override
  91 + public MesProRouteProductDO getRouteProduct(Long id) {
  92 + return routeProductMapper.selectById(id);
  93 + }
  94 +
  95 + @Override
  96 + public List<MesProRouteProductDO> getRouteProductListByRouteId(Long routeId) {
  97 + return routeProductMapper.selectListByRouteId(routeId);
  98 + }
  99 +
  100 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.pro.route;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.MesProRoutePageReqVO;
  5 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.MesProRouteSaveReqVO;
  6 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteDO;
  7 +import jakarta.validation.Valid;
  8 +
  9 +import java.util.List;
  10 +
  11 +/**
  12 + * MES 工艺路线 Service 接口
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +public interface MesProRouteService {
  17 +
  18 + /**
  19 + * 创建工艺路线
  20 + */
  21 + Long createRoute(@Valid MesProRouteSaveReqVO createReqVO);
  22 +
  23 + /**
  24 + * 更新工艺路线
  25 + */
  26 + void updateRoute(@Valid MesProRouteSaveReqVO updateReqVO);
  27 +
  28 + /**
  29 + * 删除工艺路线
  30 + */
  31 + void deleteRoute(Long id);
  32 +
  33 + /**
  34 + * 获得工艺路线
  35 + */
  36 + MesProRouteDO getRoute(Long id);
  37 +
  38 + /**
  39 + * 获得工艺路线分页
  40 + */
  41 + PageResult<MesProRouteDO> getRoutePage(MesProRoutePageReqVO pageReqVO);
  42 +
  43 + /**
  44 + * 获得启用状态的工艺路线列表
  45 + */
  46 + List<MesProRouteDO> getRouteListByStatus(Integer status);
  47 +
  48 +}
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.service.pro.route;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  6 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.MesProRoutePageReqVO;
  7 +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.MesProRouteSaveReqVO;
  8 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteDO;
  9 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO;
  10 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO;
  11 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO;
  12 +import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProRouteMapper;
  13 +import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProRouteProcessMapper;
  14 +import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProRouteProductBomMapper;
  15 +import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProRouteProductMapper;
  16 +import jakarta.annotation.Resource;
  17 +import org.springframework.stereotype.Service;
  18 +import org.springframework.transaction.annotation.Transactional;
  19 +import org.springframework.validation.annotation.Validated;
  20 +
  21 +import java.util.List;
  22 +
  23 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  24 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
  25 +
  26 +/**
  27 + * MES 工艺路线 Service 实现类
  28 + *
  29 + * @author 芋道源码
  30 + */
  31 +@Service
  32 +@Validated
  33 +public class MesProRouteServiceImpl implements MesProRouteService {
  34 +
  35 + @Resource
  36 + private MesProRouteMapper routeMapper;
  37 +
  38 + // todo @AI:不要直接使用对方模块的 mapper,而是通过 service;
  39 + @Resource
  40 + private MesProRouteProcessMapper routeProcessMapper;
  41 + @Resource
  42 + private MesProRouteProductMapper routeProductMapper;
  43 + @Resource
  44 + private MesProRouteProductBomMapper routeProductBomMapper;
  45 +
  46 + @Override
  47 + public Long createRoute(MesProRouteSaveReqVO createReqVO) {
  48 + // 1. 校验编码唯一性
  49 + validateRouteCodeUnique(null, createReqVO.getCode());
  50 + // 2. 插入
  51 + MesProRouteDO route = BeanUtils.toBean(createReqVO, MesProRouteDO.class);
  52 + routeMapper.insert(route);
  53 + return route.getId();
  54 + }
  55 +
  56 + @Override
  57 + public void updateRoute(MesProRouteSaveReqVO updateReqVO) {
  58 + // 1.1 校验存在
  59 + validateRouteExists(updateReqVO.getId());
  60 + // 1.2 校验编码唯一性
  61 + validateRouteCodeUnique(updateReqVO.getId(), updateReqVO.getCode());
  62 + // 1.3 启用时的校验
  63 + // TODO @AI:开启禁用,独立接口;保持更新接口的独立;
  64 + if (CommonStatusEnum.ENABLE.getStatus().equals(updateReqVO.getStatus())) {
  65 + validateRouteEnable(updateReqVO.getId());
  66 + }
  67 +
  68 + // 2. 更新
  69 + MesProRouteDO updateObj = BeanUtils.toBean(updateReqVO, MesProRouteDO.class);
  70 + routeMapper.updateById(updateObj);
  71 + }
  72 +
  73 + @Override
  74 + @Transactional(rollbackFor = Exception.class)
  75 + public void deleteRoute(Long id) {
  76 + // 1. 校验存在
  77 + validateRouteExists(id);
  78 +
  79 + // 2.1 级联删除
  80 + routeProcessMapper.deleteByRouteId(id);
  81 + routeProductMapper.deleteByRouteId(id);
  82 + routeProductBomMapper.deleteByRouteId(id);
  83 + // 2.2 删除工艺路线
  84 + routeMapper.deleteById(id);
  85 + }
  86 +
  87 + private void validateRouteExists(Long id) {
  88 + if (routeMapper.selectById(id) == null) {
  89 + throw exception(PRO_ROUTE_NOT_EXISTS);
  90 + }
  91 + }
  92 +
  93 + private void validateRouteCodeUnique(Long id, String code) {
  94 + MesProRouteDO route = routeMapper.selectByCode(code);
  95 + if (route == null) {
  96 + return;
  97 + }
  98 + // TODO @AI:ObjUtil notequals;
  99 + if (id == null || !route.getId().equals(id)) {
  100 + throw exception(PRO_ROUTE_CODE_DUPLICATE);
  101 + }
  102 + }
  103 +
  104 + /**
  105 + * 启用工艺路线时的校验
  106 + */
  107 + private void validateRouteEnable(Long routeId) {
  108 + // 1. 必须有工序
  109 + List<MesProRouteProcessDO> processList = routeProcessMapper.selectListByRouteId(routeId);
  110 + if (processList.isEmpty()) {
  111 + throw exception(PRO_ROUTE_ENABLE_NO_PROCESS);
  112 + }
  113 + // 2. 必须有关键工序
  114 + boolean hasKeyProcess = processList.stream().anyMatch(MesProRouteProcessDO::getKeyFlag);
  115 + // TODO @AI:BooleanUtils.isFalue(hasKeyProcess)
  116 + if (!hasKeyProcess) {
  117 + throw exception(PRO_ROUTE_ENABLE_NO_KEY_PROCESS);
  118 + }
  119 + // 3. 所有产品必须配置了 BOM 消耗
  120 + List<MesProRouteProductDO> productList = routeProductMapper.selectListByRouteId(routeId);
  121 + for (MesProRouteProductDO product : productList) {
  122 + List<MesProRouteProductBomDO> bomList = routeProductBomMapper
  123 + .selectListByRouteIdAndProductId(routeId, product.getItemId());
  124 + // TODO @AI:CollUtil.isEmpty(bomList)
  125 + if (bomList.isEmpty()) {
  126 + throw exception(PRO_ROUTE_ENABLE_PRODUCT_NO_BOM, product.getItemId());
  127 + }
  128 + }
  129 + }
  130 +
  131 + @Override
  132 + public MesProRouteDO getRoute(Long id) {
  133 + return routeMapper.selectById(id);
  134 + }
  135 +
  136 + @Override
  137 + public PageResult<MesProRouteDO> getRoutePage(MesProRoutePageReqVO pageReqVO) {
  138 + return routeMapper.selectPage(pageReqVO);
  139 + }
  140 +
  141 + @Override
  142 + public List<MesProRouteDO> getRouteListByStatus(Integer status) {
  143 + return routeMapper.selectListByStatus(status);
  144 + }
  145 +
  146 +}
... ...