diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteController.java new file mode 100644 index 0000000..8a7f29b --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteController.java @@ -0,0 +1,102 @@ +package cn.iocoder.yudao.module.mes.controller.admin.pro.route; + +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.MesProRoutePageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.MesProRouteRespVO; +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.MesProRouteSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteDO; +import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; +import java.util.List; + +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; + +@Tag(name = "管理后台 - MES 工艺路线") +@RestController +@RequestMapping("/mes/pro/route") +@Validated +public class MesProRouteController { + + @Resource + private MesProRouteService routeService; + + @PostMapping("/create") + @Operation(summary = "创建工艺路线") + @PreAuthorize("@ss.hasPermission('mes:pro-route:create')") + public CommonResult createRoute(@Valid @RequestBody MesProRouteSaveReqVO createReqVO) { + return success(routeService.createRoute(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新工艺路线") + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')") + public CommonResult updateRoute(@Valid @RequestBody MesProRouteSaveReqVO updateReqVO) { + routeService.updateRoute(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除工艺路线") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('mes:pro-route:delete')") + public CommonResult deleteRoute(@RequestParam("id") Long id) { + routeService.deleteRoute(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得工艺路线") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('mes:pro-route:query')") + public CommonResult getRoute(@RequestParam("id") Long id) { + MesProRouteDO route = routeService.getRoute(id); + return success(BeanUtils.toBean(route, MesProRouteRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得工艺路线分页") + @PreAuthorize("@ss.hasPermission('mes:pro-route:query')") + public CommonResult> getRoutePage(@Valid MesProRoutePageReqVO pageReqVO) { + PageResult pageResult = routeService.getRoutePage(pageReqVO); + return success(BeanUtils.toBean(pageResult, MesProRouteRespVO.class)); + } + + @GetMapping("/simple-list") + @Operation(summary = "获得工艺路线精简列表", description = "只包含被开启的工艺路线,主要用于前端的下拉选项") + public CommonResult> getRouteSimpleList() { + List list = routeService.getRouteListByStatus(CommonStatusEnum.ENABLE.getStatus()); + return success(convertList(list, route -> new MesProRouteRespVO() + .setId(route.getId()).setName(route.getName()).setCode(route.getCode()))); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出工艺路线 Excel") + @PreAuthorize("@ss.hasPermission('mes:pro-route:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportRouteExcel(@Valid MesProRoutePageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = routeService.getRoutePage(pageReqVO).getList(); + List data = BeanUtils.toBean(list, MesProRouteRespVO.class); + ExcelUtils.write(response, "工艺路线.xls", "数据", MesProRouteRespVO.class, data); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProcessController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProcessController.java new file mode 100644 index 0000000..5915be4 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProcessController.java @@ -0,0 +1,127 @@ +package cn.iocoder.yudao.module.mes.controller.admin.pro.route; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process.MesProRouteProcessRespVO; +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process.MesProRouteProcessSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.MesProProcessDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; +import cn.iocoder.yudao.module.mes.service.pro.MesProProcessService; +import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; + +@Tag(name = "管理后台 - MES 工艺路线工序") +@RestController +@RequestMapping("/mes/pro/route-process") +@Validated +public class MesProRouteProcessController { + + @Resource + private MesProRouteProcessService routeProcessService; + + @Resource + private MesProProcessService processService; + + @PostMapping("/create") + @Operation(summary = "创建工艺路线工序") + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')") + public CommonResult createRouteProcess(@Valid @RequestBody MesProRouteProcessSaveReqVO createReqVO) { + return success(routeProcessService.createRouteProcess(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新工艺路线工序") + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')") + public CommonResult updateRouteProcess(@Valid @RequestBody MesProRouteProcessSaveReqVO updateReqVO) { + routeProcessService.updateRouteProcess(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除工艺路线工序") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')") + public CommonResult deleteRouteProcess(@RequestParam("id") Long id) { + routeProcessService.deleteRouteProcess(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得工艺路线工序") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('mes:pro-route:query')") + public CommonResult getRouteProcess(@RequestParam("id") Long id) { + MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcess(id); + return success(buildRouteProcessRespVO(routeProcess)); + } + + @GetMapping("/list-by-route") + @Operation(summary = "按工艺路线获得工序列表") + @Parameter(name = "routeId", description = "工艺路线编号", required = true, example = "1") + @PreAuthorize("@ss.hasPermission('mes:pro-route:query')") + public CommonResult> getRouteProcessListByRoute(@RequestParam("routeId") Long routeId) { + List list = routeProcessService.getRouteProcessListByRouteId(routeId); + return success(buildRouteProcessRespVOList(list)); + } + + // ==================== 拼接 VO ==================== + + private List buildRouteProcessRespVOList(List list) { + // TODO @AI:collutil 去判断空; + if (list.isEmpty()) { + return List.of(); + } + // 批量查询工序信息 + // TODO @AI:我记得有 CollUtil 可以搞多个的; + List processIds = new ArrayList<>(); + for (MesProRouteProcessDO item : list) { + processIds.add(item.getProcessId()); + if (item.getNextProcessId() != null) { + processIds.add(item.getNextProcessId()); + } + } + // TODO @AI:processService.getProcessMap 直接返回 Map 就好了; + List processList = processService.getProcessList(processIds); + Map processMap = convertMap(processList, MesProProcessDO::getId); + // 拼装 + List result = BeanUtils.toBean(list, MesProRouteProcessRespVO.class); + for (MesProRouteProcessRespVO vo : result) { + // TODO @AI:MapUtil findMap + MesProProcessDO process = processMap.get(vo.getProcessId()); + if (process != null) { + vo.setProcessCode(process.getCode()).setProcessName(process.getName()); + } + // TODO @AI:MapUtil findMap + if (vo.getNextProcessId() != null) { + MesProProcessDO nextProcess = processMap.get(vo.getNextProcessId()); + if (nextProcess != null) { + vo.setNextProcessName(nextProcess.getName()); + } + } + } + return result; + } + + // TODO @AI:需要的地方,直接调用 buildRouteProcessRespVOList; + private MesProRouteProcessRespVO buildRouteProcessRespVO(MesProRouteProcessDO routeProcess) { + if (routeProcess == null) { + return null; + } + return buildRouteProcessRespVOList(List.of(routeProcess)).get(0); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProductBomController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProductBomController.java new file mode 100644 index 0000000..cb46a2e --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProductBomController.java @@ -0,0 +1,134 @@ +package cn.iocoder.yudao.module.mes.controller.admin.pro.route; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.productbom.MesProRouteProductBomRespVO; +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.productbom.MesProRouteProductBomSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO; +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; +import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService; +import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductBomService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; + +@Tag(name = "管理后台 - MES 工艺路线产品 BOM") +@RestController +@RequestMapping("/mes/pro/route-product-bom") +@Validated +public class MesProRouteProductBomController { + + @Resource + private MesProRouteProductBomService routeProductBomService; + + @Resource + private MesMdItemService itemService; + + @Resource + private MesMdUnitMeasureService unitMeasureService; + + @PostMapping("/create") + @Operation(summary = "创建工艺路线产品 BOM") + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')") + public CommonResult createRouteProductBom(@Valid @RequestBody MesProRouteProductBomSaveReqVO createReqVO) { + return success(routeProductBomService.createRouteProductBom(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新工艺路线产品 BOM") + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')") + public CommonResult updateRouteProductBom(@Valid @RequestBody MesProRouteProductBomSaveReqVO updateReqVO) { + routeProductBomService.updateRouteProductBom(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除工艺路线产品 BOM") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')") + public CommonResult deleteRouteProductBom(@RequestParam("id") Long id) { + routeProductBomService.deleteRouteProductBom(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得工艺路线产品 BOM") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('mes:pro-route:query')") + public CommonResult getRouteProductBom(@RequestParam("id") Long id) { + MesProRouteProductBomDO routeProductBom = routeProductBomService.getRouteProductBom(id); + return success(buildRouteProductBomRespVO(routeProductBom)); + } + + @GetMapping("/list") + @Operation(summary = "查询工艺路线产品 BOM 列表") + @Parameters({ + @Parameter(name = "routeId", description = "工艺路线编号", required = true, example = "1"), + @Parameter(name = "processId", description = "工序编号", example = "1"), + @Parameter(name = "productId", description = "产品物料编号", example = "1") + }) + @PreAuthorize("@ss.hasPermission('mes:pro-route:query')") + public CommonResult> getRouteProductBomList( + @RequestParam("routeId") Long routeId, + @RequestParam(value = "processId", required = false) Long processId, + @RequestParam(value = "productId", required = false) Long productId) { + List list = routeProductBomService.getRouteProductBomList(routeId, processId, productId); + return success(buildRouteProductBomRespVOList(list)); + } + + // ==================== 拼接 VO ==================== + + // 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; + + private List buildRouteProductBomRespVOList(List list) { + if (list.isEmpty()) { + return List.of(); + } + // 批量查询物料信息 + List itemIds = convertList(list, MesProRouteProductBomDO::getItemId); + List itemList = itemService.getItemList(itemIds); + Map itemMap = convertMap(itemList, MesMdItemDO::getId); + // 批量查询单位信息 + List unitMeasureIds = convertList(itemList, MesMdItemDO::getUnitMeasureId); + Map unitMap = convertMap( + unitMeasureService.getUnitMeasureList(unitMeasureIds), MesMdUnitMeasureDO::getId); + // 拼装 + List result = BeanUtils.toBean(list, MesProRouteProductBomRespVO.class); + for (MesProRouteProductBomRespVO vo : result) { + MesMdItemDO item = itemMap.get(vo.getItemId()); + if (item != null) { + vo.setItemCode(item.getCode()); + vo.setItemName(item.getName()); + vo.setSpecification(item.getSpecification()); + MesMdUnitMeasureDO unit = unitMap.get(item.getUnitMeasureId()); + if (unit != null) { + vo.setUnitName(unit.getName()); + } + } + } + return result; + } + + private MesProRouteProductBomRespVO buildRouteProductBomRespVO(MesProRouteProductBomDO routeProductBom) { + if (routeProductBom == null) { + return null; + } + return buildRouteProductBomRespVOList(List.of(routeProductBom)).get(0); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProductController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProductController.java new file mode 100644 index 0000000..cceee7e --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProductController.java @@ -0,0 +1,125 @@ +package cn.iocoder.yudao.module.mes.controller.admin.pro.route; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.product.MesProRouteProductRespVO; +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.product.MesProRouteProductSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO; +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; +import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService; +import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; + +@Tag(name = "管理后台 - MES 工艺路线产品") +@RestController +@RequestMapping("/mes/pro/route-product") +@Validated +public class MesProRouteProductController { + + @Resource + private MesProRouteProductService routeProductService; + + @Resource + private MesMdItemService itemService; + + @Resource + private MesMdUnitMeasureService unitMeasureService; + + @PostMapping("/create") + @Operation(summary = "创建工艺路线产品") + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')") + public CommonResult createRouteProduct(@Valid @RequestBody MesProRouteProductSaveReqVO createReqVO) { + return success(routeProductService.createRouteProduct(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新工艺路线产品") + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')") + public CommonResult updateRouteProduct(@Valid @RequestBody MesProRouteProductSaveReqVO updateReqVO) { + routeProductService.updateRouteProduct(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除工艺路线产品") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('mes:pro-route:update')") + public CommonResult deleteRouteProduct(@RequestParam("id") Long id) { + routeProductService.deleteRouteProduct(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得工艺路线产品") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('mes:pro-route:query')") + public CommonResult getRouteProduct(@RequestParam("id") Long id) { + MesProRouteProductDO routeProduct = routeProductService.getRouteProduct(id); + return success(buildRouteProductRespVO(routeProduct)); + } + + @GetMapping("/list-by-route") + @Operation(summary = "按工艺路线获得产品列表") + @Parameter(name = "routeId", description = "工艺路线编号", required = true, example = "1") + @PreAuthorize("@ss.hasPermission('mes:pro-route:query')") + public CommonResult> getRouteProductListByRoute(@RequestParam("routeId") Long routeId) { + List list = routeProductService.getRouteProductListByRouteId(routeId); + return success(buildRouteProductRespVOList(list)); + } + + // ==================== 拼接 VO ==================== + // 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; + + private List buildRouteProductRespVOList(List list) { + if (list.isEmpty()) { + return List.of(); + } + // 批量查询物料信息 + List itemIds = convertList(list, MesProRouteProductDO::getItemId); + List itemList = itemService.getItemList(itemIds); + Map itemMap = convertMap(itemList, MesMdItemDO::getId); + // 批量查询单位信息 + List unitMeasureIds = convertList(itemList, MesMdItemDO::getUnitMeasureId); + Map unitMap = convertMap( + unitMeasureService.getUnitMeasureList(unitMeasureIds), MesMdUnitMeasureDO::getId); + // 拼装 + List result = BeanUtils.toBean(list, MesProRouteProductRespVO.class); + for (MesProRouteProductRespVO vo : result) { + MesMdItemDO item = itemMap.get(vo.getItemId()); + if (item != null) { + vo.setItemCode(item.getCode()); + vo.setItemName(item.getName()); + vo.setSpecification(item.getSpecification()); + MesMdUnitMeasureDO unit = unitMap.get(item.getUnitMeasureId()); + if (unit != null) { + vo.setUnitName(unit.getName()); + } + } + } + return result; + } + + private MesProRouteProductRespVO buildRouteProductRespVO(MesProRouteProductDO routeProduct) { + if (routeProduct == null) { + return null; + } + return buildRouteProductRespVOList(List.of(routeProduct)).get(0); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/MesProRoutePageReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/MesProRoutePageReqVO.java new file mode 100644 index 0000000..2c8a50e --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/MesProRoutePageReqVO.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - MES 工艺路线分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class MesProRoutePageReqVO extends PageParam { + + @Schema(description = "工艺路线编码", example = "ROUTE001") + private String code; + + @Schema(description = "工艺路线名称", example = "标准路线") + private String name; + + @Schema(description = "状态", example = "0") + private Integer status; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/MesProRouteRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/MesProRouteRespVO.java new file mode 100644 index 0000000..749d4a2 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/MesProRouteRespVO.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo; + +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - MES 工艺路线 Response VO") +@Data +@ExcelIgnoreUnannotated +public class MesProRouteRespVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @ExcelProperty("编号") + private Long id; + + @Schema(description = "工艺路线编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "ROUTE001") + @ExcelProperty("工艺路线编码") + private String code; + + @Schema(description = "工艺路线名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "标准路线") + @ExcelProperty("工艺路线名称") + private String name; + + @Schema(description = "工艺路线说明") + @ExcelProperty("工艺路线说明") + private String description; + + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") + @ExcelProperty("状态") + private Integer status; + + @Schema(description = "备注") + @ExcelProperty("备注") + private String remark; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/MesProRouteSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/MesProRouteSaveReqVO.java new file mode 100644 index 0000000..b6c917b --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/MesProRouteSaveReqVO.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Schema(description = "管理后台 - MES 工艺路线新增/修改 Request VO") +@Data +public class MesProRouteSaveReqVO { + + @Schema(description = "编号", example = "1") + private Long id; + + @Schema(description = "工艺路线编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "ROUTE001") + @NotBlank(message = "工艺路线编码不能为空") + private String code; + + @Schema(description = "工艺路线名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "标准路线") + @NotBlank(message = "工艺路线名称不能为空") + private String name; + + @Schema(description = "工艺路线说明") + private String description; + + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") + @NotNull(message = "状态不能为空") + private Integer status; + + @Schema(description = "备注") + private String remark; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/process/MesProRouteProcessRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/process/MesProRouteProcessRespVO.java new file mode 100644 index 0000000..78608e6 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/process/MesProRouteProcessRespVO.java @@ -0,0 +1,60 @@ +package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - MES 工艺路线工序 Response VO") +@Data +public class MesProRouteProcessRespVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long id; + + @Schema(description = "工艺路线编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long routeId; + + @Schema(description = "工序编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long processId; + + @Schema(description = "工序编码") + private String processCode; + + @Schema(description = "工序名称") + private String processName; + + @Schema(description = "序号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer sort; + + @Schema(description = "下一道工序编号") + private Long nextProcessId; + + @Schema(description = "下一道工序名称") + private String nextProcessName; + + @Schema(description = "与下一道工序关系", example = "0") + private Integer linkType; + + @Schema(description = "准备时间(分钟)", example = "10") + private Integer prepareTime; + + @Schema(description = "等待时间(分钟)", example = "5") + private Integer waitTime; + + @Schema(description = "甘特图显示颜色", example = "#00AEF3") + private String colorCode; + + @Schema(description = "是否关键工序", example = "false") + private Boolean keyFlag; + + @Schema(description = "是否质检工序", example = "false") + private Boolean checkFlag; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/process/MesProRouteProcessSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/process/MesProRouteProcessSaveReqVO.java new file mode 100644 index 0000000..9cde37c --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/process/MesProRouteProcessSaveReqVO.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Schema(description = "管理后台 - MES 工艺路线工序新增/修改 Request VO") +@Data +public class MesProRouteProcessSaveReqVO { + + @Schema(description = "编号", example = "1") + private Long id; + + @Schema(description = "工艺路线编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "工艺路线编号不能为空") + private Long routeId; + + @Schema(description = "工序编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "工序编号不能为空") + private Long processId; + + @Schema(description = "序号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "序号不能为空") + private Integer sort; + + @Schema(description = "与下一道工序关系", example = "0") + private Integer linkType; + + @Schema(description = "准备时间(分钟)", example = "10") + private Integer prepareTime; + + @Schema(description = "等待时间(分钟)", example = "5") + private Integer waitTime; + + @Schema(description = "甘特图显示颜色", example = "#00AEF3") + private String colorCode; + + @Schema(description = "是否关键工序", example = "false") + private Boolean keyFlag; + + @Schema(description = "是否质检工序", example = "false") + private Boolean checkFlag; + + @Schema(description = "备注") + private String remark; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/product/MesProRouteProductRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/product/MesProRouteProductRespVO.java new file mode 100644 index 0000000..8df87e9 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/product/MesProRouteProductRespVO.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.product; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - MES 工艺路线产品 Response VO") +@Data +public class MesProRouteProductRespVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long id; + + @Schema(description = "工艺路线编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long routeId; + + @Schema(description = "产品物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long itemId; + + @Schema(description = "产品物料编码") + private String itemCode; + + @Schema(description = "产品物料名称") + private String itemName; + + @Schema(description = "规格型号") + private String specification; + + @Schema(description = "单位名称") + private String unitName; + + @Schema(description = "生产数量", example = "100") + private Integer quantity; + + @Schema(description = "生产用时", example = "60.00") + private BigDecimal productionTime; + + @Schema(description = "时间单位", example = "MINUTE") + private String timeUnitType; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/product/MesProRouteProductSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/product/MesProRouteProductSaveReqVO.java new file mode 100644 index 0000000..db5ecf1 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/product/MesProRouteProductSaveReqVO.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.product; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.math.BigDecimal; + +@Schema(description = "管理后台 - MES 工艺路线产品新增/修改 Request VO") +@Data +public class MesProRouteProductSaveReqVO { + + @Schema(description = "编号", example = "1") + private Long id; + + @Schema(description = "工艺路线编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "工艺路线编号不能为空") + private Long routeId; + + @Schema(description = "产品物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "产品物料编号不能为空") + private Long itemId; + + @Schema(description = "生产数量", example = "100") + private Integer quantity; + + @Schema(description = "生产用时", example = "60.00") + private BigDecimal productionTime; + + @Schema(description = "时间单位", example = "MINUTE") + private String timeUnitType; + + @Schema(description = "备注") + private String remark; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/productbom/MesProRouteProductBomRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/productbom/MesProRouteProductBomRespVO.java new file mode 100644 index 0000000..a802f12 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/productbom/MesProRouteProductBomRespVO.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.productbom; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - MES 工艺路线产品 BOM Response VO") +@Data +public class MesProRouteProductBomRespVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long id; + + @Schema(description = "工艺路线编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long routeId; + + @Schema(description = "工序编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long processId; + + @Schema(description = "产品物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long productId; + + @Schema(description = "BOM 物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long itemId; + + @Schema(description = "BOM 物料编码") + private String itemCode; + + @Schema(description = "BOM 物料名称") + private String itemName; + + @Schema(description = "规格型号") + private String specification; + + @Schema(description = "单位名称") + private String unitName; + + @Schema(description = "用料比例", example = "1.50") + private BigDecimal quantity; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/productbom/MesProRouteProductBomSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/productbom/MesProRouteProductBomSaveReqVO.java new file mode 100644 index 0000000..7dad3d5 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/productbom/MesProRouteProductBomSaveReqVO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.productbom; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.math.BigDecimal; + +@Schema(description = "管理后台 - MES 工艺路线产品 BOM 新增/修改 Request VO") +@Data +public class MesProRouteProductBomSaveReqVO { + + @Schema(description = "编号", example = "1") + private Long id; + + @Schema(description = "工艺路线编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "工艺路线编号不能为空") + private Long routeId; + + @Schema(description = "工序编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "工序编号不能为空") + private Long processId; + + @Schema(description = "产品物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "产品物料编号不能为空") + private Long productId; + + @Schema(description = "BOM 物料编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "BOM 物料编号不能为空") + private Long itemId; + + @Schema(description = "用料比例", example = "1.50") + private BigDecimal quantity; + + @Schema(description = "备注") + private String remark; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteDO.java new file mode 100644 index 0000000..755b86c --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteDO.java @@ -0,0 +1,68 @@ +package cn.iocoder.yudao.module.mes.dal.dataobject.pro.route; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * MES 工艺路线 DO + * + * @author 芋道源码 + */ +@TableName("mes_pro_route") +@KeySequence("mes_pro_route_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MesProRouteDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 工艺路线编码 + */ + private String code; + /** + * 工艺路线名称 + */ + private String name; + /** + * 工艺路线说明 + */ + private String description; + /** + * 状态 + * + * 枚举 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum} + */ + private Integer status; + /** + * 备注 + */ + private String remark; + /** + * 预留字段1 + */ + private String attribute1; + /** + * 预留字段2 + */ + private String attribute2; + /** + * 预留字段3 + */ + private Integer attribute3; + /** + * 预留字段4 + */ + private Integer attribute4; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteProcessDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteProcessDO.java new file mode 100644 index 0000000..c037a84 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteProcessDO.java @@ -0,0 +1,95 @@ +package cn.iocoder.yudao.module.mes.dal.dataobject.pro.route; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * MES 工艺路线工序 DO + * + * @author 芋道源码 + */ +@TableName("mes_pro_route_process") +@KeySequence("mes_pro_route_process_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MesProRouteProcessDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + // TODO @AI:外链 @ 加下,参考别的模块 + /** + * 工艺路线编号 + */ + private Long routeId; + // TODO @AI:外链 @ 加下,参考别的模块 + /** + * 工序编号 + */ + private Long processId; + /** + * 序号 + */ + private Integer sort; + // TODO @AI:外链 @ 加下,参考别的模块 + /** + * 下一道工序编号 + */ + private Long nextProcessId; + /** + * 与下一道工序关系 + * + * 枚举 {@link cn.iocoder.yudao.module.mes.enums.pro.MesProLinkTypeEnum} + */ + private Integer linkType; + /** + * 准备时间(分钟) + */ + private Integer prepareTime; + /** + * 等待时间(分钟) + */ + private Integer waitTime; + /** + * 甘特图显示颜色 + */ + private String colorCode; + /** + * 是否关键工序 + */ + private Boolean keyFlag; + /** + * 是否质检工序 + */ + private Boolean checkFlag; + /** + * 备注 + */ + private String remark; + /** + * 预留字段1 + */ + private String attribute1; + /** + * 预留字段2 + */ + private String attribute2; + /** + * 预留字段3 + */ + private Integer attribute3; + /** + * 预留字段4 + */ + private Integer attribute4; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteProductBomDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteProductBomDO.java new file mode 100644 index 0000000..02cdf85 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteProductBomDO.java @@ -0,0 +1,76 @@ +package cn.iocoder.yudao.module.mes.dal.dataobject.pro.route; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.math.BigDecimal; + +/** + * MES 工艺路线产品 BOM DO + * + * @author 芋道源码 + */ +@TableName("mes_pro_route_product_bom") +@KeySequence("mes_pro_route_product_bom_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MesProRouteProductBomDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + // TODO @AI:外链 @ 加下,参考别的模块 + /** + * 工艺路线编号 + */ + private Long routeId; + // TODO @AI:外链 @ 加下,参考别的模块 + /** + * 工序编号 + */ + private Long processId; + // TODO @AI:外链 @ 加下,参考别的模块 + /** + * 产品物料编号 + */ + private Long productId; + // TODO @AI:外链 @ 加下,参考别的模块 + /** + * BOM 物料编号 + */ + private Long itemId; + /** + * 用料比例 + */ + private BigDecimal quantity; + /** + * 备注 + */ + private String remark; + /** + * 预留字段1 + */ + private String attribute1; + /** + * 预留字段2 + */ + private String attribute2; + /** + * 预留字段3 + */ + private Integer attribute3; + /** + * 预留字段4 + */ + private Integer attribute4; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteProductDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteProductDO.java new file mode 100644 index 0000000..64dc6ac --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteProductDO.java @@ -0,0 +1,75 @@ +package cn.iocoder.yudao.module.mes.dal.dataobject.pro.route; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.math.BigDecimal; + +/** + * MES 工艺路线产品 DO + * + * @author 芋道源码 + */ +@TableName("mes_pro_route_product") +@KeySequence("mes_pro_route_product_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MesProRouteProductDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + // TODO @AI:外链 @ 加下,参考别的模块 + /** + * 工艺路线编号 + */ + private Long routeId; + // TODO @AI:外链 @ 加下,参考别的模块 + /** + * 产品物料编号 + */ + private Long itemId; + /** + * 生产数量 + */ + private Integer quantity; + /** + * 生产用时 + */ + private BigDecimal productionTime; + /** + * 时间单位 + */ + // TODO @AI:外链 @ 加下,字典 + 枚举类; + private String timeUnitType; + /** + * 备注 + */ + private String remark; + /** + * 预留字段1 + */ + private String attribute1; + /** + * 预留字段2 + */ + private String attribute2; + /** + * 预留字段3 + */ + private Integer attribute3; + /** + * 预留字段4 + */ + private Integer attribute4; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/MesProRouteMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/MesProRouteMapper.java new file mode 100644 index 0000000..0ac6d44 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/MesProRouteMapper.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.mes.dal.mysql.pro; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.MesProRoutePageReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * MES 工艺路线 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface MesProRouteMapper extends BaseMapperX { + + default PageResult selectPage(MesProRoutePageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(MesProRouteDO::getCode, reqVO.getCode()) + .likeIfPresent(MesProRouteDO::getName, reqVO.getName()) + .eqIfPresent(MesProRouteDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(MesProRouteDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(MesProRouteDO::getId)); + } + + default MesProRouteDO selectByCode(String code) { + return selectOne(MesProRouteDO::getCode, code); + } + + default List selectListByStatus(Integer status) { + return selectList(MesProRouteDO::getStatus, status); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/MesProRouteProcessMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/MesProRouteProcessMapper.java new file mode 100644 index 0000000..38a65b8 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/MesProRouteProcessMapper.java @@ -0,0 +1,69 @@ +package cn.iocoder.yudao.module.mes.dal.mysql.pro; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * MES 工艺路线工序 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface MesProRouteProcessMapper extends BaseMapperX { + + default List selectListByRouteId(Long routeId) { + return selectList(new LambdaQueryWrapperX() + .eq(MesProRouteProcessDO::getRouteId, routeId) + .orderByAsc(MesProRouteProcessDO::getSort)); + } + + default MesProRouteProcessDO selectByRouteIdAndSort(Long routeId, Integer sort) { + return selectOne(new LambdaQueryWrapperX() + .eq(MesProRouteProcessDO::getRouteId, routeId) + .eq(MesProRouteProcessDO::getSort, sort)); + } + + default MesProRouteProcessDO selectByRouteIdAndProcessId(Long routeId, Long processId) { + return selectOne(new LambdaQueryWrapperX() + .eq(MesProRouteProcessDO::getRouteId, routeId) + .eq(MesProRouteProcessDO::getProcessId, processId)); + } + + default MesProRouteProcessDO selectKeyProcessByRouteId(Long routeId) { + return selectOne(new LambdaQueryWrapperX() + .eq(MesProRouteProcessDO::getRouteId, routeId) + .eq(MesProRouteProcessDO::getKeyFlag, true)); + } + + default void deleteByRouteId(Long routeId) { + delete(new LambdaQueryWrapperX() + .eq(MesProRouteProcessDO::getRouteId, routeId)); + } + + default List selectListByProcessId(Long processId) { + return selectList(MesProRouteProcessDO::getProcessId, processId); + } + + default MesProRouteProcessDO findPreProcess(Long routeId, Integer sort) { + return selectOne(new LambdaQueryWrapperX() + .eq(MesProRouteProcessDO::getRouteId, routeId) + .lt(MesProRouteProcessDO::getSort, sort) + .orderByDesc(MesProRouteProcessDO::getSort) + // TODO @AI:limit 1,使用 mybatis utils + .last("LIMIT 1")); + } + + default MesProRouteProcessDO findNextProcess(Long routeId, Integer sort) { + return selectOne(new LambdaQueryWrapperX() + .eq(MesProRouteProcessDO::getRouteId, routeId) + .gt(MesProRouteProcessDO::getSort, sort) + .orderByAsc(MesProRouteProcessDO::getSort) + // TODO @AI:limit 1,使用 mybatis utils + .last("LIMIT 1")); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/MesProRouteProductBomMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/MesProRouteProductBomMapper.java new file mode 100644 index 0000000..f62d2cc --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/MesProRouteProductBomMapper.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.mes.dal.mysql.pro; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * MES 工艺路线产品 BOM Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface MesProRouteProductBomMapper extends BaseMapperX { + + default List selectList(Long routeId, Long processId, Long productId) { + return selectList(new LambdaQueryWrapperX() + .eqIfPresent(MesProRouteProductBomDO::getRouteId, routeId) + .eqIfPresent(MesProRouteProductBomDO::getProcessId, processId) + .eqIfPresent(MesProRouteProductBomDO::getProductId, productId)); + } + + default MesProRouteProductBomDO selectByUnique(Long itemId, Long processId, Long productId) { + return selectOne(new LambdaQueryWrapperX() + .eq(MesProRouteProductBomDO::getItemId, itemId) + .eq(MesProRouteProductBomDO::getProcessId, processId) + .eq(MesProRouteProductBomDO::getProductId, productId)); + } + + default void deleteByRouteId(Long routeId) { + delete(new LambdaQueryWrapperX() + .eq(MesProRouteProductBomDO::getRouteId, routeId)); + } + + default void deleteByRouteIdAndProductId(Long routeId, Long productId) { + delete(new LambdaQueryWrapperX() + .eq(MesProRouteProductBomDO::getRouteId, routeId) + .eq(MesProRouteProductBomDO::getProductId, productId)); + } + + default List selectListByRouteIdAndProductId(Long routeId, Long productId) { + return selectList(new LambdaQueryWrapperX() + .eq(MesProRouteProductBomDO::getRouteId, routeId) + .eq(MesProRouteProductBomDO::getProductId, productId)); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/MesProRouteProductMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/MesProRouteProductMapper.java new file mode 100644 index 0000000..777a4a5 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/MesProRouteProductMapper.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.mes.dal.mysql.pro; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * MES 工艺路线产品 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface MesProRouteProductMapper extends BaseMapperX { + + default List selectListByRouteId(Long routeId) { + return selectList(MesProRouteProductDO::getRouteId, routeId); + } + + default MesProRouteProductDO selectByItemId(Long itemId) { + return selectOne(MesProRouteProductDO::getItemId, itemId); + } + + default void deleteByRouteId(Long routeId) { + delete(new LambdaQueryWrapperX() + .eq(MesProRouteProductDO::getRouteId, routeId)); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/MesProProcessServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/MesProProcessServiceImpl.java index 6c12960..020afe4 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/MesProProcessServiceImpl.java +++ b/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 import cn.iocoder.yudao.module.mes.controller.admin.pro.process.vo.MesProProcessSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.MesProProcessDO; import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProProcessMapper; +import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProRouteProcessMapper; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -31,6 +32,9 @@ public class MesProProcessServiceImpl implements MesProProcessService { @Resource private MesProProcessContentService processContentService; + @Resource + private MesProRouteProcessMapper routeProcessMapper; + @Override public Long createProcess(MesProProcessSaveReqVO createReqVO) { // 1. 校验工序编码唯一性 @@ -61,10 +65,13 @@ public class MesProProcessServiceImpl implements MesProProcessService { public void deleteProcess(Long id) { // 1. 校验存在 validateProcessExists(id); - // TODO @芋艿:校验是否被工艺路线引用(pro_route_process 表实现后) - // 2. 删除工序 + // 2. 校验是否被工艺路线引用 + if (!routeProcessMapper.selectListByProcessId(id).isEmpty()) { + throw exception(PRO_PROCESS_USED_BY_ROUTE); + } + // 3. 删除工序 processMapper.deleteById(id); - // 3. 级联删除工序内容 + // 4. 级联删除工序内容 processContentService.deleteProcessContentByProcessId(id); } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProcessService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProcessService.java new file mode 100644 index 0000000..8f4b07a --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProcessService.java @@ -0,0 +1,41 @@ +package cn.iocoder.yudao.module.mes.service.pro.route; + +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process.MesProRouteProcessSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; +import jakarta.validation.Valid; + +import java.util.List; + +/** + * MES 工艺路线工序 Service 接口 + * + * @author 芋道源码 + */ +public interface MesProRouteProcessService { + + /** + * 创建工艺路线工序 + */ + Long createRouteProcess(@Valid MesProRouteProcessSaveReqVO createReqVO); + + /** + * 更新工艺路线工序 + */ + void updateRouteProcess(@Valid MesProRouteProcessSaveReqVO updateReqVO); + + /** + * 删除工艺路线工序 + */ + void deleteRouteProcess(Long id); + + /** + * 获得工艺路线工序 + */ + MesProRouteProcessDO getRouteProcess(Long id); + + /** + * 按工艺路线获得工序列表 + */ + List getRouteProcessListByRouteId(Long routeId); + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProcessServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProcessServiceImpl.java new file mode 100644 index 0000000..591b3b6 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProcessServiceImpl.java @@ -0,0 +1,166 @@ +package cn.iocoder.yudao.module.mes.service.pro.route; + +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process.MesProRouteProcessSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.MesProProcessDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; +import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProRouteProcessMapper; +import cn.iocoder.yudao.module.mes.service.pro.MesProProcessService; +import jakarta.annotation.Resource; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import java.util.Comparator; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; + +// TODO @AI:参考别的模块,需要校验下相关的工艺路线、工序是否存在;(别的 route 也是);最好对方 service 提供校验方法; +/** + * MES 工艺路线工序 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class MesProRouteProcessServiceImpl implements MesProRouteProcessService { + + @Resource + private MesProRouteProcessMapper routeProcessMapper; + + // TODO @AI:貌似没用到?是不是应该要用下哈? + @Resource + @Lazy + private MesProProcessService processService; + + @Override + @Transactional(rollbackFor = Exception.class) + public Long createRouteProcess(MesProRouteProcessSaveReqVO createReqVO) { + // 1. 校验 + validateRouteProcessCreate(createReqVO); + + // 2. 插入 + MesProRouteProcessDO routeProcess = BeanUtils.toBean(createReqVO, MesProRouteProcessDO.class); + routeProcessMapper.insert(routeProcess); + + // 3. 更新工序链 + rebuildProcessChain(createReqVO.getRouteId()); + return routeProcess.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateRouteProcess(MesProRouteProcessSaveReqVO updateReqVO) { + // 1.1 校验存在 + validateRouteProcessExists(updateReqVO.getId()); + // 1.2 校验唯一性 + validateRouteProcessUpdate(updateReqVO); + + // 2. 更新 + MesProRouteProcessDO updateObj = BeanUtils.toBean(updateReqVO, MesProRouteProcessDO.class); + routeProcessMapper.updateById(updateObj); + + // 3. 重建工序链 + rebuildProcessChain(updateReqVO.getRouteId()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteRouteProcess(Long id) { + // 1. 校验存在 + MesProRouteProcessDO routeProcess = routeProcessMapper.selectById(id); + if (routeProcess == null) { + throw exception(PRO_ROUTE_PROCESS_NOT_EXISTS); + } + + // 2. 删除 + routeProcessMapper.deleteById(id); + + // 3. 重建工序链 + rebuildProcessChain(routeProcess.getRouteId()); + } + + /** + * 重建工序链(更新所有工序的 nextProcessId) + */ + private void rebuildProcessChain(Long routeId) { + List list = routeProcessMapper.selectListByRouteId(routeId); + // TODO @AI:CollUtil isEmpty; + if (list.isEmpty()) { + return; + } + // 按 sort 排序 + list.sort(Comparator.comparing(MesProRouteProcessDO::getSort)); + for (int i = 0; i < list.size(); i++) { + MesProRouteProcessDO item = list.get(i); + if (i + 1 < list.size()) { + item.setNextProcessId(list.get(i + 1).getProcessId()); + } else { + item.setNextProcessId(null); + } + routeProcessMapper.updateById(item); + } + } + + private void validateRouteProcessExists(Long id) { + if (routeProcessMapper.selectById(id) == null) { + throw exception(PRO_ROUTE_PROCESS_NOT_EXISTS); + } + } + + // TODO @AI:参考别的模块,拆分为多个模块 + private void validateRouteProcessCreate(MesProRouteProcessSaveReqVO reqVO) { + // 序号唯一 + MesProRouteProcessDO existing = routeProcessMapper.selectByRouteIdAndSort(reqVO.getRouteId(), reqVO.getSort()); + if (existing != null) { + throw exception(PRO_ROUTE_PROCESS_SORT_DUPLICATE); + } + // 工序不重复 + existing = routeProcessMapper.selectByRouteIdAndProcessId(reqVO.getRouteId(), reqVO.getProcessId()); + if (existing != null) { + throw exception(PRO_ROUTE_PROCESS_DUPLICATE); + } + // 关键工序唯一 + if (Boolean.TRUE.equals(reqVO.getKeyFlag())) { + existing = routeProcessMapper.selectKeyProcessByRouteId(reqVO.getRouteId()); + if (existing != null) { + throw exception(PRO_ROUTE_PROCESS_KEY_DUPLICATE); + } + } + } + + // TODO @AI:参考别的模块,拆分为多个模块 + private void validateRouteProcessUpdate(MesProRouteProcessSaveReqVO reqVO) { + // 序号唯一(排除自身) + MesProRouteProcessDO existing = routeProcessMapper.selectByRouteIdAndSort(reqVO.getRouteId(), reqVO.getSort()); + if (existing != null && !existing.getId().equals(reqVO.getId())) { + throw exception(PRO_ROUTE_PROCESS_SORT_DUPLICATE); + } + // 工序不重复(排除自身) + existing = routeProcessMapper.selectByRouteIdAndProcessId(reqVO.getRouteId(), reqVO.getProcessId()); + if (existing != null && !existing.getId().equals(reqVO.getId())) { + throw exception(PRO_ROUTE_PROCESS_DUPLICATE); + } + // 关键工序唯一(排除自身) + if (Boolean.TRUE.equals(reqVO.getKeyFlag())) { + existing = routeProcessMapper.selectKeyProcessByRouteId(reqVO.getRouteId()); + if (existing != null && !existing.getId().equals(reqVO.getId())) { + throw exception(PRO_ROUTE_PROCESS_KEY_DUPLICATE); + } + } + } + + @Override + public MesProRouteProcessDO getRouteProcess(Long id) { + return routeProcessMapper.selectById(id); + } + + @Override + public List getRouteProcessListByRouteId(Long routeId) { + return routeProcessMapper.selectListByRouteId(routeId); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProductBomService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProductBomService.java new file mode 100644 index 0000000..42baf8b --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProductBomService.java @@ -0,0 +1,41 @@ +package cn.iocoder.yudao.module.mes.service.pro.route; + +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.productbom.MesProRouteProductBomSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO; +import jakarta.validation.Valid; + +import java.util.List; + +/** + * MES 工艺路线产品 BOM Service 接口 + * + * @author 芋道源码 + */ +public interface MesProRouteProductBomService { + + /** + * 创建工艺路线产品 BOM + */ + Long createRouteProductBom(@Valid MesProRouteProductBomSaveReqVO createReqVO); + + /** + * 更新工艺路线产品 BOM + */ + void updateRouteProductBom(@Valid MesProRouteProductBomSaveReqVO updateReqVO); + + /** + * 删除工艺路线产品 BOM + */ + void deleteRouteProductBom(Long id); + + /** + * 获得工艺路线产品 BOM + */ + MesProRouteProductBomDO getRouteProductBom(Long id); + + /** + * 按条件查询工艺路线产品 BOM 列表 + */ + List getRouteProductBomList(Long routeId, Long processId, Long productId); + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProductBomServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProductBomServiceImpl.java new file mode 100644 index 0000000..80b2732 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProductBomServiceImpl.java @@ -0,0 +1,83 @@ +package cn.iocoder.yudao.module.mes.service.pro.route; + +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.productbom.MesProRouteProductBomSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO; +import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProRouteProductBomMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; + +/** + * MES 工艺路线产品 BOM Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class MesProRouteProductBomServiceImpl implements MesProRouteProductBomService { + + @Resource + private MesProRouteProductBomMapper routeProductBomMapper; + + @Override + public Long createRouteProductBom(MesProRouteProductBomSaveReqVO createReqVO) { + // 1. 校验唯一性 + validateBomUnique(null, createReqVO.getItemId(), createReqVO.getProcessId(), createReqVO.getProductId()); + // 2. 插入 + MesProRouteProductBomDO routeProductBom = BeanUtils.toBean(createReqVO, MesProRouteProductBomDO.class); + routeProductBomMapper.insert(routeProductBom); + return routeProductBom.getId(); + } + + @Override + public void updateRouteProductBom(MesProRouteProductBomSaveReqVO updateReqVO) { + // 1. 校验存在 + validateRouteProductBomExists(updateReqVO.getId()); + // 2. 校验唯一性 + validateBomUnique(updateReqVO.getId(), updateReqVO.getItemId(), updateReqVO.getProcessId(), updateReqVO.getProductId()); + // 3. 更新 + MesProRouteProductBomDO updateObj = BeanUtils.toBean(updateReqVO, MesProRouteProductBomDO.class); + routeProductBomMapper.updateById(updateObj); + } + + @Override + public void deleteRouteProductBom(Long id) { + // 1. 校验存在 + validateRouteProductBomExists(id); + // 2. 删除 + routeProductBomMapper.deleteById(id); + } + + private void validateRouteProductBomExists(Long id) { + if (routeProductBomMapper.selectById(id) == null) { + throw exception(PRO_ROUTE_PRODUCT_BOM_NOT_EXISTS); + } + } + + private void validateBomUnique(Long id, Long itemId, Long processId, Long productId) { + MesProRouteProductBomDO existing = routeProductBomMapper.selectByUnique(itemId, processId, productId); + if (existing == null) { + return; + } + if (id == null || !existing.getId().equals(id)) { + throw exception(PRO_ROUTE_PRODUCT_BOM_DUPLICATE); + } + } + + @Override + public MesProRouteProductBomDO getRouteProductBom(Long id) { + return routeProductBomMapper.selectById(id); + } + + @Override + public List getRouteProductBomList(Long routeId, Long processId, Long productId) { + return routeProductBomMapper.selectList(routeId, processId, productId); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProductService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProductService.java new file mode 100644 index 0000000..f4b78c0 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProductService.java @@ -0,0 +1,41 @@ +package cn.iocoder.yudao.module.mes.service.pro.route; + +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.product.MesProRouteProductSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO; +import jakarta.validation.Valid; + +import java.util.List; + +/** + * MES 工艺路线产品 Service 接口 + * + * @author 芋道源码 + */ +public interface MesProRouteProductService { + + /** + * 创建工艺路线产品 + */ + Long createRouteProduct(@Valid MesProRouteProductSaveReqVO createReqVO); + + /** + * 更新工艺路线产品 + */ + void updateRouteProduct(@Valid MesProRouteProductSaveReqVO updateReqVO); + + /** + * 删除工艺路线产品 + */ + void deleteRouteProduct(Long id); + + /** + * 获得工艺路线产品 + */ + MesProRouteProductDO getRouteProduct(Long id); + + /** + * 按工艺路线获得产品列表 + */ + List getRouteProductListByRouteId(Long routeId); + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProductServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProductServiceImpl.java new file mode 100644 index 0000000..fce5266 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteProductServiceImpl.java @@ -0,0 +1,100 @@ +package cn.iocoder.yudao.module.mes.service.pro.route; + +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.product.MesProRouteProductSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO; +import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProRouteProductBomMapper; +import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProRouteProductMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; + +/** + * MES 工艺路线产品 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class MesProRouteProductServiceImpl implements MesProRouteProductService { + + @Resource + private MesProRouteProductMapper routeProductMapper; + + // TODO @AI:别人模块的操作,需要通过 service; + @Resource + private MesProRouteProductBomMapper routeProductBomMapper; + + @Override + public Long createRouteProduct(MesProRouteProductSaveReqVO createReqVO) { + // 1. 校验产品唯一性(一个产品只能关联一条工艺路线) + validateItemUnique(null, createReqVO.getItemId()); + + // 2. 插入 + MesProRouteProductDO routeProduct = BeanUtils.toBean(createReqVO, MesProRouteProductDO.class); + routeProductMapper.insert(routeProduct); + return routeProduct.getId(); + } + + @Override + public void updateRouteProduct(MesProRouteProductSaveReqVO updateReqVO) { + // 1.1 校验存在 + validateRouteProductExists(updateReqVO.getId()); + // 1.2 校验产品唯一性 + validateItemUnique(updateReqVO.getId(), updateReqVO.getItemId()); + + // 2. 更新 + MesProRouteProductDO updateObj = BeanUtils.toBean(updateReqVO, MesProRouteProductDO.class); + routeProductMapper.updateById(updateObj); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteRouteProduct(Long id) { + // 1. 校验存在 + // TODO @AI:复用 validateRouteProductExists 方法; + MesProRouteProductDO routeProduct = routeProductMapper.selectById(id); + if (routeProduct == null) { + throw exception(PRO_ROUTE_PRODUCT_NOT_EXISTS); + } + + // 2.1 级联删除关联的 BOM + routeProductBomMapper.deleteByRouteIdAndProductId(routeProduct.getRouteId(), routeProduct.getItemId()); + // 2.2 删除产品关联 + routeProductMapper.deleteById(id); + } + + private void validateRouteProductExists(Long id) { + if (routeProductMapper.selectById(id) == null) { + throw exception(PRO_ROUTE_PRODUCT_NOT_EXISTS); + } + } + + private void validateItemUnique(Long id, Long itemId) { + MesProRouteProductDO existing = routeProductMapper.selectByItemId(itemId); + if (existing == null) { + return; + } + // TODO @AI:notEquals + if (id == null || !existing.getId().equals(id)) { + throw exception(PRO_ROUTE_PRODUCT_ITEM_DUPLICATE); + } + } + + @Override + public MesProRouteProductDO getRouteProduct(Long id) { + return routeProductMapper.selectById(id); + } + + @Override + public List getRouteProductListByRouteId(Long routeId) { + return routeProductMapper.selectListByRouteId(routeId); + } + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteService.java new file mode 100644 index 0000000..b1beac3 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteService.java @@ -0,0 +1,48 @@ +package cn.iocoder.yudao.module.mes.service.pro.route; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.MesProRoutePageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.MesProRouteSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteDO; +import jakarta.validation.Valid; + +import java.util.List; + +/** + * MES 工艺路线 Service 接口 + * + * @author 芋道源码 + */ +public interface MesProRouteService { + + /** + * 创建工艺路线 + */ + Long createRoute(@Valid MesProRouteSaveReqVO createReqVO); + + /** + * 更新工艺路线 + */ + void updateRoute(@Valid MesProRouteSaveReqVO updateReqVO); + + /** + * 删除工艺路线 + */ + void deleteRoute(Long id); + + /** + * 获得工艺路线 + */ + MesProRouteDO getRoute(Long id); + + /** + * 获得工艺路线分页 + */ + PageResult getRoutePage(MesProRoutePageReqVO pageReqVO); + + /** + * 获得启用状态的工艺路线列表 + */ + List getRouteListByStatus(Integer status); + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteServiceImpl.java new file mode 100644 index 0000000..1e6338d --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/route/MesProRouteServiceImpl.java @@ -0,0 +1,146 @@ +package cn.iocoder.yudao.module.mes.service.pro.route; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.MesProRoutePageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.MesProRouteSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductBomDO; +import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProRouteMapper; +import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProRouteProcessMapper; +import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProRouteProductBomMapper; +import cn.iocoder.yudao.module.mes.dal.mysql.pro.MesProRouteProductMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; + +/** + * MES 工艺路线 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class MesProRouteServiceImpl implements MesProRouteService { + + @Resource + private MesProRouteMapper routeMapper; + + // todo @AI:不要直接使用对方模块的 mapper,而是通过 service; + @Resource + private MesProRouteProcessMapper routeProcessMapper; + @Resource + private MesProRouteProductMapper routeProductMapper; + @Resource + private MesProRouteProductBomMapper routeProductBomMapper; + + @Override + public Long createRoute(MesProRouteSaveReqVO createReqVO) { + // 1. 校验编码唯一性 + validateRouteCodeUnique(null, createReqVO.getCode()); + // 2. 插入 + MesProRouteDO route = BeanUtils.toBean(createReqVO, MesProRouteDO.class); + routeMapper.insert(route); + return route.getId(); + } + + @Override + public void updateRoute(MesProRouteSaveReqVO updateReqVO) { + // 1.1 校验存在 + validateRouteExists(updateReqVO.getId()); + // 1.2 校验编码唯一性 + validateRouteCodeUnique(updateReqVO.getId(), updateReqVO.getCode()); + // 1.3 启用时的校验 + // TODO @AI:开启禁用,独立接口;保持更新接口的独立; + if (CommonStatusEnum.ENABLE.getStatus().equals(updateReqVO.getStatus())) { + validateRouteEnable(updateReqVO.getId()); + } + + // 2. 更新 + MesProRouteDO updateObj = BeanUtils.toBean(updateReqVO, MesProRouteDO.class); + routeMapper.updateById(updateObj); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteRoute(Long id) { + // 1. 校验存在 + validateRouteExists(id); + + // 2.1 级联删除 + routeProcessMapper.deleteByRouteId(id); + routeProductMapper.deleteByRouteId(id); + routeProductBomMapper.deleteByRouteId(id); + // 2.2 删除工艺路线 + routeMapper.deleteById(id); + } + + private void validateRouteExists(Long id) { + if (routeMapper.selectById(id) == null) { + throw exception(PRO_ROUTE_NOT_EXISTS); + } + } + + private void validateRouteCodeUnique(Long id, String code) { + MesProRouteDO route = routeMapper.selectByCode(code); + if (route == null) { + return; + } + // TODO @AI:ObjUtil notequals; + if (id == null || !route.getId().equals(id)) { + throw exception(PRO_ROUTE_CODE_DUPLICATE); + } + } + + /** + * 启用工艺路线时的校验 + */ + private void validateRouteEnable(Long routeId) { + // 1. 必须有工序 + List processList = routeProcessMapper.selectListByRouteId(routeId); + if (processList.isEmpty()) { + throw exception(PRO_ROUTE_ENABLE_NO_PROCESS); + } + // 2. 必须有关键工序 + boolean hasKeyProcess = processList.stream().anyMatch(MesProRouteProcessDO::getKeyFlag); + // TODO @AI:BooleanUtils.isFalue(hasKeyProcess) + if (!hasKeyProcess) { + throw exception(PRO_ROUTE_ENABLE_NO_KEY_PROCESS); + } + // 3. 所有产品必须配置了 BOM 消耗 + List productList = routeProductMapper.selectListByRouteId(routeId); + for (MesProRouteProductDO product : productList) { + List bomList = routeProductBomMapper + .selectListByRouteIdAndProductId(routeId, product.getItemId()); + // TODO @AI:CollUtil.isEmpty(bomList) + if (bomList.isEmpty()) { + throw exception(PRO_ROUTE_ENABLE_PRODUCT_NO_BOM, product.getItemId()); + } + } + } + + @Override + public MesProRouteDO getRoute(Long id) { + return routeMapper.selectById(id); + } + + @Override + public PageResult getRoutePage(MesProRoutePageReqVO pageReqVO) { + return routeMapper.selectPage(pageReqVO); + } + + @Override + public List getRouteListByStatus(Integer status) { + return routeMapper.selectListByStatus(status); + } + +}