已添加10个文件
已修改38个文件
已删除6个文件
1926 ■■■■ 文件已修改
doc/宁夏-中盛建材.sql 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/CodeGenerator.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/controller/AppendixController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/controller/ProcessRouteItemInstanceController.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/controller/ProcessRouteItemParamInstanceController.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/controller/ProductProcessParamInstanceController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/controller/ProductStructureInstanceController.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/dto/ProcessRouteItemInstanceDto.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/dto/ProcessRouteItemParamInstanceDto.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/dto/ProductStructureInstanceDto.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/mapper/ProductProcessParamInstanceMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/pojo/ProcessRouteItemInstance.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/pojo/ProcessRouteItemParamInstance.java 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/pojo/ProductProcessParamInstance.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/pojo/ProductStructureInstance.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/AppendixService.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/ProcessRouteItemInstanceService.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/ProcessRouteItemParamInstanceService.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/ProductProcessParamInstanceService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/ProductStructureInstanceService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/impl/AppendixServiceImpl.java 143 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/impl/ProcessRouteItemInstanceServiceImpl.java 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/impl/ProcessRouteItemParamInstanceServiceImpl.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/impl/ProductProcessParamInstanceServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/appendix/service/impl/ProductStructureInstanceServiceImpl.java 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/task/CustomerTask.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/framework/config/AliDingConfig.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProductOrderDto.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProductProcessParamDto.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProcessRouteItemParam.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductOrder.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductProcessParam.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProductOrderService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProcessRouteItemParamServiceImpl.java 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductProcessParamServiceImpl.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/controller/SalesDeliveryController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/dto/ProductionPlanDto.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/mapper/SalesDeliveryMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/pojo/SalesDelivery.java 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/service/SalesDeliveryService.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/service/impl/ProductionPlanServiceImpl.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/service/impl/SalesDeliveryServiceImpl.java 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/task/SalesDeliveryTask.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-zsjc.yml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/appendix/ProcessRouteItemInstanceMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/appendix/ProcessRouteItemParamInstanceMapper.xml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/appendix/ProductProcessParamInstanceMapper.xml 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/appendix/ProductStructureInstanceMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProcessRouteItemParamMapper.xml 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductOrderMapper.xml 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductProcessParamMapper.xml 51 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/productionPlan/SalesDeliveryMapper.xml 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/ÄþÏÄ-ÖÐÊ¢½¨²Ä.sql
@@ -304,54 +304,36 @@
-- 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',
    `order_id`         bigint                                                                 DEFAULT NULL 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,
    `process_param_id` bigint                                                                 DEFAULT NULL COMMENT '来源工序参数ID',
    `param_key`        varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci          DEFAULT NULL COMMENT '参数唯一标识',
    `param_name`       varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '参数名称',
    `param_type`       tinyint                                                       NOT NULL COMMENT '参数类型(1数字 2文本 3下拉选择 4时间)',
    `param_format`     varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci          DEFAULT NULL COMMENT '参数格式',
    `value_mode`       tinyint                                                                DEFAULT '1' COMMENT '值模式(1单值 2区间)',
    `unit`             varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci           DEFAULT NULL COMMENT '单位',
    `remark`           varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci          DEFAULT NULL COMMENT '备注',
    `standard_value`   varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci          DEFAULT NULL COMMENT '标准值',
    `min_value`        decimal(10, 2)                                                         DEFAULT NULL COMMENT '此路线节点设定的标准最小值',
    `max_value`        decimal(10, 2)                                                         DEFAULT NULL COMMENT '此路线节点设定的标准最大值',
    `is_required`      tinyint                                                       NOT NULL DEFAULT '0' COMMENT '是否必填',
    `sort`             int                                                           NOT NULL DEFAULT '0' COMMENT '排序',
    `tenant_id`        bigint                                                                 DEFAULT NULL COMMENT '租户ID',
    `create_time`      datetime                                                               DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    `update_time`      datetime                                                               DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    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
    KEY `idx_route_item_id` (`route_item_id`) USING BTREE,
    KEY `idx_param_key` (`param_key`)
) 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;
  AUTO_INCREMENT = 1
  DEFAULT CHARSET = utf8mb4
  COLLATE = utf8mb4_0900_ai_ci
  ROW_FORMAT = DYNAMIC COMMENT ='工艺路线工序参数实例表';
-- ----------------------------
-- Table structure for product_structure_instance
@@ -375,3 +357,70 @@
  ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
ALTER TABLE `process_route_item_instance`
    ADD COLUMN `order_id` bigint NOT NULL COMMENT '生产订单id' AFTER `id`,
    ADD INDEX `idx_order_id` (`order_id`);
ALTER TABLE `process_route_item_param_instance`
    ADD COLUMN `order_id` bigint NOT NULL COMMENT '生产订单id' AFTER `id`,
    ADD INDEX `idx_order_id` (`order_id`);
ALTER TABLE `product_structure_instance`
    ADD COLUMN `order_id` bigint NOT NULL COMMENT '生产订单id' AFTER `id`,
    ADD INDEX `idx_order_id` (`order_id`);
ALTER TABLE `product-inventory-management-zsjc`.`product_order`
    ADD COLUMN `strength` varchar(255) NULL COMMENT '产品类型' AFTER `plan_complete_time`;
CREATE TABLE `product-inventory-management-zsjc`.`sales_delivery`  (
   `id` int NOT NULL AUTO_INCREMENT,
   `delivery_date` date NULL COMMENT '供货日期',
   `delivery_code` varchar(255) NULL COMMENT '发货单编号',
    `project_name` varchar(255) NULL COMMENT '项目名称',
    `delivery_place` varchar(255) NULL COMMENT '送货地点',
    `link_man` varchar(255) NULL COMMENT '联系人',
    `link_phone` varchar(255) NULL COMMENT '联系电话',
    `delivery_remark` varchar(255) NULL COMMENT '发货备注',
    `material_code` varchar(255) NULL COMMENT '物料代码',
    `product_name` varchar(255) NULL COMMENT '产品名称',
    `model` varchar(255) NULL COMMENT '产品规格',
    `volume` decimal(10, 4) NULL COMMENT '方量',
    `unit_price` decimal(10, 2) NULL COMMENT '单价',
    `price` decimal(10, 2) NULL COMMENT 'ä»·æ ¼',
    `product_remark` varchar(255) NULL COMMENT '产品备注',
    `customer` varchar(255) NULL COMMENT '客户名称',
    `salesman` varchar(255) NULL COMMENT '业务员',
    `delivery_method` varchar(255) NULL COMMENT '发货方式',
    `form_instance_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '宜搭表单实例ID',
    `form_modified_time` datetime(0) NULL DEFAULT NULL COMMENT '宜搭修改时间',
    `create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
    `update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0),
    PRIMARY KEY (`id`)
    ) COMMENT = '销售发货明细(宜搭)';
ALTER TABLE product_process_param
    DROP COLUMN param_id;
ALTER TABLE product_process_param
    ADD COLUMN `param_key`    varchar(100) DEFAULT NULL COMMENT '参数唯一标识',
    ADD COLUMN `param_name`   varchar(100) NOT NULL COMMENT '参数名称',
    ADD COLUMN `param_type`   tinyint      NOT NULL COMMENT '参数类型(1数字 2文本 3下拉选择 4时间)',
    ADD COLUMN `param_format` varchar(255) DEFAULT NULL COMMENT '参数格式',
    ADD COLUMN `value_mode`   tinyint      DEFAULT '1' COMMENT '值模式(1单值 2区间)',
    ADD COLUMN `unit`         varchar(50)  DEFAULT NULL COMMENT '单位',
    ADD COLUMN `remark`       varchar(255) DEFAULT NULL COMMENT '备注';
ALTER TABLE process_route_item_param
    DROP COLUMN param_id;
ALTER TABLE process_route_item_param
    ADD COLUMN `param_key`    varchar(100) DEFAULT NULL COMMENT '参数唯一标识',
    ADD COLUMN `param_name`   varchar(100) NOT NULL COMMENT '参数名称',
    ADD COLUMN `param_type`   tinyint      NOT NULL COMMENT '参数类型(1数字 2文本 3下拉选择 4时间)',
    ADD COLUMN `param_format` varchar(255) DEFAULT NULL COMMENT '参数格式',
    ADD COLUMN `value_mode`   tinyint      DEFAULT '1' COMMENT '值模式(1单值 2区间)',
    ADD COLUMN `unit`         varchar(50)  DEFAULT NULL COMMENT '单位',
    ADD COLUMN `remark`       varchar(255) DEFAULT NULL COMMENT '备注';
src/main/java/com/ruoyi/CodeGenerator.java
@@ -23,7 +23,7 @@
    public static String database_username = "root";
    public static String database_password= "xd@123456..";
    public static String author = "芯导软件(江苏)有限公司";
    public static String model = "energy"; // æ¨¡å—
    public static String model = "productionPlan"; // æ¨¡å—
    public static String setParent = "com.ruoyi."+ model; // åŒ…路径
    public static String tablePrefix = ""; // è®¾ç½®è¿‡æ»¤è¡¨å‰ç¼€
    public static void main(String[] args) {
src/main/java/com/ruoyi/appendix/controller/AppendixController.java
@@ -1,8 +1,13 @@
package com.ruoyi.appendix.controller;
import com.ruoyi.appendix.service.AppendixService;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.production.pojo.ProductOrder;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
 * <br>
@@ -17,4 +22,15 @@
@RequestMapping("/appendix")
@Api("BOM-工艺路线附表控制层")
public class AppendixController {
    @Resource
    private AppendixService appendixService;
    @PostMapping("/bindingRoute")
    @ApiOperation("生产订单绑定工艺路线")
    public AjaxResult bindingRoute(@RequestBody ProductOrder productOrder) {
        appendixService.populateData(productOrder);
        return AjaxResult.success();
    }
}
src/main/java/com/ruoyi/appendix/controller/ProcessRouteItemInstanceController.java
@@ -1,8 +1,14 @@
package com.ruoyi.appendix.controller;
import com.ruoyi.appendix.dto.ProcessRouteItemInstanceDto;
import com.ruoyi.appendix.service.ProcessRouteItemInstanceService;
import com.ruoyi.framework.web.domain.AjaxResult;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
 * <br>
@@ -17,4 +23,43 @@
@RequestMapping("/processRouteItemInstance")
@Api("艺路线子集-附表控制层")
public class ProcessRouteItemInstanceController {
    @Resource
    private ProcessRouteItemInstanceService processRouteItemInstanceService;
    @GetMapping("/list/{orderId}")
    @ApiOperation("获取工序列表")
    public AjaxResult getProcessItem(@PathVariable Long orderId) {
        List<ProcessRouteItemInstanceDto> list = processRouteItemInstanceService.getProcessItem(orderId);
        return AjaxResult.success(list);
    }
    @PostMapping("add")
    @ApiOperation("新增工序")
    public AjaxResult addProcessItem(@RequestBody ProcessRouteItemInstanceDto dto) {
        processRouteItemInstanceService.addProcessItem(dto);
        return AjaxResult.success();
    }
    @PutMapping("/update")
    @ApiOperation("修改工序")
    public AjaxResult updateProcessItem(@RequestBody ProcessRouteItemInstanceDto dto) {
        processRouteItemInstanceService.updateProcessItem(dto);
        return AjaxResult.success();
    }
    @DeleteMapping("/delete/{id}")
    @ApiOperation("删除工序")
    public AjaxResult deleteProcessItem(@PathVariable Long id) {
        processRouteItemInstanceService.deleteProcessItem(id);
        return AjaxResult.success();
    }
    @PostMapping("/sort")
    @ApiOperation("工序排序")
    public AjaxResult sortProcessItem(@RequestBody ProcessRouteItemInstanceDto dto) {
        processRouteItemInstanceService.sortProcessItem(dto);
        return AjaxResult.success();
    }
}
src/main/java/com/ruoyi/appendix/controller/ProcessRouteItemParamInstanceController.java
@@ -1,8 +1,14 @@
package com.ruoyi.appendix.controller;
import com.ruoyi.appendix.dto.ProcessRouteItemParamInstanceDto;
import com.ruoyi.appendix.service.ProcessRouteItemParamInstanceService;
import com.ruoyi.framework.web.domain.AjaxResult;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
 * <br>
@@ -18,4 +24,37 @@
@RestController
@RequestMapping("/processRouteItemParamInstance")
public class ProcessRouteItemParamInstanceController {
    @Resource
    private ProcessRouteItemParamInstanceService processRouteItemParamInstanceService;
    @GetMapping("/list")
    @ApiOperation("生产订单-获取工序绑定的参数列表")
    public AjaxResult routeItemParamList(@RequestParam("orderId") Long orderId, @RequestParam("routeItemId") Long routeItemId) {
        List<ProcessRouteItemParamInstanceDto> list = processRouteItemParamInstanceService.routeItemParamList(orderId, routeItemId);
        return AjaxResult.success(list);
    }
    @PostMapping("/add")
    @ApiOperation("生产订单-工序新增参数")
    public AjaxResult addRouteItemParam(@RequestBody ProcessRouteItemParamInstanceDto dto) {
        processRouteItemParamInstanceService.addRouteItemParam(dto);
        return AjaxResult.success();
    }
    @PutMapping("/update")
    @ApiOperation("生产订单-工序更新参数")
    public AjaxResult updateRouteItemParam(@RequestBody ProcessRouteItemParamInstanceDto dto){
        processRouteItemParamInstanceService.updateRouteItemParam(dto);
        return AjaxResult.success();
    }
    @DeleteMapping("/delete/{id}")
    @ApiOperation("生产订单-工序删除参数")
    public AjaxResult deleteRouteItemParam(@PathVariable Long id) {
        processRouteItemParamInstanceService.deleteRouteItemParam(id);
        return AjaxResult.success();
    }
}
src/main/java/com/ruoyi/appendix/controller/ProductProcessParamInstanceController.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/appendix/controller/ProductStructureInstanceController.java
@@ -1,8 +1,14 @@
package com.ruoyi.appendix.controller;
import com.ruoyi.appendix.dto.ProductStructureInstanceDto;
import com.ruoyi.appendix.service.ProductStructureInstanceService;
import com.ruoyi.framework.web.domain.AjaxResult;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
 * <br>
@@ -17,4 +23,22 @@
@RestController
@RequestMapping("/productStructureInstance")
public class ProductStructureInstanceController {
    @Resource
    private ProductStructureInstanceService productStructureInstanceService;
    @GetMapping("/getBomStructs/{orderId}")
    @ApiOperation("根据生产订单ID获取绑定的BOM子集结构树")
    public AjaxResult getBomStructs(@PathVariable Long orderId) {
        List<ProductStructureInstanceDto> list = productStructureInstanceService.listByOrderId(orderId);
        return AjaxResult.success(list);
    }
    @PutMapping("/addOrUpdateBomStructs")
    @ApiOperation("新增/更新BOM子集结构")
    public AjaxResult addOrUpdateBomStructs(@RequestBody ProductStructureInstanceDto instanceDto) {
        productStructureInstanceService.addOrUpdateBomStructs(instanceDto);
        return AjaxResult.success();
    }
}
src/main/java/com/ruoyi/appendix/dto/ProcessRouteItemInstanceDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package com.ruoyi.appendix.dto;
import com.ruoyi.appendix.pojo.ProcessRouteItemInstance;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * <br>
 * å·¥è‰ºè·¯çº¿å­é›†-附表Dto
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/19 10:46
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class ProcessRouteItemInstanceDto extends ProcessRouteItemInstance {
    @ApiModelProperty("工序名称")
    private String processName;
}
src/main/java/com/ruoyi/appendix/dto/ProcessRouteItemParamInstanceDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package com.ruoyi.appendix.dto;
import com.ruoyi.appendix.pojo.ProcessRouteItemParamInstance;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * <br>
 *
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/19 11:49
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class ProcessRouteItemParamInstanceDto extends ProcessRouteItemParamInstance {
    @ApiModelProperty("工序ID")
    private Long processId;
}
src/main/java/com/ruoyi/appendix/dto/ProductStructureInstanceDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
package com.ruoyi.appendix.dto;
import com.ruoyi.appendix.pojo.ProductStructureInstance;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.ArrayList;
import java.util.List;
/**
 * <br>
 * BOM子集-附表Dto
 * </br>
 *
 * @author deslrey
 * @version 1.0
 * @since 2026/03/19 10:08
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class ProductStructureInstanceDto extends ProductStructureInstance {
    @ApiModelProperty("子类")
    private List<ProductStructureInstanceDto> children = new ArrayList<>();
    @ApiModelProperty("临时ID")
    private String tempId;
    @ApiModelProperty("父节点临时ID")
    private String parentTempId;
}
src/main/java/com/ruoyi/appendix/mapper/ProductProcessParamInstanceMapper.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/appendix/pojo/ProcessRouteItemInstance.java
@@ -28,6 +28,9 @@
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("生产订单id")
    private Long orderId;
    @ApiModelProperty("工艺路线id")
    private Long routeId;
src/main/java/com/ruoyi/appendix/pojo/ProcessRouteItemParamInstance.java
@@ -28,14 +28,32 @@
    @ApiModelProperty("主键ID")
    private Long id;
    @ApiModelProperty("生产订单id")
    private Long orderId;
    @ApiModelProperty("关联工艺路线明细ID")
    private Long routeItemId;
    @ApiModelProperty("关联基础参数定义ID")
    private Long paramId;
    @ApiModelProperty("参数唯一标识")
    private String paramKey;
    @ApiModelProperty("来源工序参数ID")
    private Long processParamId;
    @ApiModelProperty("参数名称")
    private String paramName;
    @ApiModelProperty("参数类型(1数字 2文本 3下拉选择 4时间)")
    private Integer paramType;
    @ApiModelProperty("参数格式")
    private String paramFormat;
    @ApiModelProperty("值模式(1单值 2区间)")
    private Integer valueMode;
    @ApiModelProperty("单位")
    private String unit;
    @ApiModelProperty("备注")
    private String remark;
    @ApiModelProperty("标准值")
    private String standardValue;
@@ -47,7 +65,7 @@
    private BigDecimal maxValue;
    @ApiModelProperty("是否必填")
    private Integer isRequired;
    private Boolean isRequired;
    @ApiModelProperty("排序")
    private Integer sort;
src/main/java/com/ruoyi/appendix/pojo/ProductProcessParamInstance.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/appendix/pojo/ProductStructureInstance.java
@@ -27,6 +27,9 @@
    @ApiModelProperty("主键ID")
    private Long id;
    @ApiModelProperty("生产订单id")
    private Long orderId;
    @ApiModelProperty("父节点ID")
    private Long parentId;
@@ -50,4 +53,5 @@
    @ApiModelProperty("BOM ID")
    private Long bomId;
}
src/main/java/com/ruoyi/appendix/service/AppendixService.java
@@ -1,5 +1,6 @@
package com.ruoyi.appendix.service;
import com.ruoyi.production.pojo.ProductOrder;
import com.ruoyi.productionPlan.dto.ProductionPlanDto;
/**
@@ -13,33 +14,33 @@
 */
public interface AppendixService {
    /**
     * å°†å¯¹åº”的工艺路线子集与绑定的BOM子集填充到附表中
     *
     * @param productOrderId ç”Ÿäº§è®¢å•ID
     * @param processRouteId å·¥è‰ºè·¯çº¿ID
     */
    void populateData(Long productOrderId, Long processRouteId);
    void populateData(ProductOrder productOrder);
    /**
     * ç»™ä¸‹å‘的砌块拉取对应的工艺路线子集与绑定的BOM子集填充到附表中
     *
     * @param orderId           ç”Ÿäº§è®¢å•ID
     * @param productionPlanDto äº§å“è¯¦æƒ…
     */
    Long populateBlocks(ProductionPlanDto productionPlanDto);
    Long populateBlocks(Long orderId, ProductionPlanDto productionPlanDto);
    /**
     * ç»™ä¸‹å‘的板材拉取对应的工艺路线子集与绑定的BOM子集填充到附表中
     * <p>
     *
     * @param orderId           ç”Ÿäº§è®¢å•ID
     * @param productionPlanDto äº§å“è¯¦æƒ…
     */
    Long populatePlates(ProductionPlanDto productionPlanDto);
    Long populatePlates(Long orderId, ProductionPlanDto productionPlanDto);
    /**
     * åˆ é™¤è¯¥è®¢å•携带的附表数据
     *
     * @param orderId        ç”Ÿäº§è®¢å•ID
     * @param processRouteId å·¥è‰ºè·¯çº¿ID
     */
    void deleteData(Long processRouteId);
    void deleteData(Long orderId, Long processRouteId);
}
src/main/java/com/ruoyi/appendix/service/ProcessRouteItemInstanceService.java
@@ -1,11 +1,14 @@
package com.ruoyi.appendix.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.appendix.dto.ProcessRouteItemInstanceDto;
import com.ruoyi.appendix.pojo.ProcessRouteItemInstance;
import java.util.List;
/**
 * <br>
 *工艺路线子集-附表Service
 * å·¥è‰ºè·¯çº¿å­é›†-附表Service
 * </br>
 *
 * @author deslrey
@@ -13,4 +16,13 @@
 * @since 2026/03/18 13:07
 */
public interface ProcessRouteItemInstanceService extends IService<ProcessRouteItemInstance> {
    List<ProcessRouteItemInstanceDto> getProcessItem(Long orderId);
    void addProcessItem(ProcessRouteItemInstanceDto dto);
    void updateProcessItem(ProcessRouteItemInstanceDto dto);
    void deleteProcessItem(Long id);
    void sortProcessItem(ProcessRouteItemInstanceDto dto);
}
src/main/java/com/ruoyi/appendix/service/ProcessRouteItemParamInstanceService.java
@@ -1,7 +1,10 @@
package com.ruoyi.appendix.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.appendix.dto.ProcessRouteItemParamInstanceDto;
import com.ruoyi.appendix.pojo.ProcessRouteItemParamInstance;
import java.util.List;
/**
 * <br>
@@ -13,4 +16,13 @@
 * @since 2026/03/18 13:11
 */
public interface ProcessRouteItemParamInstanceService extends IService<ProcessRouteItemParamInstance> {
    List<ProcessRouteItemParamInstanceDto> routeItemParamList(Long orderId, Long routeItemId);
    void addRouteItemParam(ProcessRouteItemParamInstanceDto dto);
    void updateRouteItemParam(ProcessRouteItemParamInstanceDto dto);
    void deleteRouteItemParam(Long id);
}
src/main/java/com/ruoyi/appendix/service/ProductProcessParamInstanceService.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/appendix/service/ProductStructureInstanceService.java
@@ -1,7 +1,10 @@
package com.ruoyi.appendix.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.appendix.dto.ProductStructureInstanceDto;
import com.ruoyi.appendix.pojo.ProductStructureInstance;
import java.util.List;
/**
 * <br>
@@ -13,4 +16,8 @@
 * @since 2026/03/18 13:21
 */
public interface ProductStructureInstanceService extends IService<ProductStructureInstance> {
    List<ProductStructureInstanceDto> listByOrderId(Long orderId);
    void addOrUpdateBomStructs(ProductStructureInstanceDto instanceDto);
}
src/main/java/com/ruoyi/appendix/service/impl/AppendixServiceImpl.java
@@ -3,9 +3,9 @@
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.basic.service.BaseParamService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.production.pojo.*;
@@ -16,7 +16,9 @@
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
@@ -39,10 +41,10 @@
    private ProcessRouteItemParamInstanceService processRouteItemParamInstanceService;
    @Resource
    private ProductProcessParamInstanceService productProcessParamInstanceService;
    private ProductStructureInstanceService productStructureInstanceService;
    @Resource
    private ProductStructureInstanceService productStructureInstanceService;
    private BaseParamService baseParamService;
    @Resource
    private ProcessRouteService processRouteService;
@@ -54,16 +56,13 @@
    private ProcessRouteItemParamService processRouteItemParamService;
    @Resource
    private ProductProcessParamService productProcessParamService;
    @Resource
    private ProductStructureService productStructureService;
    @Resource
    private ProductOrderService productOrderService;
    @Override
    public Long populateBlocks(ProductionPlanDto productionPlanDto) {
    public Long populateBlocks(Long orderId, ProductionPlanDto productionPlanDto) {
        if (productionPlanDto == null) {
            throw new ServiceException("下发数据不能为空");
        }
@@ -75,12 +74,12 @@
            log.info("下发产品【{}】未查询出工艺路线", productionPlanDto.getProductName());
            return null;
        }
        migration(processRoute);
        migration(orderId, processRoute);
        return processRoute.getId();
    }
    @Override
    public Long populatePlates(ProductionPlanDto productionPlanDto) {
    public Long populatePlates(Long orderId, ProductionPlanDto productionPlanDto) {
        if (productionPlanDto == null) {
            throw new ServiceException("下发数据不能为空");
        }
@@ -90,127 +89,141 @@
            log.info("下发产品【{}】未查询出工艺路线", productionPlanDto.getProductName());
            return null;
        }
        migration(processRoute);
        migration(orderId, 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;
    public void populateData(ProductOrder productOrder) {
        if (productOrder == null) {
            throw new ServiceException("绑定失败.数据不能为空");
        }
        migration(processRoute);
        if (productOrder.getId() == null || productOrder.getRouteId() == null) {
            throw new ServiceException("绑定失败,生产订单或工艺路线不能为空");
        }
        ProcessRoute processRoute = processRouteService.getById(productOrder.getRouteId());
        if (processRoute == null) {
            throw new ServiceException("该工艺路线不存在,绑定失败");
        }
        migration(productOrder.getId(), 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));
        }
    public void deleteData(Long orderId, Long processRouteId) {
        //  åˆ é™¤å·¥è‰ºè·¯çº¿å·¥åºå‚数附表
        processRouteItemParamInstanceService.remove(new LambdaQueryWrapper<ProcessRouteItemParamInstance>()
                .eq(ProcessRouteItemParamInstance::getOrderId, orderId));
        //  åˆ é™¤å·¥è‰ºè·¯çº¿å­é›†é™„表
        processRouteItemInstanceService.remove(
                new LambdaQueryWrapper<ProcessRouteItemInstance>().eq(ProcessRouteItemInstance::getRouteId, processRouteId));
        processRouteItemInstanceService.remove(new LambdaQueryWrapper<ProcessRouteItemInstance>()
                .eq(ProcessRouteItemInstance::getOrderId, orderId)
                .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()));
            productStructureInstanceService.remove(new LambdaQueryWrapper<ProductStructureInstance>()
                    .eq(ProductStructureInstance::getOrderId, orderId)
                    .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);
    private void migration(Long orderId, ProcessRoute processRoute) {
        //  è¿ç§»å·¥è‰ºè·¯çº¿å­é›†è¡¨æ•°æ®ï¼Œè¿”回旧id->新instance映射
        List<ProcessRouteItem> processRouteItemList = processRouteItemService.list(
                new LambdaQueryWrapper<ProcessRouteItem>().eq(ProcessRouteItem::getRouteId, processRoute.getId()));
        Map<Long, ProcessRouteItemInstance> routeItemOldIdMap = migrationProcessRouteItem(orderId, 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);
                ProcessRouteItemInstance newInstance = routeItemOldIdMap.get(item.getId());
                Long newRouteItemInstanceId = newInstance != null ? newInstance.getId() : item.getId();
                List<ProductProcessParam> processParamList = productProcessParamService.list(new LambdaQueryWrapper<ProductProcessParam>().eq(ProductProcessParam::getProcessId, item.getProcessId()));
                migrationProductProcessParam(processParamList);
                List<ProcessRouteItemParam> paramList = processRouteItemParamService.list(
                        new LambdaQueryWrapper<ProcessRouteItemParam>().eq(ProcessRouteItemParam::getRouteItemId, item.getId()));
                migrationProcessRouteItemParam(orderId, paramList, newRouteItemInstanceId);
            }
        }
        //  è¿ç§»BOM子集表数据
        if (processRoute.getBomId() != null) {
            List<ProductStructure> structureList = productStructureService.list(new LambdaQueryWrapper<ProductStructure>().eq(ProductStructure::getBomId, processRoute.getBomId()));
            migrationProductStructure(structureList);
            List<ProductStructure> structureList = productStructureService.list(
                    new LambdaQueryWrapper<ProductStructure>().eq(ProductStructure::getBomId, processRoute.getBomId()));
            migrationProductStructure(orderId, structureList);
        }
    }
    private void migrationProcessRouteItem(List<ProcessRouteItem> list) {
    private Map<Long, ProcessRouteItemInstance> migrationProcessRouteItem(Long orderId, List<ProcessRouteItem> list) {
        Map<Long, ProcessRouteItemInstance> oldIdMap = new HashMap<>();
        if (list == null || list.isEmpty()) {
            return;
            return oldIdMap;
        }
        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);
            instance.setOrderId(orderId);
            if (item.getId() != null) {
                oldIdMap.put(item.getId(), instance);
            }
            return instance;
        }).collect(Collectors.toList());
        processRouteItemInstanceService.saveBatch(instances);
        return oldIdMap;
    }
    private void migrationProcessRouteItemParam(List<ProcessRouteItemParam> list) {
    private void migrationProcessRouteItemParam(Long orderId, List<ProcessRouteItemParam> list, Long newRouteItemInstanceId) {
        if (list == null || list.isEmpty()) {
            return;
        }
        List<ProcessRouteItemParamInstance> instances = list.stream().map(item -> {
            ProcessRouteItemParamInstance instance = new ProcessRouteItemParamInstance();
            BeanUtils.copyProperties(item, instance, "id");
            instance.setOrderId(orderId);
            instance.setRouteItemId(newRouteItemInstanceId);
            return instance;
        }).collect(Collectors.toList());
        processRouteItemParamInstanceService.saveBatch(instances);
    }
    private void migrationProductProcessParam(List<ProductProcessParam> list) {
    private void migrationProductStructure(Long orderId, List<ProductStructure> 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;
        }
        Map<Long, ProductStructureInstance> oldIdMap = new HashMap<>();
        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);
            instance.setOrderId(orderId);
            if (item.getId() != null) {
                oldIdMap.put(item.getId(), instance);
            }
            return instance;
        }).collect(Collectors.toList());
        productStructureInstanceService.saveBatch(instances);
        //  æ–°å¢žåŽæœ‰id,旧id->新id,修正parentId
        Map<Long, Long> oldToNewId = new HashMap<>();
        list.forEach(item -> {
            if (item.getId() != null && oldIdMap.containsKey(item.getId())) {
                oldToNewId.put(item.getId(), oldIdMap.get(item.getId()).getId());
            }
        });
        List<ProductStructureInstance> toUpdate = instances.stream()
                .filter(i -> i.getParentId() != null && oldToNewId.containsKey(i.getParentId()))
                .peek(i -> i.setParentId(oldToNewId.get(i.getParentId())))
                .collect(Collectors.toList());
        if (!toUpdate.isEmpty()) {
            productStructureInstanceService.updateBatchById(toUpdate);
        }
    }
}
src/main/java/com/ruoyi/appendix/service/impl/ProcessRouteItemInstanceServiceImpl.java
@@ -1,11 +1,27 @@
package com.ruoyi.appendix.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.appendix.dto.ProcessRouteItemInstanceDto;
import com.ruoyi.appendix.mapper.ProcessRouteItemInstanceMapper;
import com.ruoyi.appendix.pojo.ProcessRouteItemInstance;
import com.ruoyi.appendix.pojo.ProcessRouteItemParamInstance;
import com.ruoyi.appendix.service.ProcessRouteItemInstanceService;
import com.ruoyi.appendix.service.ProcessRouteItemParamInstanceService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.production.pojo.ProcessRouteItemParam;
import com.ruoyi.production.pojo.ProductProcess;
import com.ruoyi.production.service.ProcessRouteItemParamService;
import com.ruoyi.production.service.ProductProcessService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <br>
@@ -20,5 +36,139 @@
@Service
public class ProcessRouteItemInstanceServiceImpl extends ServiceImpl<ProcessRouteItemInstanceMapper, ProcessRouteItemInstance> implements ProcessRouteItemInstanceService {
    @Resource
    private ProductProcessService productProcessService;
}
    @Resource
    private ProcessRouteItemParamInstanceService processRouteItemParamInstanceService;
    @Resource
    private ProcessRouteItemParamService processRouteItemParamService;
    @Override
    public List<ProcessRouteItemInstanceDto> getProcessItem(Long orderId) {
        List<ProcessRouteItemInstance> list = list(new LambdaQueryWrapper<ProcessRouteItemInstance>()
                .eq(ProcessRouteItemInstance::getOrderId, orderId)
                .orderByAsc(ProcessRouteItemInstance::getDragSort));
        return list.stream().map(item -> {
            ProcessRouteItemInstanceDto dto = new ProcessRouteItemInstanceDto();
            BeanUtils.copyProperties(item, dto);
            if (item.getProcessId() != null) {
                ProductProcess process = productProcessService.getById(item.getProcessId());
                if (process != null) {
                    dto.setProcessName(process.getName());
                }
            }
            return dto;
        }).collect(Collectors.toList());
    }
    @Override
    public void addProcessItem(ProcessRouteItemInstanceDto dto) {
        if (dto == null) {
            throw new ServiceException("新增数据不能为空");
        }
        if (dto.getOrderId() == null) {
            throw new ServiceException("生产订单ID不能为空");
        }
        if (dto.getProcessId() == null) {
            throw new ServiceException("工序ID不能为空");
        }
        ProcessRouteItemInstance entity = new ProcessRouteItemInstance();
        BeanUtils.copyProperties(dto, entity);
        entity.setId(null);
        entity.setTenantId(SecurityUtils.getLoginUser().getTenantId());
        entity.setCreateTime(LocalDateTime.now());
        //  å–当前订单下最大 dragSort + 1
        ProcessRouteItemInstance maxSortItem = getOne(new LambdaQueryWrapper<ProcessRouteItemInstance>()
                .eq(ProcessRouteItemInstance::getOrderId, dto.getOrderId())
                .orderByDesc(ProcessRouteItemInstance::getDragSort)
                .last("limit 1"));
        entity.setDragSort(maxSortItem != null && maxSortItem.getDragSort() != null ? maxSortItem.getDragSort() + 1 : 1);
        save(entity);
    }
    @Override
    public void updateProcessItem(ProcessRouteItemInstanceDto dto) {
        if (dto == null || dto.getId() == null) {
            throw new ServiceException("更新数据或ID不能为空");
        }
        ProcessRouteItemInstance old = getById(dto.getId());
        if (old == null) {
            throw new ServiceException("数据不存在");
        }
        // å·¥åºå˜æ›´ï¼Œåˆ é™¤æ—§å‚数附表,迁移新工序参数
        if (dto.getProcessId() != null && !dto.getProcessId().equals(old.getProcessId())) {
            // åˆ é™¤å·¥è‰ºè·¯çº¿å·¥åºå‚数附表
            processRouteItemParamInstanceService.remove(new LambdaQueryWrapper<ProcessRouteItemParamInstance>()
                    .eq(ProcessRouteItemParamInstance::getOrderId, old.getOrderId())
                    .eq(ProcessRouteItemParamInstance::getRouteItemId, old.getId()));
            // è¿ç§»æ–°å·¥åºçš„ process_route_item_param
            List<ProcessRouteItemParam> routeItemParams = processRouteItemParamService.list(
                    new LambdaQueryWrapper<ProcessRouteItemParam>().eq(ProcessRouteItemParam::getRouteItemId, old.getId()));
            if (!routeItemParams.isEmpty()) {
                List<ProcessRouteItemParamInstance> newInstances = routeItemParams.stream().map(p -> {
                    ProcessRouteItemParamInstance instance = new ProcessRouteItemParamInstance();
                    BeanUtils.copyProperties(p, instance, "id");
                    instance.setOrderId(old.getOrderId());
                    return instance;
                }).collect(Collectors.toList());
                processRouteItemParamInstanceService.saveBatch(newInstances);
            }
        }
        ProcessRouteItemInstance entity = new ProcessRouteItemInstance();
        BeanUtils.copyProperties(dto, entity);
        entity.setUpdateTime(LocalDateTime.now());
        updateById(entity);
    }
    @Override
    public void deleteProcessItem(Long id) {
        if (id == null) {
            throw new ServiceException("ID不能为空");
        }
        ProcessRouteItemInstance old = getById(id);
        if (old == null) {
            throw new ServiceException("数据不存在");
        }
        // åˆ é™¤å·¥è‰ºè·¯çº¿å·¥åºå‚数附表
        processRouteItemParamInstanceService.remove(new LambdaQueryWrapper<ProcessRouteItemParamInstance>()
                .eq(ProcessRouteItemParamInstance::getOrderId, old.getOrderId())
                .eq(ProcessRouteItemParamInstance::getRouteItemId, id));
        removeById(id);
    }
    @Override
    public void sortProcessItem(ProcessRouteItemInstanceDto dto) {
        if (dto == null || dto.getId() == null) {
            throw new ServiceException("数据或ID不能为空");
        }
        ProcessRouteItemInstance old = getById(dto.getId());
        if (old == null) {
            throw new ServiceException("数据不存在");
        }
        List<ProcessRouteItemInstance> items = list(new LambdaQueryWrapper<ProcessRouteItemInstance>()
                .eq(ProcessRouteItemInstance::getOrderId, old.getOrderId())
                .orderByAsc(ProcessRouteItemInstance::getDragSort));
        Integer targetPosition = dto.getDragSort();
        if (targetPosition != null && targetPosition >= 1) {
            items.removeIf(item -> item.getId().equals(old.getId()));
            items.add(targetPosition - 1, old);
            for (int i = 0; i < items.size(); i++) {
                ProcessRouteItemInstance item = items.get(i);
                int newSort = i + 1;
                if (!item.getId().equals(old.getId())) {
                    if (!Integer.valueOf(newSort).equals(item.getDragSort())) {
                        item.setDragSort(newSort);
                        updateById(item);
                    }
                } else {
                    old.setDragSort(newSort);
                    updateById(old);
                }
            }
        }
    }
}
src/main/java/com/ruoyi/appendix/service/impl/ProcessRouteItemParamInstanceServiceImpl.java
@@ -1,11 +1,21 @@
package com.ruoyi.appendix.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.appendix.dto.ProcessRouteItemParamInstanceDto;
import com.ruoyi.appendix.mapper.ProcessRouteItemParamInstanceMapper;
import com.ruoyi.appendix.pojo.ProcessRouteItemParamInstance;
import com.ruoyi.appendix.service.ProcessRouteItemParamInstanceService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <br>
@@ -19,4 +29,77 @@
@Slf4j
@Service
public class ProcessRouteItemParamInstanceServiceImpl extends ServiceImpl<ProcessRouteItemParamInstanceMapper, ProcessRouteItemParamInstance> implements ProcessRouteItemParamInstanceService {
}
    @Override
    public List<ProcessRouteItemParamInstanceDto> routeItemParamList(Long orderId, Long routeItemId) {
        List<ProcessRouteItemParamInstance> list = list(new LambdaQueryWrapper<ProcessRouteItemParamInstance>()
                .eq(ProcessRouteItemParamInstance::getOrderId, orderId)
                .eq(ProcessRouteItemParamInstance::getRouteItemId, routeItemId)
                .orderByAsc(ProcessRouteItemParamInstance::getSort));
        return list.stream().map(item -> {
            ProcessRouteItemParamInstanceDto dto = new ProcessRouteItemParamInstanceDto();
            BeanUtils.copyProperties(item, dto);
            return dto;
        }).collect(Collectors.toList());
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addRouteItemParam(ProcessRouteItemParamInstanceDto dto) {
        if (dto == null) {
            throw new ServiceException("新增数据不能为空");
        }
        if (dto.getOrderId() == null) {
            throw new ServiceException("生产订单ID不能为空");
        }
        if (dto.getRouteItemId() == null) {
            throw new ServiceException("工艺路线明细ID不能为空");
        }
        Long tenantId = SecurityUtils.getLoginUser().getTenantId();
        ProcessRouteItemParamInstance entity = new ProcessRouteItemParamInstance();
        BeanUtils.copyProperties(dto, entity);
        entity.setId(null);
        entity.setOrderId(dto.getOrderId());
        entity.setRouteItemId(dto.getRouteItemId());
        entity.setIsRequired(dto.getIsRequired());
        //  å–当前订单+路线明细下最大 sort + 1
        ProcessRouteItemParamInstance maxSortItem = getOne(new LambdaQueryWrapper<ProcessRouteItemParamInstance>()
                .select(ProcessRouteItemParamInstance::getSort)
                .eq(ProcessRouteItemParamInstance::getOrderId, dto.getOrderId())
                .eq(ProcessRouteItemParamInstance::getRouteItemId, dto.getRouteItemId())
                .orderByDesc(ProcessRouteItemParamInstance::getSort)
                .last("limit 1"));
        entity.setSort(maxSortItem != null && maxSortItem.getSort() != null ? maxSortItem.getSort() + 1 : 1);
        entity.setTenantId(tenantId);
        entity.setCreateTime(LocalDateTime.now());
        save(entity);
    }
    @Override
    public void updateRouteItemParam(ProcessRouteItemParamInstanceDto dto) {
        if (dto == null || dto.getId() == null) {
            throw new ServiceException("更新数据或ID不能为空");
        }
        if (getById(dto.getId()) == null) {
            throw new ServiceException("数据不存在");
        }
        ProcessRouteItemParamInstance entity = new ProcessRouteItemParamInstance();
        BeanUtils.copyProperties(dto, entity);
        entity.setUpdateTime(LocalDateTime.now());
        updateById(entity);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRouteItemParam(Long id) {
        if (id == null) {
            throw new ServiceException("ID不能为空");
        }
        if (getById(id) == null) {
            throw new ServiceException("数据不存在");
        }
        removeById(id);
    }
}
src/main/java/com/ruoyi/appendix/service/impl/ProductProcessParamInstanceServiceImpl.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/appendix/service/impl/ProductStructureInstanceServiceImpl.java
@@ -1,11 +1,23 @@
package com.ruoyi.appendix.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.appendix.dto.ProductStructureInstanceDto;
import com.ruoyi.appendix.mapper.ProductStructureInstanceMapper;
import com.ruoyi.appendix.pojo.ProductStructureInstance;
import com.ruoyi.appendix.service.ProductStructureInstanceService;
import com.ruoyi.common.utils.bean.BeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/**
 * <br>
@@ -19,4 +31,123 @@
@Slf4j
@Service
public class ProductStructureInstanceServiceImpl extends ServiceImpl<ProductStructureInstanceMapper, ProductStructureInstance> implements ProductStructureInstanceService {
    @Override
    public List<ProductStructureInstanceDto> listByOrderId(Long orderId) {
        List<ProductStructureInstance> list = list(new LambdaQueryWrapper<ProductStructureInstance>().eq(ProductStructureInstance::getOrderId, orderId));
        List<ProductStructureInstanceDto> dtoList = list.stream().map(item -> {
            ProductStructureInstanceDto dto = new ProductStructureInstanceDto();
            BeanUtils.copyProperties(item, dto);
            return dto;
        }).collect(java.util.stream.Collectors.toList());
        Map<Long, ProductStructureInstanceDto> map = new HashMap<>();
        for (ProductStructureInstanceDto node : dtoList) {
            map.put(node.getId(), node);
        }
        List<ProductStructureInstanceDto> tree = new ArrayList<>();
        for (ProductStructureInstanceDto node : dtoList) {
            Long parentId = node.getParentId();
            if (parentId == null || !map.containsKey(parentId)) {
                tree.add(node);
            } else {
                map.get(parentId).getChildren().add(node);
            }
        }
        return tree;
    }
    @Override
    public void addOrUpdateBomStructs(ProductStructureInstanceDto instanceDto) {
        Long orderId = instanceDto.getOrderId();
        // æ‰å¹³åŒ–前端传入的树
        List<ProductStructureInstanceDto> flatList = new ArrayList<>();
        flattenTree(instanceDto.getChildren(), flatList);
        // æŸ¥è¯¢æ•°æ®åº“已有数据
        List<ProductStructureInstance> dbList = list(new LambdaQueryWrapper<ProductStructureInstance>()
                .eq(ProductStructureInstance::getOrderId, orderId));
        // å‰ç«¯å·²æœ‰id集合
        Set<Long> frontendIds = flatList.stream()
                .map(ProductStructureInstanceDto::getId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        // éœ€è¦åˆ é™¤çš„节点
        Set<Long> deleteIds = dbList.stream()
                .map(ProductStructureInstance::getId)
                .filter(id -> !frontendIds.contains(id))
                .collect(Collectors.toSet());
        if (!deleteIds.isEmpty()) {
            removeByIds(deleteIds);
        }
        List<ProductStructureInstance> insertList = new ArrayList<>();
        List<ProductStructureInstance> updateList = new ArrayList<>();
        Map<String, ProductStructureInstance> tempEntityMap = new HashMap<>();
        for (ProductStructureInstanceDto dto : flatList) {
            ProductStructureInstance entity = new ProductStructureInstance();
            BeanUtils.copyProperties(dto, entity);
            entity.setOrderId(orderId);
            if (dto.getId() == null) {
                entity.setId(null);
                entity.setParentId(null);
                insertList.add(entity);
                if (dto.getTempId() != null) {
                    tempEntityMap.put(dto.getTempId(), entity);
                }
            } else {
                updateList.add(entity);
            }
        }
        if (!insertList.isEmpty()) {
            saveBatch(insertList);
        }
        // å›žå†™æ–°å¢žèŠ‚ç‚¹çš„ parentId
        List<ProductStructureInstance> parentFixList = new ArrayList<>();
        for (ProductStructureInstanceDto dto : flatList) {
            if (dto.getId() != null) continue;
            ProductStructureInstance 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 {
                    try {
                        realParentId = Long.valueOf(parentTempId);
                    } catch (NumberFormatException e) {
                        realParentId = 0L;
                    }
                }
                child.setParentId(realParentId);
            } else {
                child.setParentId(0L);
            }
            parentFixList.add(child);
        }
        if (!parentFixList.isEmpty()) {
            updateBatchById(parentFixList);
        }
        if (!updateList.isEmpty()) {
            updateBatchById(updateList);
        }
    }
    private void flattenTree(List<ProductStructureInstanceDto> source, List<ProductStructureInstanceDto> result) {
        if (source == null) return;
        for (ProductStructureInstanceDto node : source) {
            result.add(node);
            flattenTree(node.getChildren(), result);
        }
    }
}
src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
@@ -276,7 +276,7 @@
    @Override
    public void syncCustomerJob() {
        syncCustomerData(2);
        syncCustomerData();
    }
    @Override
@@ -322,11 +322,7 @@
     * åŒæ­¥æ•°æ®
     */
    @Transactional(rollbackFor = Exception.class)
    public void syncCustomerData(Integer dataSyncType) {
        if (!syncLock.tryLock()) {
            log.warn("同步正在进行中,本次 {} åŒæ­¥è¯·æ±‚被跳过", dataSyncType == 1 ? "手动" : "定时任务");
            return;
        }
    public void syncCustomerData() {
        try {
            JSONArray searchConditions = new JSONArray();
            JSONObject statusCondition = new JSONObject();
@@ -368,9 +364,6 @@
        } catch (Exception e) {
            log.error("同步客户信息异常", e);
        } finally {
            // é‡Šæ”¾é”
            syncLock.unlock();
        }
    }
src/main/java/com/ruoyi/basic/task/CustomerTask.java
@@ -11,7 +11,7 @@
    @Autowired
    private ICustomerService customerService;
    @Scheduled(cron = "0 0 * * * ?")
    @Scheduled(cron = "0 0 0 * * ?")
    public void syncCustomerDataJob() {
        customerService.syncCustomerJob();
    }
src/main/java/com/ruoyi/framework/config/AliDingConfig.java
@@ -58,6 +58,11 @@
    private String customerCodeFormUuid;
    /**
     * é”€å”®å‘货明细-宜搭表单ID
     */
    private String salesDeliveryFormUuid;
    /**
     * å®œæ­åº”用密钥
     * ç”¨äºŽè®¿é—®å®œæ­è¡¨å• API
     */
src/main/java/com/ruoyi/production/dto/ProductOrderDto.java
@@ -15,25 +15,29 @@
@ExcelIgnoreUnannotated
public class ProductOrderDto extends ProductOrder {
    @ApiModelProperty(value = "销售合同号")
    @Excel(name = "销售合同号")
    private String salesContractNo;
    @ApiModelProperty(value = "项目名")
    @Excel(name = "项目名")
    private String projectName;
    @ApiModelProperty(value = "客户名称")
    @Excel(name = "客户名称")
    private String customerName;
    @ApiModelProperty(value = "产品名称")
    @Excel(name = "产品名称")
    private String productCategory;
    private String productName;
    @ApiModelProperty(value = "规格")
    @Excel(name = "规格")
    private String specificationModel;
    private String model;
    @ApiModelProperty(value = "产品类型")
    @Excel(name = "产品类型")
    private String strength;
    @ApiModelProperty(value = "工艺路线描述")
    @Excel(name = "工艺路线描述")
    private String description;
    @ApiModelProperty(value = "工艺路线产品类型")
    @Excel(name = "工艺路线产品类型")
    private String dictLabel;
    @ApiModelProperty(value = "物料编码")
    @Excel(name = "物料编码")
    private String materialCode;
    @ApiModelProperty(value = "工艺路线编号")
    @Excel(name = "工艺路线编号")
@@ -43,6 +47,10 @@
    @Excel(name = "完成进度", suffix = "%")
    private BigDecimal completionStatus;
    @ApiModelProperty(value = "BOM ID")
    @Excel(name = "BOM ID")
    private String bomId;
    @ApiModelProperty(value = "BOM编号")
    @Excel(name = "BOM编号")
    private String bomNo;
src/main/java/com/ruoyi/production/dto/ProductProcessParamDto.java
@@ -3,10 +3,12 @@
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.production.pojo.ProductProcessParam;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
@@ -21,53 +23,8 @@
 * @since 2026/03/14 15:33
 */
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "ProductProcessParamDto对象", description = "工序绑定参数Dto")
public class ProductProcessParamDto {
public class ProductProcessParamDto extends ProductProcessParam {
    @ApiModelProperty("主键ID")
    private Long id;
    @ApiModelProperty("所属工序ID (product_process.id)")
    private Long processId;
    @ApiModelProperty("关联基础参数ID (base_param.id)")
    private Long paramId;
    @ApiModelProperty("在此工序设定的标准值(单值模式使用)")
    private String standardValue;
    @ApiModelProperty("在此工序设定的标准最小值(区间模式使用)")
    private BigDecimal minValue;
    @ApiModelProperty("在此工序设定的标准最大值(区间模式使用)")
    private BigDecimal maxValue;
    @ApiModelProperty("在此工序中是否必填(0-否, 1-是)")
    private Integer isRequired;
    @ApiModelProperty("排序号")
    private Integer sort;
    @ApiModelProperty("参数名称")
    private String paramName;
    @ApiModelProperty("参数类型(1数字 2文本 3下拉选择 4时间)")
    private Integer paramType;
    @ApiModelProperty("参数格式")
    private String paramFormat;
    @ApiModelProperty("值模式(1单值 2区间)")
    private Integer valueMode;
    @ApiModelProperty("单位")
    private String unit;
    @ApiModelProperty("创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;
    @ApiModelProperty("更新时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date updateTime;
}
src/main/java/com/ruoyi/production/pojo/ProcessRouteItemParam.java
@@ -34,8 +34,26 @@
    @ApiModelProperty("关联工艺路线明细ID (process_route_item.id)")
    private Long routeItemId;
    @ApiModelProperty("关联基础参数定义ID (base_param.id)")
    private Long paramId;
    @ApiModelProperty("参数唯一标识")
    private String paramKey;
    @ApiModelProperty("参数名称")
    private String paramName;
    @ApiModelProperty("参数类型(1数字 2文本 3下拉选择 4时间)")
    private Integer paramType;
    @ApiModelProperty("参数格式")
    private String paramFormat;
    @ApiModelProperty("值模式(1单值 2区间)")
    private Integer valueMode;
    @ApiModelProperty("单位")
    private String unit;
    @ApiModelProperty("备注")
    private String remark;
    @ApiModelProperty("来源工序参数ID")
    private Long processParamId;
@@ -50,7 +68,7 @@
    private BigDecimal maxValue;
    @ApiModelProperty("是否必填")
    private Integer isRequired;
    private Boolean isRequired;
    @ApiModelProperty("排序")
    private Integer sort;
src/main/java/com/ruoyi/production/pojo/ProductOrder.java
@@ -92,6 +92,10 @@
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime endTime;
    @Excel(name = "产品类型")
    @ApiModelProperty("产品类型")
    private String strength;
    @ApiModelProperty(value = "状态(1.待开始、2.进行中、3.已完成、4.已取消)")
    private Integer status;
}
src/main/java/com/ruoyi/production/pojo/ProductProcessParam.java
@@ -1,6 +1,7 @@
package com.ruoyi.production.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
@@ -30,10 +31,32 @@
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("参数唯一标识")
    private String paramKey;
    @ApiModelProperty("参数名称")
    private String paramName;
    @ApiModelProperty("参数类型(1数字 2文本 3下拉选择 4时间)")
    private Integer paramType;
    @ApiModelProperty("参数格式")
    private String paramFormat;
    @ApiModelProperty("值模式(1单值 2区间)")
    private Integer valueMode;
    @ApiModelProperty("单位")
    private String unit;
    @ApiModelProperty("备注")
    private String remark;
    @ApiModelProperty("所属工序ID (product_process.id)")
    private Long processId;
    @ApiModelProperty("关联基础参数ID (base_param.id)")
    @TableField(exist = false)
    private Long paramId;
    @ApiModelProperty("在此工序设定的标准值(单值模式使用)")
@@ -46,7 +69,7 @@
    private BigDecimal maxValue;
    @ApiModelProperty("在此工序中是否必填(0-否, 1-是)")
    private Integer isRequired;
    private Boolean isRequired;
    @ApiModelProperty("排序号")
    private Integer sort;
@@ -61,4 +84,4 @@
    @ApiModelProperty("更新时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date updateTime;
}
}
src/main/java/com/ruoyi/production/service/ProductOrderService.java
@@ -29,5 +29,7 @@
    Boolean addProductOrder(ProductOrder productOrder);
    Long insertProductOrder(ProductOrder productOrder);
    Boolean delete(Long[] id);
}
src/main/java/com/ruoyi/production/service/impl/ProcessRouteItemParamServiceImpl.java
@@ -4,8 +4,6 @@
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.basic.pojo.BaseParam;
import com.ruoyi.basic.service.BaseParamService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.production.dto.ProcessRouteItemParamDto;
@@ -13,7 +11,6 @@
import com.ruoyi.production.pojo.ProcessRouteItemParam;
import com.ruoyi.production.service.ProcessRouteItemParamService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -31,9 +28,6 @@
@Slf4j
@Service
public class ProcessRouteItemParamServiceImpl extends ServiceImpl<ProcessRouteItemParamMapper, ProcessRouteItemParam> implements ProcessRouteItemParamService {
    @Autowired
    private BaseParamService baseParamService;
    @Override
    public IPage<ProcessRouteItemParamDto> pageList(Page<ProcessRouteItemParam> page, ProcessRouteItemParam param) {
@@ -57,22 +51,17 @@
        if (param == null) {
            throw new ServiceException("新增失败,参数不能为空");
        }
        if (param.getRouteItemId() == null || param.getParamId() == null) {
            throw new ServiceException("关联工序ID和参数项ID不能为空");
        if (param.getRouteItemId() == null || param.getParamKey() == null) {
            throw new ServiceException("关联工序ID和参数标识不能为空");
        }
        Long tenantId = SecurityUtils.getLoginUser().getTenantId();
        Long count = baseMapper.selectCount(Wrappers.<ProcessRouteItemParam>lambdaQuery()
                .eq(ProcessRouteItemParam::getRouteItemId, param.getRouteItemId())
                .eq(ProcessRouteItemParam::getParamId, param.getParamId())
                .eq(ProcessRouteItemParam::getParamKey, param.getParamKey())
                .eq(ProcessRouteItemParam::getTenantId, tenantId));
        if (count > 0) {
            throw new ServiceException("该工序已存在此参数项,请勿重复添加");
        }
        BaseParam baseParam = baseParamService.getById(param.getParamId());
        if (baseParam == null) {
            throw new ServiceException("新增失败,改基础参数不存在");
            throw new ServiceException("该工序已存在参数项,请勿重复添加");
        }
        Integer maxSort = baseMapper.selectMaxSortByRouteItemId(param.getRouteItemId());
src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
@@ -170,14 +170,24 @@
    @Override
    public Boolean addProductOrder(ProductOrder productOrder) {
        String string = generateNextOrderNo(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
        productOrder.setNpsNo(string);
        fillAndSaveProductOrder(productOrder);
        return true;
    }
    @Override
    public Long insertProductOrder(ProductOrder productOrder) {
        fillAndSaveProductOrder(productOrder);
        return productOrder.getId();
    }
    private void fillAndSaveProductOrder(ProductOrder productOrder) {
        String orderNo = generateNextOrderNo(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
        productOrder.setNpsNo(orderNo);
        productOrder.setCompleteQuantity(BigDecimal.ZERO);
        this.save(productOrder);
        if (ObjectUtils.isNotEmpty(productOrder.getRouteId())) {
            this.bindingRoute(productOrder);
        }
        return true;
    }
    @Override
@@ -248,7 +258,7 @@
        //  åˆ é™¤é™„表的工艺路线与BOM
        for (Long id : ids) {
            ProductOrder productOrder = baseMapper.selectById(id);
            appendixService.deleteData(productOrder.getRouteId());
            appendixService.deleteData(productOrder.getId(), productOrder.getRouteId());
        }
//        productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>().in(ProductProcessRouteItem::getProductOrderId, ids));
src/main/java/com/ruoyi/production/service/impl/ProductProcessParamServiceImpl.java
@@ -1,6 +1,8 @@
package com.ruoyi.production.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.mapper.BaseParamMapper;
import com.ruoyi.basic.pojo.BaseParam;
import com.ruoyi.basic.service.BaseParamService;
import com.ruoyi.production.dto.ProductProcessParamDto;
import com.ruoyi.production.dto.ProductProcessParamSortDTO;
@@ -29,7 +31,7 @@
public class ProductProcessParamServiceImpl extends ServiceImpl<ProductProcessParamMapper, ProductProcessParam> implements ProductProcessParamService {
    @Autowired
    private BaseParamService baseParamService;
    BaseParamMapper baseParamMapper;
    @Override
    public List<ProductProcessParamDto> listByProcessId(Long processId) {
@@ -47,6 +49,12 @@
        if (productProcessParam.getParamId() == null) {
            throw new IllegalArgumentException("关联基础参数ID不能为空");
        }
        BaseParam baseParam = baseParamMapper.selectById(productProcessParam.getParamId());
        productProcessParam.setParamKey(baseParam.getParamKey());
        productProcessParam.setParamName(baseParam.getParamName());
        productProcessParam.setParamType(baseParam.getParamType());
        productProcessParam.setParamFormat(baseParam.getParamFormat());
        productProcessParam.setUnit(baseParam.getUnit());
        productProcessParam.setCreateTime(new Date());
        if (!this.save(productProcessParam)) {
            throw new RuntimeException("新增失败");
src/main/java/com/ruoyi/productionPlan/controller/SalesDeliveryController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.productionPlan.controller;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 * é”€å”®å‘货明细(宜搭) å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-19 11:49:57
 */
@RestController
@RequestMapping("/salesDelivery")
@Api(tags = "销售发货明细")
public class SalesDeliveryController {
}
src/main/java/com/ruoyi/productionPlan/dto/ProductionPlanDto.java
@@ -55,4 +55,5 @@
     */
    @ApiModelProperty("关联物料信息表ID")
    private Long productMaterialId;
}
src/main/java/com/ruoyi/productionPlan/mapper/SalesDeliveryMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.productionPlan.mapper;
import com.ruoyi.productionPlan.pojo.SalesDelivery;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
 * <p>
 * é”€å”®å‘货明细(宜搭) Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-19 11:49:57
 */
@Mapper
public interface SalesDeliveryMapper extends BaseMapper<SalesDelivery> {
}
src/main/java/com/ruoyi/productionPlan/pojo/SalesDelivery.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,105 @@
package com.ruoyi.productionPlan.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
/**
 * <p>
 * é”€å”®å‘货明细(宜搭)
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-19 11:49:57
 */
@Getter
@Setter
@TableName("sales_delivery")
@ApiModel(value = "SalesDelivery对象", description = "销售发货明细(宜搭)")
public class SalesDelivery implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty("供货日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate deliveryDate;
    @ApiModelProperty("发货单编号")
    private String deliveryCode;
    @ApiModelProperty("项目名称")
    private String projectName;
    @ApiModelProperty("送货地点")
    private String deliveryPlace;
    @ApiModelProperty("联系人")
    private String linkMan;
    @ApiModelProperty("联系电话")
    private String linkPhone;
    @ApiModelProperty("发货备注")
    private String deliveryRemark;
    @ApiModelProperty("物料代码")
    private String materialCode;
    @ApiModelProperty("产品名称")
    private String productName;
    @ApiModelProperty("产品规格")
    private String model;
    @ApiModelProperty("方量")
    private BigDecimal volume;
    @ApiModelProperty("单价")
    private BigDecimal unitPrice;
    @ApiModelProperty("ä»·æ ¼")
    private BigDecimal price;
    @ApiModelProperty("产品备注")
    private String productRemark;
    @ApiModelProperty("客户名称")
    private String customer;
    @ApiModelProperty("业务员")
    private String salesman;
    @ApiModelProperty("发货方式")
    private String deliveryMethod;
    @ApiModelProperty("宜搭表单实例ID")
    private String formInstanceId;
    @ApiModelProperty("宜搭修改时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime formModifiedTime;
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
}
src/main/java/com/ruoyi/productionPlan/service/SalesDeliveryService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.productionPlan.service;
import com.ruoyi.productionPlan.pojo.SalesDelivery;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * é”€å”®å‘货明细(宜搭) æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-19 11:49:57
 */
public interface SalesDeliveryService extends IService<SalesDelivery> {
    void syncSalesDeliveryJob();
}
src/main/java/com/ruoyi/productionPlan/service/impl/ProductionPlanServiceImpl.java
@@ -147,15 +147,19 @@
        productOrder.setQuantity(productionPlanDto.getTotalAssignedQuantity());
        productOrder.setPlanCompleteTime(productionPlanDto.getPlanCompleteTime());
        productOrder.setStatus(ProductOrderStatusEnum.WAIT.getCode());
        productOrder.setStrength(productionPlanDto.getStrength());
        Long orderId = productOrderService.insertProductOrder(productOrder);
        //  å½“下发的产品为砌块或板材,就拉取BOM子集与工艺路线子集数据存入到附表中
        if ("砌块".equals(productionPlanDto.getProductName())) {
            productOrder.setRouteId(appendixService.populateBlocks(productionPlanDto));
            productOrder.setRouteId(appendixService.populateBlocks(orderId, productionPlanDto));
        }
        if ("板材".equals(productionPlanDto.getProductName())) {
            productOrder.setRouteId(appendixService.populatePlates(productionPlanDto));
            productOrder.setRouteId(appendixService.populatePlates(orderId, productionPlanDto));
        }
        productOrderService.addProductOrder(productOrder);
        //  æ›´æ–°ç»‘定的工艺路线
        productOrderService.updateById(productOrder);
        // æ ¹æ®ä¸‹å‘数量,从第一个生产计划开始分配方数
        BigDecimal assignedVolume = BigDecimal.ZERO;
src/main/java/com/ruoyi/productionPlan/service/impl/SalesDeliveryServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,176 @@
package com.ruoyi.productionPlan.service.impl;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.config.AliDingConfig;
import com.ruoyi.framework.util.AliDingUtils;
import com.ruoyi.production.pojo.ProductMaterialSku;
import com.ruoyi.productionPlan.enums.DataSourceTypeEnum;
import com.ruoyi.productionPlan.pojo.ProductionPlan;
import com.ruoyi.productionPlan.pojo.SalesDelivery;
import com.ruoyi.productionPlan.mapper.SalesDeliveryMapper;
import com.ruoyi.productionPlan.service.SalesDeliveryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
 * <p>
 * é”€å”®å‘货明细(宜搭) æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-19 11:49:57
 */
@Service
@Slf4j
public class SalesDeliveryServiceImpl extends ServiceImpl<SalesDeliveryMapper, SalesDelivery> implements SalesDeliveryService {
    @Autowired
    private SalesDeliveryMapper salesDeliveryMapper;
    @Autowired
    private AliDingConfig aliDingConfig;
    @Override
    public void syncSalesDeliveryJob() {
        syncSalesDelivery();
    }
    /**
     * åŒæ­¥æ•°æ®
     */
    @Transactional(rollbackFor = Exception.class)
    public void syncSalesDelivery() {
        try {
            JSONArray searchConditions = new JSONArray();
            JSONObject condition = new JSONObject();
            condition.put("key", "processApprovedResult");
            JSONArray valueArray = new JSONArray();
            valueArray.add("agree");
            condition.put("value", valueArray);
            condition.put("type", "ARRAY");
            condition.put("operator", "in");
            condition.put("componentName", "SelectField");
            searchConditions.add(condition);
            JSONObject statusCondition = new JSONObject();
            statusCondition.put("key", "processInstanceStatus");
            JSONArray statusValueArray = new JSONArray();
            statusValueArray.add("COMPLETED");
            statusCondition.put("value", statusValueArray);
            statusCondition.put("type", "ARRAY");
            statusCondition.put("operator", "in");
            statusCondition.put("componentName", "SelectField");
            searchConditions.add(statusCondition);
            String searchFieldJson = searchConditions.toJSONString();
            JSONArray dataArr = AliDingUtils.getFormDataList(aliDingConfig, aliDingConfig.getSalesDeliveryFormUuid(), searchFieldJson, this, SalesDelivery::getFormModifiedTime);
            if (dataArr.isEmpty()) {
                return;
            }
            //  è§£æžå¹¶ä¿å­˜æ•°æ®
            List<SalesDelivery> list = parseSalesDeliverys(dataArr);
            if (!list.isEmpty()) {
                //  å¤„理更新或新增
                int affected = processSaveOrUpdate(list);
                log.info("数据同步完成,共同步 {} æ¡æ•°æ®", affected);
            }
        } catch (Exception e) {
            log.error("同步生产计划异常", e);
        }
    }
    private List<SalesDelivery> parseSalesDeliverys(JSONArray dataArr) {
        List<SalesDelivery> list = new ArrayList<>();
        for (int i = 0; i < dataArr.size(); i++) {
            JSONObject item = dataArr.getJSONObject(i);
            String formInstanceId = item.getString("formInstanceId");
            JSONObject formData = item.getJSONObject("formData");
            JSONArray tableArr = formData.getJSONArray("tableField_kt8b0qse");
            if (tableArr == null || tableArr.isEmpty()) {
                continue;
            }
            for (int j = 0; j < tableArr.size(); j++) {
                JSONObject row = tableArr.getJSONObject(j);
                SalesDelivery salesDelivery = new SalesDelivery();
                salesDelivery.setFormInstanceId(formInstanceId);
                Long time = formData.getLong("dateField_kt8b0qsm");
                LocalDate date = Instant.ofEpochMilli(time).atZone(ZoneId.of("Asia/Shanghai")).toLocalDate();
                salesDelivery.setDeliveryDate(date);//供货日期
                salesDelivery.setDeliveryCode(formData.getString("textField_kt8b0qrp"));//发货单编号
                salesDelivery.setProjectName(formData.getString("textField_l92dg1tg"));//项目名称
                salesDelivery.setDeliveryPlace(formData.getString("textField_kt8b0qsd"));//送货地点
                salesDelivery.setLinkMan(formData.getString("textField_kt8b0qsb"));//联系人
                salesDelivery.setLinkPhone(formData.getString("textField_kt8b0qsc"));//联系电话
                salesDelivery.setDeliveryRemark(formData.getString("textareaField_kt8b0qsl"));//发货备注
                salesDelivery.setCustomer(formData.getString("textField_la98q3sg"));//客户名称
                salesDelivery.setSalesman(formData.getString("textField_ladnkyu1"));//业务员
                salesDelivery.setDeliveryMethod(formData.getString("radioField_ldoc0027"));//发货方式
                String materialCode = row.getString("textField_l92dg1tc");
                // æ ¹æ®ç‰©æ–™ç¼–码查询物料信息表,关联物料ID
//                if (StringUtils.isNotEmpty(materialCode)) {
//                    LambdaQueryWrapper<ProductMaterialSku> skuQueryWrapper = new LambdaQueryWrapper<>();
//                    skuQueryWrapper.eq(ProductMaterialSku::getMaterialCode, materialCode);
//                    ProductMaterialSku sku = productMaterialSkuService.getOne(skuQueryWrapper);
//                    if (sku != null) {
//                        salesDelivery.setProductMaterialSkuId(sku.getId());
//                    }
//                }
                salesDelivery.setMaterialCode(materialCode);//物料编码
                salesDelivery.setProductName(row.getString("textField_l96srw8x"));//产品名称
                salesDelivery.setModel(row.getString("textField_l9tljfl8"));//产品规格
                salesDelivery.setVolume(row.getBigDecimal("numberField_kt8b0qsg_value"));//方量
                salesDelivery.setUnitPrice(row.getBigDecimal("numberField_la0tb2x9_value"));//单价
                salesDelivery.setPrice(row.getBigDecimal("numberField_l9w2piwf"));//ä»·æ ¼
                salesDelivery.setProductRemark(row.getString("textField_kt8b0qsi"));//产品备注
                salesDelivery.setFormModifiedTime(AliDingUtils.parseUtcTime(item.getString("modifiedTimeGMT")));
                list.add(salesDelivery);
            }
        }
        return list;
    }
    private int processSaveOrUpdate(List<SalesDelivery> list) {
        if (list == null || list.isEmpty()) {
            return 0;
        }
        int affected = 0;
        for (SalesDelivery salesDelivery : list) {
            LambdaQueryWrapper<SalesDelivery> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SalesDelivery::getFormInstanceId, salesDelivery.getFormInstanceId());
            SalesDelivery exist = this.getOne(wrapper);
            if (exist == null) {
                this.save(salesDelivery);
                affected++;
            } else {
                if (exist.getFormModifiedTime() == null || !exist.getFormModifiedTime().equals(salesDelivery.getFormModifiedTime())) {
                    salesDelivery.setId(exist.getId());
                    this.updateById(salesDelivery);
                    affected++;
                }
            }
        }
        return affected;
    }
}
src/main/java/com/ruoyi/productionPlan/task/SalesDeliveryTask.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.ruoyi.productionPlan.task;
import com.ruoyi.productionPlan.service.ProductionPlanService;
import com.ruoyi.productionPlan.service.SalesDeliveryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
//销售发货明细对接宜搭定时任务
@Component
public class SalesDeliveryTask {
    @Autowired
    private SalesDeliveryService salesDeliveryService;
    @Scheduled(cron = "0 0 0 * * ?")
    public void syncSalesDeliveryJob() {
        salesDeliveryService.syncSalesDeliveryJob();
    }
}
src/main/resources/application-zsjc.yml
@@ -33,6 +33,7 @@
    produce-plan-form-uuid: "FORM-4IA66891C5H3QWMDBSGO05C0OX9628GRPYF7L8"
    material-code-form-uuid: "FORM-8I666N718RW4ALO4ETYDDB0U6U8T3EIWTQ0ALL1"
    customer-code-form-uuid: "FORM-4V966QC1M8B5W4Q89M1VL4ZURJ6C3FVA021ALE"
    sales-delivery-form-uuid: "FORM-78766VC18V25CTDL82XSZBXKHBPX3BVEHI6ALE2"
    system-token: "4J766L91OFH3V612E7LG5B4DI8M13MQF9VF7LG4"
    # æŽ¥å£åœ°å€
    access-token-url: "https://oapi.dingtalk.com/gettoken"
src/main/resources/mapper/appendix/ProcessRouteItemInstanceMapper.xml
@@ -7,6 +7,7 @@
    <resultMap id="ProcessRouteItemInstanceMap" type="com.ruoyi.appendix.pojo.ProcessRouteItemInstance">
        <id property="id" column="id"/>
        <result property="orderId" column="order_id"/>
        <result property="routeId" column="route_id"/>
        <result property="productModelId" column="product_model_id"/>
        <result property="processId" column="process_id"/>
src/main/resources/mapper/appendix/ProcessRouteItemParamInstanceMapper.xml
@@ -7,9 +7,15 @@
    <resultMap id="BaseResultMap" type="com.ruoyi.appendix.pojo.ProcessRouteItemParamInstance">
        <id property="id" column="id"/>
        <result property="orderId" column="order_id"/>
        <result property="routeItemId" column="route_item_id"/>
        <result property="paramId" column="param_id"/>
        <result property="processParamId" column="process_param_id"/>
        <result property="paramKey" column="param_key"/>
        <result property="paramName" column="param_name"/>
        <result property="paramType" column="param_type"/>
        <result property="paramFormat" column="param_format"/>
        <result property="valueMode" column="value_mode"/>
        <result property="unit" column="unit"/>
        <result property="remark" column="remark"/>
        <result property="standardValue" column="standard_value"/>
        <result property="minValue" column="min_value"/>
        <result property="maxValue" column="max_value"/>
src/main/resources/mapper/appendix/ProductProcessParamInstanceMapper.xml
ÎļþÒÑɾ³ý
src/main/resources/mapper/appendix/ProductStructureInstanceMapper.xml
@@ -7,6 +7,7 @@
    <resultMap id="BaseResultMap" type="com.ruoyi.appendix.pojo.ProductStructureInstance">
        <id property="id" column="id"/>
        <result property="orderId" column="order_id"/>
        <result property="parentId" column="parent_id"/>
        <result property="productModelId" column="product_model_id"/>
        <result property="processId" column="process_id"/>
src/main/resources/mapper/production/ProcessRouteItemParamMapper.xml
@@ -7,7 +7,6 @@
    <resultMap id="ProcessRouteItemParamResultMap" type="com.ruoyi.production.pojo.ProcessRouteItemParam">
        <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"/>
@@ -17,37 +16,56 @@
        <result property="tenantId" column="tenant_id"/>
        <result property="createTime" column="create_time"/>
        <result property="updateTime" column="update_time"/>
        <result property="paramKey" column="param_key"/>
        <result property="paramName" column="param_name"/>
        <result property="paramType" column="param_type"/>
        <result property="paramFormat" column="param_format"/>
        <result property="valueMode" column="value_mode"/>
        <result property="unit" column="unit"/>
        <result property="remark" column="remark"/>
    </resultMap>
    <insert id="insertFromProcessTemplate">
        INSERT INTO process_route_item_param (route_item_id, param_id, process_param_id,
                                              standard_value, min_value, max_value,
                                              is_required, sort, tenant_id, create_time)
        INSERT INTO process_route_item_param (route_item_id,
                                              process_param_id,
                                              standard_value,
                                              min_value,
                                              max_value,
                                              is_required,
                                              sort,
                                              tenant_id,
                                              create_time,
                                              param_key,
                                              param_name,
                                              param_type,
                                              param_format,
                                              value_mode,
                                              unit,
                                              remark)
        SELECT #{routeItemId},
               param_id,
               id,
               standard_value,
               min_value,
               max_value,
               is_required,
               sort,
               ppp.id,
               ppp.standard_value,
               ppp.min_value,
               ppp.max_value,
               ppp.is_required,
               ppp.sort,
               #{tenantId},
               NOW()
        FROM product_process_param
        WHERE process_id = #{processId}
               NOW(),
               ppp.param_key,
               ppp.param_name,
               ppp.param_type,
               ppp.param_format,
               ppp.value_mode,
               ppp.unit,
               ppp.remark
        FROM product_process_param ppp
        WHERE ppp.process_id = #{processId}
    </insert>
    <select id="selectParamPage" resultType="com.ruoyi.production.dto.ProcessRouteItemParamDto">
        select
        prip.*,
        bp.param_name,
        bp.param_key,
        bp.unit,
        bp.param_type,
        bp.param_format,
        bp.value_mode
        prip.*
        from process_route_item_param prip
        left join base_param bp on prip.param_id = bp.id
        <where>
            <if test="p.routeItemId != null">
                and prip.route_item_id = #{p.routeItemId}
src/main/resources/mapper/production/ProductOrderMapper.xml
@@ -15,23 +15,45 @@
    </resultMap>
    <select id="pageProductOrder" resultType="com.ruoyi.production.dto.ProductOrderDto">
        select po.*,
        ppr.process_route_code,
        ROUND(po.complete_quantity / po.quantity * 100, 2) AS completionStatus
        from product_order po
        left join product_process_route ppr on po.id = ppr.product_order_id
        SELECT
        po.id,
        po.nps_no,
        po.tenant_id,
        po.create_time,
        po.update_time,
        po.route_id,
        po.quantity,
        po.complete_quantity,
        po.start_time,
        po.end_time,
        po.plan_complete_time,
        po.status,
        pm.product_name,
        po.strength AS strength,
        pr.process_route_code AS processRouteCode,
        pr.description,
        pb.id AS bomId,
        pb.bom_no AS bomNo,
        ROUND(po.complete_quantity / po.quantity * 100, 2) AS completionStatus,
        pms.model,
        pms.material_code AS materialCode
        FROM product_order po
        LEFT JOIN process_route pr ON po.route_id = pr.id
        LEFT JOIN product_bom pb ON pr.bom_id = pb.id
        LEFT JOIN product_order_plan pop ON po.id = pop.product_order_id
        LEFT JOIN production_plan pp ON pop.production_plan_id = pp.id
        LEFT JOIN product_material_sku pms ON pms.id = pp.product_material_sku_id
        LEFT JOIN product_material pm ON pm.id = pms.product_id
        <where>
            <if test="c.npsNo != null and c.npsNo != ''">
                and po.nps_no like concat('%',#{c.npsNo},'%')
            </if>
            <if test="c.customerName != null and c.customerName != ''">
                and sl.customer_name like concat('%',#{c.customerName},'%')
                AND po.nps_no LIKE CONCAT('%', #{c.npsNo}, '%')
            </if>
            <if test="c.startTime != null and c.endTime != null">
                and po.create_time between #{c.startTime} and #{c.endTime}
                AND po.create_time BETWEEN #{c.startTime} AND #{c.endTime}
            </if>
        </where>
    </select>
    <select id="listProcessRoute" resultType="com.ruoyi.production.pojo.ProcessRoute">
        select pr.*
        from process_route pr
@@ -46,35 +68,40 @@
               ps.unit_quantity * po.quantity as demandedQuantity,
               ps.unit,
               p.product_name,
               pp.name as  process_name,
               pp.name                        as process_name,
               pm.product_id,
               pm.model
        from
            product_structure ps
                left join product_model pm on ps.product_model_id = pm.id
                left join product p on pm.product_id = p.id
                left join product_process pp on ps.process_id = pp.id
                left join product_process_route ppr on ps.bom_id = ppr.bom_id
                left join product_order po on po.id = ppr.product_order_id
        from product_structure ps
                 left join product_model pm on ps.product_model_id = pm.id
                 left join product p on pm.product_id = p.id
                 left join product_process pp on ps.process_id = pp.id
                 left join product_process_route ppr on ps.bom_id = ppr.bom_id
                 left join product_order po on po.id = ppr.product_order_id
        where ppr.product_order_id = #{orderId}
        order by ps.id
    </select>
    <select id="countCreated" resultType="java.lang.Integer">
        SELECT count(1) FROM product_order
        WHERE create_time &gt;= #{startDate} AND create_time &lt;= #{endDate}
        SELECT count(1)
        FROM product_order
        WHERE create_time &gt;= #{startDate}
          AND create_time &lt;= #{endDate}
    </select>
    <select id="countCompleted" resultType="java.lang.Integer">
        SELECT count(1) FROM product_order
        WHERE end_time &gt;= #{startDate} AND end_time &lt;= #{endDate}
        SELECT count(1)
        FROM product_order
        WHERE end_time &gt;= #{startDate}
          AND end_time &lt;= #{endDate}
          AND complete_quantity &gt;= quantity
    </select>
    <select id="countPending" resultType="java.lang.Integer">
        SELECT count(1) FROM product_order
        WHERE create_time &gt;= #{startDate} AND create_time &lt;= #{endDate}
        SELECT count(1)
        FROM product_order
        WHERE create_time &gt;= #{startDate}
          AND create_time &lt;= #{endDate}
          AND complete_quantity &lt; quantity
    </select>
</mapper>
src/main/resources/mapper/production/ProductProcessParamMapper.xml
@@ -1,13 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<?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.production.mapper.ProductProcessParamMapper">
    <resultMap id="ProductProcessParamResult" type="com.ruoyi.production.pojo.ProductProcessParam">
        <id property="id" column="id"/>
        <result property="processId" column="process_id"/>
        <result property="paramId" column="param_id"/>
        <result property="paramKey" column="param_key"/>
        <result property="paramName" column="param_name"/>
        <result property="paramType" column="param_type"/>
        <result property="paramFormat" column="param_format"/>
        <result property="valueMode" column="value_mode"/>
        <result property="unit" column="unit"/>
        <result property="remark" column="remark"/>
        <result property="standardValue" column="standard_value"/>
        <result property="minValue" column="min_value"/>
        <result property="maxValue" column="max_value"/>
@@ -20,26 +24,25 @@
    <select id="selectDtoListByProcessId" resultType="com.ruoyi.production.dto.ProductProcessParamDto"
            parameterType="java.lang.Long">
        SELECT ppp.id,
               ppp.process_id,
               ppp.param_id,
               ppp.standard_value,
               ppp.min_value,
               ppp.max_value,
               ppp.is_required,
               ppp.sort,
               ppp.create_time,
               ppp.update_time,
               bp.param_name,
               bp.param_type,
               bp.param_format,
               bp.value_mode,
               bp.unit
        FROM product_process_param ppp
                 LEFT JOIN base_param bp ON ppp.param_id = bp.id
        WHERE ppp.process_id = #{processId}
        ORDER BY ppp.sort ASC
        SELECT id,
               process_id,
               param_key,
               param_name,
               param_type,
               param_format,
               value_mode,
               unit,
               remark,
               standard_value,
               min_value,
               max_value,
               is_required,
               sort,
               create_time,
               update_time
        FROM product_process_param
        WHERE process_id = #{processId}
        ORDER BY sort ASC
    </select>
</mapper>
src/main/resources/mapper/productionPlan/SalesDeliveryMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
<?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.productionPlan.mapper.SalesDeliveryMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.productionPlan.pojo.SalesDelivery">
        <id column="id" property="id" />
        <result column="delivery_date" property="deliveryDate" />
        <result column="delivery_code" property="deliveryCode" />
        <result column="project_name" property="projectName" />
        <result column="delivery_place" property="deliveryPlace" />
        <result column="link_man" property="linkMan" />
        <result column="link_phone" property="linkPhone" />
        <result column="delivery_remark" property="deliveryRemark" />
        <result column="material_code" property="materialCode" />
        <result column="product_name" property="productName" />
        <result column="model" property="model" />
        <result column="volume" property="volume" />
        <result column="unit_price" property="unitPrice" />
        <result column="price" property="price" />
        <result column="product_remark" property="productRemark" />
        <result column="customer" property="customer" />
        <result column="salesman" property="salesman" />
        <result column="delivery_method" property="deliveryMethod" />
        <result column="form_instance_id" property="formInstanceId" />
        <result column="form_modified_time" property="formModifiedTime" />
        <result column="create_time" property="createTime" />
        <result column="update_time" property="updateTime" />
    </resultMap>
</mapper>