src/main/java/com/ruoyi/production/controller/ProductOrderController.java
@@ -48,8 +48,14 @@ @PostMapping("/revoke") @ApiOperation("撤回生产计划") public R revoke(@RequestBody ProductOrder productOrder) { return R.ok(productOrderService.revoke(productOrder)); public R revoke(@RequestBody List<Long> ids) { return R.ok(productOrderService.revoke(ids)); } @ApiOperation("删除生产订单") @DeleteMapping("/{id}") public R delete(@PathVariable("id") Long ids) { return R.ok(productOrderService.delete(ids)); } /** @@ -76,9 +82,5 @@ return R.ok(productOrderService.addProductOrder(productOrder)); } @ApiOperation("删除生产订单") @DeleteMapping("/{ids}") public R delete(@PathVariable("ids") Long[] ids) { return R.ok(productOrderService.delete(ids)); } } src/main/java/com/ruoyi/production/controller/ProductStructureController.java
@@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.*; import java.util.Arrays; import java.util.List; @RequestMapping("productStructure") @RestController @@ -27,9 +28,9 @@ @ApiOperation("新增BOM子集") @PostMapping() public R addOrUpdate(@RequestBody ProductStructureDto productStructureDto){ return R.ok(productStructureService.addProductStructureDto(productStructureDto)); @PostMapping("/{bomId}") public R addOrUpdate(@PathVariable Integer bomId, @RequestBody List<ProductStructureDto> list){ return R.ok(productStructureService.addProductStructureDto(bomId, list)); } @ApiOperation("BOM查看子集详情") src/main/java/com/ruoyi/production/controller/ProductionOrderStructureController.java
@@ -33,10 +33,10 @@ return AjaxResult.success(list); } @PutMapping("/addOrUpdateBomStructs") @PutMapping("/addOrUpdateBomStructs/{orderId}") @ApiOperation("新增/更新BOM子集结构") public AjaxResult addOrUpdateBomStructs(@RequestBody ProductionOrderStructureDto instanceDto) { productionOrderStructureService.addOrUpdateBomStructs(instanceDto); public AjaxResult addOrUpdateBomStructs(@PathVariable Long orderId, @RequestBody List<ProductionOrderStructureDto> list) { productionOrderStructureService.addOrUpdateBomStructs(orderId, list); return AjaxResult.success(); } src/main/java/com/ruoyi/production/dto/ProductionOrderStructureDto.java
@@ -31,4 +31,12 @@ @ApiModelProperty("父节点临时ID") private String parentTempId; @ApiModelProperty("工序名称") private String processName; @ApiModelProperty("产品名称") private String productName; @ApiModelProperty("产品规格") private String model; } src/main/java/com/ruoyi/production/enums/ProductOrderStatusEnum.java
@@ -43,13 +43,20 @@ } /** * 判断是否允许删除(1、4) * 判断是否允许删除(4) */ public static boolean canDelete(Integer code) { return WAIT.getCode().equals(code) || CANCEL.getCode().equals(code); } /** * 判断是否允许撤回(1) */ public static boolean canRevoke(Integer code) { return WAIT.getCode().equals(code); } /** * 判断是否已开始生产(2、3) */ public static boolean isStarted(Integer code) { src/main/java/com/ruoyi/production/mapper/ProductionOrderStructureMapper.java
@@ -1,7 +1,10 @@ package com.ruoyi.production.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.production.dto.ProductionOrderStructureDto; import com.ruoyi.production.pojo.ProductionOrderStructure; import java.util.List; /** * <p> @@ -13,4 +16,6 @@ */ public interface ProductionOrderStructureMapper extends BaseMapper<ProductionOrderStructure> { List<ProductionOrderStructureDto> listByOrderId(Long orderId); } src/main/java/com/ruoyi/production/service/IProductionOrderStructureService.java
@@ -18,5 +18,5 @@ List<ProductionOrderStructureDto> listByOrderId(Long orderId); void addOrUpdateBomStructs(ProductionOrderStructureDto instanceDto); void addOrUpdateBomStructs(Long orderId, List<ProductionOrderStructureDto> list); } src/main/java/com/ruoyi/production/service/ProductOrderService.java
@@ -21,7 +21,7 @@ /** * 撤回生产计划 */ Boolean revoke(ProductOrder productOrder); Boolean revoke(List<Long> ids); List<ProcessRoute> listProcessRoute(Long productModelId); @@ -31,5 +31,5 @@ Long insertProductOrder(ProductOrder productOrder); Boolean delete(Long[] id); Boolean delete(Long id); } src/main/java/com/ruoyi/production/service/ProductStructureService.java
@@ -10,7 +10,7 @@ public interface ProductStructureService extends IService<ProductStructure> { Boolean addProductStructureDto(ProductStructureDto productStructureDto); Boolean addProductStructureDto(Integer bomId, List<ProductStructureDto> list); List<ProductStructureDto> listByBomId(Integer bomId); src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
@@ -1,6 +1,5 @@ package com.ruoyi.production.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; @@ -137,25 +136,48 @@ @Override @Transactional(rollbackFor = Exception.class) public Boolean revoke(ProductOrder productOrder) { // todo 判断是否产生报工信息 // 查询合并的生产计划 List<ProductOrderPlan> productOrderPlans = productOrderPlanMapper.selectList(Wrappers.<ProductOrderPlan>lambdaQuery().in(ProductOrderPlan::getProductOrderId, productOrder.getId())); if (productOrderPlans.isEmpty()) { throw new RuntimeException("合并的生产计划不存在"); public Boolean revoke(List<Long> ids) { List<ProductOrder> orders = productOrderMapper.selectBatchIds(ids); if (orders.isEmpty()) { throw new RuntimeException("生产订单不存在"); } for (ProductOrder order : orders) { if (!ProductOrderStatusEnum.canRevoke(order.getStatus())) { throw new RuntimeException("只有【待开始】状态的订单才可以撤回"); } } // 回退生产计划 List<ProductOrderPlan> productOrderPlans = productOrderPlanMapper.selectList(Wrappers.<ProductOrderPlan>lambdaQuery().in(ProductOrderPlan::getProductOrderId, ids)); for (ProductOrderPlan productOrderPlan : productOrderPlans) { ProductionPlan productionPlan = productionPlanMapper.selectById(productOrderPlan.getProductionPlanId()); productionPlan.setAssignedQuantity(productionPlan.getAssignedQuantity().subtract(productOrderPlan.getAssignedQuantity())); productionPlanMapper.updateById(productionPlan); if (productionPlan != null) { BigDecimal newAssigned = productionPlan.getAssignedQuantity().subtract(productOrderPlan.getAssignedQuantity()); if (newAssigned.compareTo(BigDecimal.ZERO) < 0) { newAssigned = BigDecimal.ZERO; } productionPlan.setAssignedQuantity(newAssigned); BigDecimal volume = productionPlan.getVolume() == null ? BigDecimal.ZERO : productionPlan.getVolume(); int status; if (newAssigned.compareTo(BigDecimal.ZERO) == 0) { status = 0; // 未下发 } else if (newAssigned.compareTo(volume) < 0) { status = 1; // 部分下发 } else { status = 2; // 已下发 } productionPlan.setStatus(status); productionPlanMapper.updateById(productionPlan); } } // 删除关联关系 productOrderPlanMapper.delete(Wrappers.<ProductOrderPlan>lambdaQuery().in(ProductOrderPlan::getProductOrderId, productOrder.getId())); // 删除订单 productOrderMapper.deleteById(productOrder.getId()); // todo 删除订单下的工艺路线子表 return null; // 将订单状态改为已取消 for (ProductOrder order : orders) { order.setStatus(ProductOrderStatusEnum.CANCEL.getCode()); } updateBatchById(orders); return true; } @Override @@ -192,20 +214,18 @@ @Override @Transactional(rollbackFor = Exception.class) public Boolean delete(Long[] ids) { List<ProductOrder> orders = productOrderMapper.selectList(Wrappers.<ProductOrder>lambdaQuery().in(ProductOrder::getId, ids)); public Boolean delete(Long id) { ProductOrder order = productOrderMapper.selectById(id); if (orders.isEmpty()) { if (order == null) { throw new RuntimeException("生产订单不存在"); } for (ProductOrder order : orders) { if (!ProductOrderStatusEnum.canDelete(order.getStatus())) { throw new RuntimeException("只有【待开始、已取消】状态的订单才可以删除"); } if (!ProductOrderStatusEnum.canDelete(order.getStatus())) { throw new RuntimeException("只有【待开始、已取消】状态的订单才可以删除"); } // 是否已生产 List<ProductWorkOrder> productWorkOrders = productWorkOrderMapper.selectList(Wrappers.<ProductWorkOrder>lambdaQuery().in(ProductWorkOrder::getProductOrderId, ids)); List<ProductWorkOrder> productWorkOrders = productWorkOrderMapper.selectList(Wrappers.<ProductWorkOrder>lambdaQuery().eq(ProductWorkOrder::getProductOrderId, id)); if (!productWorkOrders.isEmpty()) { List<Long> workOrderIds = productWorkOrders.stream() @@ -218,11 +238,11 @@ } // 删除工单 productWorkOrderMapper.delete(Wrappers.<ProductWorkOrder>lambdaQuery().in(ProductWorkOrder::getProductOrderId, ids)); productWorkOrderMapper.delete(Wrappers.<ProductWorkOrder>lambdaQuery().eq(ProductWorkOrder::getProductOrderId, id)); } // 回退生产计划 List<ProductOrderPlan> productOrderPlans = productOrderPlanMapper.selectList(Wrappers.<ProductOrderPlan>lambdaQuery().in(ProductOrderPlan::getProductOrderId, ids)); List<ProductOrderPlan> productOrderPlans = productOrderPlanMapper.selectList(Wrappers.<ProductOrderPlan>lambdaQuery().eq(ProductOrderPlan::getProductOrderId, id)); for (ProductOrderPlan productOrderPlan : productOrderPlans) { ProductionPlan productionPlan = productionPlanMapper.selectById(productOrderPlan.getProductionPlanId()); @@ -253,19 +273,13 @@ } // 删除中间表 productOrderPlanMapper.delete(Wrappers.<ProductOrderPlan>lambdaQuery().in(ProductOrderPlan::getProductOrderId, ids)); productOrderPlanMapper.delete(Wrappers.<ProductOrderPlan>lambdaQuery().eq(ProductOrderPlan::getProductOrderId, id)); // 删除附表的工艺路线与BOM for (Long id : ids) { ProductOrder productOrder = baseMapper.selectById(id); productionOrderAppendixService.deleteData(productOrder.getId(), productOrder.getRouteId()); } // productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>().in(ProductProcessRouteItem::getProductOrderId, ids)); // productProcessRouteMapper.delete(new LambdaQueryWrapper<ProductProcessRoute>().in(ProductProcessRoute::getProductOrderId, ids)); productionOrderAppendixService.deleteData(order.getId(), order.getRouteId()); // 删除订单 productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>().in(ProductOrder::getId, ids)); productOrderMapper.deleteById(id); return true; } src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java
@@ -25,13 +25,14 @@ @Override @Transactional public Boolean addProductStructureDto(ProductStructureDto dto) { public Boolean addProductStructureDto(Integer bomId, List<ProductStructureDto> list) { Integer bomId = dto.getBomId(); // 将树扁平化 // 扁平化传入的树 List<ProductStructureDto> flatDtoList = new ArrayList<>(); flattenTree(dto.getChildren(), flatDtoList); for (ProductStructureDto root : list) { flatDtoList.add(root); flattenTree(root.getChildren(), flatDtoList); } // 查询数据库中已有的 BOM 数据 List<ProductStructure> dbList = this.list(new LambdaQueryWrapper<ProductStructure>().eq(ProductStructure::getBomId, bomId)); @@ -65,13 +66,13 @@ entity.setBomId(bomId); if (psDto.getId() == null) { // 新增 entity.setId(null); entity.setParentId(null); insertList.add(entity); tempEntityMap.put(psDto.getTempId(), entity); if (psDto.getTempId() != null) { tempEntityMap.put(psDto.getTempId(), entity); } } else { // 更新 updateList.add(entity); } } @@ -83,32 +84,27 @@ // 回写新增节点 parentId List<ProductStructure> parentFixList = new ArrayList<>(); // 真实的父节点 ID Long realParentId; for (ProductStructureDto psDto : flatDtoList) { if (psDto.getId() != null) continue; ProductStructure child = tempEntityMap.get(psDto.getTempId()); if (child == null) continue; String parentTempId = psDto.getParentTempId(); if (psDto.getId() == null && parentTempId != null && !parentTempId.isEmpty()) { ProductStructure child = tempEntityMap.get(psDto.getTempId()); if (parentTempId != null && !parentTempId.isEmpty()) { if (tempEntityMap.containsKey(parentTempId)) { // 父节点是新节点 realParentId = tempEntityMap.get(parentTempId).getId(); } else { // 父节点是老节点 try { realParentId = Long.valueOf(parentTempId); } catch (NumberFormatException e) { realParentId = 0L; } } child.setParentId(realParentId); parentFixList.add(child); } else if (psDto.getId() == null) { // 如果 parentTempId 为空,则是顶级节点 ProductStructure child = tempEntityMap.get(psDto.getTempId()); } else { child.setParentId(0L); parentFixList.add(child); } parentFixList.add(child); } if (!parentFixList.isEmpty()) { src/main/java/com/ruoyi/production/service/impl/ProductionOrderStructureServiceImpl.java
@@ -2,7 +2,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.production.dto.ProductionOrderStructureDto; import com.ruoyi.production.mapper.ProductionOrderStructureMapper; import com.ruoyi.production.pojo.ProductionOrderStructure; @@ -32,13 +31,7 @@ @Override public List<ProductionOrderStructureDto> listByOrderId(Long orderId) { List<ProductionOrderStructure> list = list(new LambdaQueryWrapper<ProductionOrderStructure>().eq(ProductionOrderStructure::getOrderId, orderId)); List<ProductionOrderStructureDto> dtoList = list.stream().map(item -> { ProductionOrderStructureDto dto = new ProductionOrderStructureDto(); BeanUtils.copyProperties(item, dto); return dto; }).collect(Collectors.toList()); List<ProductionOrderStructureDto> dtoList = baseMapper.listByOrderId(orderId); Map<Long, ProductionOrderStructureDto> map = new HashMap<>(); for (ProductionOrderStructureDto node : dtoList) { @@ -58,12 +51,13 @@ } @Override public void addOrUpdateBomStructs(ProductionOrderStructureDto instanceDto) { Long orderId = instanceDto.getOrderId(); public void addOrUpdateBomStructs(Long orderId, List<ProductionOrderStructureDto> list) { // 扁平化前端传入的树 List<ProductionOrderStructureDto> flatList = new ArrayList<>(); flattenTree(instanceDto.getChildren(), flatList); for (ProductionOrderStructureDto root : list) { flatList.add(root); flattenTree(root.getChildren(), flatList); } // 查询数据库已有数据 List<ProductionOrderStructure> dbList = list(new LambdaQueryWrapper<ProductionOrderStructure>() @@ -90,7 +84,7 @@ for (ProductionOrderStructureDto dto : flatList) { ProductionOrderStructure entity = new ProductionOrderStructure(); BeanUtils.copyProperties(dto, entity); org.springframework.beans.BeanUtils.copyProperties(dto, entity); entity.setOrderId(orderId); if (dto.getId() == null) { entity.setId(null); @@ -110,13 +104,13 @@ // 回写新增节点的 parentId List<ProductionOrderStructure> parentFixList = new ArrayList<>(); Long realParentId; for (ProductionOrderStructureDto dto : flatList) { if (dto.getId() != null) continue; ProductionOrderStructure child = tempEntityMap.get(dto.getTempId()); if (child == null) continue; String parentTempId = dto.getParentTempId(); if (parentTempId != null && !parentTempId.isEmpty()) { Long realParentId; if (tempEntityMap.containsKey(parentTempId)) { realParentId = tempEntityMap.get(parentTempId).getId(); } else { src/main/resources/mapper/production/ProductionOrderStructureMapper.xml
@@ -16,4 +16,20 @@ <result column="bom_id" property="bomId"/> </resultMap> <select id="listByOrderId" resultType="com.ruoyi.production.dto.ProductionOrderStructureDto" parameterType="java.lang.Long"> SELECT s.*, pp.name AS process_name, pm.product_name AS product_name, sku.model AS model FROM production_order_structure s LEFT JOIN product_process pp ON pp.id = s.process_id LEFT JOIN product_material_sku sku ON sku.id = s.product_model_id LEFT JOIN product_material pm ON pm.id = sku.product_id WHERE s.order_id = #{orderId} </select> </mapper>