From 55fb3f5a3d6efc4e5c91c5438c137aeabb1d2c37 Mon Sep 17 00:00:00 2001
From: liyong <18434998025@163.com>
Date: 星期一, 19 一月 2026 11:57:33 +0800
Subject: [PATCH] feat(production): 新增工艺路线和BOM管理功能

---
 src/main/java/com/ruoyi/production/service/ProductProcessRouteService.java              |   18 
 src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java                     |   32 
 src/main/java/com/ruoyi/production/controller/ProductProcessRouteController.java        |   18 
 src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordOutMapper.java        |    4 
 src/main/java/com/ruoyi/production/service/impl/ProductionProductOutputServiceImpl.java |   24 
 src/main/resources/mapper/production/ProductProcessMapper.xml                           |   20 
 src/main/java/com/ruoyi/production/dto/ProductOrderDto.java                             |   46 
 src/main/java/com/ruoyi/production/pojo/ProductStructure.java                           |   56 
 src/main/java/com/ruoyi/production/service/ProductOrderService.java                     |   23 
 src/main/java/com/ruoyi/production/dto/ProcessRouteItemDto.java                         |   29 
 src/main/java/com/ruoyi/production/mapper/ProductProcessMapper.java                     |   14 
 src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java        |   41 
 src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordOut.java                |    4 
 src/main/java/com/ruoyi/production/controller/ProductionProductInputController.java     |   25 
 src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java                         |   32 
 src/main/java/com/ruoyi/production/controller/ProductStructureController.java           |   30 
 src/main/java/com/ruoyi/production/service/impl/ProductionProductInputServiceImpl.java  |   24 
 src/main/java/com/ruoyi/production/pojo/ProcessRoute.java                               |   44 
 src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java                   |   29 
 src/main/java/com/ruoyi/production/service/ProductionProductMainService.java            |   15 
 src/main/java/com/ruoyi/production/dto/ProcessRouteDto.java                             |   18 
 src/main/resources/mapper/production/ProcessRouteMapper.xml                             |   28 
 src/main/resources/mapper/production/ProductOrderMapper.xml                             |   89 +
 src/main/java/com/ruoyi/production/service/ProcessRouteItemService.java                 |   15 
 src/main/java/com/ruoyi/production/dto/ProductionProductOutputDto.java                  |   14 
 src/main/java/com/ruoyi/production/service/ProductionProductInputService.java           |   11 
 src/main/resources/mapper/production/ProcessRouteItemMapper.xml                         |   35 
 src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java                         |   37 
 src/main/java/com/ruoyi/production/service/ProcessRouteService.java                     |   14 
 src/main/java/com/ruoyi/production/controller/ProductProcessController.java             |   86 +
 src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java            |  109 +
 src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java                    |   32 
 src/main/java/com/ruoyi/production/mapper/ProcessRouteItemMapper.java                   |   17 
 src/main/java/com/ruoyi/production/mapper/ProductBomMapper.java                         |   25 
 src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java              |   22 
 src/main/java/com/ruoyi/production/service/ProductionProductOutputService.java          |   11 
 src/main/java/com/ruoyi/quality/pojo/QualityInspect.java                                |   10 
 src/main/java/com/ruoyi/production/mapper/ProductStructureMapper.java                   |   17 
 src/main/java/com/ruoyi/production/pojo/ProductOrder.java                               |   99 +
 src/main/java/com/ruoyi/production/controller/ProductOrderController.java               |   65 +
 src/main/java/com/ruoyi/production/mapper/ProductProcessRouteMapper.java                |   21 
 src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java                      |   45 
 src/main/java/com/ruoyi/production/service/ProductWorkOrderService.java                 |   15 
 src/main/java/com/ruoyi/production/pojo/ProductProcessRouteItem.java                    |   41 
 src/main/java/com/ruoyi/production/service/ProductProcessRouteItemService.java          |   18 
 src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml                 |    5 
 src/main/java/com/ruoyi/production/controller/ProductBomController.java                 |   84 +
 src/main/java/com/ruoyi/production/service/impl/ProcessRouteServiceImpl.java            |   42 
 src/main/resources/mapper/production/ProductWorkOrderMapper.xml                         |   70 +
 src/main/java/com/ruoyi/production/mapper/ProcessRouteMapper.java                       |   15 
 src/main/resources/mapper/production/ProductionProductInputMapper.xml                   |   36 
 src/main/java/com/ruoyi/production/pojo/ProductWorkOrder.java                           |  124 ++
 src/main/java/com/ruoyi/production/controller/ProcessRouteItemController.java           |   45 
 src/main/java/com/ruoyi/production/pojo/ProductBom.java                                 |   68 +
 src/main/java/com/ruoyi/production/controller/ProductionProductMainController.java      |   48 
 src/main/java/com/ruoyi/production/service/ProductBomService.java                       |   23 
 src/main/java/com/ruoyi/production/dto/ProductProcessRouteItemDto.java                  |   24 
 src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteServiceImpl.java     |   29 
 src/main/resources/mapper/procurementrecord/ProcurementRecordOutMapper.xml              |   13 
 src/main/java/com/ruoyi/production/controller/ProcessRouteController.java               |   52 
 src/main/java/com/ruoyi/production/mapper/ProductOrderMapper.java                       |   27 
 src/main/resources/mapper/production/ProductionProductOutputMapper.xml                  |   37 
 src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java           |   37 
 src/main/java/com/ruoyi/production/service/impl/ProductProcessServiceImpl.java          |   62 +
 src/main/java/com/ruoyi/production/pojo/ProductProcess.java                             |   74 +
 src/main/java/com/ruoyi/production/mapper/ProductionProductOutputMapper.java            |   21 
 src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java   |  294 ++++
 src/main/resources/mapper/production/ProductBomMapper.xml                               |   48 
 src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java              |   45 
 src/main/java/com/ruoyi/production/pojo/ProductProcessRoute.java                        |   58 
 src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteItemServiceImpl.java |  198 +++
 src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java                    |   28 
 src/main/java/com/ruoyi/production/controller/ProductProcessRouteItemController.java    |   57 
 src/main/java/com/ruoyi/production/service/ProductStructureService.java                 |   16 
 src/main/java/com/ruoyi/production/mapper/ProductProcessRouteItemMapper.java            |   14 
 src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java        |   32 
 src/main/java/com/ruoyi/production/dto/ProductBomDto.java                               |   16 
 src/main/java/com/ruoyi/production/dto/ProductionProductInputDto.java                   |   14 
 src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordMapper.java           |    3 
 src/main/java/com/ruoyi/production/dto/ProductProcessDto.java                           |   10 
 src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml                  |   28 
 src/main/resources/mapper/production/ProductStructureMapper.xml                         |   43 
 src/main/resources/mapper/production/ProductionProductMainMapper.xml                    |   48 
 src/main/java/com/ruoyi/production/mapper/ProductionProductInputMapper.java             |   21 
 src/main/java/com/ruoyi/production/pojo/ProcessRouteItem.java                           |   41 
 src/main/java/com/ruoyi/production/controller/ProductionProductOutputController.java    |   25 
 src/main/java/com/ruoyi/production/service/ProductProcessService.java                   |   21 
 src/main/java/com/ruoyi/production/dto/ProductStructureDto.java                         |   22 
 src/main/resources/mapper/production/ProductProcessRouteMapper.xml                      |   26 
 src/main/java/com/ruoyi/production/service/impl/ProcessRouteItemServiceImpl.java        |   88 +
 90 files changed, 3,554 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordMapper.java b/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordMapper.java
index 1336f39..df59bc4 100644
--- a/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordMapper.java
+++ b/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordMapper.java
@@ -9,6 +9,7 @@
 import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
 import org.apache.ibatis.annotations.Param;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -31,4 +32,6 @@
     List<ProcurementPageDtoCopy> listCopy();
 
     List<ProcurementPageDto> list();
+
+    BigDecimal getSumQuantity(@Param("productModelId") Long productModelId);
 }
diff --git a/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordOutMapper.java b/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordOutMapper.java
index 4a9390b..b2a3dfb 100644
--- a/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordOutMapper.java
+++ b/src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementRecordOutMapper.java
@@ -7,6 +7,7 @@
 import com.ruoyi.procurementrecord.pojo.ProcurementRecordOut;
 import org.apache.ibatis.annotations.Param;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -18,4 +19,7 @@
     IPage<ProcurementRecordOutPageDto> listPage(Page page,@Param("req") ProcurementRecordOutPageDto procurementDto);
 
     List<ProcurementRecordOutPageDto> list();
+    BigDecimal getSumQuantity(@Param("productModelId") Long productModelId);
+
+    ProcurementRecordOut selectCode(@Param("format") String format);
 }
diff --git a/src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordOut.java b/src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordOut.java
index b09b0f3..5c439ff 100644
--- a/src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordOut.java
+++ b/src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordOut.java
@@ -77,4 +77,8 @@
     @TableField(fill = FieldFill.INSERT)
     private Long tenantId;
 
+    private Integer type;
+
+    private Long productModelId;
+
 }
diff --git a/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java b/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
new file mode 100644
index 0000000..0d61f87
--- /dev/null
+++ b/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
@@ -0,0 +1,32 @@
+package com.ruoyi.procurementrecord.utils;
+
+import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper;
+import com.ruoyi.procurementrecord.mapper.ProcurementRecordOutMapper;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
+
+@Component
+@RequiredArgsConstructor
+public class StockUtils {
+    private final ProcurementRecordOutMapper procurementRecordOutMapper;
+    private final ProcurementRecordMapper procurementRecordMapper;
+
+    // 鑾峰彇鍟嗗搧鍏ュ簱鏁伴噺,鍑哄簱鏁伴噺,鍓╀綑搴撳瓨
+    public Map<String, BigDecimal> getStockQuantity(Long productModelId) {
+        // 鍏ュ簱鏁伴噺
+        BigDecimal sumQuantity = procurementRecordMapper.getSumQuantity(productModelId);
+        // 鍑哄簱鏁伴噺
+        BigDecimal outQuantity = procurementRecordOutMapper.getSumQuantity(productModelId);
+        // 鍓╀綑搴撳瓨
+        BigDecimal stockQuantity = outQuantity.compareTo(sumQuantity) > 0 ? BigDecimal.ZERO : sumQuantity.subtract(outQuantity);
+        Map<String, BigDecimal> stockMap = new HashMap<>();
+        stockMap.put("inboundNum", sumQuantity);
+        stockMap.put("outboundNum", outQuantity);
+        stockMap.put("stockQuantity", stockQuantity);
+        return stockMap;
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProcessRouteController.java b/src/main/java/com/ruoyi/production/controller/ProcessRouteController.java
new file mode 100644
index 0000000..31ff3fb
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/controller/ProcessRouteController.java
@@ -0,0 +1,52 @@
+package com.ruoyi.production.controller;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.dto.ProcessRouteDto;
+import com.ruoyi.production.pojo.ProcessRoute;
+import com.ruoyi.production.pojo.ProcessRouteItem;
+import com.ruoyi.production.service.ProcessRouteItemService;
+import com.ruoyi.production.service.ProcessRouteService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Arrays;
+
+@RestController
+@RequestMapping("processRoute")
+@Api(tags = "宸ヨ壓璺嚎")
+public class ProcessRouteController {
+
+    @Autowired
+    private ProcessRouteService processRouteService;
+
+    @Autowired
+    private ProcessRouteItemService processRouteItemService;
+
+    @GetMapping("page")
+    @ApiOperation("鍒嗛〉鏌ヨ")
+    public R page(Page<ProcessRouteDto>  page, ProcessRouteDto processRouteDto) {
+        return R.ok(processRouteService.pageProcessRouteDto(page, processRouteDto));
+    }
+
+    @ApiOperation("鏂板宸ヨ壓璺嚎")
+    @PostMapping ()
+    public R add(@RequestBody  ProcessRoute processRoute) {
+        return R.ok(processRouteService.saveProcessRoute(processRoute));
+    }
+    @ApiOperation("淇敼宸ヨ壓璺嚎")
+    @PutMapping ()
+    public R update(@RequestBody  ProcessRoute processRoute) {
+        return R.ok(processRouteService.updateById(processRoute));
+    }
+    @ApiOperation("鍒犻櫎宸ヨ壓璺嚎")
+    @DeleteMapping("/{ids}")
+    public R delete(@PathVariable("ids") Long[] ids) {
+        //鍒犻櫎宸ヨ壓璺嚎璇︽儏
+        processRouteItemService.remove(Wrappers.<ProcessRouteItem>lambdaQuery().in(ProcessRouteItem::getRouteId,Arrays.asList(ids)));
+        return R.ok(processRouteService.removeBatchByIds(Arrays.asList(ids)));
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProcessRouteItemController.java b/src/main/java/com/ruoyi/production/controller/ProcessRouteItemController.java
new file mode 100644
index 0000000..18e8096
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/controller/ProcessRouteItemController.java
@@ -0,0 +1,45 @@
+package com.ruoyi.production.controller;
+
+import com.ruoyi.framework.aspectj.lang.annotation.Log;
+import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.dto.ProcessRouteItemDto;
+import com.ruoyi.production.pojo.ProcessRouteItem;
+import com.ruoyi.production.service.ProcessRouteItemService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("processRouteItem")
+@Api(tags = "宸ヨ壓璺嚎鏄庣粏")
+public class ProcessRouteItemController {
+    @Autowired
+    private ProcessRouteItemService processRouteItemService;
+
+    @GetMapping("list")
+    public R listProcessRouteItemDto(ProcessRouteItemDto processRouteItemDto) {
+        return R.ok(processRouteItemService.listProcessRouteItemDto(processRouteItemDto));
+    }
+
+    @PostMapping ()
+    @ApiOperation("鏂板淇敼")
+    public R addOrUpdate(@RequestBody ProcessRouteItem processRouteItem) {
+        return R.ok(processRouteItemService.saveOrUpdate(processRouteItem));
+    }
+
+    @PostMapping ("/sort")
+    @ApiOperation("鎺掑簭")
+    public R sort(@RequestBody ProcessRouteItem processRouteItem) {
+        return R.ok(processRouteItemService.sort(processRouteItem));
+    }
+
+    @ApiOperation("鍒犻櫎宸ヨ壓璺嚎鏄庣粏")
+    @DeleteMapping("/batchDelete/{id}")
+    @Log(title = "鍒犻櫎", businessType = BusinessType.DELETE)
+    public AjaxResult batchDelete(@PathVariable("id") Long id) {
+        return AjaxResult.success(processRouteItemService.batchDelete(id));
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProductBomController.java b/src/main/java/com/ruoyi/production/controller/ProductBomController.java
new file mode 100644
index 0000000..941951b
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/controller/ProductBomController.java
@@ -0,0 +1,84 @@
+package com.ruoyi.production.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.aspectj.lang.annotation.Log;
+import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.production.dto.ProductBomDto;
+import com.ruoyi.production.pojo.ProcessRoute;
+import com.ruoyi.production.pojo.ProductBom;
+import com.ruoyi.production.service.ProcessRouteService;
+import com.ruoyi.production.service.ProductBomService;
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * <p>
+ * BOM涓昏〃 鍓嶇鎺у埗鍣�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 09:59:27
+ */
+@RestController
+@RequestMapping("/productBom")
+public class ProductBomController {
+
+    @Autowired
+    private ProductBomService productBomService;
+
+    @Autowired
+    private ProcessRouteService processRouteService;
+
+    @GetMapping("/listPage")
+    @Log(title = "BOM-鍒嗛〉鏌ヨ", businessType = BusinessType.OTHER)
+    @ApiOperation("BOM-鍒嗛〉鏌ヨ")
+    public AjaxResult listPage(Page page, ProductBomDto productBomDto) {
+        IPage<ProductBomDto> listPage = productBomService.listPage(page, productBomDto);
+        return AjaxResult.success(listPage);
+    }
+
+    @ApiModelProperty("鏂板BOM")
+    @PostMapping("/add")
+    @Log(title = "鏂板", businessType = BusinessType.INSERT)
+    public AjaxResult add( @RequestBody ProductBom productBom) {
+        return productBomService.add(productBom);
+    }
+
+    @ApiOperation("鏇存柊BOM")
+    @Log(title = "淇敼", businessType = BusinessType.UPDATE)
+    @PutMapping("/update")
+    public AjaxResult update(@RequestBody ProductBom productBom) {
+        return AjaxResult.success(productBomService.updateById(productBom));
+    }
+
+    @ApiOperation("鍒犻櫎BOM")
+    @DeleteMapping("/batchDelete")
+    @Log(title = "鍒犻櫎", businessType = BusinessType.DELETE)
+    public AjaxResult batchDelete(@RequestBody List<Integer> ids) {
+        List<ProcessRoute> list = processRouteService.list(Wrappers.<ProcessRoute>lambdaQuery().in(ProcessRoute::getBomId, ids));
+        if (list.size()>0){
+            return AjaxResult.error("璇OM宸茬粡瀛樺湪瀵瑰簲鐨勫伐鑹鸿矾绾�,鏃犳硶杩涜鍒犻櫎");
+        }
+        if(CollectionUtils.isEmpty(ids)){
+            return AjaxResult.error("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
+        }
+        return AjaxResult.success(productBomService.removeBatchByIds(ids));
+    }
+
+    @GetMapping("/getByModel")
+    @Log(title = "BOM-鏍规嵁閫夋嫨鐨勮鏍煎瀷鍙穒d鏌ヨ瀛樺湪鐨刡om", businessType = BusinessType.OTHER)
+    @ApiOperation("BOM-鏍规嵁閫夋嫨鐨勮鏍煎瀷鍙穒d鏌ヨ瀛樺湪鐨刡om")
+    public AjaxResult getByModel(Long productModelId) {
+        List<ProductBom> productBoms = productBomService.list(Wrappers.<ProductBom>lambdaQuery().eq(ProductBom::getProductModelId, productModelId));
+        return AjaxResult.success(productBoms);
+    }
+
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProductOrderController.java b/src/main/java/com/ruoyi/production/controller/ProductOrderController.java
new file mode 100644
index 0000000..0fad508
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/controller/ProductOrderController.java
@@ -0,0 +1,65 @@
+package com.ruoyi.production.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.framework.aspectj.lang.annotation.Log;
+import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.dto.ProductOrderDto;
+import com.ruoyi.production.pojo.ProductOrder;
+import com.ruoyi.production.service.ProductOrderService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+@RequestMapping("productOrder")
+@RestController
+@Api(tags = "鐢熶骇璁㈠崟")
+public class ProductOrderController {
+
+    @Autowired
+    private ProductOrderService productOrderService;
+
+
+    @ApiOperation("鍒嗛〉鏌ヨ")
+    @GetMapping("page")
+    public R page(ProductOrderDto productOrder, Page page) {
+        return R.ok(productOrderService.pageProductOrder(page, productOrder));
+    }
+
+    @ApiOperation("缁戝畾宸ヨ壓璺嚎")
+    @PostMapping("/bindingRoute")
+    public R bindingRoute(@RequestBody ProductOrder productOrder) {
+        return R.ok(productOrderService.bindingRoute(productOrder));
+    }
+
+    @ApiOperation("鏌ヨ瑙勬牸鍨嬪彿瀵瑰簲鐨勫伐鑹鸿矾绾�")
+    @GetMapping("/listProcessRoute")
+    public R listProcessRoute(Long productModelId) {
+        return R.ok(productOrderService.listProcessRoute(productModelId));
+    }
+
+    /**
+     * 瀵煎嚭鐢熶骇璁㈠崟
+     */
+    @Log(title = "鐢熶骇璁㈠崟", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, ProductOrderDto productOrderDto) {
+        List<ProductOrderDto> list;
+        list = productOrderService.pageProductOrder(new Page<>(1, -1), productOrderDto).getRecords();
+        ExcelUtil<ProductOrderDto> util = new ExcelUtil<ProductOrderDto>(ProductOrderDto.class);
+        util.exportExcel(response, list, "鐢熶骇璁㈠崟鏁版嵁");
+    }
+
+    @ApiOperation("鏌ヨ鐢熶骇璁㈠崟瀵瑰簲鐨凚OM")
+    @GetMapping("/listProcessBom")
+    public R listProcessBom(Long orderId) {
+        return R.ok(productOrderService.listProcessBom(orderId));
+    }
+
+
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProductProcessController.java b/src/main/java/com/ruoyi/production/controller/ProductProcessController.java
new file mode 100644
index 0000000..d50fb6a
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/controller/ProductProcessController.java
@@ -0,0 +1,86 @@
+package com.ruoyi.production.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.framework.aspectj.lang.annotation.Log;
+import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
+import com.ruoyi.framework.web.controller.BaseController;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.production.dto.ProductProcessDto;
+import com.ruoyi.production.pojo.ProductProcess;
+import com.ruoyi.production.service.impl.ProductProcessServiceImpl;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+@RestController
+@Api(tags = "宸ュ簭")
+@RequestMapping("/productProcess")
+public class ProductProcessController extends BaseController {
+
+
+    @Autowired
+    private ProductProcessServiceImpl productProcessService;
+
+    @GetMapping("/listPage")
+    @Log(title = "宸ュ簭-鍒嗛〉鏌ヨ", businessType = BusinessType.OTHER)
+    @ApiOperation("宸ュ簭-鍒嗛〉鏌ヨ")
+    public AjaxResult listPage(Page page, ProductProcessDto productProcessDto) {
+        IPage<ProductProcessDto> listPage = productProcessService.listPage(page, productProcessDto);
+        return AjaxResult.success(listPage);
+    }
+
+    @ApiModelProperty("鏂板宸ュ簭")
+    @PostMapping()
+    @Log(title = "鏂板", businessType = BusinessType.INSERT)
+    public AjaxResult add( @RequestBody ProductProcessDto productProcessDto) {
+        return productProcessService.add(productProcessDto);
+    }
+
+    @ApiOperation("鏇存柊宸ュ簭")
+    @Log(title = "淇敼", businessType = BusinessType.UPDATE)
+    @PutMapping("/update")
+    public AjaxResult update(@RequestBody ProductProcess productProcess) {
+        return AjaxResult.success(productProcessService.updateById(productProcess));
+    }
+
+    @ApiOperation("鍒犻櫎宸ュ簭")
+    @DeleteMapping("/batchDelete")
+    @Log(title = "鍒犻櫎", businessType = BusinessType.DELETE)
+    public AjaxResult batchDelete(@RequestBody List<Integer> ids) {
+        if(CollectionUtils.isEmpty(ids)){
+            return AjaxResult.error("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
+        }
+        return AjaxResult.success(productProcessService.removeBatchByIds(ids));
+    }
+
+    @ApiOperation("鏌ヨ鎵�鏈夊伐搴�")
+    @GetMapping("/list")
+    public AjaxResult list() {
+        return AjaxResult.success(productProcessService.list());
+        }
+
+    /**
+     * 瀵煎叆宸ュ簭
+     */
+    @Log(title = "宸ュ簭", businessType = BusinessType.IMPORT)
+    @PostMapping("/importData")
+    public AjaxResult importData(MultipartFile file) throws Exception {
+        return productProcessService.importData(file);
+    }
+
+    @PostMapping("/downloadTemplate")
+    @Log(title = "宸ュ簭-涓嬭浇妯℃澘", businessType = BusinessType.EXPORT)
+    public void downloadTemplate(HttpServletResponse response) {
+        ExcelUtil<ProductProcess> util = new ExcelUtil<ProductProcess>(ProductProcess.class);
+        util.importTemplateExcel(response, "宸ュ簭妯℃澘");
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProductProcessRouteController.java b/src/main/java/com/ruoyi/production/controller/ProductProcessRouteController.java
new file mode 100644
index 0000000..bb1b010
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/controller/ProductProcessRouteController.java
@@ -0,0 +1,18 @@
+package com.ruoyi.production.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  鍓嶇鎺у埗鍣�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 02:51:09
+ */
+@RestController
+@RequestMapping("/productProcessRoute")
+public class ProductProcessRouteController {
+
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProductProcessRouteItemController.java b/src/main/java/com/ruoyi/production/controller/ProductProcessRouteItemController.java
new file mode 100644
index 0000000..2deb126
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/controller/ProductProcessRouteItemController.java
@@ -0,0 +1,57 @@
+package com.ruoyi.production.controller;
+
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.pojo.ProductProcessRouteItem;
+import com.ruoyi.production.service.ProductProcessRouteItemService;
+import com.ruoyi.production.service.ProductProcessRouteService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+@RequestMapping("/productProcessRoute")
+@RestController
+@AllArgsConstructor
+@Api(tags = "鐢熶骇宸ヨ壓璺嚎")
+public class ProductProcessRouteItemController {
+
+
+    private ProductProcessRouteItemService productProcessRouteItemService;
+    private ProductProcessRouteService productProcessRouteService;
+
+    @GetMapping("list")
+    @ApiOperation("鏍规嵁Id鏌ヨ宸ヨ壓璺嚎瀛愯〃")
+    public R list(Long orderId) {
+        return R.ok(productProcessRouteItemService.listItem(orderId));
+    }
+
+    @GetMapping("listMain")
+    @ApiOperation("鏍规嵁Id鏌ヨ宸ヨ壓璺嚎涓昏〃")
+    public R listMain(Long orderId) {
+        return R.ok(productProcessRouteService.listMain(orderId));
+    }
+
+    @PostMapping("/addRouteItem")
+    @ApiOperation("鏂板鐢熶骇璁㈠崟鐨勫伐鑹鸿矾绾胯鎯�")
+    public R addRouteItem(@RequestBody ProductProcessRouteItem productProcessRouteItem) {
+        return productProcessRouteItemService.addRouteItem(productProcessRouteItem);
+    }
+
+    @PostMapping("/updateRouteItem")
+    @ApiOperation("淇敼鐢熶骇璁㈠崟鐨勫伐鑹鸿矾绾胯鎯�")
+    public R updateRouteItem(@RequestBody ProductProcessRouteItem productProcessRouteItem) {
+        return R.ok(productProcessRouteItemService.updateById(productProcessRouteItem));
+    }
+
+    @DeleteMapping("/deleteRouteItem/{id}")
+    @ApiOperation("鍒犻櫎鐢熶骇宸ヨ壓璺嚎")
+    public R deleteRouteItem(@PathVariable("id") Long id) {
+        return productProcessRouteItemService.deleteRouteItem(id);
+    }
+
+    @PostMapping ("/sortRouteItem")
+    @ApiOperation("鎺掑簭")
+    public R sortRouteItem(@RequestBody ProductProcessRouteItem productProcessRouteItem) {
+        return R.ok(productProcessRouteItemService.sortRouteItem(productProcessRouteItem));
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProductStructureController.java b/src/main/java/com/ruoyi/production/controller/ProductStructureController.java
new file mode 100644
index 0000000..9f6c628
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/controller/ProductStructureController.java
@@ -0,0 +1,30 @@
+package com.ruoyi.production.controller;
+
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.dto.ProductStructureDto;
+import com.ruoyi.production.service.ProductStructureService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RequestMapping("productStructure")
+@RestController
+@Api(tags = "BOM")
+public class ProductStructureController {
+    @Autowired
+    private ProductStructureService productStructureService;
+
+
+    @ApiOperation("鏂板BOM")
+    @PostMapping()
+    public R addOrUpdate(@RequestBody ProductStructureDto productStructureDto){
+        return R.ok(productStructureService.addProductStructureDto(productStructureDto));
+    }
+
+    @ApiOperation("BOM鏌ョ湅璇︽儏")
+    @GetMapping("/listBybomId/{bomId}")
+    public R listBybomId( @PathVariable("bomId") Long bomId){
+        return R.ok(productStructureService.listBybomId(bomId));
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java b/src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java
new file mode 100644
index 0000000..f595d98
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java
@@ -0,0 +1,37 @@
+package com.ruoyi.production.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.dto.ProductWorkOrderDto;
+import com.ruoyi.production.service.ProductWorkOrderService;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@AllArgsConstructor
+@RequestMapping("/productWorkOrder")
+public class ProductWorkOrderController {
+
+    private ProductWorkOrderService productWorkOrderservice;
+
+
+    /**
+     * 浜у搧宸ュ崟瀹炰綋绫诲垎椤垫煡璇�
+     */
+    @ApiOperation("浜у搧宸ュ崟瀹炰綋绫诲垎椤垫煡璇�")
+    @GetMapping("/page")
+    public R page(Page<ProductWorkOrderDto> page, ProductWorkOrderDto productWorkOrder) {
+        return R.ok(productWorkOrderservice.listPage(page, productWorkOrder));
+    }
+
+    /**
+     * 浜у搧宸ュ崟鏇存柊
+     */
+    @ApiOperation("浜у搧宸ュ崟鏇存柊")
+    @PostMapping ("/updateProductWorkOrder")
+    public R updateProductWorkOrder(@RequestBody ProductWorkOrderDto productWorkOrderDto) {
+        return R.ok(productWorkOrderservice.updateProductWorkOrder(productWorkOrderDto));
+    }
+
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProductionProductInputController.java b/src/main/java/com/ruoyi/production/controller/ProductionProductInputController.java
new file mode 100644
index 0000000..b4bf7dc
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/controller/ProductionProductInputController.java
@@ -0,0 +1,25 @@
+package com.ruoyi.production.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.dto.ProductionProductInputDto;
+import com.ruoyi.production.service.ProductionProductInputService;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RequestMapping("productionProductInput")
+@RestController
+@Api(value = "鐢熶骇鎶曞叆")
+public class ProductionProductInputController {
+
+    @Autowired
+    private ProductionProductInputService productionProductInputService;
+
+    @GetMapping("listPage")
+    public R page(Page<ProductionProductInputDto> page, ProductionProductInputDto productionProductInputDto) {
+        return R.ok(productionProductInputService.listPageProductionProductInputDto(page, productionProductInputDto));
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProductionProductMainController.java b/src/main/java/com/ruoyi/production/controller/ProductionProductMainController.java
new file mode 100644
index 0000000..4b9da77
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/controller/ProductionProductMainController.java
@@ -0,0 +1,48 @@
+package com.ruoyi.production.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.dto.ProductionProductMainDto;
+import com.ruoyi.production.service.ProductionProductMainService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+
+@RequestMapping("productionProductMain")
+@RestController
+@Api(value = "鐢熶骇鎶ュ伐")
+public class ProductionProductMainController {
+
+    @Autowired
+    private ProductionProductMainService productionProductMainService;
+
+    /**
+     * 鎶ュ伐鏌ヨ
+     * @param page
+     * @param productionProductMainDto
+     * @return
+     */
+    @GetMapping("listPage")
+    public R page(Page<ProductionProductMainDto> page, ProductionProductMainDto productionProductMainDto) {
+        return R.ok(productionProductMainService.listPageProductionProductMainDto(page, productionProductMainDto));
+    }
+
+    /**
+     * 鎶ュ伐鏂板鏇存柊
+     * @param productionProductMainDto
+     * @return
+     */
+    @PostMapping("addProductMain")
+    public R addProductMain(@RequestBody ProductionProductMainDto productionProductMainDto) {
+        return R.ok(productionProductMainService.addProductMain(productionProductMainDto));
+    }
+
+    @ApiOperation("鍒犻櫎鎶ュ伐")
+    @DeleteMapping("/delete")
+    @Transactional(rollbackFor = Exception.class)
+    public R delete(@RequestBody ProductionProductMainDto productionProductMainDto) {
+        return R.ok(productionProductMainService.removeProductMain(productionProductMainDto));
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/controller/ProductionProductOutputController.java b/src/main/java/com/ruoyi/production/controller/ProductionProductOutputController.java
new file mode 100644
index 0000000..68dde0a
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/controller/ProductionProductOutputController.java
@@ -0,0 +1,25 @@
+package com.ruoyi.production.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.dto.ProductionProductOutputDto;
+import com.ruoyi.production.service.ProductionProductOutputService;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RequestMapping("productionProductOutput")
+@RestController
+@Api(value = "鐢熶骇浜у嚭")
+public class ProductionProductOutputController {
+
+    @Autowired
+    private ProductionProductOutputService productionProductOutputService;
+
+    @GetMapping("listPage")
+    public R page(Page<ProductionProductOutputDto> page, ProductionProductOutputDto productionProductOutputDto) {
+        return R.ok(productionProductOutputService.listPageProductionProductOutputDto(page, productionProductOutputDto));
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/dto/ProcessRouteDto.java b/src/main/java/com/ruoyi/production/dto/ProcessRouteDto.java
new file mode 100644
index 0000000..232a00c
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/dto/ProcessRouteDto.java
@@ -0,0 +1,18 @@
+package com.ruoyi.production.dto;
+
+import com.ruoyi.production.pojo.ProcessRoute;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class ProcessRouteDto extends ProcessRoute {
+
+    private Long productId;
+
+    private String productName;
+
+    @ApiModelProperty("瑙勬牸")
+    private String model;
+
+    private String bomNo;
+}
diff --git a/src/main/java/com/ruoyi/production/dto/ProcessRouteItemDto.java b/src/main/java/com/ruoyi/production/dto/ProcessRouteItemDto.java
new file mode 100644
index 0000000..bd9a9a4
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/dto/ProcessRouteItemDto.java
@@ -0,0 +1,29 @@
+package com.ruoyi.production.dto;
+
+import com.ruoyi.production.pojo.ProcessRouteItem;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class ProcessRouteItemDto extends ProcessRouteItem {
+
+    @ApiModelProperty(value = "宸ュ簭鍚嶇О")
+    private String processName;
+
+    @ApiModelProperty(value = "宸ヨ壓璺嚎鍚嶇О")
+    private String routeName;
+
+    @ApiModelProperty(value = "鐢熶骇鐐掓満")
+    private String speculativeTradingName;
+
+    @ApiModelProperty(value = "浜у搧鍚嶇О")
+    private String productName;
+
+    @ApiModelProperty(value = "鍗曚綅")
+    private String unit;
+
+    private Long productId;
+
+
+    private String model;
+}
diff --git a/src/main/java/com/ruoyi/production/dto/ProductBomDto.java b/src/main/java/com/ruoyi/production/dto/ProductBomDto.java
new file mode 100644
index 0000000..b4a4c9a
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/dto/ProductBomDto.java
@@ -0,0 +1,16 @@
+package com.ruoyi.production.dto;
+
+import com.ruoyi.production.pojo.ProductBom;
+import lombok.Data;
+
+//鍒嗛〉鏌ヨ鍥炴樉鏁版嵁
+@Data
+public class ProductBomDto extends ProductBom {
+
+    //浜у搧鍚嶇О
+    private String productName;
+
+    //浜у搧瑙勬牸鍨嬪彿
+    private String productModelName;
+
+}
diff --git a/src/main/java/com/ruoyi/production/dto/ProductOrderDto.java b/src/main/java/com/ruoyi/production/dto/ProductOrderDto.java
new file mode 100644
index 0000000..b12803d
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/dto/ProductOrderDto.java
@@ -0,0 +1,46 @@
+package com.ruoyi.production.dto;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import com.ruoyi.production.pojo.ProductOrder;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+@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;
+
+    @ApiModelProperty(value = "瑙勬牸")
+    @Excel(name = "瑙勬牸")
+    private String specificationModel;
+
+    @ApiModelProperty(value = "宸ヨ壓璺嚎缂栧彿")
+    @Excel(name = "宸ヨ壓璺嚎缂栧彿")
+    private String processRouteCode;
+
+    @ApiModelProperty(value = "瀹屾垚鐘舵��")
+    @Excel(name = "瀹屾垚鐘舵��")
+    private BigDecimal completionStatus;
+
+    @ApiModelProperty(value = "BOM缂栧彿")
+    @Excel(name = "BOM缂栧彿")
+    private String bomNo;
+}
diff --git a/src/main/java/com/ruoyi/production/dto/ProductProcessDto.java b/src/main/java/com/ruoyi/production/dto/ProductProcessDto.java
new file mode 100644
index 0000000..1e40c00
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/dto/ProductProcessDto.java
@@ -0,0 +1,10 @@
+package com.ruoyi.production.dto;
+
+import com.ruoyi.production.pojo.ProductProcess;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+@Data
+@ApiModel
+public class ProductProcessDto extends ProductProcess {
+}
diff --git a/src/main/java/com/ruoyi/production/dto/ProductProcessRouteItemDto.java b/src/main/java/com/ruoyi/production/dto/ProductProcessRouteItemDto.java
new file mode 100644
index 0000000..5a0f4d2
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/dto/ProductProcessRouteItemDto.java
@@ -0,0 +1,24 @@
+package com.ruoyi.production.dto;
+
+import com.ruoyi.production.pojo.ProductProcessRouteItem;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class ProductProcessRouteItemDto extends ProductProcessRouteItem {
+
+    @ApiModelProperty(value = "宸ュ簭鍚嶇О")
+    private String processName;
+
+    @ApiModelProperty(value = "浜у搧鍚嶇О")
+    private String productCategory;
+
+    @ApiModelProperty(value = "鍗曚綅")
+    private String unit;
+
+    private Long productId;
+
+    private String productName;
+
+    private String model;
+}
diff --git a/src/main/java/com/ruoyi/production/dto/ProductStructureDto.java b/src/main/java/com/ruoyi/production/dto/ProductStructureDto.java
new file mode 100644
index 0000000..24b783c
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/dto/ProductStructureDto.java
@@ -0,0 +1,22 @@
+package com.ruoyi.production.dto;
+
+import com.ruoyi.production.pojo.ProductStructure;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ProductStructureDto extends ProductStructure {
+
+    @ApiModelProperty(value = "宸ヨ壓鍚嶇О")
+    private String processName;
+    @ApiModelProperty(value = "浜у搧鍚嶇О")
+    private String productName;
+    @ApiModelProperty(value = "浜у搧id")
+    private Long productId;
+
+    private String model;
+
+    private List<ProductStructure> productStructureList;
+}
diff --git a/src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java b/src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java
new file mode 100644
index 0000000..d8ef0f5
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java
@@ -0,0 +1,37 @@
+package com.ruoyi.production.dto;
+
+import com.ruoyi.production.pojo.ProductWorkOrder;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.math.BigDecimal;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ProductWorkOrderDto extends ProductWorkOrder {
+
+    //浜у搧鍚嶇О
+    @ApiModelProperty(value = "浜у搧鍚嶇О")
+    private String productName;
+
+    //瑙勬牸
+    @ApiModelProperty(value = "瑙勬牸")
+    private String model;
+
+    //宸ュ簭
+    @ApiModelProperty(value = "宸ュ簭")
+    private String processName;
+
+    //鍗曚綅
+    @ApiModelProperty(value = "鍗曚綅")
+    private String unit;
+
+
+    //鐢熶骇璁㈠崟鍙�
+    @ApiModelProperty(value = "鐢熶骇璁㈠崟鍙�")
+    private String productOrderNpsNo;
+
+    @ApiModelProperty(value = "瀹屾垚杩涘害")
+    private BigDecimal completionStatus;
+}
diff --git a/src/main/java/com/ruoyi/production/dto/ProductionProductInputDto.java b/src/main/java/com/ruoyi/production/dto/ProductionProductInputDto.java
new file mode 100644
index 0000000..1e6e02e
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/dto/ProductionProductInputDto.java
@@ -0,0 +1,14 @@
+package com.ruoyi.production.dto;
+
+import com.ruoyi.production.pojo.ProductionProductInput;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class ProductionProductInputDto extends ProductionProductInput {
+    @ApiModelProperty(value = "鎶ュ伐鍗曞彿")
+    private String productNo;
+
+    @ApiModelProperty(value = "浜у搧鍨嬪彿")
+    private String model;
+}
diff --git a/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java b/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java
new file mode 100644
index 0000000..f6aa5ba
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java
@@ -0,0 +1,28 @@
+package com.ruoyi.production.dto;
+
+import com.ruoyi.production.pojo.ProductionProductMain;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class ProductionProductMainDto extends ProductionProductMain {
+    @ApiModelProperty(value = "宸ュ崟缂栧彿")
+    private String workOrderNo;
+
+    @ApiModelProperty(value = "宸ュ崟鐘舵��")
+    private String workOrderStatus;
+
+    @ApiModelProperty(value = "鎶ュ伐浜哄憳鏄电О")
+    private String nickName;
+
+    @ApiModelProperty(value = "鎶ュ伐鏁伴噺")
+    private BigDecimal quantity;
+
+    @ApiModelProperty(value = "鏄惁鎶ュ伐")
+    private boolean reportWork;
+
+    @ApiModelProperty(value = "鎶ュ伐id")
+    private Long productMainId;
+}
diff --git a/src/main/java/com/ruoyi/production/dto/ProductionProductOutputDto.java b/src/main/java/com/ruoyi/production/dto/ProductionProductOutputDto.java
new file mode 100644
index 0000000..6710342
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/dto/ProductionProductOutputDto.java
@@ -0,0 +1,14 @@
+package com.ruoyi.production.dto;
+
+import com.ruoyi.production.pojo.ProductionProductOutput;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class ProductionProductOutputDto extends ProductionProductOutput {
+    @ApiModelProperty(value = "鎶ュ伐鍗曞彿")
+    private String productNo;
+
+    @ApiModelProperty(value = "浜у搧鍨嬪彿")
+    private String model;
+}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProcessRouteItemMapper.java b/src/main/java/com/ruoyi/production/mapper/ProcessRouteItemMapper.java
new file mode 100644
index 0000000..f4bde19
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/mapper/ProcessRouteItemMapper.java
@@ -0,0 +1,17 @@
+package com.ruoyi.production.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.production.dto.ProcessRouteItemDto;
+import com.ruoyi.production.pojo.ProcessRouteItem;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface ProcessRouteItemMapper  extends BaseMapper<ProcessRouteItem> {
+
+
+    List<ProcessRouteItemDto> listProcessRouteItemDto(@Param("c") ProcessRouteItemDto processRouteItemDto);
+
+}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProcessRouteMapper.java b/src/main/java/com/ruoyi/production/mapper/ProcessRouteMapper.java
new file mode 100644
index 0000000..493b764
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/mapper/ProcessRouteMapper.java
@@ -0,0 +1,15 @@
+package com.ruoyi.production.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.production.dto.ProcessRouteDto;
+import com.ruoyi.production.pojo.ProcessRoute;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+@Mapper
+public interface ProcessRouteMapper extends BaseMapper<ProcessRoute> {
+
+    IPage<ProcessRouteDto> pageProcessRouteDto(Page<ProcessRouteDto> page,@Param("c") ProcessRouteDto processRouteDto);
+}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductBomMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductBomMapper.java
new file mode 100644
index 0000000..084445e
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/mapper/ProductBomMapper.java
@@ -0,0 +1,25 @@
+package com.ruoyi.production.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.production.dto.ProductBomDto;
+import com.ruoyi.production.pojo.ProductBom;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * <p>
+ * BOM涓昏〃 Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 09:59:27
+ */
+@Mapper
+public interface ProductBomMapper extends BaseMapper<ProductBom> {
+
+    IPage<ProductBomDto> listPage(Page page, @Param("c") ProductBomDto productBomDto);
+
+    ProductBomDto getById(@Param("bomId") Long bomId);
+}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductOrderMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductOrderMapper.java
new file mode 100644
index 0000000..9da50d5
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/mapper/ProductOrderMapper.java
@@ -0,0 +1,27 @@
+package com.ruoyi.production.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.production.dto.ProductOrderDto;
+import com.ruoyi.production.dto.ProductStructureDto;
+import com.ruoyi.production.pojo.ProcessRoute;
+import com.ruoyi.production.pojo.ProductOrder;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface ProductOrderMapper extends BaseMapper<ProductOrder> {
+
+    IPage<ProductOrderDto> pageProductOrder(Page page, @Param("c") ProductOrderDto productOrder);
+    /**
+     * 鏍规嵁璁㈠崟ID鏌ヨ宸ュ崟鎶ュ伐
+     */
+     ProductOrderDto productMainByOrderId(@Param("c") ProductOrder productOrder);
+
+    List<ProcessRoute> listProcessRoute(@Param("productModelId") Long productModelId);
+
+    List<ProductStructureDto> listProcessBom(@Param("orderId") Long orderId);
+}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductProcessMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductProcessMapper.java
new file mode 100644
index 0000000..f21c308
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/mapper/ProductProcessMapper.java
@@ -0,0 +1,14 @@
+package com.ruoyi.production.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.production.dto.ProductProcessDto;
+import com.ruoyi.production.pojo.ProductProcess;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+@Mapper
+public interface ProductProcessMapper extends BaseMapper<ProductProcess> {
+    IPage<ProductProcessDto> listPage(Page page,@Param("productProcessDto") ProductProcessDto productProcessDto);
+}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductProcessRouteItemMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductProcessRouteItemMapper.java
new file mode 100644
index 0000000..48b38ec
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/mapper/ProductProcessRouteItemMapper.java
@@ -0,0 +1,14 @@
+package com.ruoyi.production.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.production.dto.ProductProcessRouteItemDto;
+import com.ruoyi.production.pojo.ProductProcessRouteItem;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface ProductProcessRouteItemMapper extends BaseMapper<ProductProcessRouteItem> {
+    List<ProductProcessRouteItemDto> listItem(@Param("orderId") Long orderId);
+}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductProcessRouteMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductProcessRouteMapper.java
new file mode 100644
index 0000000..9284c5d
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/mapper/ProductProcessRouteMapper.java
@@ -0,0 +1,21 @@
+package com.ruoyi.production.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.production.dto.ProcessRouteDto;
+import com.ruoyi.production.pojo.ProductProcessRoute;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * <p>
+ *  Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 02:51:09
+ */
+@Mapper
+public interface ProductProcessRouteMapper extends BaseMapper<ProductProcessRoute> {
+
+    ProcessRouteDto listMain(@Param("orderId") Long orderId);
+}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductStructureMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductStructureMapper.java
new file mode 100644
index 0000000..5acd2ec
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/mapper/ProductStructureMapper.java
@@ -0,0 +1,17 @@
+package com.ruoyi.production.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.production.dto.ProductStructureDto;
+import com.ruoyi.production.pojo.ProductStructure;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface ProductStructureMapper  extends BaseMapper<ProductStructure> {
+
+    List<ProductStructureDto> listBybomId(@Param("bomId") Long bomId);
+
+    List<ProductStructureDto> listByproductModelId(@Param("productModelId") Long productModelId);
+}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java
new file mode 100644
index 0000000..b581ea5
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java
@@ -0,0 +1,29 @@
+package com.ruoyi.production.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.production.dto.ProductWorkOrderDto;
+import com.ruoyi.production.pojo.ProductWorkOrder;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface ProductWorkOrderMapper extends BaseMapper<ProductWorkOrder> {
+
+    IPage<ProductWorkOrderDto> pageProductWorkOrder(Page<ProductWorkOrderDto> page, @Param("c") ProductWorkOrderDto productWorkOrder);
+
+    int updatePlanQuantity(Map<String, Object> params);
+
+    /**
+     * 鍥炴粴宸ュ崟璁″垝鏁伴噺锛氫粠production_product_output鍙杚uantity鍔犲洖plan_quantity
+     * @param productMainId
+     * @return
+     */
+    int rollbackPlanQuantity(@Param("productMainId") Long productMainId);
+
+    List<ProductWorkOrderDto> selectProductWorkOrderDtoList();
+}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionProductInputMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionProductInputMapper.java
new file mode 100644
index 0000000..78e7d2a
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionProductInputMapper.java
@@ -0,0 +1,21 @@
+package com.ruoyi.production.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.production.dto.ProductionProductInputDto;
+import com.ruoyi.production.pojo.ProductionProductInput;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface ProductionProductInputMapper extends BaseMapper<ProductionProductInput> {
+    IPage<ProductionProductInputDto> listPageProductionProductInputDto(Page page, @Param("c") ProductionProductInputDto productionProductInputDto);
+
+    /**
+     * 鏍规嵁鐢熶骇涓昏〃ID鎵归噺鍒犻櫎鎶曞叆琛ㄦ暟鎹�
+     */
+    int deleteByProductMainIds(@Param("productMainIds") List<Long> productMainIds);
+}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java
new file mode 100644
index 0000000..c9d1268
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java
@@ -0,0 +1,22 @@
+package com.ruoyi.production.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.production.dto.ProductionProductMainDto;
+import com.ruoyi.production.pojo.ProductionProductMain;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface ProductionProductMainMapper extends BaseMapper<ProductionProductMain> {
+
+    IPage<ProductionProductMainDto> listPageProductionProductMainDto(Page page, @Param("c") ProductionProductMainDto productionProductMainDto);
+
+    /**
+     * 鏍规嵁宸ュ崟ID鎵归噺鍒犻櫎鐢熶骇涓昏〃鏁版嵁
+     */
+    int deleteByWorkOrderIds(@Param("workOrderIds") List<Long> workOrderIds);
+}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionProductOutputMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionProductOutputMapper.java
new file mode 100644
index 0000000..0283d42
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionProductOutputMapper.java
@@ -0,0 +1,21 @@
+package com.ruoyi.production.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.production.dto.ProductionProductOutputDto;
+import com.ruoyi.production.pojo.ProductionProductOutput;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface ProductionProductOutputMapper extends BaseMapper<ProductionProductOutput> {
+    IPage<ProductionProductOutputDto> listPageProductionProductOutputDto(Page page, @Param("c") ProductionProductOutputDto productionProductOutputDto);
+
+    /**
+     * 鏍规嵁鐢熶骇涓昏〃ID鎵归噺鍒犻櫎浜у嚭琛ㄦ暟鎹�
+     */
+    int deleteByProductMainIds(@Param("productMainIds") List<Long> productMainIds);
+}
diff --git a/src/main/java/com/ruoyi/production/pojo/ProcessRoute.java b/src/main/java/com/ruoyi/production/pojo/ProcessRoute.java
new file mode 100644
index 0000000..2eabc15
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/pojo/ProcessRoute.java
@@ -0,0 +1,44 @@
+package com.ruoyi.production.pojo;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@TableName("process_route")
+@Data
+@ApiModel(value = "processRoute", description = "宸ヨ壓璺嚎涓昏〃")
+public class ProcessRoute {
+
+    @ApiModelProperty(value = "搴忓彿")
+    private Long id;
+
+    @ApiModelProperty(value = "浜у搧ID")
+    //product_model
+    private Long productModelId;
+
+    @ApiModelProperty(value = "鎻忚堪")
+    private String description;
+
+    @ApiModelProperty(value = "绉熸埛ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(value = "鏇存柊鏃堕棿")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty(value = "宸ヨ壓璺嚎缂栫爜")
+    private String processRouteCode;
+
+    @ApiModelProperty(value = "BOM鐨処D")
+    private Long bomId;
+}
diff --git a/src/main/java/com/ruoyi/production/pojo/ProcessRouteItem.java b/src/main/java/com/ruoyi/production/pojo/ProcessRouteItem.java
new file mode 100644
index 0000000..f2ebd44
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/pojo/ProcessRouteItem.java
@@ -0,0 +1,41 @@
+package com.ruoyi.production.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@TableName("process_route_item")
+@ApiModel(value = "processRouteItem", description = "宸ヨ壓璺嚎瀛愯〃")
+public class ProcessRouteItem {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty(value = "宸ヨ壓璺嚎id")
+    private Long routeId;
+
+    @ApiModelProperty(value = "宸ュ簭id")
+    private Long processId;
+
+    @ApiModelProperty(value ="浜у搧id")
+    private Long productModelId;
+
+    @ApiModelProperty(value = "绉熸埛ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+    @TableField(fill = FieldFill.INSERT)
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    private LocalDateTime createTime;
+    @ApiModelProperty(value = "鏇存柊鏃堕棿")
+    @TableField(fill = FieldFill.UPDATE)
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty(value ="鎷栧姩鎺掑簭")
+    private Integer dragSort;
+
+
+}
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductBom.java b/src/main/java/com/ruoyi/production/pojo/ProductBom.java
new file mode 100644
index 0000000..f4a04cb
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/pojo/ProductBom.java
@@ -0,0 +1,68 @@
+package com.ruoyi.production.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+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;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * BOM涓昏〃
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 09:59:27
+ */
+@Getter
+@Setter
+@TableName("product_bom")
+@ApiModel(value = "ProductBom瀵硅薄", description = "BOM涓昏〃")
+public class ProductBom implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty("bom缂栧彿")
+    private String bomNo;
+
+    @ApiModelProperty("浜у搧瑙勬牸id")
+    private Long productModelId;
+
+    @ApiModelProperty("澶囨敞")
+    private String remark;
+
+    @ApiModelProperty("鐗堟湰鍙�")
+    private String version;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty("鍒涘缓鑰�")
+    @TableField(fill = FieldFill.INSERT)
+    private Long createUser;
+
+    @ApiModelProperty("鏇存柊鑰�")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Long updateUser;
+
+    @ApiModelProperty("绉熸埛ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+}
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductOrder.java b/src/main/java/com/ruoyi/production/pojo/ProductOrder.java
new file mode 100644
index 0000000..f6342a9
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/pojo/ProductOrder.java
@@ -0,0 +1,99 @@
+package com.ruoyi.production.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+@TableName("product_order")
+public class ProductOrder  implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 閿�鍞彴璐d
+     */
+    @ApiModelProperty(value = "閿�鍞彴璐d")
+    private Long salesLedgerId;
+
+    /**
+     * 閿�鍞彴璐︿骇鍝乮d(sales_ledger_product)
+     */
+    @ApiModelProperty(value = "閿�鍞彴璐︿骇鍝乮d")
+    private Long productModelId;
+
+    /**
+     * 宸ヨ壓璺嚎id
+     */
+    @ApiModelProperty(value = "宸ヨ壓璺嚎id")
+    private Long routeId;
+
+    /**
+     * 鐢熶骇璁㈠崟鍙�
+     */
+    @ApiModelProperty(value = "鐢熶骇璁㈠崟鍙�")
+    @Excel(name = "鐢熶骇璁㈠崟鍙�")
+    private String npsNo;
+
+    /**
+     * 绉熸埛id
+     */
+    @ApiModelProperty(value = "绉熸埛id")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+
+    //鍒涘缓鏃堕棿
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "鍒涘缓鏃堕棿")
+    private LocalDateTime createTime;
+
+    //淇敼鏃堕棿
+    @ApiModelProperty(value = "淇敼鏃堕棿")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
+
+    /**
+     * 闇�姹傛暟閲�
+     */
+    @ApiModelProperty(value = "闇�姹傛暟閲�")
+    @Excel(name = "闇�姹傛暟閲�")
+    private BigDecimal quantity;
+
+    /**
+     * 瀹屾垚鏁伴噺
+     */
+    @ApiModelProperty(value = "瀹屾垚鏁伴噺")
+    @Excel(name = "瀹屾垚鏁伴噺")
+    private BigDecimal completeQuantity;
+
+    @Excel(name = "寮�濮嬫椂闂�")
+    @ApiModelProperty(value = "寮�濮嬫椂闂�")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime startTime;
+
+    @ApiModelProperty(value = "缁撴潫鏃堕棿")
+    @Excel(name = "缁撴潫鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime endTime;
+
+
+
+}
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductProcess.java b/src/main/java/com/ruoyi/production/pojo/ProductProcess.java
new file mode 100644
index 0000000..d25f9cf
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/pojo/ProductProcess.java
@@ -0,0 +1,74 @@
+package com.ruoyi.production.pojo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@TableName("product_process")
+@Data
+@ExcelIgnoreUnannotated
+@ApiModel(value = "productProcess", description = "宸ュ簭琛�")
+public class ProductProcess implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 宸ュ簭鍚嶇О
+     */
+    @Excel(name = "宸ュ簭鍚嶇О")
+    private String name;
+
+    /**
+     * 宸ュ簭缂栧彿
+     */
+    @Excel(name = "宸ュ簭缂栧彿")
+    private String no;
+
+    /**
+     * 澶囨敞
+     */
+    @Excel(name = "澶囨敞")
+    private String remark;
+
+
+    /**
+     * 宸ヨ祫瀹氶
+     */
+    @Excel(name = "宸ヨ祫瀹氶")
+    private BigDecimal salaryQuota;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    /**
+     * 淇敼鏃堕棿
+     */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
+    /**
+     * 绉熸埛ID
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+
+
+}
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductProcessRoute.java b/src/main/java/com/ruoyi/production/pojo/ProductProcessRoute.java
new file mode 100644
index 0000000..c0881ea
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/pojo/ProductProcessRoute.java
@@ -0,0 +1,58 @@
+package com.ruoyi.production.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 02:51:09
+ */
+@Getter
+@Setter
+@TableName("product_process_route")
+@ApiModel(value = "ProductProcessRoute瀵硅薄", description = "")
+public class ProductProcessRoute implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("浜у搧id")
+    //product_model
+    private Long productModelId;
+
+    @ApiModelProperty("鎻忚堪")
+    private String description;
+
+    @ApiModelProperty("绉熸埛id")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+
+    @ApiModelProperty("褰曞叆鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty("鍏宠仈bom鐨刬d")
+    private Long bomId;
+
+    @ApiModelProperty("宸ヨ壓璺嚎缂栫爜")
+    private String processRouteCode;
+
+    @ApiModelProperty("鐢熶骇璁㈠崟鐨刬d")
+    private Long productOrderId;
+}
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductProcessRouteItem.java b/src/main/java/com/ruoyi/production/pojo/ProductProcessRouteItem.java
new file mode 100644
index 0000000..4b6762c
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/pojo/ProductProcessRouteItem.java
@@ -0,0 +1,41 @@
+package com.ruoyi.production.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@TableName("product_process_route_item")
+public class ProductProcessRouteItem {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty(value = "鐢熶骇璁㈠崟id(product_order_id)")
+    private Long productOrderId;
+
+    @ApiModelProperty(value = "鐢熶骇璁㈠崟鐨勫伐鑹鸿矾绾縤d(product_process_route)")
+    private Long productRouteId;
+
+    @ApiModelProperty(value = "宸ュ簭id")
+    private Long processId;
+
+    @ApiModelProperty(value ="浜у搧id")
+    private Long productModelId;
+
+    @ApiModelProperty(value = "绉熸埛ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+    @TableField(fill = FieldFill.INSERT)
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    private LocalDateTime createTime;
+    @ApiModelProperty(value = "鏇存柊鏃堕棿")
+    @TableField(fill = FieldFill.UPDATE)
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty(value ="鎷栧姩鎺掑簭")
+    private Integer dragSort;
+
+}
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductStructure.java b/src/main/java/com/ruoyi/production/pojo/ProductStructure.java
new file mode 100644
index 0000000..de0d605
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/pojo/ProductStructure.java
@@ -0,0 +1,56 @@
+package com.ruoyi.production.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@TableName("product_structure")
+@Data
+@ApiModel(value = "ProductStructure", description = "BOM瀛愯〃")
+public class ProductStructure {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 浜у搧鍚嶇О
+     */
+    private Long productModelId;
+
+    /**
+     * 宸ュ簭id
+     */
+    private Long processId;
+
+    /**
+     * 鍗曚綅浜у嚭闇�瑕佹暟閲�
+     */
+    private BigDecimal unitQuantity;
+
+    /**
+     * 闇�姹傛暟閲�
+     */
+    private BigDecimal demandedQuantity;
+
+    /**
+     * 鍗曚綅
+     */
+    private String unit;
+
+    /**
+     * 绉熸埛ID
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+
+    /**
+     * 鍏宠仈BOMid
+     */
+    private Long bomId;
+
+
+}
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductWorkOrder.java b/src/main/java/com/ruoyi/production/pojo/ProductWorkOrder.java
new file mode 100644
index 0000000..d4b950e
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/pojo/ProductWorkOrder.java
@@ -0,0 +1,124 @@
+package com.ruoyi.production.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+/**
+ * 浜у搧宸ュ崟瀹炰綋绫�
+ * 瀵瑰簲鏁版嵁搴撹〃锛歱roduct_work_order
+ */
+@Data
+@TableName("product_work_order")
+public class ProductWorkOrder implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 涓婚敭id
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 宸ヨ壓璺嚎椤圭洰id
+     */
+    @ApiModelProperty(value = "宸ヨ壓璺嚎椤圭洰id")
+    private Long productProcessRouteItemId;
+
+    /**
+     * 鐢熶骇璁㈠崟id
+     */
+    @ApiModelProperty(value = "鐢熶骇璁㈠崟id")
+    private Long productOrderId;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    /**
+     * 淇敼鏃堕棿
+     */
+    @ApiModelProperty(value = "淇敼鏃堕棿")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
+    /**
+     * 宸ュ崟缂栧彿
+     */
+    @ApiModelProperty(value = "宸ュ崟缂栧彿")
+    private String workOrderNo;
+
+    /**
+     * 鐘舵��  1 寰呯‘璁�  2 寰呯敓浜� 3鐢熶骇涓� 4宸插畬鎴�
+     */
+    @ApiModelProperty(value = "鐘舵��  1 寰呯‘璁�  2 寰呯敓浜� 3鐢熶骇涓� 4宸插畬鎴�")
+    private Integer status;
+
+    /**
+     * 绉熸埛id
+     */
+    @ApiModelProperty(value = "绉熸埛id")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+
+    /**
+     * 璁″垝寮�濮嬫椂闂�
+     */
+    @ApiModelProperty(value = "璁″垝寮�濮嬫椂闂�")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate planStartTime;
+
+    /**
+     * 璁″垝缁撴潫鏃堕棿
+     */
+    @ApiModelProperty(value = "璁″垝缁撴潫鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate planEndTime;
+
+    /**
+     * 瀹為檯寮�濮嬫椂闂�
+     */
+    @ApiModelProperty(value = "瀹為檯寮�濮嬫椂闂�")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate actualStartTime;
+
+    /**
+     * 瀹為檯缁撴潫鏃堕棿
+     */
+    @ApiModelProperty(value = "瀹為檯缁撴潫鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate actualEndTime;
+
+    /**
+     * 闇�姹傞噺
+     */
+    @ApiModelProperty(value = "闇�姹傛暟閲�")
+    private BigDecimal planQuantity;
+
+    /**
+     * 瀹屾垚鏁伴噺
+     */
+    @ApiModelProperty(value = "瀹屾垚鏁伴噺")
+    private BigDecimal completeQuantity;
+
+
+}
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java b/src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java
new file mode 100644
index 0000000..c938170
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java
@@ -0,0 +1,32 @@
+package com.ruoyi.production.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+@TableName("production_product_input")
+public class ProductionProductInput {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty(value = "鎶ュ伐id")
+    private Long productMainId;
+
+    @ApiModelProperty(value = "浜у搧id")
+    private Long productModelId;
+
+    @ApiModelProperty(value = "鏁伴噺")
+    private BigDecimal quantity;
+
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(value = "绉熸埛ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+}
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java b/src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java
new file mode 100644
index 0000000..3dbe688
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java
@@ -0,0 +1,45 @@
+package com.ruoyi.production.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@TableName("production_product_main")
+public class ProductionProductMain {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty(value = "鎶ュ伐鍗曞彿")
+    private String productNo;
+
+    @ApiModelProperty(value = "鎶ュ伐浜哄憳id")
+    private Long userId;
+
+    @ApiModelProperty(value = "鎶ュ伐浜哄憳")
+    private String userName;
+
+    @ApiModelProperty(value = "鐢熶骇椤圭洰id")
+    private Long productProcessRouteItemId;
+
+    @ApiModelProperty(value = "宸ュ崟id")
+    private Long workOrderId;
+
+    @ApiModelProperty(value = "鎶ュ伐鐘舵��")
+    private Integer status;
+
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(value = "鏇存柊鏃堕棿")
+    @TableField(fill = FieldFill.UPDATE)
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty(value = "绉熸埛ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+}
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java b/src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java
new file mode 100644
index 0000000..20e52ad
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java
@@ -0,0 +1,32 @@
+package com.ruoyi.production.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+@TableName("production_product_output")
+public class ProductionProductOutput {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty(value = "鎶ュ伐id")
+    private Long productMainId;
+
+    @ApiModelProperty(value = "浜у搧id")
+    private Long productModelId;
+
+    @ApiModelProperty(value = "鏁伴噺")
+    private BigDecimal quantity;
+
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(value = "绉熸埛ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+}
diff --git a/src/main/java/com/ruoyi/production/service/ProcessRouteItemService.java b/src/main/java/com/ruoyi/production/service/ProcessRouteItemService.java
new file mode 100644
index 0000000..9ec2b5c
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/ProcessRouteItemService.java
@@ -0,0 +1,15 @@
+package com.ruoyi.production.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.production.dto.ProcessRouteItemDto;
+import com.ruoyi.production.pojo.ProcessRouteItem;
+
+import java.util.List;
+
+public interface ProcessRouteItemService extends IService<ProcessRouteItem> {
+    List<ProcessRouteItemDto> listProcessRouteItemDto( ProcessRouteItemDto processRouteItemDto);
+
+    int sort(ProcessRouteItem processRouteItem);
+
+    String batchDelete(Long id);
+}
diff --git a/src/main/java/com/ruoyi/production/service/ProcessRouteService.java b/src/main/java/com/ruoyi/production/service/ProcessRouteService.java
new file mode 100644
index 0000000..07d5b7c
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/ProcessRouteService.java
@@ -0,0 +1,14 @@
+package com.ruoyi.production.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.production.dto.ProcessRouteDto;
+import com.ruoyi.production.pojo.ProcessRoute;
+
+public interface ProcessRouteService extends IService<ProcessRoute> {
+
+    IPage<ProcessRouteDto> pageProcessRouteDto(Page<ProcessRouteDto> page, ProcessRouteDto processRouteDto);
+
+    Integer saveProcessRoute(ProcessRoute processRoute);
+}
diff --git a/src/main/java/com/ruoyi/production/service/ProductBomService.java b/src/main/java/com/ruoyi/production/service/ProductBomService.java
new file mode 100644
index 0000000..d204be6
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/ProductBomService.java
@@ -0,0 +1,23 @@
+package com.ruoyi.production.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.production.dto.ProductBomDto;
+import com.ruoyi.production.pojo.ProductBom;
+
+/**
+ * <p>
+ * BOM涓昏〃 鏈嶅姟绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 09:59:27
+ */
+public interface ProductBomService extends IService<ProductBom> {
+
+    IPage<ProductBomDto> listPage(Page page, ProductBomDto productBomDto);
+
+    AjaxResult add(ProductBom productBom);
+}
diff --git a/src/main/java/com/ruoyi/production/service/ProductOrderService.java b/src/main/java/com/ruoyi/production/service/ProductOrderService.java
new file mode 100644
index 0000000..e35905f
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/ProductOrderService.java
@@ -0,0 +1,23 @@
+package com.ruoyi.production.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.production.dto.ProductOrderDto;
+import com.ruoyi.production.dto.ProductStructureDto;
+import com.ruoyi.production.pojo.ProcessRoute;
+import com.ruoyi.production.pojo.ProductOrder;
+
+import java.util.List;
+
+
+public interface ProductOrderService extends IService<ProductOrder> {
+
+    IPage<ProductOrderDto> pageProductOrder(Page page, ProductOrderDto productOrder);
+
+    int bindingRoute(ProductOrder productOrder);
+
+    List<ProcessRoute> listProcessRoute(Long productModelId);
+
+    List<ProductStructureDto> listProcessBom(Long orderId);
+}
diff --git a/src/main/java/com/ruoyi/production/service/ProductProcessRouteItemService.java b/src/main/java/com/ruoyi/production/service/ProductProcessRouteItemService.java
new file mode 100644
index 0000000..c37eea1
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/ProductProcessRouteItemService.java
@@ -0,0 +1,18 @@
+package com.ruoyi.production.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.dto.ProductProcessRouteItemDto;
+import com.ruoyi.production.pojo.ProductProcessRouteItem;
+
+import java.util.List;
+
+public interface ProductProcessRouteItemService extends IService<ProductProcessRouteItem> {
+    List<ProductProcessRouteItemDto> listItem(Long orderId);
+
+    R deleteRouteItem(Long id);
+
+    R addRouteItem(ProductProcessRouteItem productProcessRouteItem);
+
+    int sortRouteItem(ProductProcessRouteItem productProcessRouteItem);
+}
diff --git a/src/main/java/com/ruoyi/production/service/ProductProcessRouteService.java b/src/main/java/com/ruoyi/production/service/ProductProcessRouteService.java
new file mode 100644
index 0000000..37ddb71
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/ProductProcessRouteService.java
@@ -0,0 +1,18 @@
+package com.ruoyi.production.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.production.dto.ProcessRouteDto;
+import com.ruoyi.production.pojo.ProductProcessRoute;
+
+/**
+ * <p>
+ *  鏈嶅姟绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 02:51:09
+ */
+public interface ProductProcessRouteService extends IService<ProductProcessRoute> {
+
+    ProcessRouteDto listMain(Long orderId);
+}
diff --git a/src/main/java/com/ruoyi/production/service/ProductProcessService.java b/src/main/java/com/ruoyi/production/service/ProductProcessService.java
new file mode 100644
index 0000000..4752c25
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/ProductProcessService.java
@@ -0,0 +1,21 @@
+package com.ruoyi.production.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.production.dto.ProductProcessDto;
+import com.ruoyi.production.pojo.ProductProcess;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * @author :yys
+ * @date : 2025/7/21 14:39
+ */
+public interface ProductProcessService extends IService<ProductProcess> {
+    IPage<ProductProcessDto> listPage(Page page, ProductProcessDto productProcessDto);
+
+    AjaxResult add(ProductProcessDto productProcessDto);
+
+    AjaxResult importData(MultipartFile file);
+}
diff --git a/src/main/java/com/ruoyi/production/service/ProductStructureService.java b/src/main/java/com/ruoyi/production/service/ProductStructureService.java
new file mode 100644
index 0000000..1ede09a
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/ProductStructureService.java
@@ -0,0 +1,16 @@
+package com.ruoyi.production.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.production.dto.ProductStructureDto;
+import com.ruoyi.production.pojo.ProductStructure;
+
+import java.util.List;
+
+public interface ProductStructureService extends IService<ProductStructure> {
+
+
+    Boolean addProductStructureDto(ProductStructureDto productStructureDto);
+
+    List<ProductStructureDto> listBybomId(Long bomId);
+
+}
diff --git a/src/main/java/com/ruoyi/production/service/ProductWorkOrderService.java b/src/main/java/com/ruoyi/production/service/ProductWorkOrderService.java
new file mode 100644
index 0000000..392230e
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/ProductWorkOrderService.java
@@ -0,0 +1,15 @@
+package com.ruoyi.production.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.production.dto.ProductWorkOrderDto;
+import com.ruoyi.production.pojo.ProductWorkOrder;
+
+public interface ProductWorkOrderService extends IService<ProductWorkOrder>{
+
+    IPage<ProductWorkOrderDto> listPage(Page<ProductWorkOrderDto> page, ProductWorkOrderDto productWorkOrder);
+
+    int updateProductWorkOrder(ProductWorkOrderDto productWorkOrderDto);
+
+}
diff --git a/src/main/java/com/ruoyi/production/service/ProductionProductInputService.java b/src/main/java/com/ruoyi/production/service/ProductionProductInputService.java
new file mode 100644
index 0000000..1af1772
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/ProductionProductInputService.java
@@ -0,0 +1,11 @@
+package com.ruoyi.production.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.production.dto.ProductionProductInputDto;
+import com.ruoyi.production.pojo.ProductionProductInput;
+
+public interface ProductionProductInputService extends IService<ProductionProductInput> {
+    IPage<ProductionProductInputDto> listPageProductionProductInputDto(Page page, ProductionProductInputDto productionProductInputDto);
+}
diff --git a/src/main/java/com/ruoyi/production/service/ProductionProductMainService.java b/src/main/java/com/ruoyi/production/service/ProductionProductMainService.java
new file mode 100644
index 0000000..1ef2fae
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/ProductionProductMainService.java
@@ -0,0 +1,15 @@
+package com.ruoyi.production.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.production.dto.ProductionProductMainDto;
+import com.ruoyi.production.pojo.ProductionProductMain;
+
+public interface ProductionProductMainService extends IService<ProductionProductMain> {
+    IPage<ProductionProductMainDto> listPageProductionProductMainDto(Page page, ProductionProductMainDto productionProductMainDto);
+
+    Boolean addProductMain(ProductionProductMainDto productionProductMainDto);
+
+    Boolean removeProductMain(ProductionProductMainDto productionProductMainDto);
+}
diff --git a/src/main/java/com/ruoyi/production/service/ProductionProductOutputService.java b/src/main/java/com/ruoyi/production/service/ProductionProductOutputService.java
new file mode 100644
index 0000000..dea72b5
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/ProductionProductOutputService.java
@@ -0,0 +1,11 @@
+package com.ruoyi.production.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.production.dto.ProductionProductOutputDto;
+import com.ruoyi.production.pojo.ProductionProductOutput;
+
+public interface ProductionProductOutputService extends IService<ProductionProductOutput> {
+    IPage<ProductionProductOutputDto> listPageProductionProductOutputDto(Page page, ProductionProductOutputDto productionProductOutputDto);
+}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProcessRouteItemServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProcessRouteItemServiceImpl.java
new file mode 100644
index 0000000..793ed4d
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProcessRouteItemServiceImpl.java
@@ -0,0 +1,88 @@
+package com.ruoyi.production.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.production.dto.ProcessRouteItemDto;
+import com.ruoyi.production.mapper.ProcessRouteItemMapper;
+import com.ruoyi.production.pojo.ProcessRouteItem;
+import com.ruoyi.production.service.ProcessRouteItemService;
+import lombok.AllArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Service
+@AllArgsConstructor
+@Transactional(rollbackFor = Exception.class)
+public class ProcessRouteItemServiceImpl extends ServiceImpl<ProcessRouteItemMapper, ProcessRouteItem> implements ProcessRouteItemService {
+
+    @Autowired
+    private  ProcessRouteItemMapper processRouteItemMapper;
+
+    @Override
+    public List<ProcessRouteItemDto> listProcessRouteItemDto(ProcessRouteItemDto processRouteItemDto) {
+        return processRouteItemMapper.listProcessRouteItemDto( processRouteItemDto);
+    }
+
+    //鎺掑簭
+    @Override
+    public int sort(ProcessRouteItem processRouteItem) {
+        //鏌ヨ琚敼鍔ㄧ殑杩欐潯鏁版嵁
+        ProcessRouteItem oldProcessRouteItem = processRouteItemMapper.selectById(processRouteItem.getId());
+        //鏌ヨ璇ュ伐鑹鸿矾绾跨殑鎵�鏈夊伐搴忓苟鎸夌収椤哄簭鎺掑簭
+        List<ProcessRouteItem> processRouteItems = processRouteItemMapper.selectList(Wrappers.<ProcessRouteItem>lambdaQuery()
+                .eq(ProcessRouteItem::getRouteId, oldProcessRouteItem.getRouteId())
+                .orderByAsc(ProcessRouteItem::getDragSort));
+        // 鑾峰彇鐩爣浣嶇疆锛堢Щ鍔ㄥ埌绗嚑涓箣鍚庯級
+        Integer targetPosition = processRouteItem.getDragSort();
+        if (targetPosition != null && targetPosition >= 0) {
+            // 绉诲姩鍏冪礌鍒版柊鐨勪綅缃�
+            processRouteItems.remove(oldProcessRouteItem);
+            processRouteItems.add(targetPosition-1, oldProcessRouteItem);
+            // 鏇存柊鎵�鏈夊彈褰卞搷鐨勬帓搴忓瓧娈�
+            for (int i = 0; i < processRouteItems.size(); i++) {
+                ProcessRouteItem item = processRouteItems.get(i);
+                if (!item.getId().equals(oldProcessRouteItem.getId())) {
+                    // 妫�鏌ユ槸鍚﹂渶瑕佹洿鏂版帓搴忓��
+                    if (item.getDragSort() != i+1) {
+                        item.setDragSort(i+1);
+                        processRouteItemMapper.updateById(item);
+                    }
+                } else {
+                    // 鏇存柊鍘熻褰曠殑鏂版帓搴忎綅缃�
+                    oldProcessRouteItem.setDragSort(targetPosition);
+                    processRouteItemMapper.updateById(oldProcessRouteItem);
+                }
+            }
+            return 1;
+        }
+        return 0;
+    }
+
+    @Override
+    public String batchDelete(Long id) {
+        // 鏌ヨ瑕佸垹闄ょ殑鏁版嵁
+        ProcessRouteItem deleteProcessRouteItem = processRouteItemMapper.selectById(id);
+        if (deleteProcessRouteItem == null) {
+            return "鍒犻櫎澶辫触锛屾湭鎵惧埌瀵瑰簲鏁版嵁";
+        }
+        Long routeId = deleteProcessRouteItem.getRouteId();
+        // 鍒犻櫎鎸囧畾鏁版嵁
+        processRouteItemMapper.deleteById(id);
+        // 鏌ヨ璇ュ伐鑹鸿矾绾跨殑鎵�鏈夊伐搴忓苟鎸夌収椤哄簭鎺掑簭
+        List<ProcessRouteItem> processRouteItems = processRouteItemMapper.selectList(Wrappers.<ProcessRouteItem>lambdaQuery()
+                .eq(ProcessRouteItem::getRouteId, routeId)
+                .orderByAsc(ProcessRouteItem::getDragSort));
+        // 閲嶆柊璁剧疆鎺掑簭鍊硷紝浣垮簭鍙疯繛缁�
+        for (int i = 0; i < processRouteItems.size(); i++) {
+            ProcessRouteItem item = processRouteItems.get(i);
+            if (!item.getDragSort().equals(i+1)) {
+                item.setDragSort(i+1);
+                processRouteItemMapper.updateById(item);
+            }
+        }
+        return "鍒犻櫎鎴愬姛";
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProcessRouteServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProcessRouteServiceImpl.java
new file mode 100644
index 0000000..1e48b8b
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProcessRouteServiceImpl.java
@@ -0,0 +1,42 @@
+package com.ruoyi.production.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.production.dto.ProcessRouteDto;
+import com.ruoyi.production.mapper.ProcessRouteMapper;
+import com.ruoyi.production.pojo.ProcessRoute;
+import com.ruoyi.production.service.ProcessRouteService;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+@Service
+@AllArgsConstructor
+@Slf4j
+public class ProcessRouteServiceImpl extends ServiceImpl<ProcessRouteMapper, ProcessRoute> implements ProcessRouteService {
+
+    @Autowired
+    private ProcessRouteMapper processRouteMapper;
+
+    @Override
+    public IPage<ProcessRouteDto> pageProcessRouteDto(Page<ProcessRouteDto> page, ProcessRouteDto processRouteDto) {
+
+        return processRouteMapper.pageProcessRouteDto(page, processRouteDto);
+    }
+
+    @Override
+    public Integer saveProcessRoute(ProcessRoute processRoute) {
+        this.save(processRoute);
+        String dateStr = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+        String idStr = String.format("%06d", processRoute.getId());
+        String newProductCode = "GYLX" + dateStr + idStr;
+        // 鏇存柊鏁版嵁搴撲腑鐨刾roductCode
+        processRoute.setProcessRouteCode(newProductCode);
+        return processRouteMapper.updateById(processRoute);
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java
new file mode 100644
index 0000000..ae09630
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java
@@ -0,0 +1,45 @@
+package com.ruoyi.production.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.production.dto.ProductBomDto;
+import com.ruoyi.production.mapper.ProductBomMapper;
+import com.ruoyi.production.pojo.ProductBom;
+import com.ruoyi.production.service.ProductBomService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * BOM涓昏〃 鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 09:59:27
+ */
+@Service
+public class ProductBomServiceImpl extends ServiceImpl<ProductBomMapper, ProductBom> implements ProductBomService {
+
+    @Autowired
+    private ProductBomMapper productBomMapper;
+
+    @Override
+    public IPage<ProductBomDto> listPage(Page page, ProductBomDto productBomDto) {
+        return productBomMapper.listPage(page,productBomDto);
+    }
+
+    @Override
+    public AjaxResult add(ProductBom productBom) {
+        boolean save = productBomMapper.insert(productBom) > 0;
+        if (save) {
+            // 鏍规嵁id鐢熸垚no瀛楁锛欸X + 8浣嶆暟瀛楋紙涓嶈冻8浣嶅墠闈㈣ˉ0锛�
+            String no = "BM." + String.format("%05d", productBom.getId());
+            productBom.setBomNo(no);
+            productBomMapper.updateById(productBom);
+            return AjaxResult.success();
+        }
+        return AjaxResult.error();
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
new file mode 100644
index 0000000..66f9617
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
@@ -0,0 +1,109 @@
+package com.ruoyi.production.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.production.dto.ProductOrderDto;
+import com.ruoyi.production.dto.ProductStructureDto;
+import com.ruoyi.production.mapper.*;
+import com.ruoyi.production.pojo.*;
+import com.ruoyi.production.service.ProductOrderService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+
+@Service
+public class ProductOrderServiceImpl extends ServiceImpl<ProductOrderMapper, ProductOrder> implements ProductOrderService {
+
+    @Autowired
+    private ProductOrderMapper productOrderMapper;
+
+    @Autowired
+    private ProcessRouteMapper processRouteMapper;
+
+    @Autowired
+    private ProductProcessRouteMapper productProcessRouteMapper;
+
+    @Autowired
+    private ProcessRouteItemMapper processRouteItemMapper;
+
+    @Autowired
+    private ProductProcessRouteItemMapper productProcessRouteItemMapper;
+
+    @Autowired
+    private ProductWorkOrderMapper productWorkOrderMapper;
+
+
+    @Override
+    public IPage<ProductOrderDto> pageProductOrder(Page page, ProductOrderDto productOrder) {
+        return productOrderMapper.pageProductOrder(page, productOrder);
+    }
+
+    @Override
+    public int bindingRoute(ProductOrder productOrder) {
+        //鏂板鐢熶骇璁㈠崟涓嬬殑宸ヨ壓璺嚎涓昏〃
+        ProcessRoute processRoute = processRouteMapper.selectById(productOrder.getRouteId());
+        ProductProcessRoute productProcessRoute = new ProductProcessRoute();
+        productProcessRoute.setProductModelId(processRoute.getProductModelId());
+        productProcessRoute.setProcessRouteCode(processRoute.getProcessRouteCode());
+        productProcessRoute.setProductOrderId(productOrder.getId());
+        productProcessRoute.setBomId(processRoute.getBomId());
+        productProcessRouteMapper.insert(productProcessRoute);
+        //鏂板鐢熶骇璁㈠崟涓嬬殑宸ヨ壓璺嚎瀛愯〃
+        List<ProcessRouteItem> processRouteItems = processRouteItemMapper.selectList(new QueryWrapper<ProcessRouteItem>().lambda().eq(ProcessRouteItem::getRouteId, processRoute.getId()));
+        // 鐢熸垚褰撳墠鏃ユ湡鐨勫墠缂�锛氬勾鏈堟棩
+        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+        for (ProcessRouteItem processRouteItem : processRouteItems) {
+            ProductProcessRouteItem productProcessRouteItem = new ProductProcessRouteItem();
+            productProcessRouteItem.setProductModelId(processRouteItem.getProductModelId());
+            productProcessRouteItem.setProcessId(processRouteItem.getProcessId());
+            productProcessRouteItem.setProductOrderId(productOrder.getId());
+            productProcessRouteItem.setProductRouteId(productProcessRoute.getId());
+            int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
+            if (insert > 0) {
+                // 鏌ヨ浠婃棩宸插瓨鍦ㄧ殑鏈�澶у伐鍗曞彿
+                QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
+                queryWrapper.likeRight("work_order_no", datePrefix)
+                        .orderByDesc("work_order_no")
+                        .last("LIMIT 1");
+                ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
+                int sequenceNumber = 1; // 榛樿搴忓彿
+                if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
+                    String lastNo = lastWorkOrder.getWorkOrderNo().toString();
+                    if (lastNo.startsWith(datePrefix)) {
+                        String seqStr = lastNo.substring(datePrefix.length());
+                        try {
+                            sequenceNumber = Integer.parseInt(seqStr) + 1;
+                        } catch (NumberFormatException e) {
+                            sequenceNumber = 1;
+                        }
+                    }
+                }
+                // 鐢熸垚瀹屾暣鐨勫伐鍗曞彿
+                String workOrderNoStr = String.format("%s%03d", datePrefix, sequenceNumber);
+                ProductWorkOrder productWorkOrder = new ProductWorkOrder();
+                productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId());
+                productWorkOrder.setProductOrderId(productOrder.getId());
+                productWorkOrder.setPlanQuantity(productOrder.getQuantity());
+                productWorkOrder.setWorkOrderNo(workOrderNoStr);
+                productWorkOrder.setStatus(1);
+                productWorkOrderMapper.insert(productWorkOrder);
+            }
+        }
+        return productOrderMapper.updateById(productOrder);
+    }
+
+    @Override
+    public List<ProcessRoute> listProcessRoute(Long productModelId) {
+        return productOrderMapper.listProcessRoute(productModelId);
+    }
+
+    @Override
+    public List<ProductStructureDto> listProcessBom(Long orderId) {
+        return productOrderMapper.listProcessBom(orderId);
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteItemServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteItemServiceImpl.java
new file mode 100644
index 0000000..47cba0e
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteItemServiceImpl.java
@@ -0,0 +1,198 @@
+package com.ruoyi.production.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.dto.ProductProcessRouteItemDto;
+import com.ruoyi.production.mapper.*;
+import com.ruoyi.production.pojo.*;
+import com.ruoyi.production.service.ProductProcessRouteItemService;
+import com.ruoyi.quality.mapper.QualityInspectMapper;
+import com.ruoyi.quality.pojo.QualityInspect;
+import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+
+@Service
+@Transactional(rollbackFor = Exception.class)
+@AllArgsConstructor
+public class ProductProcessRouteItemServiceImpl extends ServiceImpl<ProductProcessRouteItemMapper, ProductProcessRouteItem> implements ProductProcessRouteItemService {
+
+
+    private ProductProcessRouteItemMapper productProcessRouteItemMapper;
+
+    private ProductionProductMainMapper productionProductMainMapper;
+
+    private ProductionProductInputMapper productionProductInputMapper;
+
+    private ProductionProductOutputMapper productionProductOutputMapper;
+
+    private QualityInspectMapper qualityInspectMapper;
+
+    private SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
+
+    private ProductWorkOrderMapper productWorkOrderMapper;
+
+    private ProductOrderMapper productOrderMapper;
+
+    private ProductProcessRouteMapper productProcessRouteMapper;
+
+    private SalesLedgerProductMapper salesLedgerProductMapper;
+
+
+    @Override
+    public List<ProductProcessRouteItemDto> listItem(Long orderId) {
+        return productProcessRouteItemMapper.listItem(orderId);
+    }
+
+    @Override
+    public R deleteRouteItem(Long id) {
+        Long routeItemId = id;
+        try {
+            // 鏌ヨ宸ュ崟
+            ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectOne(
+                    new LambdaQueryWrapper<ProductWorkOrder>()
+                            .eq(ProductWorkOrder::getProductProcessRouteItemId, routeItemId)
+                            .last("LIMIT 1")
+            );
+            if (productWorkOrder == null) {
+                throw new RuntimeException("鍒犻櫎澶辫触锛氭湭鎵惧埌鍏宠仈鐨勭敓浜у伐鍗�");
+            }
+            Long workOrderId = productWorkOrder.getId();
+            Long productOrderId = productWorkOrder.getProductOrderId();
+            // 鏌ヨ鐢熶骇涓昏〃
+            List<ProductionProductMain> productionProductMains = productionProductMainMapper.selectList(
+                    new LambdaQueryWrapper<ProductionProductMain>()
+                            .eq(ProductionProductMain::getWorkOrderId, workOrderId)
+            );
+            if (!productionProductMains.isEmpty()) {
+                // 鎵归噺鍒犻櫎瀛愯〃
+                for (ProductionProductMain main : productionProductMains) {
+                    Long mainId = main.getId();
+                    // 鍒犻櫎鎶曞叆
+                    productionProductInputMapper.delete(new LambdaQueryWrapper<ProductionProductInput>()
+                            .eq(ProductionProductInput::getProductMainId, mainId));
+                    // 鍒犻櫎浜у嚭
+                    productionProductOutputMapper.delete(new LambdaQueryWrapper<ProductionProductOutput>()
+                            .eq(ProductionProductOutput::getProductMainId, mainId));
+                    // 鍒犻櫎璐ㄦ
+                    qualityInspectMapper.delete(new LambdaQueryWrapper<QualityInspect>()
+                            .eq(QualityInspect::getProductMainId, mainId));
+                }
+            }
+            //  鍒犻櫎鎶ュ伐锛堢敓浜т富琛級
+            productionProductMainMapper.delete(new LambdaQueryWrapper<ProductionProductMain>()
+                    .eq(ProductionProductMain::getWorkOrderId, workOrderId));
+            // 鏌ヨ璁㈠崟 + 鍒犻櫎鏍哥畻
+            ProductOrder productOrder = productOrderMapper.selectById(productOrderId);
+            if (productOrder != null && productOrder.getSalesLedgerId() != null) {
+                salesLedgerProductionAccountingMapper.delete(new LambdaQueryWrapper<SalesLedgerProductionAccounting>()
+                        .eq(SalesLedgerProductionAccounting::getSalesLedgerId, productOrder.getSalesLedgerId()));
+            }
+            // 鍒犻櫎鍏宠仈宸ュ崟
+            productWorkOrderMapper.delete(new LambdaQueryWrapper<ProductWorkOrder>()
+                    .eq(ProductWorkOrder::getProductProcessRouteItemId, routeItemId));
+
+            // 鍒犻櫎涓昏〃鏁版嵁
+            ProductProcessRouteItem deleteProductProcessRouteItem = productProcessRouteItemMapper.selectById(routeItemId);
+            Long productRouteId = deleteProductProcessRouteItem.getProductRouteId();
+            // 鍒犻櫎鎸囧畾鏁版嵁
+            productProcessRouteItemMapper.deleteById(id);
+            // 鏌ヨ璇ュ伐鑹鸿矾绾跨殑鎵�鏈夊伐搴忓苟鎸夌収椤哄簭鎺掑簭
+            List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery()
+                    .eq(ProductProcessRouteItem::getProductRouteId, productRouteId)
+                    .orderByAsc(ProductProcessRouteItem::getDragSort));
+            // 閲嶆柊璁剧疆鎺掑簭鍊硷紝浣垮簭鍙疯繛缁�
+            for (int i = 0; i < productProcessRouteItems.size(); i++) {
+                ProductProcessRouteItem item = productProcessRouteItems.get(i);
+                if (!item.getDragSort().equals(i + 1)) {
+                    item.setDragSort(i + 1);
+                    productProcessRouteItemMapper.updateById(item);
+                }
+            }
+            return R.ok();
+        } catch (Exception e) {
+            throw new RuntimeException("鍒犻櫎鐢熶骇宸ヨ壓璺嚎澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @Override
+    public R addRouteItem(ProductProcessRouteItem productProcessRouteItem) {
+        ProductOrder productOrder = productOrderMapper.selectById(productProcessRouteItem.getProductOrderId());
+        int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
+        // 鐢熸垚褰撳墠鏃ユ湡鐨勫墠缂�锛氬勾鏈堟棩
+        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+        if (insert > 0) {
+            // 鏌ヨ浠婃棩宸插瓨鍦ㄧ殑鏈�澶у伐鍗曞彿
+            QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
+            queryWrapper.likeRight("work_order_no", datePrefix)
+                    .orderByDesc("work_order_no")
+                    .last("LIMIT 1");
+            ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
+            int sequenceNumber = 1; // 榛樿搴忓彿
+            if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
+                String lastNo = lastWorkOrder.getWorkOrderNo().toString();
+                if (lastNo.startsWith(datePrefix)) {
+                    String seqStr = lastNo.substring(datePrefix.length());
+                    try {
+                        sequenceNumber = Integer.parseInt(seqStr) + 1;
+                    } catch (NumberFormatException e) {
+                        sequenceNumber = 1;
+                    }
+                }
+            }
+            // 鐢熸垚瀹屾暣鐨勫伐鍗曞彿
+            String workOrderNoStr = String.format("%s%03d", datePrefix, sequenceNumber);
+            ProductWorkOrder productWorkOrder = new ProductWorkOrder();
+            productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId());
+            productWorkOrder.setProductOrderId(productProcessRouteItem.getProductOrderId());
+            productWorkOrder.setPlanQuantity(productOrder.getQuantity());
+            productWorkOrder.setWorkOrderNo(workOrderNoStr);
+            productWorkOrder.setStatus(1);
+            productWorkOrderMapper.insert(productWorkOrder);
+        }
+        return R.ok();
+    }
+
+    @Override
+    public int sortRouteItem(ProductProcessRouteItem productProcessRouteItem) {
+        //鏌ヨ琚敼鍔ㄧ殑杩欐潯鏁版嵁
+        ProductProcessRouteItem oldProductProcessRouteItem = productProcessRouteItemMapper.selectById(productProcessRouteItem.getId());
+        //鏌ヨ璇ュ伐鑹鸿矾绾跨殑鎵�鏈夊伐搴忓苟鎸夌収椤哄簭鎺掑簭
+        List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery()
+                .eq(ProductProcessRouteItem::getProductRouteId, oldProductProcessRouteItem.getProductRouteId())
+                .orderByAsc(ProductProcessRouteItem::getDragSort));
+        // 鑾峰彇鐩爣浣嶇疆锛堢Щ鍔ㄥ埌绗嚑涓箣鍚庯級
+        Integer targetPosition = productProcessRouteItem.getDragSort();
+        if (targetPosition != null && targetPosition >= 0) {
+            // 绉诲姩鍏冪礌鍒版柊鐨勪綅缃�
+            productProcessRouteItems.remove(oldProductProcessRouteItem);
+            productProcessRouteItems.add(targetPosition-1, oldProductProcessRouteItem);
+            // 鏇存柊鎵�鏈夊彈褰卞搷鐨勬帓搴忓瓧娈�
+            for (int i = 0; i < productProcessRouteItems.size(); i++) {
+                ProductProcessRouteItem item = productProcessRouteItems.get(i);
+                if (!item.getId().equals(oldProductProcessRouteItem.getId())) {
+                    // 妫�鏌ユ槸鍚﹂渶瑕佹洿鏂版帓搴忓��
+                    if (item.getDragSort() != i+1) {
+                        item.setDragSort(i+1);
+                        productProcessRouteItemMapper.updateById(item);
+                    }
+                } else {
+                    // 鏇存柊鍘熻褰曠殑鏂版帓搴忎綅缃�
+                    oldProductProcessRouteItem.setDragSort(targetPosition);
+                    productProcessRouteItemMapper.updateById(oldProductProcessRouteItem);
+                }
+            }
+            return 1;
+        }
+        return 0;
+    }
+
+}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteServiceImpl.java
new file mode 100644
index 0000000..b856e34
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteServiceImpl.java
@@ -0,0 +1,29 @@
+package com.ruoyi.production.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.production.dto.ProcessRouteDto;
+import com.ruoyi.production.mapper.ProductProcessRouteMapper;
+import com.ruoyi.production.pojo.ProductProcessRoute;
+import com.ruoyi.production.service.ProductProcessRouteService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-15 02:51:09
+ */
+@Service
+public class ProductProcessRouteServiceImpl extends ServiceImpl<ProductProcessRouteMapper, ProductProcessRoute> implements ProductProcessRouteService {
+
+    @Autowired
+    private ProductProcessRouteMapper productProcessRouteMapper;
+
+    @Override
+    public ProcessRouteDto listMain(Long orderId) {
+        return productProcessRouteMapper.listMain(orderId);
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductProcessServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductProcessServiceImpl.java
new file mode 100644
index 0000000..fc2944e
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductProcessServiceImpl.java
@@ -0,0 +1,62 @@
+package com.ruoyi.production.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.production.dto.ProductProcessDto;
+import com.ruoyi.production.mapper.ProductProcessMapper;
+import com.ruoyi.production.pojo.ProductProcess;
+import com.ruoyi.production.service.ProductProcessService;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+@Service
+public class ProductProcessServiceImpl extends ServiceImpl<ProductProcessMapper, ProductProcess> implements ProductProcessService {
+    @Autowired
+    private ProductProcessMapper productProcessMapper;
+
+    @Override
+    public IPage<ProductProcessDto> listPage(Page page, ProductProcessDto productProcessDto) {
+        return productProcessMapper.listPage(page, productProcessDto);
+    }
+
+    @Override
+    public AjaxResult add(ProductProcessDto productProcessDto) {
+        ProductProcess productProcess = new ProductProcess();
+        BeanUtils.copyProperties(productProcessDto,productProcess);
+        boolean save = productProcessMapper.insert(productProcess) > 0;
+        if (save && ObjectUtils.isNotNull(productProcessDto.getNo())) {
+            // 鏍规嵁id鐢熸垚no瀛楁锛欸X + 8浣嶆暟瀛楋紙涓嶈冻8浣嶅墠闈㈣ˉ0锛�
+            String no = "GX" + String.format("%08d", productProcess.getId());
+            productProcess.setNo(no);
+
+            productProcessMapper.updateById(productProcess);
+            return AjaxResult.success();
+        }
+        return AjaxResult.error();
+    }
+
+    @Override
+    public AjaxResult importData(MultipartFile file) {
+        try {
+            ExcelUtil<ProductProcess> util = new ExcelUtil<ProductProcess>(ProductProcess.class);
+            List<ProductProcess> productProcessList = util.importExcel(file.getInputStream());
+            if(CollectionUtils.isEmpty(productProcessList)){
+                return AjaxResult.warn("妯℃澘閿欒鎴栧鍏ユ暟鎹负绌�");
+            }
+            this.saveOrUpdateBatch(productProcessList);
+            return AjaxResult.success(true);
+        }catch (Exception e){
+            e.printStackTrace();
+            return AjaxResult.error("瀵煎叆澶辫触");
+        }
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java
new file mode 100644
index 0000000..9b76222
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java
@@ -0,0 +1,41 @@
+package com.ruoyi.production.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.production.dto.ProductStructureDto;
+import com.ruoyi.production.mapper.ProductStructureMapper;
+import com.ruoyi.production.pojo.ProductStructure;
+import com.ruoyi.production.service.ProductStructureService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class ProductStructureServiceImpl extends ServiceImpl<ProductStructureMapper, ProductStructure> implements ProductStructureService {
+
+    @Autowired
+    private  ProductStructureMapper productStructureMapper;
+
+
+
+    @Override
+    public Boolean addProductStructureDto(ProductStructureDto productStructureDto) {
+        this.remove(new QueryWrapper<ProductStructure>().lambda().eq(ProductStructure::getBomId, productStructureDto.getBomId()));
+        productStructureDto.getProductStructureList().forEach(productStructure -> {
+            productStructure.setBomId(productStructureDto.getBomId());
+        });
+        return this.saveBatch(productStructureDto.getProductStructureList());
+    }
+
+    @Override
+    public List<ProductStructureDto> listBybomId(Long bomId) {
+        List<ProductStructureDto> tree = productStructureMapper.listBybomId(bomId);
+        return tree;
+
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java
new file mode 100644
index 0000000..6f70e7c
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java
@@ -0,0 +1,32 @@
+package com.ruoyi.production.service.impl;
+
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.production.dto.ProductWorkOrderDto;
+import com.ruoyi.production.mapper.ProductWorkOrderMapper;
+import com.ruoyi.production.pojo.ProductWorkOrder;
+import com.ruoyi.production.service.ProductWorkOrderService;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@AllArgsConstructor
+@Transactional(rollbackFor = Exception.class)
+public class ProductWorkOrderServiceImpl extends ServiceImpl<ProductWorkOrderMapper, ProductWorkOrder> implements ProductWorkOrderService {
+
+    private ProductWorkOrderMapper productWorkOrdermapper;
+
+    @Override
+    public IPage<ProductWorkOrderDto> listPage(Page<ProductWorkOrderDto> page, ProductWorkOrderDto productWorkOrder) {
+        return productWorkOrdermapper.pageProductWorkOrder(page, productWorkOrder);
+    }
+
+    @Override
+    public int updateProductWorkOrder(ProductWorkOrderDto productWorkOrderDto) {
+        return productWorkOrdermapper.updateById(productWorkOrderDto);
+    }
+
+}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionProductInputServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionProductInputServiceImpl.java
new file mode 100644
index 0000000..49765c0
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductInputServiceImpl.java
@@ -0,0 +1,24 @@
+package com.ruoyi.production.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.production.dto.ProductionProductInputDto;
+import com.ruoyi.production.mapper.ProductionProductInputMapper;
+import com.ruoyi.production.pojo.ProductionProductInput;
+import com.ruoyi.production.service.ProductionProductInputService;
+import lombok.AllArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+@AllArgsConstructor
+public class ProductionProductInputServiceImpl extends ServiceImpl<ProductionProductInputMapper, ProductionProductInput> implements ProductionProductInputService {
+    @Autowired
+    private ProductionProductInputMapper productionProductInputMapper;
+
+    @Override
+    public IPage<ProductionProductInputDto> listPageProductionProductInputDto(Page page, ProductionProductInputDto productionProductInputDto) {
+        return productionProductInputMapper.listPageProductionProductInputDto(page, productionProductInputDto);
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
new file mode 100644
index 0000000..5699332
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -0,0 +1,294 @@
+package com.ruoyi.production.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.basic.mapper.ProductMapper;
+import com.ruoyi.basic.mapper.ProductModelMapper;
+import com.ruoyi.basic.pojo.Product;
+import com.ruoyi.basic.pojo.ProductModel;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.common.utils.bean.BeanUtils;
+import com.ruoyi.procurementrecord.mapper.ProcurementRecordOutMapper;
+import com.ruoyi.procurementrecord.pojo.ProcurementRecordOut;
+import com.ruoyi.procurementrecord.utils.StockUtils;
+import com.ruoyi.production.controller.ProductWorkOrderController;
+import com.ruoyi.production.dto.ProductStructureDto;
+import com.ruoyi.production.dto.ProductionProductMainDto;
+import com.ruoyi.production.mapper.*;
+import com.ruoyi.production.pojo.*;
+import com.ruoyi.production.service.ProductionProductMainService;
+import com.ruoyi.project.system.domain.SysUser;
+import com.ruoyi.quality.mapper.QualityInspectMapper;
+import com.ruoyi.quality.mapper.QualityInspectParamMapper;
+import com.ruoyi.quality.mapper.QualityTestStandardMapper;
+import com.ruoyi.quality.pojo.QualityInspect;
+import com.ruoyi.quality.pojo.QualityInspectParam;
+import com.ruoyi.quality.pojo.QualityTestStandard;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+@AllArgsConstructor
+public class ProductionProductMainServiceImpl extends ServiceImpl<ProductionProductMainMapper, ProductionProductMain> implements ProductionProductMainService {
+
+    private final ProcurementRecordOutMapper procurementRecordOutMapper;
+    private ProductionProductMainMapper productionProductMainMapper;
+
+    private ProductWorkOrderController productWorkOrderController;
+
+    private ProductWorkOrderMapper productWorkOrderMapper;
+
+    private ProductProcessRouteItemMapper productProcessRouteItemMapper;
+
+    private ProductionProductOutputMapper productionProductOutputMapper;
+
+    private ProcessRouteItemMapper processRouteItemMapper;
+
+    private ProductModelMapper productModelMapper;
+
+    private QualityInspectMapper qualityInspectMapper;
+
+    private ProductProcessMapper productProcessMapper;
+
+    private ProductMapper productMapper;
+
+    private QualityTestStandardMapper qualityTestStandardMapper;
+
+    private QualityInspectParamMapper qualityInspectParamMapper;
+
+    private ProductStructureMapper productStructureMapper;
+
+    private ProductionProductInputMapper productionProductInputMapper;
+
+    private ProductOrderMapper productOrderMapper;
+
+    private SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
+
+    private StockUtils stockUtils;
+
+
+    @Override
+    public IPage<ProductionProductMainDto> listPageProductionProductMainDto(Page page, ProductionProductMainDto productionProductMainDto) {
+        return productionProductMainMapper.listPageProductionProductMainDto(page, productionProductMainDto);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean addProductMain(ProductionProductMainDto dto) {
+        if (dto == null) {
+            throw new RuntimeException("鍙傛暟涓嶈兘涓虹┖");
+        }
+
+        SysUser user = SecurityUtils.getLoginUser().getUser();
+
+
+        // 鏂板閫昏緫
+        ProductionProductMain productionProductMain = new ProductionProductMain();
+        ProductProcessRouteItem productProcessRouteItem = productProcessRouteItemMapper.selectById(dto.getProductProcessRouteItemId());
+        if (productProcessRouteItem == null) {
+            throw new RuntimeException("宸ヨ壓璺嚎椤逛笉瀛樺湪");
+        }
+
+        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+
+        QueryWrapper<ProductionProductMain> queryWrapper = new QueryWrapper<>();
+        queryWrapper.select("MAX(product_no) as maxNo")
+                .likeRight("product_no", datePrefix);
+
+        List<Map<String, Object>> resultList = productionProductMainMapper.selectMaps(queryWrapper);
+
+        int sequenceNumber = 1;
+        if (resultList != null && !resultList.isEmpty()) {
+            Map<String, Object> result = resultList.get(0);
+
+            if (result != null) {
+                Object maxNoObj = result.get("maxNo");
+                if (maxNoObj != null) {
+                    String lastNo = maxNoObj.toString();
+                    System.out.println("lastNo: " + lastNo);
+
+                    if (lastNo.startsWith(datePrefix)) {
+                        try {
+                            String seqStr = lastNo.substring(datePrefix.length());
+                            sequenceNumber = Integer.parseInt(seqStr) + 1;
+                        } catch (NumberFormatException e) {
+                            sequenceNumber = 1;
+                        }
+                    }
+                }
+            }
+        }
+
+        String productNo = String.format("%s%03d", datePrefix, sequenceNumber);
+        productionProductMain.setProductNo(productNo);
+        productionProductMain.setUserId(user.getUserId());
+        productionProductMain.setProductProcessRouteItemId(dto.getProductProcessRouteItemId());
+        productionProductMain.setWorkOrderId(dto.getWorkOrderId());
+        productionProductMain.setStatus(0);
+        // 娣诲姞鎶ュ伐涓昏〃
+        int insert = productionProductMainMapper.insert(productionProductMain);
+
+        //鏇存柊宸ュ崟
+        if (insert > 0) {
+            Map<String, Object> params = new HashMap<>();
+            params.put("workOrderId", dto.getWorkOrderId());
+            params.put("deductQuantity", dto.getQuantity());
+
+            productWorkOrderMapper.updatePlanQuantity(params);
+        }
+        ProductProcess productProcess = productProcessMapper.selectById(productProcessRouteItem.getProcessId());
+        ProductModel productModel = productProcessRouteItem.getProductModelId() != null ?
+                productModelMapper.selectById(productProcessRouteItem.getProductModelId()) : null;
+
+        if (productModel != null) {
+            Product product = productMapper.selectById(productModel.getProductId());
+            int inspectType = "缁勮".equals(productProcess.getName()) ? 2 : 1;
+
+            QualityInspect qualityInspect = new QualityInspect();
+            qualityInspect.setProductId(product.getId());
+            qualityInspect.setProductName(product.getProductName());
+            qualityInspect.setModel(productModel.getModel());
+            qualityInspect.setUnit(productModel.getUnit());
+            qualityInspect.setQuantity(dto.getQuantity());
+            qualityInspect.setProcess(productProcess.getName());
+            qualityInspect.setInspectState(0);
+            qualityInspect.setInspectType(inspectType);
+            qualityInspect.setProductMainId(productionProductMain.getId());
+            qualityInspect.setProductModelId(productModel.getId());
+            qualityInspectMapper.insert(qualityInspect);
+
+            qualityTestStandardMapper.selectList(
+                    new LambdaQueryWrapper<QualityTestStandard>()
+                            .eq(QualityTestStandard::getProductId, product.getId())
+            ).forEach(standard -> {
+                QualityInspectParam param = new QualityInspectParam();
+                BeanUtils.copyProperties(standard, param);
+                param.setId(null);
+                param.setInspectId(qualityInspect.getId());
+                qualityInspectParamMapper.insert(param);
+            });
+        }
+        // 娣诲姞鎶曞叆
+        if (productModel != null) {
+            List<ProductStructureDto> productStructureDtos = productStructureMapper.listByproductModelId(productModel.getId());
+            for (ProductStructureDto productStructureDto : productStructureDtos) {
+                ProductModel productModel1 = productModelMapper.selectById(productStructureDto.getProductModelId());
+                Product product = productMapper.selectById(productModel1.getProductId());
+                BigDecimal stockQuantity = stockUtils.getStockQuantity(productModel1.getId()).get("stockQuantity");
+                if (!(stockQuantity.compareTo(BigDecimal.ZERO) > 0)) {
+                    throw new RuntimeException(product.getProductName() + "搴撳瓨涓�0");
+                }
+                if (stockQuantity.compareTo(productStructureDto.getUnitQuantity().multiply(dto.getQuantity())) < 0) {
+                    throw new RuntimeException(product.getProductName() + "搴撳瓨涓嶈冻");
+                }
+                ProductionProductInput productionProductInput = new ProductionProductInput();
+                productionProductInput.setProductModelId(productStructureDto.getProductModelId());
+                productionProductInput.setQuantity(productStructureDto.getUnitQuantity().multiply(dto.getQuantity()));
+                productionProductInput.setProductMainId(productionProductMain.getId());
+                productionProductInputMapper.insert(productionProductInput);
+
+
+                DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyyMMdd");
+                LocalDate now = LocalDate.now();
+                ProcurementRecordOut procurementRecordOut1 = procurementRecordOutMapper.selectCode(dateFormat.format(now));
+                Long aLong = procurementRecordOut1 == null ? 1L : Long.valueOf(procurementRecordOut1.getCode().split("LS"+dateFormat.format(now))[1]);
+                //娣诲姞鍑哄簱澶勭悊
+                ProcurementRecordOut.ProcurementRecordOutBuilder procurementRecordOut = ProcurementRecordOut.builder()
+                        .procurementRecordStorageId(0)
+                        .code("LS" + dateFormat.format(now) + String.format("%03d", aLong + 1))
+                        .salesLedgerProductId(0)
+                        .inboundBatches(aLong.equals(0L) ? "绗�1鎵规" : "绗�"+ (aLong + 1) + "鎵规")
+                        .inboundNum(productionProductInput.getQuantity())
+                        .type(4)
+                        .createTime(LocalDateTime.now())
+                        .createUser(user.getUserId())
+                        .createBy(user.getNickName())
+                        .updateUser(user.getUserId())
+                        .updateTime(LocalDateTime.now())
+                        .productModelId(productModel1.getId());
+                procurementRecordOutMapper.insert(procurementRecordOut.build());
+            }
+        }
+
+        // 娣诲姞浜у嚭
+        ProductionProductOutput productionProductOutput = new ProductionProductOutput();
+        productionProductOutput.setProductMainId(productionProductMain.getId());
+        productionProductOutput.setProductModelId(productProcessRouteItem.getProductModelId());
+        productionProductOutput.setQuantity(dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO);
+        productionProductOutputMapper.insert(productionProductOutput);
+
+        // 鑾峰彇鐢熶骇璁㈠崟
+        ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId());
+        List<ProductionProductMain> productionProductMains = productionProductMainMapper.selectList(new QueryWrapper<ProductionProductMain>().lambda().eq(ProductionProductMain::getWorkOrderId, dto.getWorkOrderId()));
+
+        if (productionProductMains.isEmpty()) {
+            productWorkOrder.setActualStartTime(LocalDate.now());
+        }
+        ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId());
+        if (productOrder == null) {
+            throw new RuntimeException("鐢熶骇璁㈠崟涓嶅瓨鍦�");
+        }
+        // 娣诲姞鐢熶骇鏍哥畻
+        SalesLedgerProductionAccounting salesLedgerProductionAccounting = SalesLedgerProductionAccounting.builder()
+                .salesLedgerWorkId(productionProductMain.getId())
+                .salesLedgerSchedulingId(0L)
+                .salesLedgerId(productOrder.getSalesLedgerId())
+                .salesLedgerProductId(productOrder.getProductModelId())
+                .schedulingUserId(user.getUserId())
+                .schedulingUserName(user.getNickName())
+                .finishedNum(dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO)
+                .workHours(productProcess.getSalaryQuota())
+                .process(productProcess.getName())
+                .schedulingDate(LocalDate.now())
+                .tenantId(dto.getTenantId())
+                .build();
+        salesLedgerProductionAccountingMapper.insert(salesLedgerProductionAccounting);
+
+        return true;
+    }
+
+    @Override
+    @Transactional
+    public Boolean removeProductMain(ProductionProductMainDto dto) {
+        Long id = dto.getId();
+
+        // 鏇存柊宸ュ崟
+        productWorkOrderMapper.rollbackPlanQuantity(id);
+        // 鍒犻櫎璐ㄦ鍙傛暟鍜岃川妫�璁板綍
+        qualityInspectMapper.selectList(
+                new LambdaQueryWrapper<QualityInspect>()
+                        .eq(QualityInspect::getProductMainId, id)
+        ).forEach(q -> {
+            qualityInspectParamMapper.delete(
+                    new LambdaQueryWrapper<QualityInspectParam>()
+                            .eq(QualityInspectParam::getInspectId, q.getId()));
+            qualityInspectMapper.deleteById(q.getId());
+        });
+
+        // 鍒犻櫎浜у嚭璁板綍
+        productionProductOutputMapper.delete(new LambdaQueryWrapper<ProductionProductOutput>()
+                .eq(ProductionProductOutput::getProductMainId, id)
+        );
+
+        // 鍒犻櫎鍏宠仈鐨勬牳绠楁暟鎹�
+        salesLedgerProductionAccountingMapper.delete(
+                new LambdaQueryWrapper<SalesLedgerProductionAccounting>()
+                        .eq(SalesLedgerProductionAccounting::getSalesLedgerWorkId, id)
+        );
+
+        // 鍒犻櫎涓昏〃
+        return productionProductMainMapper.deleteById(id) > 0;
+    }
+}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionProductOutputServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionProductOutputServiceImpl.java
new file mode 100644
index 0000000..654b9af
--- /dev/null
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductOutputServiceImpl.java
@@ -0,0 +1,24 @@
+package com.ruoyi.production.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.production.dto.ProductionProductOutputDto;
+import com.ruoyi.production.mapper.ProductionProductOutputMapper;
+import com.ruoyi.production.pojo.ProductionProductOutput;
+import com.ruoyi.production.service.ProductionProductOutputService;
+import lombok.AllArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+@AllArgsConstructor
+public class ProductionProductOutputServiceImpl extends ServiceImpl<ProductionProductOutputMapper, ProductionProductOutput> implements ProductionProductOutputService {
+    @Autowired
+    private ProductionProductOutputMapper productionProductOutputMapper;
+
+    @Override
+    public IPage<ProductionProductOutputDto> listPageProductionProductOutputDto(Page page, ProductionProductOutputDto productionProductOutputDto) {
+        return productionProductOutputMapper.listPageProductionProductOutputDto(page, productionProductOutputDto);
+    }
+}
diff --git a/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java b/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
index e1b2e6a..7a95c99 100644
--- a/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
+++ b/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
@@ -137,6 +137,16 @@
      * 绫诲埆(0:鏈彁浜�;1:宸叉彁浜�)
      */
     private Integer inspectState;
+    private Long purchaseLedgerId;
+
+    /**
+     * 鎶ュ伐id
+     */
+    private Long productMainId;
+
+    private Long productModelId;
+    //涓嶅悎鏍肩幇璞�
+    private String defectivePhenomena;
 
 
 }
diff --git a/src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml b/src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
index 0ce76e2..14fe896 100644
--- a/src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
+++ b/src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
@@ -163,4 +163,9 @@
                   left join sales_ledger_product t2 on t2.id = t1.sales_ledger_product_id
                   left join purchase_ledger t3 on t3.id = t2.sales_ledger_id
     </select>
+    <select id="getSumQuantity" resultType="BigDecimal">
+        select COALESCE(sum(inbound_num), 0)
+        from procurement_record_storage
+        where product_model_id = #{productModelId}
+    </select>
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/procurementrecord/ProcurementRecordOutMapper.xml b/src/main/resources/mapper/procurementrecord/ProcurementRecordOutMapper.xml
index ec91c53..2a880ba 100644
--- a/src/main/resources/mapper/procurementrecord/ProcurementRecordOutMapper.xml
+++ b/src/main/resources/mapper/procurementrecord/ProcurementRecordOutMapper.xml
@@ -50,4 +50,17 @@
                   left join sales_ledger_product t2 on t2.id = t1.sales_ledger_product_id
                   left join purchase_ledger t3 on t3.id = t2.sales_ledger_id
     </select>
+    <select id="getSumQuantity" resultType="BigDecimal">
+        select COALESCE(sum(inbound_num), 0)
+        from procurement_record_out
+        where
+            product_model_id = #{productModelId}
+    </select>
+    <select id="selectCode" resultType="com.ruoyi.procurementrecord.pojo.ProcurementRecordOut">
+        select *
+        from procurement_record_out
+        where code like concat('%', #{format})
+        order by id desc
+        limit 1
+    </select>
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/production/ProcessRouteItemMapper.xml b/src/main/resources/mapper/production/ProcessRouteItemMapper.xml
new file mode 100644
index 0000000..1b5e2b4
--- /dev/null
+++ b/src/main/resources/mapper/production/ProcessRouteItemMapper.xml
@@ -0,0 +1,35 @@
+<?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.ProcessRouteItemMapper">
+
+    <resultMap id="basicMap" type="com.ruoyi.production.pojo.ProcessRouteItem">
+        <id property="id" column="id"/>
+        <result property="routeId" column="route_id"/>
+        <result property="processId" column="process_id"/>
+        <result property="productModelId" column="product_model_id"/>
+        <result property="tenantId" column="tenant_id"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="dragSort" column="drag_sort"/>
+    </resultMap>
+
+    <select id="listProcessRouteItemDto" resultType="com.ruoyi.production.dto.ProcessRouteItemDto">
+        select pri.*,
+               pr.description ,
+               pp.name as process_name,
+               pm.speculative_trading_name,
+               pm.product_id,
+               pm.model,
+               p.product_name,
+               pm.unit
+        from
+            process_route_item pri
+                left join product_model pm on pri.product_model_id = pm.id
+                left join product_process pp on pp.id = pri.process_id
+                left join product p on p.id = pm.product_id
+                left join process_route pr on pr.id = pri.route_id
+        where
+            pri.route_id = #{c.routeId}
+        order by pri.drag_sort
+    </select>
+</mapper>
diff --git a/src/main/resources/mapper/production/ProcessRouteMapper.xml b/src/main/resources/mapper/production/ProcessRouteMapper.xml
new file mode 100644
index 0000000..51c11b4
--- /dev/null
+++ b/src/main/resources/mapper/production/ProcessRouteMapper.xml
@@ -0,0 +1,28 @@
+<?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.ProcessRouteMapper">
+
+
+    <resultMap id="basicMap" type="com.ruoyi.production.pojo.ProcessRoute">
+            <id property="id" column="id"/>
+            <result property="productModelId" column="product_model_id"/>
+            <result property="description" column="description"/>
+            <result property="tenantId" column="tenant_id"/>
+            <result property="createTime" column="create_time"/>
+            <result property="updateTime" column="update_time"/>
+    </resultMap>
+
+    <select id="pageProcessRouteDto" resultType="com.ruoyi.production.dto.ProcessRouteDto">
+        select ps.*, p.product_name,pm.product_id,pm.model,pb.bom_no
+        from process_route ps
+        left join product_bom pb on ps.bom_id = pb.id
+        left join product_model pm on ps.product_model_id = pm.id
+        left join product p on pm.product_id = p.id
+        <where>
+            <if test="c.model != null and c.model != ''">
+                and pm.model like concat('%',#{c.model},'%')
+            </if>
+        </where>
+        order by ps.id asc
+    </select>
+</mapper>
diff --git a/src/main/resources/mapper/production/ProductBomMapper.xml b/src/main/resources/mapper/production/ProductBomMapper.xml
new file mode 100644
index 0000000..ec06cd3
--- /dev/null
+++ b/src/main/resources/mapper/production/ProductBomMapper.xml
@@ -0,0 +1,48 @@
+<?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.ProductBomMapper">
+
+    <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+    <resultMap id="BaseResultMap" type="com.ruoyi.production.pojo.ProductBom">
+        <id column="id" property="id"/>
+        <result column="product_model_id" property="productModelId"/>
+        <result column="bom_no" property="bomNo"/>
+        <result column="remark" property="remark"/>
+        <result column="version" property="version"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="create_user" property="createUser"/>
+        <result column="update_user" property="updateUser"/>
+        <result column="tenant_id" property="tenantId"/>
+    </resultMap>
+    <select id="listPage" resultType="com.ruoyi.production.dto.ProductBomDto">
+        select * from (select pb.*,
+        pm.model productModelName,
+        p.product_name productName
+        from product_bom pb
+        left join product_model pm on pb.product_model_id = pm.id
+        left join product p on pm.product_id = p.id)A
+        where 1=1
+        <if test="c.productModelName != null">
+            and productModelName = #{c.productModelName}
+        </if>
+        <if test="c.productName != null">
+            and productName = #{c.productName}
+        </if>
+        <if test="c.bomNo != null">
+            and bom_no = #{c.bomNo}
+        </if>
+        <if test="c.version != null">
+            and version = #{c.version}
+        </if>
+    </select>
+    <select id="getById" resultType="com.ruoyi.production.dto.ProductBomDto">
+        select pb.*,
+               pm.model productModelName,
+               p.product_name productName
+        from product_bom pb
+                 left join product_model pm on pb.product_model_id = pm.id
+                 left join product p on pm.product_id = p.id
+    </select>
+
+</mapper>
diff --git a/src/main/resources/mapper/production/ProductOrderMapper.xml b/src/main/resources/mapper/production/ProductOrderMapper.xml
new file mode 100644
index 0000000..b47d5cf
--- /dev/null
+++ b/src/main/resources/mapper/production/ProductOrderMapper.xml
@@ -0,0 +1,89 @@
+<?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.ProductOrderMapper">
+
+
+    <resultMap id="basicMap" type="com.ruoyi.production.pojo.ProductOrder">
+        <id property="id" column="id"/>
+        <result property="productModelId" column="product_model_id"/>
+        <result property="tenantId" column="tenant_id"/>
+        <result property="salesLedgerId" column="sales_ledger_id"/>
+        <result property="routeId" column="route_id"/>
+        <result property="npsNo" column="nps_no"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateTime" column="update_time"/>
+    </resultMap>
+    <select id="pageProductOrder" resultType="com.ruoyi.production.dto.ProductOrderDto">
+        select po.*,
+        sl.sales_contract_no,
+        sl.customer_name,
+        slp.product_category,
+        slp.specification_model,
+        ppr.process_route_code,
+        pb.bom_no,
+        ROUND(po.complete_quantity / po.quantity * 100, 2) AS completionStatus
+        from product_order po
+        left join sales_ledger sl on po.sales_ledger_id = sl.id
+        left join sales_ledger_product slp on po.product_model_id = slp.id
+        left join product_process_route ppr on po.id = ppr.product_order_id
+        left join product_bom pb on pb.id = ppr.bom_id
+        <where>
+            <if test="c.npsNo != null and c.npsNo != ''">
+                and po.nps_no like concat('%',#{c.npsNo},'%')
+            </if>
+            <if test="c.salesContractNo != null and c.salesContractNo != ''">
+                and sl.sales_contract_no like concat('%',#{c.salesContractNo},'%')
+            </if>
+            <if test="c.customerName != null and c.customerName != ''">
+                and sl.customer_name like concat('%',#{c.customerName},'%')
+            </if>
+            <if test="c.productCategory != null and c.productCategory != ''">
+                and slp.product_category like concat('%',#{c.productCategory},'%')
+            </if>
+            <if test="c.specificationModel != null and c.specificationModel != ''">
+                and slp.specification_model like concat('%',#{c.specificationModel},'%')
+            </if>
+        </where>
+    </select>
+    <select id="productMainByOrderId" resultType="com.ruoyi.production.dto.ProductOrderDto">
+        select po.*,
+               pwo.work_order_no,
+               pwo.report_work,
+               pwo.status,
+               pwo.quantity,
+               pwo.plan_quantity
+        from product_order po
+                 left join product_work_order pwo on po.id = pwo.product_order_id
+        where po.id = #{c.id}
+    </select>
+    <select id="listProcessRoute" resultType="com.ruoyi.production.pojo.ProcessRoute">
+        select pr.*
+        from process_route pr
+                 left join product_model pm on pr.product_model_id = pm.id
+                 left join sales_ledger_product slp on pm.id = slp.product_model_id
+        where slp.id = #{productModelId}
+    </select>
+    <select id="listProcessBom" resultType="com.ruoyi.production.dto.ProductStructureDto">
+        select ps.id,
+               ps.product_model_id,
+               ps.process_id,
+               ps.unit_quantity,
+               ps.unit_quantity * po.quantity as demandedQuantity,
+               ps.unit,
+               p.product_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
+        where ppr.product_order_id = #{orderId}
+        order by ps.id
+    </select>
+
+
+</mapper>
diff --git a/src/main/resources/mapper/production/ProductProcessMapper.xml b/src/main/resources/mapper/production/ProductProcessMapper.xml
new file mode 100644
index 0000000..a2292e2
--- /dev/null
+++ b/src/main/resources/mapper/production/ProductProcessMapper.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.production.mapper.ProductProcessMapper">
+
+    <select id="listPage" resultType="com.ruoyi.production.dto.ProductProcessDto">
+        SELECT
+        *
+        FROM
+        product_process p
+        <where>
+            <if test="productProcessDto.name != null and productProcessDto.name != '' ">
+                AND  p.name LIKE CONCAT('%',#{productProcessDto.name},'%')
+            </if>
+            <if test="productProcessDto.no != null and productProcessDto.no != '' ">
+                AND  p.no LIKE CONCAT('%',#{productProcessDto.no},'%')
+            </if>
+        </where>
+        order by p.id asc
+    </select>
+</mapper>
diff --git a/src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml b/src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml
new file mode 100644
index 0000000..13f0ad7
--- /dev/null
+++ b/src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml
@@ -0,0 +1,28 @@
+<?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.ProductProcessRouteItemMapper">
+
+
+    <resultMap id="basicMap" type="com.ruoyi.production.pojo.ProductProcessRouteItem">
+        <id property="id" column="id"/>
+        <result property="productModelId" column="product_model_id"/>
+        <result property="tenantId" column="tenant_id"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateTime" column="update_time"/>
+    </resultMap>
+    <select id="listItem" resultType="com.ruoyi.production.dto.ProductProcessRouteItemDto">
+        select ppri.*,
+               pp.name as process_name,
+               pm.model,
+               pm.unit,
+               p.product_name
+        from product_process_route_item ppri
+                 left join product_model pm on ppri.product_model_id = pm.id
+                 left join product p on pm.product_id = p.id
+                 left join product_process pp on pp.id = ppri.process_id
+        where ppri.product_order_id = #{orderId}
+        order by ppri.drag_sort
+    </select>
+
+
+</mapper>
diff --git a/src/main/resources/mapper/production/ProductProcessRouteMapper.xml b/src/main/resources/mapper/production/ProductProcessRouteMapper.xml
new file mode 100644
index 0000000..dd4809f
--- /dev/null
+++ b/src/main/resources/mapper/production/ProductProcessRouteMapper.xml
@@ -0,0 +1,26 @@
+<?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.ProductProcessRouteMapper">
+
+    <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+    <resultMap id="BaseResultMap" type="com.ruoyi.production.pojo.ProductProcessRoute">
+        <id column="id" property="id"/>
+        <result column="product_model_id" property="productModelId"/>
+        <result column="description" property="description"/>
+        <result column="tenant_id" property="tenantId"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="bom_id" property="bomId"/>
+        <result column="process_route_code" property="processRouteCode"/>
+        <result column="product_order_id" property="productOrderId"/>
+    </resultMap>
+    <select id="listMain" resultType="com.ruoyi.production.dto.ProcessRouteDto">
+        select ppr.*, p.product_name, pm.product_id, pm.model, pb.bom_no
+        from product_process_route ppr
+                 left join product_bom pb on ppr.bom_id = pb.id
+                 left join product_model pm on ppr.product_model_id = pm.id
+                 left join product p on pm.product_id = p.id
+        where ppr.product_order_id = #{orderId}
+    </select>
+
+</mapper>
diff --git a/src/main/resources/mapper/production/ProductStructureMapper.xml b/src/main/resources/mapper/production/ProductStructureMapper.xml
new file mode 100644
index 0000000..1833487
--- /dev/null
+++ b/src/main/resources/mapper/production/ProductStructureMapper.xml
@@ -0,0 +1,43 @@
+<?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.ProductStructureMapper">
+
+    <resultMap id="basicMap" type="com.ruoyi.production.pojo.ProductStructure">
+        <id property="id" column="id"/>
+        <result property="productModelId" column="product_model_id"/>
+        <result property="processId" column="process_id"/>
+        <result property="unitQuantity" column="unit_quantity"/>
+        <result property="demandedQuantity" column="demanded_quantity"/>
+        <result property="unit" column="unit"/>
+        <result property="tenantId" column="tenant_id"/>
+    </resultMap>
+    <select id="listBybomId" resultType="com.ruoyi.production.dto.ProductStructureDto">
+        select ps.*,
+               p.product_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
+        where ps.bom_id = #{bomId}
+        order by ps.id
+    </select>
+    <select id="listByproductModelId" resultType="com.ruoyi.production.dto.ProductStructureDto">
+        select ps.*,
+               p.product_name,
+               pp.name as  process_name,
+               pm.product_id,
+               pm.model
+        from
+            product_structure ps
+                left join product_bom pb on ps.bom_id = pb.id
+                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
+        where pb.product_model_id = #{productModelId}
+        order by ps.id
+    </select>
+</mapper>
diff --git a/src/main/resources/mapper/production/ProductWorkOrderMapper.xml b/src/main/resources/mapper/production/ProductWorkOrderMapper.xml
new file mode 100644
index 0000000..2ab8057
--- /dev/null
+++ b/src/main/resources/mapper/production/ProductWorkOrderMapper.xml
@@ -0,0 +1,70 @@
+<?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.ProductWorkOrderMapper">
+
+    <resultMap id="BaseResultMap" type="com.ruoyi.production.pojo.ProductWorkOrder">
+        <result column="id" property="id"/>
+        <result column="product_process_route_item_id" property="productProcessRouteItemId"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="work_order_no" property="workOrderNo"/>
+        <result column="status" property="status"/>
+        <result column="tenant_id" property="tenantId"/>
+        <result column="actual_end_time" property="planStartTime"/>
+        <result column="plan_end_time" property="planEndTime"/>
+        <result column="actual_start_time" property="actualStartTime"/>
+        <result column="actualEndTime" property="actualEndTime"/>
+    </resultMap>
+
+    <select id="pageProductWorkOrder" resultType="com.ruoyi.production.dto.ProductWorkOrderDto">
+        SELECT
+        pwo.*,
+        pp.NAME as processName,
+        pm.model,
+        pm.unit,
+        p.product_name AS productName,
+        po.nps_no AS productOrderNpsNo,
+        ROUND(pwo.complete_quantity / pwo.plan_quantity * 100, 2) AS completionStatus
+        FROM
+        product_work_order pwo
+        LEFT JOIN product_process_route_item ppri ON ppri.id = pwo.product_process_route_item_id
+        LEFT JOIN product_order po ON po.id = pwo.product_order_id
+        LEFT JOIN product_process pp ON pp.id = ppri.process_id
+        LEFT JOIN product_model pm ON pm.id = ppri.product_model_id
+        LEFT JOIN product p ON p.id = pm.product_id
+        <where>
+            <if test="c.workOrderNo != null and c.workOrderNo != ''">
+                pwo.work_order_no like concat('%',#{c.workOrderNo},'%')
+            </if>
+        </where>
+    </select>
+    <select id="selectProductWorkOrderDtoList" resultType="com.ruoyi.production.dto.ProductWorkOrderDto">
+        select *
+        from product_work_order pwo
+        left join product_order po on po.id = pwo.product_order_id
+    </select>
+
+    <update id="updatePlanQuantity" parameterType="java.util.Map">
+        UPDATE product_work_order
+        SET
+            report_work = #{reportWork},
+            plan_quantity = plan_quantity - #{deductQuantity}
+        WHERE id = #{workOrderId}
+    </update>
+
+    <update id="rollbackPlanQuantity" parameterType="java.lang.Long">
+        UPDATE product_work_order pwo
+        INNER JOIN production_product_main ppm
+        ON pwo.id = ppm.work_order_id
+        AND ppm.id = #{productMainId}
+        INNER JOIN production_product_output ppo
+        ON ppo.product_main_id = ppm.id
+        SET
+        pwo.plan_quantity = pwo.plan_quantity + ppo.quantity,
+        pwo.report_work = 0,
+        pwo.quantity = 0
+        WHERE pwo.id = ppm.work_order_id
+    </update>
+</mapper>
diff --git a/src/main/resources/mapper/production/ProductionProductInputMapper.xml b/src/main/resources/mapper/production/ProductionProductInputMapper.xml
new file mode 100644
index 0000000..7d203f3
--- /dev/null
+++ b/src/main/resources/mapper/production/ProductionProductInputMapper.xml
@@ -0,0 +1,36 @@
+<?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.ProductionProductInputMapper">
+
+    <resultMap id="basicMap" type="com.ruoyi.production.pojo.ProductionProductInput">
+        <id property="id" column="id"/>
+        <result property="productMainId" column="product_main_id"/>
+        <result property="productModelId" column="product_model_id"/>
+        <result property="quantity" column="quantity"/>
+        <result property="tenantId" column="tenant_id"/>
+        <result property="createTime" column="create_time"/>
+    </resultMap>
+    <select id="listPageProductionProductInputDto" resultType="com.ruoyi.production.dto.ProductionProductInputDto">
+        select ppi.*,
+        pm.model as model,
+        ppm.product_no as productNo
+        from
+        production_product_input ppi
+        left join production_product_main ppm on ppm.id = ppi.product_main_id
+        left join product_model pm on pm.id = ppi.product_model_id
+        <where>
+            <if test="c.productMainId != null and c.productMainId > 0">
+                and ppm.id = #{c.productMainId}
+            </if>
+        </where>
+        order by ppi.id
+    </select>
+
+    <delete id="deleteByProductMainIds" parameterType="java.util.List">
+        DELETE FROM production_product_input
+        WHERE product_main_id IN
+        <foreach collection="productMainIds" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>
diff --git a/src/main/resources/mapper/production/ProductionProductMainMapper.xml b/src/main/resources/mapper/production/ProductionProductMainMapper.xml
new file mode 100644
index 0000000..3a0542c
--- /dev/null
+++ b/src/main/resources/mapper/production/ProductionProductMainMapper.xml
@@ -0,0 +1,48 @@
+<?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.ProductionProductMainMapper">
+
+    <resultMap id="basicMap" type="com.ruoyi.production.pojo.ProductionProductMain">
+        <id property="id" column="id"/>
+        <result property="productNo" column="product_no"/>
+        <result property="userId" column="user_id"/>
+        <result property="workOrderId" column="work_order_id"/>
+        <result property="tenantId" column="tenant_id"/>
+        <result property="createTime" column="create_time"/>
+        <result property="status" column="status"/>
+    </resultMap>
+
+    <select id="listPageProductionProductMainDto" resultType="com.ruoyi.production.dto.ProductionProductMainDto">
+        select ppm.*,
+               pwo.work_order_no as workOrderNo,
+               pwo.status as workOrderStatus,
+               u.nick_name as nickName
+        from
+            production_product_main ppm
+                left join product_work_order pwo on pwo.id = ppm.work_order_id
+                left join sys_user u on u.user_id = ppm.user_id
+        <where>
+            <if test="c.nickName != null and c.nickName != ''">
+                and u.nick_name like concat('%',#{c.nickName},'%')
+            </if>
+            <if test="c.workOrderNo != null and c.workOrderNo != ''">
+                and pwo.work_order_no like concat('%',#{c.workOrderNo},'%')
+            </if>
+            <if test="c.workOrderStatus != null and c.workOrderStatus != ''">
+                and pwo.status = #{c.workOrderStatus}
+            </if>
+            <if test="c.status != null and c.status != ''">
+                and ppm.status = #{c.status}
+            </if>
+        </where>
+        order by ppm.id
+    </select>
+
+    <delete id="deleteByWorkOrderIds" parameterType="java.util.List">
+        DELETE FROM production_product_main
+        WHERE work_order_id IN
+        <foreach collection="workOrderIds" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>
diff --git a/src/main/resources/mapper/production/ProductionProductOutputMapper.xml b/src/main/resources/mapper/production/ProductionProductOutputMapper.xml
new file mode 100644
index 0000000..e5d17fc
--- /dev/null
+++ b/src/main/resources/mapper/production/ProductionProductOutputMapper.xml
@@ -0,0 +1,37 @@
+<?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.ProductionProductOutputMapper">
+
+    <resultMap id="basicMap" type="com.ruoyi.production.pojo.ProductionProductOutput">
+        <id property="id" column="id"/>
+        <result property="productMainId" column="product_main_id"/>
+        <result property="productModelId" column="product_model_id"/>
+        <result property="quantity" column="quantity"/>
+        <result property="tenantId" column="tenant_id"/>
+        <result property="createTime" column="create_time"/>
+    </resultMap>
+
+    <select id="listPageProductionProductOutputDto" resultType="com.ruoyi.production.dto.ProductionProductOutputDto">
+        select ppo.*,
+        pm.model as model,
+        ppm.product_no as productNo
+        from
+        production_product_output ppo
+        left join production_product_main ppm on ppm.id = ppo.product_main_id
+        left join product_model pm on pm.id = ppo.product_model_id
+        <where>
+            <if test="c.productMainId != null and c.productMainId > 0">
+                and ppm.id = #{c.productMainId}
+            </if>
+        </where>
+        order by ppo.id
+    </select>
+
+    <delete id="deleteByProductMainIds" parameterType="java.util.List">
+        DELETE FROM production_product_output
+        WHERE product_main_id IN
+        <foreach collection="productMainIds" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

--
Gitblit v1.9.3