已添加29个文件
已修改31个文件
1605 ■■■■■ 文件已修改
doc/宁夏-中盛建材.sql 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/controller/AppendixController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/controller/ProcessRouteItemInstanceController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/controller/ProcessRouteItemParamInstanceController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/controller/ProductProcessParamInstanceController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/controller/ProductStructureInstanceController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/mapper/ProcessRouteItemInstanceMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/mapper/ProcessRouteItemParamInstanceMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/mapper/ProductProcessParamInstanceMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/mapper/ProductStructureInstanceMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/pojo/ProcessRouteItemInstance.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/pojo/ProcessRouteItemParamInstance.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/pojo/ProductProcessParamInstance.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/pojo/ProductStructureInstance.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/AppendixService.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/ProcessRouteItemInstanceService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/ProcessRouteItemParamInstanceService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/ProductProcessParamInstanceService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/ProductStructureInstanceService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/impl/AppendixServiceImpl.java 216 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/impl/ProcessRouteItemInstanceServiceImpl.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/impl/ProcessRouteItemParamInstanceServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/impl/ProductProcessParamInstanceServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/impl/ProductStructureInstanceServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/energy/controller/EnergyConsumptionDetailController.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/energy/dto/EnergyAccountDto.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/energy/dto/EnergyConsumptionDetailDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/energy/dto/EnergyStatisticsDto.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/energy/mapper/EnergyConsumptionDetailMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/energy/service/EnergyConsumptionDetailService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/energy/service/impl/EnergyConsumptionDetailServiceImpl.java 35 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProcessRouteController.java 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProcessRouteItemController.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductBomController.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductOrderController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/BomImportDto.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProcessRouteDto.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProcessRouteItemDto.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/enums/ProductOrderStatusEnum.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/mapper/ProcessRouteMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProcessRoute.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductOrder.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProcessRouteService.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProcessRouteItemServiceImpl.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProcessRouteServiceImpl.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java 94 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/service/impl/ProductionPlanServiceImpl.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/appendix/ProcessRouteItemInstanceMapper.xml 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/appendix/ProcessRouteItemParamInstanceMapper.xml 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/appendix/ProductProcessParamInstanceMapper.xml 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/appendix/ProductStructureInstanceMapper.xml 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/energy/EnergyConsumptionDetailMapper.xml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProcessRouteItemMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProcessRouteMapper.xml 35 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductOrderMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductStructureMapper.xml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/productionPlan/ProductionPlanMapper.xml 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/ÄþÏÄ-ÖÐÊ¢½¨²Ä.sql
@@ -272,4 +272,106 @@
ALTER TABLE `product_bom`
    ADD COLUMN `dict_code` bigint NOT NULL COMMENT '关联字典数据编码(sys_dict_data.dict_code)';
ALTER TABLE `product_bom` ADD INDEX `idx_dict_code` (`dict_code`);
ALTER TABLE `product_bom` ADD INDEX `idx_dict_code` (`dict_code`);
ALTER TABLE `product-inventory-management-zsjc`.`process_route`
    ADD COLUMN `dict_code` bigint NOT NULL COMMENT '产品类型字典编码' AFTER `status`;
ALTER TABLE `product-inventory-management-zsjc`.`product_order`
    ADD COLUMN `status` int NULL COMMENT '状态(1.待开始、2.进行中、3.已完成、4.已取消)' AFTER `plan_complete_time`;
DROP TABLE IF EXISTS `process_route_item_instance`;
CREATE TABLE `process_route_item_instance`
(
    `id`               bigint     NOT NULL AUTO_INCREMENT,
    `route_id`         bigint     NOT NULL DEFAULT 0 COMMENT '工艺路线id',
    `product_model_id` bigint     NULL     DEFAULT 0 COMMENT '产品id',
    `process_id`       bigint     NOT NULL DEFAULT 0 COMMENT '工序id',
    `tenant_id`        bigint     NOT NULL COMMENT '租户id',
    `create_time`      datetime   NULL     DEFAULT NULL COMMENT '录入时间',
    `update_time`      datetime   NULL     DEFAULT NULL COMMENT '更新时间',
    `drag_sort`        int        NULL     DEFAULT NULL COMMENT '拖动排序',
    `is_quality`       tinyint(1) NULL     DEFAULT 1 COMMENT '是否质检工序',
    PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB
  AUTO_INCREMENT = 83
  CHARACTER SET = utf8mb4
  COLLATE = utf8mb4_0900_ai_ci COMMENT = '工艺路线子集-附表'
  ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for process_route_item_param_instance
-- ----------------------------
DROP TABLE IF EXISTS `process_route_item_param_instance`;
CREATE TABLE `process_route_item_param_instance`
(
    `id`               bigint                                                        NOT NULL AUTO_INCREMENT COMMENT '主键ID',
    `route_item_id`    bigint                                                        NOT NULL COMMENT '关联工艺路线明细ID (process_route_item.id)',
    `param_id`         bigint                                                        NOT NULL COMMENT '关联基础参数定义ID (base_param.id)',
    `process_param_id` bigint                                                        NULL     DEFAULT NULL COMMENT '来源工序参数ID',
    `standard_value`   varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL     DEFAULT NULL COMMENT '此路线节点设定的标准值',
    `min_value`        decimal(10, 2)                                                NULL     DEFAULT NULL COMMENT '此路线节点设定的标准最小值',
    `max_value`        decimal(10, 2)                                                NULL     DEFAULT NULL COMMENT '此路线节点设定的标准最大值',
    `is_required`      tinyint                                                       NOT NULL DEFAULT 0 COMMENT '是否必填',
    `sort`             int                                                           NOT NULL DEFAULT 0 COMMENT '排序',
    `tenant_id`        bigint                                                        NULL     DEFAULT NULL COMMENT '租户ID',
    `create_time`      datetime                                                      NULL     DEFAULT CURRENT_TIMESTAMP,
    `update_time`      datetime                                                      NULL     DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`) USING BTREE,
    INDEX `idx_route_item_id` (`route_item_id` ASC) USING BTREE,
    INDEX `idx_param_id` (`param_id` ASC) USING BTREE
) ENGINE = InnoDB
  AUTO_INCREMENT = 178
  CHARACTER SET = utf8mb4
  COLLATE = utf8mb4_0900_ai_ci COMMENT = '工艺路线工序参数-附表'
  ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for product_process_param_instance
-- ----------------------------
DROP TABLE IF EXISTS `product_process_param_instance`;
CREATE TABLE `product_process_param_instance`
(
    `id`             bigint                                                        NOT NULL AUTO_INCREMENT COMMENT '主键ID',
    `process_id`     bigint                                                        NOT NULL COMMENT '所属工序ID (product_process.id)',
    `param_id`       bigint                                                        NOT NULL COMMENT '关联基础参数ID (base_param.id)',
    `standard_value` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL     DEFAULT NULL COMMENT '在此工序设定的标准值(单值模式)',
    `min_value`      decimal(10, 2)                                                NULL     DEFAULT NULL COMMENT '在此工序设定的标准最小值(区间模式)',
    `max_value`      decimal(10, 2)                                                NULL     DEFAULT NULL COMMENT '在此工序设定的标准最大值(区间模式)',
    `is_required`    tinyint                                                       NOT NULL DEFAULT 0 COMMENT '在此工序中是否必填(0-否, 1-是)',
    `sort`           int                                                           NOT NULL DEFAULT 0 COMMENT '排序号',
    `tenant_id`      bigint                                                        NULL     DEFAULT NULL COMMENT '租户ID',
    `create_time`    datetime                                                      NULL     DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    `update_time`    datetime                                                      NULL     DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    PRIMARY KEY (`id`) USING BTREE,
    INDEX `idx_process_id` (`process_id` ASC) USING BTREE,
    INDEX `idx_param_id` (`param_id` ASC) USING BTREE
) ENGINE = InnoDB
  AUTO_INCREMENT = 61
  CHARACTER SET = utf8mb4
  COLLATE = utf8mb4_0900_ai_ci COMMENT = '工序绑定参数-附表'
  ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for product_structure_instance
-- ----------------------------
DROP TABLE IF EXISTS `product_structure_instance`;
CREATE TABLE `product_structure_instance`
(
    `id`                bigint                                                        NOT NULL AUTO_INCREMENT,
    `parent_id`         bigint                                                        NULL DEFAULT NULL COMMENT '父节点ID',
    `product_model_id`  bigint                                                        NULL DEFAULT NULL COMMENT '产品id',
    `process_id`        bigint                                                        NULL DEFAULT NULL COMMENT '工序id',
    `unit_quantity`     decimal(16, 4)                                                NOT NULL COMMENT '单位产出需要数量',
    `demanded_quantity` decimal(16, 4)                                                NULL DEFAULT NULL COMMENT '需求数量',
    `unit`              varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '单位',
    `tenant_id`         bigint                                                        NULL DEFAULT NULL COMMENT '租户id',
    `bom_id`            bigint                                                        NOT NULL COMMENT 'bom的id',
    PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB
  CHARACTER SET = utf8mb4
  COLLATE = utf8mb4_0900_ai_ci COMMENT = 'BOM子集-附表'
  ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
src/main/java/com/ruoyi/appendix/controller/AppendixController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.appendix.controller;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <br>
 * BOM-工艺路线附表控制层
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 14:44
 */
@RestController
@RequestMapping("/appendix")
@Api("BOM-工艺路线附表控制层")
public class AppendixController {
}
src/main/java/com/ruoyi/appendix/controller/ProcessRouteItemInstanceController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.appendix.controller;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <br>
 * å·¥è‰ºè·¯çº¿å­é›†-附表控制层
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:07
 */
@RestController
@RequestMapping("/processRouteItemInstance")
@Api("艺路线子集-附表控制层")
public class ProcessRouteItemInstanceController {
}
src/main/java/com/ruoyi/appendix/controller/ProcessRouteItemParamInstanceController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package com.ruoyi.appendix.controller;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <br>
 * å·¥è‰ºè·¯çº¿å·¥åºå‚数接口
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:14
 */
@Api(tags = "工艺路线工序参数接口")
@RestController
@RequestMapping("/processRouteItemParamInstance")
public class ProcessRouteItemParamInstanceController {
}
src/main/java/com/ruoyi/appendix/controller/ProductProcessParamInstanceController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.appendix.controller;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <br>
 * å·¥åºç»‘定参数-附表Controller
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:19
 */
@Api(tags = "工序绑定参数接口")
@RestController
@RequestMapping("/productProcessParamInstance")
public class ProductProcessParamInstanceController {
}
src/main/java/com/ruoyi/appendix/controller/ProductStructureInstanceController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.appendix.controller;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <br>
 * BOM子集-附表Controller
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:22
 */
@Api(tags = "BOM结构接口")
@RestController
@RequestMapping("/productStructureInstance")
public class ProductStructureInstanceController {
}
src/main/java/com/ruoyi/appendix/mapper/ProcessRouteItemInstanceMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.appendix.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.appendix.pojo.ProcessRouteItemInstance;
/**
 * <br>
 * å·¥è‰ºè·¯çº¿å­é›†-附表Mapper
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:02
 */
public interface ProcessRouteItemInstanceMapper extends BaseMapper<ProcessRouteItemInstance> {
}
src/main/java/com/ruoyi/appendix/mapper/ProcessRouteItemParamInstanceMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.appendix.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.appendix.pojo.ProcessRouteItemParamInstance;
/**
 * <br>
 * å·¥è‰ºè·¯çº¿å·¥åºå‚æ•°-附表Mapper
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:10
 */
public interface ProcessRouteItemParamInstanceMapper extends BaseMapper<ProcessRouteItemParamInstance> {
}
src/main/java/com/ruoyi/appendix/mapper/ProductProcessParamInstanceMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.appendix.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.appendix.pojo.ProductProcessParamInstance;
/**
 * <br>
 * å·¥åºç»‘定参数-附表Mapper
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:15
 */
public interface ProductProcessParamInstanceMapper extends BaseMapper<ProductProcessParamInstance> {
}
src/main/java/com/ruoyi/appendix/mapper/ProductStructureInstanceMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.appendix.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.appendix.pojo.ProductStructureInstance;
/**
 * <br>
 * BOM子集-附表Mapper
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:20
 */
public interface ProductStructureInstanceMapper extends BaseMapper<ProductStructureInstance> {
}
src/main/java/com/ruoyi/appendix/pojo/ProcessRouteItemInstance.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
package com.ruoyi.appendix.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
/**
 * <br>
 * å·¥è‰ºè·¯çº¿å­é›†-附表
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 11:43
 */
@Data
@TableName("process_route_item_instance")
@Api(tags = "工艺路线子集-附表")
public class ProcessRouteItemInstance {
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("工艺路线id")
    private Long routeId;
    @ApiModelProperty("产品id")
    private Long productModelId;
    @ApiModelProperty("工序id")
    private Long processId;
    @ApiModelProperty("租户id")
    private Long tenantId;
    @ApiModelProperty("录入时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @ApiModelProperty("更新时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    @ApiModelProperty("拖动排序")
    private Integer dragSort;
    @ApiModelProperty("是否质检工序")
    private Integer isQuality;
}
src/main/java/com/ruoyi/appendix/pojo/ProcessRouteItemParamInstance.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
package com.ruoyi.appendix.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
 * <br>
 * å·¥è‰ºè·¯çº¿å·¥åºå‚æ•°-附表
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:09
 */
@Data
@TableName("process_route_item_param_instance")
@Api(tags = "工艺路线工序参数-附表")
public class ProcessRouteItemParamInstance {
    @TableId(type = IdType.AUTO)
    @ApiModelProperty("主键ID")
    private Long id;
    @ApiModelProperty("关联工艺路线明细ID")
    private Long routeItemId;
    @ApiModelProperty("关联基础参数定义ID")
    private Long paramId;
    @ApiModelProperty("来源工序参数ID")
    private Long processParamId;
    @ApiModelProperty("标准值")
    private String standardValue;
    @ApiModelProperty("最小值")
    private BigDecimal minValue;
    @ApiModelProperty("最大值")
    private BigDecimal maxValue;
    @ApiModelProperty("是否必填")
    private Integer isRequired;
    @ApiModelProperty("排序")
    private Integer sort;
    @ApiModelProperty("租户ID")
    private Long tenantId;
    @ApiModelProperty("创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty("更新时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
}
src/main/java/com/ruoyi/appendix/pojo/ProductProcessParamInstance.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
package com.ruoyi.appendix.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
 * <br>
 * å·¥åºç»‘定参数-附表
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:14
 */
@Data
@TableName("product_process_param_instance")
@Api(tags = "工序绑定参数-附表")
public class ProductProcessParamInstance {
    @TableId(type = IdType.AUTO)
    @ApiModelProperty("主键ID")
    private Long id;
    @ApiModelProperty("所属工序ID")
    private Long processId;
    @ApiModelProperty("关联基础参数ID")
    private Long paramId;
    @ApiModelProperty("标准值(单值模式)")
    private String standardValue;
    @ApiModelProperty("最小值(区间模式)")
    private BigDecimal minValue;
    @ApiModelProperty("最大值(区间模式)")
    private BigDecimal maxValue;
    @ApiModelProperty("是否必填(0-否,1-是)")
    private Boolean isRequired;
    @ApiModelProperty("排序号")
    private Integer sort;
    @ApiModelProperty("租户ID")
    private Long tenantId;
    @ApiModelProperty("创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty("更新时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
}
src/main/java/com/ruoyi/appendix/pojo/ProductStructureInstance.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,53 @@
package com.ruoyi.appendix.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
 * <br>
 * BOM子集-附表
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:20
 */
@Data
@TableName("product_structure_instance")
@Api(tags = "BOM子集-附表")
public class ProductStructureInstance {
    @TableId(type = IdType.AUTO)
    @ApiModelProperty("主键ID")
    private Long id;
    @ApiModelProperty("父节点ID")
    private Long parentId;
    @ApiModelProperty("产品ID")
    private Long productModelId;
    @ApiModelProperty("工序ID")
    private Long processId;
    @ApiModelProperty("单位产出需要数量")
    private BigDecimal unitQuantity;
    @ApiModelProperty("需求数量")
    private BigDecimal demandedQuantity;
    @ApiModelProperty("单位")
    private String unit;
    @ApiModelProperty("租户ID")
    private Long tenantId;
    @ApiModelProperty("BOM ID")
    private Long bomId;
}
src/main/java/com/ruoyi/appendix/service/AppendixService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
package com.ruoyi.appendix.service;
import com.ruoyi.productionPlan.dto.ProductionPlanDto;
/**
 * <br>
 * BOM-工艺路线附表Service接口
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 14:45
 */
public interface AppendixService {
    /**
     * å°†å¯¹åº”的工艺路线子集与绑定的BOM子集填充到附表中
     *
     * @param productOrderId ç”Ÿäº§è®¢å•ID
     * @param processRouteId å·¥è‰ºè·¯çº¿ID
     */
    void populateData(Long productOrderId, Long processRouteId);
    /**
     * ç»™ä¸‹å‘的砌块拉取对应的工艺路线子集与绑定的BOM子集填充到附表中
     *
     * @param productionPlanDto äº§å“è¯¦æƒ…
     */
    Long populateBlocks(ProductionPlanDto productionPlanDto);
    /**
     * ç»™ä¸‹å‘的板材拉取对应的工艺路线子集与绑定的BOM子集填充到附表中
     *
     * @param productionPlanDto äº§å“è¯¦æƒ…
     */
    Long populatePlates(ProductionPlanDto productionPlanDto);
    /**
     * åˆ é™¤è¯¥è®¢å•携带的附表数据
     *
     * @param processRouteId å·¥è‰ºè·¯çº¿ID
     */
    void deleteData(Long processRouteId);
}
src/main/java/com/ruoyi/appendix/service/ProcessRouteItemInstanceService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.appendix.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.appendix.pojo.ProcessRouteItemInstance;
/**
 * <br>
 *工艺路线子集-附表Service
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:07
 */
public interface ProcessRouteItemInstanceService extends IService<ProcessRouteItemInstance> {
}
src/main/java/com/ruoyi/appendix/service/ProcessRouteItemParamInstanceService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.appendix.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.appendix.pojo.ProcessRouteItemParamInstance;
/**
 * <br>
 * å·¥è‰ºè·¯çº¿å·¥åºå‚æ•°-附表Service
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:11
 */
public interface ProcessRouteItemParamInstanceService extends IService<ProcessRouteItemParamInstance> {
}
src/main/java/com/ruoyi/appendix/service/ProductProcessParamInstanceService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.appendix.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.appendix.pojo.ProductProcessParamInstance;
/**
 * <br>
 * å·¥åºç»‘定参数-附表Service接口
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:16
 */
public interface ProductProcessParamInstanceService extends IService<ProductProcessParamInstance> {
}
src/main/java/com/ruoyi/appendix/service/ProductStructureInstanceService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.appendix.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.appendix.pojo.ProductStructureInstance;
/**
 * <br>
 * BOM子集-附表Service接口
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:21
 */
public interface ProductStructureInstanceService extends IService<ProductStructureInstance> {
}
src/main/java/com/ruoyi/appendix/service/impl/AppendixServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,216 @@
package com.ruoyi.appendix.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.appendix.pojo.ProcessRouteItemInstance;
import com.ruoyi.appendix.pojo.ProcessRouteItemParamInstance;
import com.ruoyi.appendix.pojo.ProductProcessParamInstance;
import com.ruoyi.appendix.pojo.ProductStructureInstance;
import com.ruoyi.appendix.service.*;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.production.pojo.*;
import com.ruoyi.production.service.*;
import com.ruoyi.productionPlan.dto.ProductionPlanDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <br>
 * BOM-工艺路线附表Service接口实现类
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 14:45
 */
@Slf4j
@Service
public class AppendixServiceImpl implements AppendixService {
    @Resource
    private ProcessRouteItemInstanceService processRouteItemInstanceService;
    @Resource
    private ProcessRouteItemParamInstanceService processRouteItemParamInstanceService;
    @Resource
    private ProductProcessParamInstanceService productProcessParamInstanceService;
    @Resource
    private ProductStructureInstanceService productStructureInstanceService;
    @Resource
    private ProcessRouteService processRouteService;
    @Resource
    private ProcessRouteItemService processRouteItemService;
    @Resource
    private ProcessRouteItemParamService processRouteItemParamService;
    @Resource
    private ProductProcessParamService productProcessParamService;
    @Resource
    private ProductStructureService productStructureService;
    @Resource
    private ProductOrderService productOrderService;
    @Override
    public Long populateBlocks(ProductionPlanDto productionPlanDto) {
        if (productionPlanDto == null) {
            throw new ServiceException("下发数据不能为空");
        }
        if (StringUtils.isEmpty(productionPlanDto.getStrength())) {
            throw new ServiceException("砌块的产品类型不能为空");
        }
        ProcessRoute processRoute = processRouteService.latestTypeDate(productionPlanDto.getProductName(), productionPlanDto.getStrength());
        if (processRoute == null) {
            log.info("下发产品【{}】未查询出工艺路线", productionPlanDto.getProductName());
            return null;
        }
        migration(processRoute);
        return processRoute.getId();
    }
    @Override
    public Long populatePlates(ProductionPlanDto productionPlanDto) {
        if (productionPlanDto == null) {
            throw new ServiceException("下发数据不能为空");
        }
        //  æ¿æä¸åŒºåˆ†å¼ºåº¦ï¼Œstrengthä¼ null
        ProcessRoute processRoute = processRouteService.latestTypeDate(productionPlanDto.getProductName(), null);
        if (processRoute == null) {
            log.info("下发产品【{}】未查询出工艺路线", productionPlanDto.getProductName());
            return null;
        }
        migration(processRoute);
        return processRoute.getId();
    }
    @Override
    public void populateData(Long productOrderId, Long processRouteId) {
        ProcessRoute processRoute = processRouteService.getById(processRouteId);
        if (processRoute == null) {
            log.info("生产订单【{}】未查询出工艺路线【{}】", productOrderId, processRouteId);
            return;
        }
        migration(processRoute);
        //  å›žå†™å·¥è‰ºè·¯çº¿id到生产订单
        ProductOrder productOrder = new ProductOrder();
        productOrder.setId(productOrderId);
        productOrder.setRouteId(processRouteId);
        productOrderService.updateById(productOrder);
    }
    @Override
    public void deleteData(Long processRouteId) {
        //  æŸ¥å‡ºå·¥è‰ºè·¯çº¿å­é›†ï¼Œç”¨äºŽå…³è”删除参数附表
        List<ProcessRouteItem> itemList = processRouteItemService.list(new LambdaQueryWrapper<ProcessRouteItem>().eq(ProcessRouteItem::getRouteId, processRouteId));
        if (itemList != null && !itemList.isEmpty()) {
            List<Long> itemIds = itemList.stream().map(ProcessRouteItem::getId).collect(Collectors.toList());
            List<Long> processIds = itemList.stream().map(ProcessRouteItem::getProcessId).collect(Collectors.toList());
            //  åˆ é™¤å·¥è‰ºè·¯çº¿å·¥åºå‚数附表
            processRouteItemParamInstanceService.remove(new LambdaQueryWrapper<ProcessRouteItemParamInstance>().in(ProcessRouteItemParamInstance::getRouteItemId, itemIds));
            //  åˆ é™¤å·¥åºç»‘定参数附表
            productProcessParamInstanceService.remove(new LambdaQueryWrapper<ProductProcessParamInstance>().in(ProductProcessParamInstance::getProcessId, processIds));
        }
        //  åˆ é™¤å·¥è‰ºè·¯çº¿å­é›†é™„表
        processRouteItemInstanceService.remove(
                new LambdaQueryWrapper<ProcessRouteItemInstance>().eq(ProcessRouteItemInstance::getRouteId, processRouteId));
        //  åˆ é™¤BOM子集附表
        ProcessRoute processRoute = processRouteService.getById(processRouteId);
        if (processRoute != null && processRoute.getBomId() != null) {
            productStructureInstanceService.remove(new LambdaQueryWrapper<ProductStructureInstance>().eq(ProductStructureInstance::getBomId, processRoute.getBomId()));
        }
    }
    /**
     * æ ¹æ®å·¥è‰ºè·¯çº¿è¿ç§»å››å¼ é™„表数据
     */
    private void migration(ProcessRoute processRoute) {
        //  è¿ç§»å·¥è‰ºè·¯çº¿å­é›†è¡¨æ•°æ®
        List<ProcessRouteItem> processRouteItemList = processRouteItemService.list(new LambdaQueryWrapper<ProcessRouteItem>().eq(ProcessRouteItem::getRouteId, processRoute.getId()));
        migrationProcessRouteItem(processRouteItemList);
        //  è¿ç§»å·¥è‰ºè·¯çº¿å†…绑定的工序及工序参数
        if (processRouteItemList != null && !processRouteItemList.isEmpty()) {
            for (ProcessRouteItem item : processRouteItemList) {
                List<ProcessRouteItemParam> paramList = processRouteItemParamService.list(new LambdaQueryWrapper<ProcessRouteItemParam>().eq(ProcessRouteItemParam::getRouteItemId, item.getId()));
                migrationProcessRouteItemParam(paramList);
                List<ProductProcessParam> processParamList = productProcessParamService.list(new LambdaQueryWrapper<ProductProcessParam>().eq(ProductProcessParam::getProcessId, item.getProcessId()));
                migrationProductProcessParam(processParamList);
            }
        }
        //  è¿ç§»BOM子集表数据
        if (processRoute.getBomId() != null) {
            List<ProductStructure> structureList = productStructureService.list(new LambdaQueryWrapper<ProductStructure>().eq(ProductStructure::getBomId, processRoute.getBomId()));
            migrationProductStructure(structureList);
        }
    }
    private void migrationProcessRouteItem(List<ProcessRouteItem> list) {
        if (list == null || list.isEmpty()) {
            return;
        }
        List<ProcessRouteItemInstance> instances = list.stream().map(item -> {
            ProcessRouteItemInstance instance = new ProcessRouteItemInstance();
            BeanUtils.copyProperties(item, instance, "id");
            instance.setIsQuality(item.getIsQuality() != null && item.getIsQuality() ? 1 : 0);
            return instance;
        }).collect(Collectors.toList());
        processRouteItemInstanceService.saveBatch(instances);
    }
    private void migrationProcessRouteItemParam(List<ProcessRouteItemParam> list) {
        if (list == null || list.isEmpty()) {
            return;
        }
        List<ProcessRouteItemParamInstance> instances = list.stream().map(item -> {
            ProcessRouteItemParamInstance instance = new ProcessRouteItemParamInstance();
            BeanUtils.copyProperties(item, instance, "id");
            return instance;
        }).collect(Collectors.toList());
        processRouteItemParamInstanceService.saveBatch(instances);
    }
    private void migrationProductProcessParam(List<ProductProcessParam> list) {
        if (list == null || list.isEmpty()) {
            return;
        }
        List<ProductProcessParamInstance> instances = list.stream().map(item -> {
            ProductProcessParamInstance instance = new ProductProcessParamInstance();
            BeanUtils.copyProperties(item, instance, "id");
            instance.setIsRequired(item.getIsRequired() != null && item.getIsRequired() == 1);
            return instance;
        }).collect(Collectors.toList());
        productProcessParamInstanceService.saveBatch(instances);
    }
    private void migrationProductStructure(List<ProductStructure> list) {
        if (list == null || list.isEmpty()) {
            return;
        }
        List<ProductStructureInstance> instances = list.stream().map(item -> {
            ProductStructureInstance instance = new ProductStructureInstance();
            BeanUtils.copyProperties(item, instance, "id");
            instance.setBomId(item.getBomId() != null ? item.getBomId().longValue() : null);
            return instance;
        }).collect(Collectors.toList());
        productStructureInstanceService.saveBatch(instances);
    }
}
src/main/java/com/ruoyi/appendix/service/impl/ProcessRouteItemInstanceServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package com.ruoyi.appendix.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.appendix.mapper.ProcessRouteItemInstanceMapper;
import com.ruoyi.appendix.pojo.ProcessRouteItemInstance;
import com.ruoyi.appendix.service.ProcessRouteItemInstanceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
 * <br>
 * å·¥è‰ºè·¯çº¿å­é›†-附表Service实现类
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:08
 */
@Slf4j
@Service
public class ProcessRouteItemInstanceServiceImpl extends ServiceImpl<ProcessRouteItemInstanceMapper, ProcessRouteItemInstance> implements ProcessRouteItemInstanceService {
}
src/main/java/com/ruoyi/appendix/service/impl/ProcessRouteItemParamInstanceServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.appendix.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.appendix.mapper.ProcessRouteItemParamInstanceMapper;
import com.ruoyi.appendix.pojo.ProcessRouteItemParamInstance;
import com.ruoyi.appendix.service.ProcessRouteItemParamInstanceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
 * <br>
 * å·¥è‰ºè·¯çº¿å·¥åºå‚æ•°-附表Service实现类
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:12
 */
@Slf4j
@Service
public class ProcessRouteItemParamInstanceServiceImpl extends ServiceImpl<ProcessRouteItemParamInstanceMapper, ProcessRouteItemParamInstance> implements ProcessRouteItemParamInstanceService {
}
src/main/java/com/ruoyi/appendix/service/impl/ProductProcessParamInstanceServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.appendix.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.appendix.mapper.ProductProcessParamInstanceMapper;
import com.ruoyi.appendix.pojo.ProductProcessParamInstance;
import com.ruoyi.appendix.service.ProductProcessParamInstanceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
 * <br>
 * å·¥åºç»‘定参数-附表Service实现类
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:18
 */
@Slf4j
@Service
public class ProductProcessParamInstanceServiceImpl extends ServiceImpl<ProductProcessParamInstanceMapper, ProductProcessParamInstance> implements ProductProcessParamInstanceService {
}
src/main/java/com/ruoyi/appendix/service/impl/ProductStructureInstanceServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.appendix.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.appendix.mapper.ProductStructureInstanceMapper;
import com.ruoyi.appendix.pojo.ProductStructureInstance;
import com.ruoyi.appendix.service.ProductStructureInstanceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
 * <br>
 * BOM子集-附表Service实现类
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 13:21
 */
@Slf4j
@Service
public class ProductStructureInstanceServiceImpl extends ServiceImpl<ProductStructureInstanceMapper, ProductStructureInstance> implements ProductStructureInstanceService {
}
src/main/java/com/ruoyi/energy/controller/EnergyConsumptionDetailController.java
@@ -77,9 +77,16 @@
    /*******************************************汇总统计*****************************************************************************************************************************************************************************/
    @GetMapping("/statistics")
    @ApiOperation("按日月年汇总统计")
    @ApiOperation("能耗统计---按日月年汇总统计")
    public R statistics(EnergyStatisticsVo energyStatisticsVo) {
        return R.ok(energyConsumptionDetailService.statistics(energyStatisticsVo));
    }
    @GetMapping("/account")
    @ApiOperation("能耗成本核算---按日月汇总统计")
    public R account(EnergyStatisticsVo energyStatisticsVo) {
        energyStatisticsVo.setType(null);
        return R.ok(energyConsumptionDetailService.account(energyStatisticsVo));
    }
}
src/main/java/com/ruoyi/energy/dto/EnergyAccountDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package com.ruoyi.energy.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
@ApiModel("能耗成本核算---按日月汇总统计")
public class EnergyAccountDto {
    @ApiModelProperty("总能耗成本")
    private BigDecimal totalEnergyCost;
    @ApiModelProperty("生产能耗成本")
    private BigDecimal productEnergyCost;
    @ApiModelProperty("办公能耗成本")
    private BigDecimal officeEnergyCost;
    @ApiModelProperty("平均成本")
    private BigDecimal averageEnergyCost;
    @ApiModelProperty("能耗类型成本占比")
    private List<EnergyConsumptionTypeDto> energyConsumptionTypeProportion;
    @ApiModelProperty("能耗类型明细")
    private List<EnergyConsumptionDetailDto> energyConsumptionDetailDtoList;
}
src/main/java/com/ruoyi/energy/dto/EnergyConsumptionDetailDto.java
@@ -32,4 +32,7 @@
    //费用
    private BigDecimal cost;
    //单价
    private BigDecimal unitPrice;
}
src/main/java/com/ruoyi/energy/dto/EnergyStatisticsDto.java
@@ -9,7 +9,7 @@
import java.util.Map;
@Data
@ApiModel("按日月年汇总统计的能耗数据")
@ApiModel("能耗统计---按日月年汇总统计的能耗数据")
public class EnergyStatisticsDto {
    @ApiModelProperty("总耗用量")
src/main/java/com/ruoyi/energy/mapper/EnergyConsumptionDetailMapper.java
@@ -33,4 +33,6 @@
    List<EnergyConsumptionTypeDto> energyConsumptionTypeProportion(@Param("c") EnergyStatisticsVo energyStatisticsVo);
    List<EnergyCostDto> energyCostDtos(@Param("c") EnergyStatisticsVo energyStatisticsVo);
    List<EnergyConsumptionDetailDto> energyConsumptionDetailDtos(@Param("c") EnergyStatisticsVo energyStatisticsVo);
}
src/main/java/com/ruoyi/energy/service/EnergyConsumptionDetailService.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.energy.dto.EnergyAccountDto;
import com.ruoyi.energy.dto.EnergyConsumptionDetailDto;
import com.ruoyi.energy.dto.EnergyStatisticsDto;
import com.ruoyi.energy.pojo.EnergyConsumptionDetail;
@@ -30,4 +31,5 @@
    EnergyStatisticsDto statistics(EnergyStatisticsVo energyStatisticsVo);
    EnergyAccountDto account(EnergyStatisticsVo energyStatisticsVo);
}
src/main/java/com/ruoyi/energy/service/impl/EnergyConsumptionDetailServiceImpl.java
@@ -6,10 +6,7 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.energy.dto.EnergyConsumptionDetailDto;
import com.ruoyi.energy.dto.EnergyConsumptionTypeDto;
import com.ruoyi.energy.dto.EnergyCostDto;
import com.ruoyi.energy.dto.EnergyStatisticsDto;
import com.ruoyi.energy.dto.*;
import com.ruoyi.energy.mapper.EnergyMapper;
import com.ruoyi.energy.pojo.Energy;
import com.ruoyi.energy.pojo.EnergyConsumptionDetail;
@@ -115,7 +112,11 @@
        oldenergyStatisticsVo.setEndDate(masDays);
        Map<String, BigDecimal> oldmap=energyConsumptionDetailMapper.calculateEnergy(oldenergyStatisticsVo);
        if (ObjectUtils.isNotEmpty(oldmap)) {
            BigDecimal changeVite = (map.get("totalEnergyConsumption").subtract(oldmap.get("totalEnergyConsumption"))).divide(oldmap.get("totalEnergyConsumption"), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
            BigDecimal subtract = map.get("totalEnergyConsumption").subtract(oldmap.get("totalEnergyConsumption"));
            BigDecimal changeVite=BigDecimal.ZERO;
            if (oldmap.get("totalEnergyConsumption").compareTo(BigDecimal.ZERO)>0){
                changeVite = (subtract).divide(oldmap.get("totalEnergyConsumption"), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
            }
            energyStatisticsDto.setChangeVite(changeVite);
        }
        //能耗类型占比
@@ -126,4 +127,28 @@
        energyStatisticsDto.setEnergyCostDtos(energyCostDtos);
        return energyStatisticsDto;
    }
    @Override
    public EnergyAccountDto account(EnergyStatisticsVo energyStatisticsVo) {
        EnergyAccountDto energyAccountDto = new EnergyAccountDto();
        //计算总能耗成本+生产能耗成本+办公能耗成本
        Map<String, BigDecimal> map=energyConsumptionDetailMapper.calculateEnergy(energyStatisticsVo);
        energyAccountDto.setTotalEnergyCost(map.get("totalEnergyCost"));//总能耗成本
        energyStatisticsVo.setType("生产");
        Map<String, BigDecimal> map1=energyConsumptionDetailMapper.calculateEnergy(energyStatisticsVo);
        energyAccountDto.setProductEnergyCost(map1.get("totalEnergyCost"));//生产能耗成本
        energyStatisticsVo.setType("办公");
        Map<String, BigDecimal> map2=energyConsumptionDetailMapper.calculateEnergy(energyStatisticsVo);
        energyAccountDto.setOfficeEnergyCost(map2.get("totalEnergyCost"));//办公能耗成本
        energyStatisticsVo.setType(null);//恢复查询全部
        //平均成本
        energyAccountDto.setAverageEnergyCost(energyAccountDto.getTotalEnergyCost().divide(new BigDecimal(energyStatisticsVo.getDays()),2, RoundingMode.HALF_UP));
        //能耗类型成本占比
        List<EnergyConsumptionTypeDto> energyConsumptionTypeDtos=energyConsumptionDetailMapper.energyConsumptionTypeProportion(energyStatisticsVo);
        energyAccountDto.setEnergyConsumptionTypeProportion(energyConsumptionTypeDtos);
        //能耗类型明细
        List<EnergyConsumptionDetailDto> energyConsumptionDetailDtoList=energyConsumptionDetailMapper.energyConsumptionDetailDtos(energyStatisticsVo);
        energyAccountDto.setEnergyConsumptionDetailDtoList(energyConsumptionDetailDtoList);
        return energyAccountDto;
    }
}
src/main/java/com/ruoyi/production/controller/ProcessRouteController.java
@@ -2,8 +2,10 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.production.dto.ProcessRouteDto;
import com.ruoyi.production.dto.ProductStructureDto;
import com.ruoyi.production.pojo.ProcessRoute;
import com.ruoyi.production.pojo.ProcessRouteItem;
import com.ruoyi.production.service.ProcessRouteItemService;
@@ -14,34 +16,44 @@
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
@RestController
@RequestMapping("processRoute")
@RequestMapping("/processRoute")
@Api(tags = "工艺路线")
public class ProcessRouteController {
    @Autowired
    private ProcessRouteService processRouteService;
    @GetMapping("page")
    @GetMapping("/page")
    @ApiOperation("分页查询")
    public R page(Page<ProcessRouteDto>  page, ProcessRouteDto processRouteDto) {
    public R page(Page<ProcessRouteDto> page, ProcessRouteDto processRouteDto) {
        return R.ok(processRouteService.pageProcessRouteDto(page, processRouteDto));
    }
    @ApiOperation("新增工艺路线")
    @PostMapping ()
    public R add(@RequestBody  ProcessRoute processRoute) {
    @PostMapping("")
    public R add(@RequestBody ProcessRoute processRoute) {
        return R.ok(processRouteService.saveProcessRoute(processRoute));
    }
    @ApiOperation("修改工艺路线")
    @PutMapping ()
    public R update(@RequestBody  ProcessRoute processRoute) {
    @PutMapping("")
    public R update(@RequestBody ProcessRoute processRoute) {
        return R.ok(processRouteService.updateById(processRoute));
    }
    @ApiOperation("删除工艺路线")
    @DeleteMapping("/{ids}")
    public R delete(@PathVariable("ids") Long[] ids) {
        return R.ok(processRouteService.batchDelete(Arrays.asList(ids)));
    }
    @GetMapping("/getRouteBom/{id}")
    @ApiOperation("获取工艺路线绑定的BOM子集")
    public AjaxResult getRouteBom(@PathVariable Long id) {
        List<ProductStructureDto> list = processRouteService.getRouteBom(id);
        return AjaxResult.success(list);
    }
}
src/main/java/com/ruoyi/production/controller/ProcessRouteItemController.java
@@ -21,13 +21,13 @@
import java.util.List;
@RestController
@RequestMapping("processRouteItem")
@RequestMapping("/processRouteItem")
@Api(tags = "工艺路线明细")
public class ProcessRouteItemController {
    @Autowired
    private ProcessRouteItemService processRouteItemService;
    @GetMapping("list")
    @GetMapping("/list")
    public R listProcessRouteItemDto(ProcessRouteItemDto processRouteItemDto) {
        return R.ok(processRouteItemService.listProcessRouteItemDto(processRouteItemDto));
    }
@@ -50,4 +50,5 @@
    public AjaxResult batchDelete(@PathVariable("id") Long id) {
        return AjaxResult.success(processRouteItemService.batchDelete(id));
    }
}
src/main/java/com/ruoyi/production/controller/ProductBomController.java
@@ -1,5 +1,6 @@
package com.ruoyi.production.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -101,6 +102,14 @@
        return AjaxResult.success(productBoms);
    }
    @GetMapping("/getDictCode")
    @Log(title = "BOM-根据选择的产品型号查询存在的bom", businessType = BusinessType.OTHER)
    @ApiOperation("BOM-根据选择的产品型号查询存在的bom")
    public AjaxResult getDictCode(Long dictCode) {
        List<ProductBom> bomList = productBomService.list(new LambdaQueryWrapper<ProductBom>().eq(ProductBom::getDictCode, dictCode));
        return AjaxResult.success(bomList);
    }
    @PostMapping("uploadBom")
    @PreAuthorize("@ss.hasPermi('product:bom:import')")
src/main/java/com/ruoyi/production/controller/ProductOrderController.java
@@ -19,7 +19,7 @@
import java.math.BigDecimal;
import java.util.List;
@RequestMapping("productOrder")
@RequestMapping("/productOrder")
@RestController
@Api(tags = "生产订单")
public class ProductOrderController {
@@ -29,7 +29,7 @@
    @ApiOperation("分页查询")
    @GetMapping("page")
    @GetMapping("/page")
    public R page(ProductOrderDto productOrder, Page<ProductOrder> page) {
        return R.ok(productOrderService.pageProductOrder(page, productOrder));
    }
src/main/java/com/ruoyi/production/dto/BomImportDto.java
@@ -8,11 +8,17 @@
@Data
public class BomImportDto {
    @Excel(name = "编号")
    private String code;
    @Excel(name = "父项产品名称")
    private String parentName;
    @Excel(name = "父项编号")
    private String parentCode;
    @Excel(name = "父项产品规格")
    private String parentSpec;
    @Excel(name = "子项产品名称")
    private String childName;
    @Excel(name = "子项产品规格")
    private String childSpec;
    @Excel(name = "单位用量")
    private BigDecimal unitQty;
@@ -22,4 +28,4 @@
    @Excel(name = "备注")
    private String remark;
}
}
src/main/java/com/ruoyi/production/dto/ProcessRouteDto.java
@@ -11,8 +11,8 @@
    private String productName;
    @ApiModelProperty("规格")
    private String model;
    @ApiModelProperty("产品类型")
    private String dictLabel;
    private String bomNo;
}
src/main/java/com/ruoyi/production/dto/ProcessRouteItemDto.java
@@ -26,4 +26,8 @@
    @ApiModelProperty("工序参数个数")
    private Integer paramCount;
    @ApiModelProperty("产品类型")
    private String dictLabel;
}
src/main/java/com/ruoyi/production/enums/ProductOrderStatusEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
package com.ruoyi.production.enums;
import lombok.Getter;
/**
 * <br>
 * ç”Ÿäº§è®¢å•状态枚举类
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/18 14:18
 */
@Getter
public enum ProductOrderStatusEnum {
    WAIT(1, "待开始"),
    RUNNING(2, "进行中"),
    FINISHED(3, "已完成"),
    CANCEL(4, "已取消");
    private final Integer code;
    private final String desc;
    ProductOrderStatusEnum(Integer code, String desc) {
        this.code = code;
        this.desc = desc;
    }
    /**
     * æ ¹æ®code获取枚举
     */
    public static ProductOrderStatusEnum getByCode(Integer code) {
        if (code == null) {
            return null;
        }
        for (ProductOrderStatusEnum item : values()) {
            if (item.getCode().equals(code)) {
                return item;
            }
        }
        return null;
    }
    /**
     * åˆ¤æ–­æ˜¯å¦å…è®¸åˆ é™¤ï¼ˆ1、4)
     */
    public static boolean canDelete(Integer code) {
        return WAIT.getCode().equals(code) || CANCEL.getCode().equals(code);
    }
    /**
     * åˆ¤æ–­æ˜¯å¦å·²å¼€å§‹ç”Ÿäº§ï¼ˆ2、3)
     */
    public static boolean isStarted(Integer code) {
        return RUNNING.getCode().equals(code) || FINISHED.getCode().equals(code);
    }
}
src/main/java/com/ruoyi/production/mapper/ProcessRouteMapper.java
@@ -12,4 +12,6 @@
public interface ProcessRouteMapper extends BaseMapper<ProcessRoute> {
    IPage<ProcessRouteDto> pageProcessRouteDto(Page<ProcessRouteDto> page,@Param("c") ProcessRouteDto processRouteDto);
    ProcessRoute latestTypeDate(String productName, String strength);
}
src/main/java/com/ruoyi/production/pojo/ProcessRoute.java
@@ -44,4 +44,7 @@
    @ApiModelProperty(value = "状态:0-草稿,1-已批准")
    private Boolean status;
    @ApiModelProperty(value = "产品类型字典编码")
    private Long dictCode;
}
src/main/java/com/ruoyi/production/pojo/ProductOrder.java
@@ -16,7 +16,7 @@
@Data
@TableName("product_order")
public class ProductOrder  implements Serializable {
public class ProductOrder implements Serializable {
    private static final long serialVersionUID = 1L;
@@ -91,4 +91,7 @@
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime endTime;
    @ApiModelProperty(value = "状态(1.待开始、2.进行中、3.已完成、4.已取消)")
    private Integer status;
}
src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java
@@ -33,6 +33,7 @@
    private Long workOrderId;
    @ApiModelProperty(value = "生产订单id")
    @TableField(exist = false)
    private Long productOrderId;
    @ApiModelProperty(value = "报工状态")
src/main/java/com/ruoyi/production/service/ProcessRouteService.java
@@ -4,8 +4,8 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.production.dto.ProcessRouteDto;
import com.ruoyi.production.dto.ProductStructureDto;
import com.ruoyi.production.pojo.ProcessRoute;
import io.swagger.models.auth.In;
import java.util.List;
@@ -16,4 +16,8 @@
    Integer saveProcessRoute(ProcessRoute processRoute);
    int batchDelete(List<Long> ids);
    List<ProductStructureDto> getRouteBom(Long id);
    ProcessRoute latestTypeDate(String productName, String strength);
}
src/main/java/com/ruoyi/production/service/impl/ProcessRouteItemServiceImpl.java
@@ -11,7 +11,6 @@
import com.ruoyi.production.pojo.ProcessRouteItem;
import com.ruoyi.production.pojo.ProcessRouteItemParam;
import com.ruoyi.production.service.ProcessRouteItemService;
import com.ruoyi.production.service.ProductMaterialSkuService;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -29,9 +28,6 @@
    @Autowired
    private ProcessRouteItemParamMapper processRouteItemParamMapper;
    @Autowired
    private ProductMaterialSkuService productMaterialSkuService;
    @Override
    public List<ProcessRouteItemDto> listProcessRouteItemDto(ProcessRouteItemDto processRouteItemDto) {
@@ -107,14 +103,7 @@
        if (processRouteItem == null) {
            throw new ServiceException("数据不能为空");
        }
        if (processRouteItem.getProductModelId() != null) {
            Object product = productMaterialSkuService.getById(processRouteItem.getProductModelId());
            if (product == null) {
                throw new ServiceException("操作失败:关联的产品(ID:" + processRouteItem.getProductModelId() + ")不存在");
            }
        } else {
            throw new ServiceException("产品ID不能为空");
        }
        Long tenantId = SecurityUtils.getLoginUser().getTenantId();
        processRouteItem.setTenantId(tenantId);
src/main/java/com/ruoyi/production/service/impl/ProcessRouteServiceImpl.java
@@ -4,16 +4,19 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.production.dto.ProcessRouteDto;
import com.ruoyi.production.dto.ProductStructureDto;
import com.ruoyi.production.mapper.ProcessRouteItemMapper;
import com.ruoyi.production.mapper.ProcessRouteMapper;
import com.ruoyi.production.mapper.ProductOrderMapper;
import com.ruoyi.production.mapper.ProductProcessRouteMapper;
import com.ruoyi.production.pojo.ProcessRoute;
import com.ruoyi.production.pojo.ProcessRouteItem;
import com.ruoyi.production.pojo.ProductOrder;
import com.ruoyi.production.pojo.ProductProcessRoute;
import com.ruoyi.production.service.ProcessRouteService;
import com.ruoyi.production.service.ProductStructureService;
import com.ruoyi.project.system.domain.SysDictData;
import com.ruoyi.project.system.mapper.SysDictDataMapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -22,7 +25,7 @@
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
@Service
@@ -39,6 +42,13 @@
    @Autowired
    private ProductOrderMapper productOrderMapper;
    @Autowired
    private ProductStructureService productStructureService;
    @Autowired
    private SysDictDataMapper sysDictDataMapper;
    @Override
    public IPage<ProcessRouteDto> pageProcessRouteDto(Page<ProcessRouteDto> page, ProcessRouteDto processRouteDto) {
@@ -48,6 +58,14 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer saveProcessRoute(ProcessRoute processRoute) {
        if (processRoute == null || processRoute.getDictCode() == null) {
            throw new ServiceException("新增工艺路线失败,产品类型不能为空");
        }
        SysDictData sysDictData = sysDictDataMapper.selectDictDataById(processRoute.getDictCode());
        if (sysDictData == null) {
            throw new ServiceException("新增工艺路线失败,产品类型不存在");
        }
        save(processRoute);
        if (processRoute.getProcessRouteCode() == null || processRoute.getProcessRouteCode().trim().isEmpty()) {
            String dateStr = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
@@ -70,4 +88,27 @@
        processRouteItemMapper.delete(Wrappers.<ProcessRouteItem>lambdaQuery().in(ProcessRouteItem::getRouteId, ids));
        return processRouteMapper.deleteBatchIds(ids);
    }
    @Override
    public List<ProductStructureDto> getRouteBom(Long id) {
        if (id == null) {
            return new ArrayList<>(0);
        }
        ProcessRoute processRoute = getById(id);
        if (processRoute == null) {
            throw new ServiceException("工艺路线不存在");
        }
        List<ProductStructureDto> list = productStructureService.listByBomId(processRoute.getBomId());
        if (list == null) {
            list = new ArrayList<>(0);
        }
        return list;
    }
    @Override
    public ProcessRoute latestTypeDate(String productName, String strength) {
        return baseMapper.latestTypeDate(productName, strength);
    }
}
src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java
@@ -4,6 +4,8 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.production.pojo.ProductMaterial;
import com.ruoyi.production.pojo.ProductMaterialSku;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
@@ -42,12 +44,17 @@
    @Autowired
    private ProductBomMapper productBomMapper;
    @Autowired
    private ProductStructureService productStructureService;
    @Autowired
    private ProductProcessService productProcessService;
    @Autowired
    private ProductMaterialService productMaterialService;
    @Autowired
    private ProductMaterialSkuService productMaterialSkuService;
    @Autowired
    private SysDictDataMapper sysDictDataMapper;
@@ -61,12 +68,12 @@
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(ProductBom productBom) {
        if (productBom == null || productBom.getDictCode() == null) {
            throw new ServiceException("新增失败,产品类型不能为空");
            throw new ServiceException("新增BOM失败,产品类型不能为空");
        }
        SysDictData sysDictData = sysDictDataMapper.selectDictDataById(productBom.getDictCode());
        if (sysDictData == null) {
            throw new ServiceException("新增失败,产品类型不存在");
            throw new ServiceException("新增BOM失败,产品类型不存在");
        }
        boolean save = productBomMapper.insert(productBom) > 0;
@@ -90,7 +97,6 @@
        if (sysDictData == null) {
            return AjaxResult.error("导入失败,产品类型不存在");
        }
        ExcelUtil<BomImportDto> util = new ExcelUtil<>(BomImportDto.class);
        List<BomImportDto> list;
        try {
@@ -99,68 +105,81 @@
            return AjaxResult.error("Excel解析失败");
        }
        if (list == null || list.isEmpty()) return AjaxResult.error("数据为空");
        if (list == null || list.isEmpty()) {
            return AjaxResult.error("数据为空");
        }
        //  å¤„理字段清理
        //  å¤„理工序
        list.forEach(dto -> {
            dto.setParentCode(clean(dto.getParentCode()));
            dto.setCode(clean(dto.getCode()));
            dto.setParentName(clean(dto.getParentName()));
            dto.setParentSpec(clean(dto.getParentSpec()));
            dto.setChildName(clean(dto.getChildName()));
            dto.setChildSpec(clean(dto.getChildSpec()));
        });
        handleProcess(list);
        Map<String, Long> processMap = productProcessService.list().stream()
                .collect(Collectors.toMap(ProductProcess::getName, ProductProcess::getId, (k1, k2) -> k1));
        //  åˆ›å»º BOM æ•°æ®
        BomImportDto first = list.get(0);
        ProductMaterialSku rootModel = findModel(first.getParentName(), first.getParentSpec());
        ProductBom bom = new ProductBom();
        bom.setVersion("1.0");
        bom.setDictCode(dictCode);
        bom.setVersion("1.0");
        productBomMapper.insert(bom);
        bom.setBomNo("BM." + String.format("%05d", bom.getId()));
        productBomMapper.updateById(bom);
        // è®°å½•已经插入结构的节点:Key = "编码", Value = structure_id
        // è®°å½•已经插入结构的节点:Key = "名称+规格", Value = structure_id
        Map<String, Long> treePathMap = new HashMap<>();
        for (int i = 0; i < list.size(); i++) {
            BomImportDto dto = list.get(i);
            String currentCode = dto.getCode();
            String parentCode = dto.getParentCode();
            String parentKey = dto.getParentName() + "|" + dto.getParentSpec();
            String childKey = dto.getChildName() + "|" + dto.getChildSpec();
            // å¤„理根节点:一般指第一行且没有父项编号
            if (i == 0 && StringUtils.isBlank(parentCode)) {
            //处理根节点,第一行且子项为空
            if (i == 0 && StringUtils.isBlank(dto.getChildName())) {
                ProductStructure rootNode = new ProductStructure();
                rootNode.setBomId(bom.getId());
                rootNode.setParentId(null); // é¡¶å±‚没有父节点
                if (processMap.containsKey(dto.getProcess())) {
                    rootNode.setProcessId(processMap.get(dto.getProcess()));
                }
                rootNode.setProductModelId(rootModel.getId());
                rootNode.setUnitQuantity(BigDecimal.ONE);
                ProductMaterial rootMaterial = productMaterialService.getById(rootModel.getProductId());
                rootNode.setUnit(rootMaterial != null ? rootMaterial.getUnit() : null);
                productStructureService.save(rootNode);
                treePathMap.put(currentCode, rootNode.getId());
                treePathMap.put(parentKey, rootNode.getId());
                continue;
            }
            //  å¤„理子层级节点
            //  æ‰¾åˆ°çˆ¶èŠ‚ç‚¹åœ¨æ•°æ®åº“é‡Œçš„ ID
            Long parentStructureId = treePathMap.get(parentCode);
            Long parentStructureId = treePathMap.get(parentKey);
            if (parentStructureId == null) {
                // å¦‚æžœ Map é‡Œæ‰¾ä¸åˆ°ï¼Œè¯´æ˜Ž Excel é¡ºåºä¹±äº†æˆ–者数据有误
                throw new ServiceException("导入失败: çˆ¶é¡¹[" + parentCode + "]必须在其子项之前定义");
                throw new ServiceException("导入失败: çˆ¶é¡¹[" + dto.getParentName() + "]必须在其子项之前定义");
            }
            //  èŽ·å–å­é¡¹æ¨¡åž‹ä¿¡æ¯
            ProductMaterialSku childModel = findModel(dto.getChildName(), dto.getChildSpec());
            //  æ’入结构表
            ProductStructure node = new ProductStructure();
            node.setBomId(bom.getId());
            node.setParentId(parentStructureId); // çˆ¶èŠ‚ç‚¹ID
            node.setProductModelId(childModel.getId());
            node.setUnitQuantity(dto.getUnitQty());
            ProductMaterial childMaterial = productMaterialService.getById(childModel.getProductId());
            node.setUnit(childMaterial != null ? childMaterial.getUnit() : null);
            if (processMap.containsKey(dto.getProcess())) {
                node.setProcessId(processMap.get(dto.getProcess()));
            }
            productStructureService.save(node);
            //  æŠŠå½“前项记录到 Map, ä½œä¸ºä»¥åŽæ›´æ·±å±‚级的父项查找依据
            treePathMap.put(currentCode, node.getId());
            //  æŠŠå½“前子项记录到 Map,作为以后更深层级的父项查找依据
            //  åŒä¸€çˆ¶é¡¹ä¸‹çš„同名子项不需要重复记录
            treePathMap.put(childKey, node.getId());
        }
        return AjaxResult.success("BOM导入成功");
@@ -189,7 +208,8 @@
        for (ProductStructureDto root : treeData) {
            //  æ·»åŠ æ ¹èŠ‚ç‚¹
            BomImportDto rootRow = new BomImportDto();
            rootRow.setCode(root.getId().toString());
            rootRow.setParentName(root.getProductName());
            rootRow.setParentSpec(root.getModel());
            rootRow.setUnitQty(root.getUnitQuantity());
            rootRow.setRemark("");
            exportList.add(rootRow);
@@ -211,14 +231,14 @@
                }
                BomImportDto row = new BomImportDto();
                // çˆ¶ç±»ç¼–号
                row.setParentCode(parent.getId().toString());
                // æœ¬èº«ç¼–号
                row.setCode(child.getId().toString());
                // çˆ¶ç±»ä¿¡æ¯
                row.setParentName(parent.getProductName());
                row.setParentSpec(parent.getModel());
                // å­ç±»ä¿¡æ¯
                row.setChildName(child.getProductName());
                row.setChildSpec(child.getModel());
                row.setUnitQty(child.getUnitQuantity());
                row.setProcess(child.getProcessName());
//                row.setProcess();
                row.setRemark("");
                exportList.add(row);
@@ -241,6 +261,18 @@
            map.put(node.getId(), node);
            populateMap(node.getChildren(), map);
        }
    }
    private ProductMaterialSku findModel(String name, String spec) {
        ProductMaterial product = productMaterialService.getOne(new LambdaQueryWrapper<ProductMaterial>()
                .eq(ProductMaterial::getProductName, name).last("limit 1"));
        if (product == null) throw new ServiceException("产品未维护:" + name);
        ProductMaterialSku model = productMaterialSkuService.getOne(new LambdaQueryWrapper<ProductMaterialSku>()
                .eq(ProductMaterialSku::getProductId, product.getId())
                .eq(ProductMaterialSku::getModel, spec).last("limit 1"));
        if (model == null) throw new ServiceException("规格未维护:" + name + "[" + spec + "]");
        return model;
    }
    private void handleProcess(List<BomImportDto> list) {
@@ -283,5 +315,3 @@
        return s.replaceAll("[\\u00A0\\u3000]", "").trim();
    }
}
src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
@@ -7,11 +7,11 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
import com.ruoyi.appendix.service.AppendixService;
import com.ruoyi.procurementrecord.utils.StockUtils;
import com.ruoyi.production.dto.ProductOrderDto;
import com.ruoyi.production.dto.ProductStructureDto;
import com.ruoyi.production.enums.ProductOrderStatusEnum;
import com.ruoyi.production.mapper.*;
import com.ruoyi.production.pojo.*;
import com.ruoyi.production.service.ProductOrderService;
@@ -20,7 +20,6 @@
import com.ruoyi.productionPlan.pojo.ProductOrderPlan;
import com.ruoyi.productionPlan.pojo.ProductionPlan;
import com.ruoyi.quality.mapper.QualityInspectMapper;
import com.ruoyi.quality.pojo.QualityInspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -75,6 +74,9 @@
    @Autowired
    private StockUtils stockUtils;
    @Autowired
    private AppendixService appendixService;
    @Override
    public IPage<ProductOrderDto> pageProductOrder(Page<ProductOrder> page, ProductOrderDto productOrder) {
@@ -179,28 +181,82 @@
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(Long[] ids) {
        //如果已经开始生产,不能删除
        //查询生产订单下的工单
        List<ProductOrder> orders = productOrderMapper.selectList(Wrappers.<ProductOrder>lambdaQuery().in(ProductOrder::getId, ids));
        if (orders.isEmpty()) {
            throw new RuntimeException("生产订单不存在");
        }
        for (ProductOrder order : orders) {
            if (!ProductOrderStatusEnum.canDelete(order.getStatus())) {
                throw new RuntimeException("只有【待开始、已取消】状态的订单才可以删除");
            }
        }
        //  æ˜¯å¦å·²ç”Ÿäº§
        List<ProductWorkOrder> productWorkOrders = productWorkOrderMapper.selectList(Wrappers.<ProductWorkOrder>lambdaQuery().in(ProductWorkOrder::getProductOrderId, ids));
        if (productWorkOrders.size()>0){
            //判断是否有报工数据
            List<ProductionProductMain> productionProductMains = productionProductMainMapper.selectList(Wrappers.<ProductionProductMain>lambdaQuery()
                    .in(ProductionProductMain::getWorkOrderId, productWorkOrders.stream().map(ProductWorkOrder::getId).collect(Collectors.toList())));
            if (productionProductMains.size()>0){
        if (!productWorkOrders.isEmpty()) {
            List<Long> workOrderIds = productWorkOrders.stream()
                    .map(ProductWorkOrder::getId)
                    .collect(Collectors.toList());
            List<ProductionProductMain> productionProductMains = productionProductMainMapper.selectList(Wrappers.<ProductionProductMain>lambdaQuery().in(ProductionProductMain::getWorkOrderId, workOrderIds));
            if (!productionProductMains.isEmpty()) {
                throw new RuntimeException("生产订单已经开始生产,不能删除");
            }
            //删除工单
            //  åˆ é™¤å·¥å•
            productWorkOrderMapper.delete(Wrappers.<ProductWorkOrder>lambdaQuery().in(ProductWorkOrder::getProductOrderId, ids));
        }
        //删除工艺路线
        productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>()
                .in(ProductProcessRouteItem::getProductOrderId, ids));
        productProcessRouteMapper.delete(new LambdaQueryWrapper<ProductProcessRoute>()
                .in(ProductProcessRoute::getProductOrderId, ids));
        //删除生产订单
        productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>()
                .in(ProductOrder::getId, ids));
        //  å›žé€€ç”Ÿäº§è®¡åˆ’
        List<ProductOrderPlan> productOrderPlans = productOrderPlanMapper.selectList(Wrappers.<ProductOrderPlan>lambdaQuery().in(ProductOrderPlan::getProductOrderId, ids));
        for (ProductOrderPlan productOrderPlan : productOrderPlans) {
            ProductionPlan productionPlan = productionPlanMapper.selectById(productOrderPlan.getProductionPlanId());
            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, ids));
        //  åˆ é™¤é™„表的工艺路线与BOM
        for (Long id : ids) {
            ProductOrder productOrder = baseMapper.selectById(id);
            appendixService.deleteData(productOrder.getRouteId());
        }
//        productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>().in(ProductProcessRouteItem::getProductOrderId, ids));
//        productProcessRouteMapper.delete(new LambdaQueryWrapper<ProductProcessRoute>().in(ProductProcessRoute::getProductOrderId, ids));
        //  åˆ é™¤è®¢å•
        productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>().in(ProductOrder::getId, ids));
        return true;
    }
src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java
@@ -86,17 +86,27 @@
        //  çœŸå®žçš„父节点 ID
        Long realParentId;
        for (ProductStructureDto psDto : flatDtoList) {
            if (psDto.getId() == null && psDto.getParentTempId() != null) {
            String parentTempId = psDto.getParentTempId();
            if (psDto.getId() == null && parentTempId != null && !parentTempId.isEmpty()) {
                ProductStructure child = tempEntityMap.get(psDto.getTempId());
                if (tempEntityMap.containsKey(psDto.getParentTempId())) {
                if (tempEntityMap.containsKey(parentTempId)) {
                    // çˆ¶èŠ‚ç‚¹æ˜¯æ–°èŠ‚ç‚¹
                    realParentId = tempEntityMap.get(psDto.getParentTempId()).getId();
                    realParentId = tempEntityMap.get(parentTempId).getId();
                } else {
                    // çˆ¶èŠ‚ç‚¹æ˜¯è€èŠ‚ç‚¹
                    realParentId = Long.valueOf(psDto.getParentTempId());
                    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());
                child.setParentId(0L);
                parentFixList.add(child);
            }
        }
@@ -104,7 +114,6 @@
        if (!parentFixList.isEmpty()) {
            this.updateBatchById(parentFixList);
        }
        if (!updateList.isEmpty()) {
            this.updateBatchById(updateList);
        }
src/main/java/com/ruoyi/productionPlan/service/impl/ProductionPlanServiceImpl.java
@@ -7,6 +7,7 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.appendix.service.AppendixService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.StringUtils;
@@ -14,6 +15,7 @@
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.config.AliDingConfig;
import com.ruoyi.framework.util.AliDingUtils;
import com.ruoyi.production.enums.ProductOrderStatusEnum;
import com.ruoyi.production.pojo.ProductMaterialSku;
import com.ruoyi.production.pojo.ProductOrder;
import com.ruoyi.production.service.ProductMaterialService;
@@ -75,6 +77,9 @@
    @Autowired
    private ProductMaterialService productMaterialService;
    @Autowired
    private AppendixService appendixService;
    /**
     * åŒæ­¥é”ï¼Œç¡®ä¿æ‰‹åŠ¨å’Œå®šæ—¶ä»»åŠ¡ä¸åŒæ—¶æ‰§è¡Œ
@@ -141,6 +146,15 @@
        ProductOrder productOrder = new ProductOrder();
        productOrder.setQuantity(productionPlanDto.getTotalAssignedQuantity());
        productOrder.setPlanCompleteTime(productionPlanDto.getPlanCompleteTime());
        productOrder.setStatus(ProductOrderStatusEnum.WAIT.getCode());
        //  å½“下发的产品为砌块或板材,就拉取BOM子集与工艺路线子集数据存入到附表中
        if ("砌块".equals(productionPlanDto.getProductName())) {
            productOrder.setRouteId(appendixService.populateBlocks(productionPlanDto));
        }
        if ("板材".equals(productionPlanDto.getProductName())) {
            productOrder.setRouteId(appendixService.populatePlates(productionPlanDto));
        }
        productOrderService.addProductOrder(productOrder);
        // æ ¹æ®ä¸‹å‘数量,从第一个生产计划开始分配方数
@@ -164,10 +178,10 @@
                // æœ€åŽä¸€ä¸ªè®¡åˆ’,分配剩余方数
                BigDecimal lastRemainingVolume = productionPlanDto.getTotalAssignedQuantity().subtract(assignedVolume);
                plan.setStatus(1);
                if (lastRemainingVolume.compareTo(BigDecimal.ZERO) <= 0) {
                plan.setAssignedQuantity(plan.getAssignedQuantity().add(lastRemainingVolume));
                if (plan.getAssignedQuantity().compareTo(plan.getVolume()) >= 0) {
                    plan.setStatus(2);
                }
                plan.setAssignedQuantity(plan.getAssignedQuantity().add(lastRemainingVolume));
                productOrderPlan.setAssignedQuantity(lastRemainingVolume);
                productionPlanMapper.updateById(plan);
                productOrderPlanMapper.insert(productOrderPlan);
src/main/resources/mapper/appendix/ProcessRouteItemInstanceMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.appendix.mapper.ProcessRouteItemInstanceMapper">
    <resultMap id="ProcessRouteItemInstanceMap" type="com.ruoyi.appendix.pojo.ProcessRouteItemInstance">
        <id property="id" column="id"/>
        <result property="routeId" column="route_id"/>
        <result property="productModelId" column="product_model_id"/>
        <result property="processId" column="process_id"/>
        <result property="tenantId" column="tenant_id"/>
        <result property="createTime" column="create_time"/>
        <result property="updateTime" column="update_time"/>
        <result property="dragSort" column="drag_sort"/>
        <result property="isQuality" column="is_quality"/>
    </resultMap>
</mapper>
src/main/resources/mapper/appendix/ProcessRouteItemParamInstanceMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.appendix.mapper.ProcessRouteItemParamInstanceMapper">
    <resultMap id="BaseResultMap" type="com.ruoyi.appendix.pojo.ProcessRouteItemParamInstance">
        <id property="id" column="id"/>
        <result property="routeItemId" column="route_item_id"/>
        <result property="paramId" column="param_id"/>
        <result property="processParamId" column="process_param_id"/>
        <result property="standardValue" column="standard_value"/>
        <result property="minValue" column="min_value"/>
        <result property="maxValue" column="max_value"/>
        <result property="isRequired" column="is_required"/>
        <result property="sort" column="sort"/>
        <result property="tenantId" column="tenant_id"/>
        <result property="createTime" column="create_time"/>
        <result property="updateTime" column="update_time"/>
    </resultMap>
</mapper>
src/main/resources/mapper/appendix/ProductProcessParamInstanceMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.appendix.mapper.ProductProcessParamInstanceMapper">
    <resultMap id="BaseResultMap" type="com.ruoyi.appendix.pojo.ProductProcessParamInstance">
        <id property="id" column="id"/>
        <result property="processId" column="process_id"/>
        <result property="paramId" column="param_id"/>
        <result property="standardValue" column="standard_value"/>
        <result property="minValue" column="min_value"/>
        <result property="maxValue" column="max_value"/>
        <result property="isRequired" column="is_required"/>
        <result property="sort" column="sort"/>
        <result property="tenantId" column="tenant_id"/>
        <result property="createTime" column="create_time"/>
        <result property="updateTime" column="update_time"/>
    </resultMap>
</mapper>
src/main/resources/mapper/appendix/ProductStructureInstanceMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.appendix.mapper.ProductStructureInstanceMapper">
    <resultMap id="BaseResultMap" type="com.ruoyi.appendix.pojo.ProductStructureInstance">
        <id property="id" column="id"/>
        <result property="parentId" column="parent_id"/>
        <result property="productModelId" column="product_model_id"/>
        <result property="processId" column="process_id"/>
        <result property="unitQuantity" column="unit_quantity"/>
        <result property="demandedQuantity" column="demanded_quantity"/>
        <result property="unit" column="unit"/>
        <result property="tenantId" column="tenant_id"/>
        <result property="bomId" column="bom_id"/>
    </resultMap>
</mapper>
src/main/resources/mapper/energy/EnergyConsumptionDetailMapper.xml
@@ -41,7 +41,9 @@
         </where>
    </select>
    <select id="calculateEnergy" resultType="java.util.Map">
        select SUM(ecd.dosage) totalEnergyConsumption,
        select  COALESCE(t.totalEnergyConsumption, 0) AS totalEnergyConsumption,
                COALESCE(t.totalEnergyCost, 0) AS totalEnergyCost
        from (select SUM(ecd.dosage) totalEnergyConsumption,
               SUM(ecd.dosage * e.unit_price) totalEnergyCost
            from energy_consumption_detail ecd
            left join  energy e on ecd.energy_id = e.id
@@ -49,6 +51,7 @@
            <if test="c.type != null and c.type != ''">
                and ecd.type =#{c.type}
            </if>
        )t
    </select>
    <select id="energyConsumptionTypeProportion"
            resultType="com.ruoyi.energy.dto.EnergyConsumptionTypeDto">
@@ -115,5 +118,24 @@
        on z.meter_reading_date=C.meter_reading_date
    order by z.meter_reading_date
    </select>
    <select id="energyConsumptionDetailDtos"
            resultType="com.ruoyi.energy.dto.EnergyConsumptionDetailDto">
        select ecd.meter_reading_date,
               e.energy_tyep,
               ecd.type,
               e.unit,
               e.unit_price,
               sum(ecd.dosage) dosage,
               sum(ecd.dosage * e.unit_price) cost
            from energy_consumption_detail ecd
            left join  energy e on ecd.energy_id = e.id
            where ecd.meter_reading_date between #{c.startDate} and #{c.endDate}
            group by ecd.meter_reading_date,
                     e.energy_tyep,
                     ecd.type,
                     e.unit,
                     e.unit_price
        order by ecd.meter_reading_date
    </select>
</mapper>
src/main/resources/mapper/production/ProcessRouteItemMapper.xml
@@ -17,18 +17,12 @@
        select pri.*,
               pr.description,
               pp.name                             as process_name,
               pms.product_id,
               pms.model,
               pm.product_name,
               pm.unit,
               (SELECT COUNT(1)
                FROM process_route_item_param prip
                WHERE prip.route_item_id = pri.id) as paramCount
        from process_route_item pri
                 left join process_route pr on pr.id = pri.route_id
                 left join product_process pp on pp.id = pri.process_id
                 left join product_material_sku pms on pms.id = pri.product_model_id
                 left join product_material pm on pm.id = pms.product_id
        where pri.route_id = #{c.routeId}
        order by pri.drag_sort
    </select>
src/main/resources/mapper/production/ProcessRouteMapper.xml
@@ -17,17 +17,36 @@
    <select id="pageProcessRouteDto" resultType="com.ruoyi.production.dto.ProcessRouteDto">
        select
        ps.*,
        pm.product_name, pms.product_id, pms.model, pb.bom_no
        pb.bom_no,
        sdd.dict_label AS dictLabel
        from process_route ps
        left join product_bom pb on ps.bom_id = pb.id
        left join product_material_sku pms on ps.product_model_id = pms.id
        left join product_material pm on pms.product_id = pm.id
        <where>
            <if test="c.model != null and c.model != ''">
                and pms.model like concat('%', #{c.model}, '%')
            </if>
        </where>
        left join sys_dict_data sdd on sdd.dict_code = ps.dict_code
        where 1= 1
        <if test="c.dictCode != null">
            and ps.dict_code = #{c.dictCode}
        </if>
        order by ps.id
    </select>
    <select id="latestTypeDate" resultType="com.ruoyi.production.pojo.ProcessRoute">
        SELECT *
        FROM process_route pr
        WHERE pr.dict_code = (SELECT d.dict_code
                              FROM sys_dict_data d
                              WHERE d.dict_label =
                                <choose>
                                    <when test="strength != null and strength != ''">
                                        CONCAT(#{productName}, '-', #{strength})
                                    </when>
                                    <otherwise>
                                        #{productName}
                                    </otherwise>
                                </choose>
                                AND d.dict_type = 'product_type'
                              LIMIT 1)
        ORDER BY pr.create_time DESC
        LIMIT 1
    </select>
</mapper>
src/main/resources/mapper/production/ProductOrderMapper.xml
@@ -11,6 +11,7 @@
        <result property="createTime" column="create_time"/>
        <result property="updateTime" column="update_time"/>
        <result property="planCompleteTime" column="plan_complete_time"/>
        <result property="status" column="status"/>
    </resultMap>
    <select id="pageProductOrder" resultType="com.ruoyi.production.dto.ProductOrderDto">
src/main/resources/mapper/production/ProductStructureMapper.xml
@@ -18,9 +18,15 @@
               ps.bom_id,
               ps.unit_quantity,
               ps.process_id,
               pp.name AS process_name
               pp.name         AS process_name,
               pm.product_name AS productName,
               pm.unit,
               pms.model
        FROM product_structure ps
                 LEFT JOIN product_process pp ON ps.process_id = pp.id
                 LEFT JOIN product_material_sku pms ON pms.id = ps.product_model_id
                 LEFT JOIN product_material pm ON pm.id = pms.product_id
        WHERE ps.bom_id = #{bomId}
        ORDER BY ps.id
    </select>
src/main/resources/mapper/productionPlan/ProductionPlanMapper.xml
@@ -58,6 +58,9 @@
        <if test="c.model != null and c.model != '' ">
            AND pms.model LIKE CONCAT('%',#{c.model},'%')
        </if>
         <if test="c.status != null">
            AND pp.status =#{c.status}
        </if>
        <if test="c.applyNo != null and c.applyNo != '' ">
            AND pp.apply_no LIKE CONCAT('%',#{c.applyNo},'%')
        </if>
@@ -125,4 +128,4 @@
        </foreach>
        ORDER BY pp.id ASC
    </select>
</mapper>
</mapper>