소스 검색

工单工序排产

Pengxy 3 달 전
부모
커밋
c1af12d4b5
100개의 변경된 파일3133개의 추가작업 그리고 5개의 파일을 삭제
  1. 146 0
      QUICK_START_GUIDE.md
  2. 153 0
      WORKORDER_SCHEDULE_FIX_SUMMARY.md
  3. 208 0
      mapper/makeplan/WorkOrderScheduleMapper.xml
  4. 3 2
      pom.xml
  5. 126 0
      rename-product-to-makeplan.ps1
  6. 91 0
      restart-backend.ps1
  7. 10 0
      start-backend-simple.ps1
  8. 75 0
      test-workorder-api.sh
  9. 52 0
      test-workorder-data.md
  10. 84 0
      test-workorder-schedule-api.sh
  11. 96 0
      verify-module-rename.ps1
  12. 150 0
      verify-module-rename.sh
  13. 2 1
      yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java
  14. 189 0
      yudao-module-makeplan/QUICK_CHECK.md
  15. 295 0
      yudao-module-makeplan/WORKORDER_SCHEDULE_IMPLEMENTATION.md
  16. 77 0
      yudao-module-makeplan/pom.xml
  17. 100 0
      yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/controller/admin/workorder/WorkOrderScheduleController.java
  18. 16 0
      yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/controller/admin/workorder/vo/WorkOrderCloseReqVO.java
  19. 63 0
      yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/controller/admin/workorder/vo/WorkOrderSchedulePageReqVO.java
  20. 123 0
      yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/controller/admin/workorder/vo/WorkOrderScheduleRespVO.java
  21. 28 0
      yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/controller/admin/workorder/vo/WorkOrderScheduleUpdateReqVO.java
  22. 18 0
      yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/controller/admin/workorder/vo/WorkOrderUrgentReqVO.java
  23. 272 0
      yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/dal/dataobject/WorkOrderScheduleDO.java
  24. 65 0
      yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/dal/mysql/WorkOrderScheduleMapper.java
  25. 72 0
      yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/service/WorkOrderScheduleService.java
  26. 203 0
      yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/service/impl/WorkOrderScheduleServiceImpl.java
  27. 210 0
      yudao-module-makeplan/src/main/resources/mapper/makeplan/WorkOrderScheduleMapper.xml
  28. 204 0
      yudao-module-makeplan/src/main/resources/mapper/product/WorkOrderScheduleMapper.xml
  29. 0 0
      yudao-module-order/LINKAGE_PLAN_COMPLETION.md
  30. 0 0
      yudao-module-order/LINKAGE_PLAN_IMPLEMENTATION.md
  31. 0 0
      yudao-module-order/SHIPPING_PLAN_IMPLEMENTATION.md
  32. 0 0
      yudao-module-order/USER_INFO_ENHANCEMENT.md
  33. 0 0
      yudao-module-order/WORKORDER_BACKEND_SUMMARY.md
  34. 0 0
      yudao-module-order/WORKORDER_COMPLETE_SUMMARY.md
  35. 0 0
      yudao-module-order/WORKORDER_FIX_SUMMARY.md
  36. 0 0
      yudao-module-order/WORKORDER_FRONTEND_FIX_SUMMARY.md
  37. 2 2
      yudao-module-order/pom.xml
  38. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/OrderDeliveryController.java
  39. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/OrderDeliveryPageItemVO.java
  40. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/OrderDeliveryPageReqVO.java
  41. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/SalesOutboundReqVO.java
  42. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShipmentListItemVO.java
  43. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShipmentPageReqVO.java
  44. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShipmentRespVO.java
  45. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShipmentSaveReqVO.java
  46. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShippingPlanListItemVO.java
  47. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShippingPlanPageReqVO.java
  48. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShippingPlanRespVO.java
  49. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShippingPlanSaveReqVO.java
  50. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ValueStreamRespVO.java
  51. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/linkage/LinkagePlanController.java
  52. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/linkage/vo/LinkagePlanPageReqVO.java
  53. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/linkage/vo/LinkagePlanRespVO.java
  54. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/OrderChangeController.java
  55. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/OrderReviewController.java
  56. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderChangeCreateReqVO.java
  57. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderChangeRespVO.java
  58. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderEntryRespVO.java
  59. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderEntrySaveReqVO.java
  60. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderRespVO.java
  61. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderReviewPageItemVO.java
  62. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderReviewPageReqVO.java
  63. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderSaveReqVO.java
  64. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/WorkOrderController.java
  65. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/vo/MaterialCheckReqVO.java
  66. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/vo/MaterialRequirementReqVO.java
  67. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/vo/WorkOrderPoolPageReqVO.java
  68. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/vo/WorkOrderPoolRespVO.java
  69. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/vo/WorkOrderReleaseReqVO.java
  70. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/vo/WorkOrderUpdateReqVO.java
  71. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/convert/LinkagePlanConvert.java
  72. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/convert/OrderConvert.java
  73. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/convert/OrderDeliveryConvert.java
  74. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/LinkagePlanDO.java
  75. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/OrderChangeDO.java
  76. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/OrderDO.java
  77. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/OrderEntryDO.java
  78. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/ShipmentDetailDO.java
  79. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/ShipmentMasterDO.java
  80. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/ShippingPlanDO.java
  81. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/ShippingPlanDetailDO.java
  82. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/WorkOrdMasterDO.java
  83. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/LinkagePlanMapper.java
  84. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/OrderChangeMapper.java
  85. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/OrderDeliveryMapper.java
  86. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/OrderEntryMapper.java
  87. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/OrderMapper.java
  88. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/ShipmentDetailMapper.java
  89. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/ShipmentMasterMapper.java
  90. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/ShippingPlanDetailMapper.java
  91. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/ShippingPlanMapper.java
  92. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/WorkOrdMasterMapper.java
  93. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/enums/ErrorCodeConstants.java
  94. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/framework/web/config/OrderWebConfiguration.java
  95. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/service/LinkagePlanService.java
  96. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/service/OrderChangeService.java
  97. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/service/OrderDeliveryService.java
  98. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/service/OrderService.java
  99. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/service/ShipmentService.java
  100. 0 0
      yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/service/WorkOrderService.java

+ 146 - 0
QUICK_START_GUIDE.md

@@ -0,0 +1,146 @@
+# 快速启动指南
+
+## 后端启动
+
+### 方式一:直接运行 JAR 包(推荐)
+
+```bash
+# 1. 清理并打包
+cd yudao-server
+mvn clean package -DskipTests
+
+# 2. 启动服务
+java -jar target/yudao-server.jar --spring.profiles.active=local
+```
+
+### 方式二:使用 Maven 插件
+
+```bash
+cd yudao-server
+mvn spring-boot:run "-Dspring-boot.run.profiles=local"
+```
+
+### 常见问题
+
+#### 问题1:XML 解析错误
+```
+Caused by: org.xml.sax.SAXParseException: 元素内容必须由格式正确的字符数据或标记组成
+```
+
+**解决方案**:清理 target 目录后重新编译
+```bash
+# 清理所有模块的 target 目录
+mvn clean
+
+# 或者手动删除
+rm -rf yudao-module-*/target
+rm -rf yudao-server/target
+
+# 重新打包
+cd yudao-server
+mvn clean package -DskipTests
+```
+
+#### 问题2:Bean 冲突
+```
+The bean 'xxx' could not be registered. A bean with that name has already been defined
+```
+
+**解决方案**:
+1. 检查是否有重复的 Bean 定义
+2. 删除重复的配置类
+3. 参考 `BEAN_CONFLICT_FIX.md`
+
+#### 问题3:Mapper 冲突
+```
+Annotation-specified bean name 'xxxMapper' conflicts with existing
+```
+
+**解决方案**:
+1. 重命名 Mapper 接口
+2. 更新对应的 XML 文件
+3. 参考 `MAPPER_CONFLICT_FIX.md`
+
+#### 问题4:TypeAlias 冲突
+```
+MyBatis TypeAlias conflict
+```
+
+**解决方案**:
+1. 重命名 DO 类
+2. 更新所有引用
+3. 清理 target 目录
+4. 参考 `TYPEALIAS_CONFLICT_FIX.md`
+
+## 前端启动
+
+```bash
+cd yudao-ui/yudao-ui-admin-vue3
+
+# 安装依赖(首次运行)
+pnpm install
+
+# 启动开发服务器
+pnpm dev
+```
+
+访问地址:`http://localhost:80`
+
+## 验证服务
+
+### 后端服务
+- API 地址:`http://localhost:48080`
+- API 文档:`http://localhost:48080/doc.html`
+- Druid 监控:`http://localhost:48080/druid`
+
+### 前端服务
+- 管理后台:`http://localhost:80`
+
+## 完整重启流程
+
+当遇到问题需要完全重启时:
+
+```bash
+# 1. 停止所有服务
+# 按 Ctrl+C 停止前后端服务
+
+# 2. 清理编译文件
+mvn clean
+
+# 3. 重新编译后端
+cd yudao-server
+mvn clean package -DskipTests
+
+# 4. 启动后端
+java -jar target/yudao-server.jar --spring.profiles.active=local
+
+# 5. 启动前端(新终端)
+cd yudao-ui/yudao-ui-admin-vue3
+pnpm dev
+```
+
+## 开发建议
+
+1. **修改代码后**:
+   - Java 代码修改:需要重启后端
+   - Vue 代码修改:热更新自动生效
+   - XML 文件修改:需要重启后端
+
+2. **修改 DO 类后**:
+   - 必须清理 target 目录
+   - 重新编译整个项目
+   - 避免使用 `mvn install`,优先使用 `mvn clean package`
+
+3. **添加新模块后**:
+   - 更新根 pom.xml
+   - 更新 yudao-server/pom.xml
+   - 清理并重新编译
+
+4. **数据库变更后**:
+   - 更新 SQL 脚本
+   - 更新对应的 DO 类
+   - 更新 Mapper XML
+
+## 日期
+
+2026-02-04

+ 153 - 0
WORKORDER_SCHEDULE_FIX_SUMMARY.md

@@ -0,0 +1,153 @@
+# 工单工序排产列表问题修复总结
+
+## 问题描述
+前端菜单"工单工序排产"点击后打开的页面 `jiaohuo/ProductionSchedule.vue` 调用了不存在的API `/admin-api/jiaohuo/production/schedule/list`,导致后端报错404。
+
+## 根本原因
+1. 前端菜单关联的页面是 `jiaohuo/ProductionSchedule.vue`
+2. 该页面调用的是旧的 `jiaohuo/production` API
+3. 但实际后端实现的是 `product/workorder-schedule` API
+4. XML查询语句使用了SQL Server语法(如嵌套子查询的ROW_NUMBER),需要改为MySQL语法
+
+## 修复内容
+
+### 1. 修复XML查询语句 (WorkOrderScheduleMapper.xml)
+**文件**: `yudao-module-product/src/main/resources/mapper/product/WorkOrderScheduleMapper.xml`
+
+**修改内容**:
+- 将SQL Server的嵌套子查询语法改为MySQL的窗口函数语法
+- 使用 `<![CDATA[<=]]>` 和 `<![CDATA[>]]>` 来转义XML中的比较运算符
+- 简化ROW_NUMBER子查询,直接在LEFT JOIN中使用窗口函数
+
+**关键修改**:
+```sql
+-- 修改前(SQL Server嵌套子查询)
+LEFT JOIN (
+    SELECT morder_no, create_time AS checktime
+    FROM (
+        SELECT morder_no, create_time,
+               ROW_NUMBER() OVER (PARTITION BY morder_no ORDER BY create_time DESC) AS rn
+        FROM b_examine_result
+    ) ranked
+    WHERE rn = 1
+) exm ON exm.morder_no = a.WorkOrd
+
+-- 修改后(MySQL窗口函数)
+LEFT JOIN (
+    SELECT morder_no, create_time AS checktime,
+           ROW_NUMBER() OVER (PARTITION BY morder_no ORDER BY create_time DESC) AS rn
+    FROM b_examine_result
+) exm ON exm.morder_no = a.WorkOrd AND exm.rn = 1
+```
+
+### 2. 修复前端页面API调用 (ProductionSchedule.vue)
+**文件**: `yudao-ui/yudao-ui-admin-vue3/src/views/jiaohuo/ProductionSchedule.vue`
+
+**修改内容**:
+1. **修改API导入**:
+   ```javascript
+   // 修改前
+   import { 
+     getProductionScheduleList, 
+     closeWorkOrders, 
+     generateProductionSchedule, 
+     syncMaterialRequirement,
+     syncProcessRoute,
+     setWorkOrderUrgent
+   } from '@/api/jiaohuo/production'
+   
+   // 修改后
+   import { 
+     getWorkOrderSchedulePage,
+     closeWorkOrders,
+     productionSchedule,
+     syncMaterialRequirement,
+     syncRouting,
+     setUrgent
+   } from '@/api/product/workorderSchedule'
+   ```
+
+2. **修改查询方法**:
+   - 使用 `getWorkOrderSchedulePage` 替代 `getProductionScheduleList`
+   - 参数名改为小驼峰格式: `workOrd`, `itemNum`, `status`
+   - 使用 `pageNo` 和 `pageSize` 参数
+
+3. **修改字段名**:
+   - 搜索表单字段: `WorkOrd` → `workOrd`, `ItemNum` → `itemNum`, `Status` → `status`
+   - 表格列字段: 所有大驼峰改为小驼峰(如 `Priority` → `priority`)
+   - 状态值: `'p'/'r'/'c'` → `'open'/'released'/'closed'`
+
+4. **修改API调用**:
+   - `generateProductionSchedule` → `productionSchedule(domain)`
+   - `syncProcessRoute(workOrd)` → `syncRouting(id)`
+   - `setWorkOrderUrgent({workOrd, urgentLevel})` → `setUrgent({id, urgent})`
+
+5. **启用自动查询**:
+   ```javascript
+   // 修改前
+   // handleSearch()  // 注释掉
+   
+   // 修改后
+   handleSearch()  // 启用
+   ```
+
+### 3. 重新编译后端模块
+```bash
+mvn clean install -DskipTests -pl yudao-module-product -am
+```
+
+### 4. 重启后端服务
+```bash
+# 停止旧进程
+Get-Process -Name java | Stop-Process -Force
+
+# 启动新进程
+cd yudao-server
+mvn spring-boot:run -Dspring-boot.run.profiles=local
+```
+
+## 验证步骤
+
+1. **等待后端启动完成** (约1-2分钟)
+   - 访问 `http://localhost:48080/doc.html` 确认后端已启动
+
+2. **登录系统**
+   - 访问前端页面
+   - 使用管理员账号登录
+
+3. **测试工单工序排产页面**
+   - 点击菜单"工单工序排产"
+   - 应该能看到数据列表(如果数据库中有数据)
+   - 测试查询、分页等功能
+
+4. **检查浏览器控制台**
+   - 打开F12开发者工具
+   - 查看Network标签,确认API请求成功
+   - 查看Console标签,确认没有JavaScript错误
+
+## 注意事项
+
+1. **数据库数据**: 如果WorkOrdMaster表中没有数据或Status字段为空,列表将显示为空
+2. **权限配置**: 确保用户拥有 `product:workorder-schedule:query` 权限
+3. **Domain参数**: 生产排程和同步物料需求功能需要传入正确的domain参数
+4. **状态映射**: 后端返回的状态值是小写的 `open/released/closed`,前端需要正确映射显示文本
+
+## 相关文件
+
+### 后端文件
+- `yudao-module-product/src/main/resources/mapper/product/WorkOrderScheduleMapper.xml`
+- `yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/controller/admin/workorder/WorkOrderScheduleController.java`
+- `yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/service/impl/WorkOrderScheduleServiceImpl.java`
+- `yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/WorkOrderScheduleMapper.java`
+
+### 前端文件
+- `yudao-ui/yudao-ui-admin-vue3/src/views/jiaohuo/ProductionSchedule.vue`
+- `yudao-ui/yudao-ui-admin-vue3/src/api/product/workorderSchedule.ts`
+
+## 后续优化建议
+
+1. **统一命名规范**: 建议统一使用小驼峰命名,避免混用大小驼峰
+2. **Domain参数获取**: 从用户登录信息或系统配置中获取domain参数
+3. **错误处理**: 增强错误提示,区分不同类型的错误(网络错误、权限错误、数据错误等)
+4. **数据验证**: 添加前端表单验证,确保输入数据的有效性
+5. **页面整合**: 考虑是否需要保留两个工单排产页面(`product/WorkOrderSchedule.vue` 和 `jiaohuo/ProductionSchedule.vue`),建议统一使用一个

+ 208 - 0
mapper/makeplan/WorkOrderScheduleMapper.xml

@@ -0,0 +1,208 @@
+<?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="cn.iocoder.yudao.module.makeplan.dal.mysql.WorkOrderScheduleMapper">
+
+    <!-- 工单排产列表查询 -->
+    <select id="selectSchedulePage" resultType="cn.iocoder.yudao.module.makeplan.controller.admin.workorder.vo.WorkOrderScheduleRespVO">
+        SELECT 
+            a.RecID AS id,
+            exm.checktime,
+            a.Batch AS batch,
+            a.Drawing AS drawing,
+            a.Typed AS typed,
+            a.WorkOrd AS workOrd,
+            a.OrdDate AS ordDate,
+            a.DueDate AS dueDate,
+            a.ItemNum AS itemNum,
+            a.Project AS project,
+            a.QtyOrded AS qtyOrded,
+            a.QtyCompleted AS qtyCompleted,
+            a.Remark AS remark,
+            LOWER(a.Status) AS status,
+            a.WoTyped AS woTyped,
+            b.Descr AS descr,
+            b.Descr1 AS descr1,
+            a.lbrvar,
+            r.Area AS area,
+            se.custom_no AS customNo,
+            cm.Terms AS terms,
+            a.IsInitial AS isInitial,
+            CASE 
+                WHEN cm.Terms = '' OR cm.Terms IS NULL THEN
+                    CASE r.Area 
+                        WHEN '中国' THEN DATE_ADD(a.DueDate, INTERVAL 15 DAY)
+                        WHEN '海外' THEN DATE_ADD(a.DueDate, INTERVAL 8 DAY)
+                        ELSE NULL 
+                    END
+                ELSE
+                    CASE 
+                        WHEN cm.Terms = '海外' THEN DATE_ADD(a.DueDate, INTERVAL 8 DAY)
+                        ELSE DATE_ADD(a.DueDate, INTERVAL 15 DAY)
+                    END
+            END AS mjtime,
+            a.LotSerial AS lotSerial,
+            CASE WHEN a.CreateGLforLaborVar = 1 THEN '是' ELSE '否' END AS createGLforLaborVar,
+            a.QtyOrded - a.QtyCompleted AS zz,
+            s.PlanDate AS planDate,
+            s.ProdDate AS prodDate,
+            CASE 
+                WHEN s.PlanDate IS NULL THEN ''
+                WHEN s.PlanDate IS NOT NULL AND s.ProdDate IS NULL THEN
+                    CASE 
+                        WHEN DATEDIFF(CURDATE(), s.PlanDate) <= 2 AND DATEDIFF(CURDATE(), s.PlanDate) > 0 THEN '低'
+                        WHEN DATEDIFF(CURDATE(), s.PlanDate) <= 5 AND DATEDIFF(CURDATE(), s.PlanDate) > 2 THEN '中'
+                        WHEN DATEDIFF(CURDATE(), s.PlanDate) > 5 THEN '高'
+                    END
+                WHEN s.PlanDate IS NOT NULL AND s.ProdDate IS NOT NULL THEN
+                    CASE 
+                        WHEN DATEDIFF(s.ProdDate, s.PlanDate) <= 2 AND DATEDIFF(s.ProdDate, s.PlanDate) > 0 THEN '低'
+                        WHEN DATEDIFF(s.ProdDate, s.PlanDate) <= 5 AND DATEDIFF(s.ProdDate, s.PlanDate) > 2 THEN '中'
+                        WHEN DATEDIFF(s.ProdDate, s.PlanDate) > 5 THEN '高'
+                    END
+            END AS level,
+            a.IssueSite AS issueSite,
+            IFNULL(ins.WorkOrd, '') AS insWorkOrd,
+            CASE 
+                WHEN a.DispatchWeek = '' OR a.DispatchWeek IS NULL THEN
+                    CASE 
+                        WHEN a.LotSerial != '' AND a.LotSerial IS NOT NULL THEN
+                            CONCAT('WK', WEEK(STR_TO_DATE(SUBSTRING(a.LotSerial, 1, 6), '%y%m%d')))
+                        ELSE ''
+                    END
+                ELSE a.DispatchWeek
+            END AS checkweek,
+            a.Priority AS priority,
+            IFNULL(a.LocationStock, 0) + IFNULL(a.OpQtyCompleted, 0) AS locationStock
+        FROM WorkOrdMaster a
+        LEFT JOIN ItemMaster b ON a.ItemNum = b.ItemNum AND b.Domain = a.Domain
+        LEFT JOIN ReplenishmentWeekPlan r ON a.WorkOrd = r.ProductionOrder AND a.Domain = r.factory_id
+        LEFT JOIN crm_seorder se ON se.bill_no = a.SalesJob
+        LEFT JOIN CustMaster cm ON cm.Cust = se.custom_no
+        LEFT JOIN (
+            SELECT Domain, WorkOrds, MIN(PlanDate) AS PlanDate, MIN(ProdDate) AS ProdDate 
+            FROM PeriodSequenceDet 
+            GROUP BY Domain, WorkOrds
+        ) s ON a.Domain = s.Domain AND a.WorkOrd = s.WorkOrds
+        LEFT JOIN (
+            SELECT morder_no, create_time AS checktime
+            FROM (
+                SELECT morder_no, create_time,
+                       ROW_NUMBER() OVER (PARTITION BY morder_no ORDER BY create_time DESC) AS rn
+                FROM b_examine_result
+            ) ranked
+            WHERE rn = 1
+        ) exm ON exm.morder_no = a.WorkOrd
+        LEFT JOIN WorkOrdInStorage ins ON a.WorkOrd = ins.WorkOrd AND ins.Remark = '工单预留'
+        <where>
+            a.Status != ''
+            <if test="workOrd != null and workOrd != ''">
+                AND a.WorkOrd LIKE CONCAT('%', #{workOrd}, '%')
+            </if>
+            <if test="itemNum != null and itemNum != ''">
+                AND a.ItemNum LIKE CONCAT('%', #{itemNum}, '%')
+            </if>
+            <if test="status != null and status != ''">
+                AND LOWER(a.Status) = #{status}
+            </if>
+            <if test="woTyped != null and woTyped != ''">
+                AND a.WoTyped = #{woTyped}
+            </if>
+            <if test="batch != null and batch != ''">
+                AND a.Batch = #{batch}
+            </if>
+            <if test="drawing != null and drawing != ''">
+                AND a.Drawing = #{drawing}
+            </if>
+            <if test="customNo != null and customNo != ''">
+                AND se.custom_no = #{customNo}
+            </if>
+            <if test="ordDateStart != null">
+                AND a.OrdDate &gt;= #{ordDateStart}
+            </if>
+            <if test="ordDateEnd != null">
+                AND a.OrdDate &lt;= #{ordDateEnd}
+            </if>
+            <if test="dueDateStart != null">
+                AND a.DueDate &gt;= #{dueDateStart}
+            </if>
+            <if test="dueDateEnd != null">
+                AND a.DueDate &lt;= #{dueDateEnd}
+            </if>
+            <if test="priority != null">
+                AND a.Priority = #{priority}
+            </if>
+            <if test="urgent != null">
+                AND a.Urgent = #{urgent}
+            </if>
+            <if test="isInitial != null">
+                AND a.IsInitial = #{isInitial}
+            </if>
+        </where>
+        ORDER BY a.UpdateTime DESC, a.Priority DESC
+    </select>
+
+    <!-- 根据ID查询工单详情 -->
+    <select id="selectScheduleById" resultType="cn.iocoder.yudao.module.makeplan.controller.admin.workorder.vo.WorkOrderScheduleRespVO">
+        SELECT 
+            a.RecID AS id,
+            a.Batch AS batch,
+            a.Drawing AS drawing,
+            a.Typed AS typed,
+            a.WorkOrd AS workOrd,
+            a.OrdDate AS ordDate,
+            a.DueDate AS dueDate,
+            a.ItemNum AS itemNum,
+            a.Project AS project,
+            a.QtyOrded AS qtyOrded,
+            a.QtyCompleted AS qtyCompleted,
+            a.Remark AS remark,
+            LOWER(a.Status) AS status,
+            a.WoTyped AS woTyped,
+            b.Descr AS descr,
+            b.Descr1 AS descr1,
+            a.lbrvar,
+            a.IsInitial AS isInitial,
+            a.LotSerial AS lotSerial,
+            CASE WHEN a.CreateGLforLaborVar = 1 THEN '是' ELSE '否' END AS createGLforLaborVar,
+            a.QtyOrded - a.QtyCompleted AS zz,
+            a.IssueSite AS issueSite,
+            a.Priority AS priority,
+            IFNULL(a.LocationStock, 0) + IFNULL(a.OpQtyCompleted, 0) AS locationStock
+        FROM WorkOrdMaster a
+        LEFT JOIN ItemMaster b ON a.ItemNum = b.ItemNum AND b.Domain = a.Domain
+        WHERE a.RecID = #{id}
+    </select>
+
+    <!-- 调用存储过程关闭工单 -->
+    <select id="callCloseWorkOrders" statementType="CALLABLE">
+        {CALL pr_MES_CloseWorkOrders(#{ids})}
+    </select>
+
+    <!-- 同步工艺路线 -->
+    <update id="syncRoutingByWorkOrd">
+        DELETE FROM WorkOrdRouting WHERE WorkOrd = #{workOrd};
+        
+        INSERT INTO WorkOrdRouting(
+            Domain, Descr, MilestoneOp, WorkOrd, OP, ParentOp, RunTime, ItemNum, 
+            QtyOrded, OverlapUnits, Status, IsActive, CommentIndex, CreateTime, 
+            StdOp, PackingQty, WorkOrdMasterRecID
+        )
+        SELECT 
+            w.Domain, r.Descr, r.MilestoneOp, w.WorkOrd, r.OP, r.ParentOp, r.RunTime, 
+            w.ItemNum, w.QtyOrded, r.OverlapUnits, w.Status, 1, r.CommentIndex, NOW(), 
+            r.StdOp, r.PackingQty, w.RecID 
+        FROM WorkOrdMaster w 
+        LEFT JOIN RoutingOpDetail r ON w.ItemNum = r.RoutingCode 
+        WHERE w.WorkOrd = #{workOrd} AND r.MilestoneOp IS NOT NULL
+    </update>
+
+    <!-- 批量查询工单信息 -->
+    <select id="selectBatchByIds" resultType="cn.iocoder.yudao.module.makeplan.dal.dataobject.WorkOrderScheduleDO">
+        SELECT * FROM WorkOrdMaster
+        WHERE RecID IN
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </select>
+
+</mapper>

+ 3 - 2
pom.xml

@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
@@ -12,7 +12,8 @@
         <module>yudao-framework</module>
         <!-- Server 主项目 -->
         <module>yudao-server</module>
-        <module>yudao-order-server</module>
+        <module>yudao-module-order</module>
+        <module>yudao-module-makeplan</module>
         <module>yudao-all-server</module>
         <module>yudao-module-qms</module>
         <!-- 各种 module 拓展 -->

+ 126 - 0
rename-product-to-makeplan.ps1

@@ -0,0 +1,126 @@
+# Rename yudao-module-product to yudao-module-makeplan
+# Including folders, packages, API paths, and all references
+
+Write-Host "========================================" -ForegroundColor Cyan
+Write-Host "Starting module rename: product -> makeplan" -ForegroundColor Cyan
+Write-Host "========================================" -ForegroundColor Cyan
+
+# 1. Rename module folder
+Write-Host "`n[1/8] Renaming module folder..." -ForegroundColor Yellow
+if (Test-Path "yudao-module-product") {
+    Rename-Item -Path "yudao-module-product" -NewName "yudao-module-makeplan"
+    Write-Host "Module folder renamed successfully" -ForegroundColor Green
+} else {
+    Write-Host "yudao-module-product folder not found" -ForegroundColor Red
+    exit 1
+}
+
+# 2. Rename mapper folder
+Write-Host "`n[2/8] Renaming mapper folder..." -ForegroundColor Yellow
+if (Test-Path "mapper/product") {
+    Rename-Item -Path "mapper/product" -NewName "mapper/makeplan"
+    Write-Host "Mapper folder renamed successfully" -ForegroundColor Green
+}
+
+# 3. Rename Java package
+Write-Host "`n[3/8] Renaming Java package..." -ForegroundColor Yellow
+$javaPath = "yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module"
+if (Test-Path "$javaPath/product") {
+    Rename-Item -Path "$javaPath/product" -NewName "makeplan"
+    Write-Host "Java package renamed successfully" -ForegroundColor Green
+}
+
+# 4. Update package references in Java files
+Write-Host "`n[4/8] Updating package references in Java files..." -ForegroundColor Yellow
+$javaFiles = Get-ChildItem -Path "yudao-module-makeplan" -Filter "*.java" -Recurse
+$count = 0
+foreach ($file in $javaFiles) {
+    $content = Get-Content $file.FullName -Raw -Encoding UTF8
+    $newContent = $content -replace 'cn\.iocoder\.yudao\.module\.product', 'cn.iocoder.yudao.module.makeplan'
+    if ($content -ne $newContent) {
+        Set-Content -Path $file.FullName -Value $newContent -Encoding UTF8 -NoNewline
+        $count++
+    }
+}
+Write-Host "Updated $count Java files" -ForegroundColor Green
+
+# 5. Update pom.xml files
+Write-Host "`n[5/8] Updating pom.xml files..." -ForegroundColor Yellow
+$pomFiles = @(
+    "pom.xml",
+    "yudao-module-makeplan/pom.xml"
+)
+$count = 0
+foreach ($pomFile in $pomFiles) {
+    if (Test-Path $pomFile) {
+        $content = Get-Content $pomFile -Raw -Encoding UTF8
+        $newContent = $content -replace 'yudao-module-product', 'yudao-module-makeplan'
+        $newContent = $newContent -replace '<artifactId>product</artifactId>', '<artifactId>makeplan</artifactId>'
+        $newContent = $newContent -replace '<module>yudao-module-product</module>', '<module>yudao-module-makeplan</module>'
+        if ($content -ne $newContent) {
+            Set-Content -Path $pomFile -Value $newContent -Encoding UTF8 -NoNewline
+            $count++
+        }
+    }
+}
+Write-Host "Updated $count pom.xml files" -ForegroundColor Green
+
+# 6. Update mapper XML files
+Write-Host "`n[6/8] Updating mapper XML files..." -ForegroundColor Yellow
+$xmlFiles = Get-ChildItem -Path "yudao-module-makeplan" -Filter "*.xml" -Recurse
+$count = 0
+foreach ($file in $xmlFiles) {
+    $content = Get-Content $file.FullName -Raw -Encoding UTF8
+    $newContent = $content -replace 'cn\.iocoder\.yudao\.module\.product', 'cn.iocoder.yudao.module.makeplan'
+    $newContent = $newContent -replace 'mapper/product/', 'mapper/makeplan/'
+    if ($content -ne $newContent) {
+        Set-Content -Path $file.FullName -Value $newContent -Encoding UTF8 -NoNewline
+        $count++
+    }
+}
+Write-Host "Updated $count XML files" -ForegroundColor Green
+
+# 7. Update frontend API paths
+Write-Host "`n[7/8] Updating frontend API paths..." -ForegroundColor Yellow
+# Rename frontend API folder
+if (Test-Path "yudao-ui/yudao-ui-admin-vue3/src/api/product") {
+    Rename-Item -Path "yudao-ui/yudao-ui-admin-vue3/src/api/product" -NewName "makeplan"
+}
+
+# Update frontend files
+$frontendFiles = Get-ChildItem -Path "yudao-ui/yudao-ui-admin-vue3/src" -Include "*.vue","*.ts","*.js" -Recurse
+$count = 0
+foreach ($file in $frontendFiles) {
+    $content = Get-Content $file.FullName -Raw -Encoding UTF8
+    $newContent = $content -replace '@/api/product/', '@/api/makeplan/'
+    $newContent = $newContent -replace '/product/workorder-schedule', '/makeplan/workorder-schedule'
+    if ($content -ne $newContent) {
+        Set-Content -Path $file.FullName -Value $newContent -Encoding UTF8 -NoNewline
+        $count++
+    }
+}
+Write-Host "Updated $count frontend files" -ForegroundColor Green
+
+# 8. Update application config files
+Write-Host "`n[8/8] Updating application config files..." -ForegroundColor Yellow
+$configFiles = Get-ChildItem -Path "yudao-server/src/main/resources" -Filter "application*.yaml" -Recurse
+$count = 0
+foreach ($file in $configFiles) {
+    $content = Get-Content $file.FullName -Raw -Encoding UTF8
+    $newContent = $content -replace 'yudao\.module\.product', 'yudao.module.makeplan'
+    $newContent = $newContent -replace 'mapper/product/', 'mapper/makeplan/'
+    if ($content -ne $newContent) {
+        Set-Content -Path $file.FullName -Value $newContent -Encoding UTF8 -NoNewline
+        $count++
+    }
+}
+Write-Host "Updated $count config files" -ForegroundColor Green
+
+Write-Host "`n========================================" -ForegroundColor Cyan
+Write-Host "Module rename completed!" -ForegroundColor Green
+Write-Host "========================================" -ForegroundColor Cyan
+Write-Host "`nNext steps:" -ForegroundColor Yellow
+Write-Host "1. Run: mvn clean install -DskipTests" -ForegroundColor White
+Write-Host "2. Start backend service" -ForegroundColor White
+Write-Host "3. Start frontend service" -ForegroundColor White
+Write-Host "4. Test work order schedule functionality" -ForegroundColor White

+ 91 - 0
restart-backend.ps1

@@ -0,0 +1,91 @@
+# 一键重启后端服务脚本
+
+Write-Host "=========================================" -ForegroundColor Cyan
+Write-Host "后端服务重启脚本" -ForegroundColor Cyan
+Write-Host "=========================================" -ForegroundColor Cyan
+Write-Host ""
+
+# 1. 停止现有的 Java 进程
+Write-Host "步骤 1: 停止现有的 Java 进程..." -ForegroundColor Yellow
+$javaProcesses = Get-Process | Where-Object {$_.ProcessName -like "*java*"}
+
+if ($javaProcesses) {
+    Write-Host "找到 $($javaProcesses.Count) 个 Java 进程" -ForegroundColor Green
+    foreach ($process in $javaProcesses) {
+        Write-Host "  - 进程 ID: $($process.Id), 启动时间: $($process.StartTime)" -ForegroundColor Gray
+    }
+    
+    $confirm = Read-Host "是否停止这些进程?(Y/N)"
+    if ($confirm -eq 'Y' -or $confirm -eq 'y') {
+        foreach ($process in $javaProcesses) {
+            try {
+                Stop-Process -Id $process.Id -Force
+                Write-Host "  ✓ 已停止进程 $($process.Id)" -ForegroundColor Green
+            } catch {
+                Write-Host "  ✗ 无法停止进程 $($process.Id): $_" -ForegroundColor Red
+            }
+        }
+    } else {
+        Write-Host "已取消停止进程" -ForegroundColor Yellow
+        exit 0
+    }
+} else {
+    Write-Host "未找到运行中的 Java 进程" -ForegroundColor Gray
+}
+
+Write-Host ""
+
+# 2. 清理并重新编译
+Write-Host "步骤 2: 清理并重新编译项目..." -ForegroundColor Yellow
+Write-Host "执行命令: mvn clean install -DskipTests" -ForegroundColor Gray
+Write-Host ""
+
+$compileConfirm = Read-Host "是否执行编译?这可能需要几分钟 (Y/N)"
+if ($compileConfirm -eq 'Y' -or $compileConfirm -eq 'y') {
+    try {
+        mvn clean install -DskipTests
+        if ($LASTEXITCODE -eq 0) {
+            Write-Host ""
+            Write-Host "✓ 编译成功!" -ForegroundColor Green
+        } else {
+            Write-Host ""
+            Write-Host "✗ 编译失败,请检查错误信息" -ForegroundColor Red
+            exit 1
+        }
+    } catch {
+        Write-Host "✗ 编译过程出错: $_" -ForegroundColor Red
+        exit 1
+    }
+} else {
+    Write-Host "已跳过编译步骤" -ForegroundColor Yellow
+}
+
+Write-Host ""
+
+# 3. 启动后端服务
+Write-Host "步骤 3: 启动后端服务..." -ForegroundColor Yellow
+Write-Host "执行命令: cd yudao-server && mvn spring-boot:run -Dspring-boot.run.profiles=local" -ForegroundColor Gray
+Write-Host ""
+
+$startConfirm = Read-Host "是否启动后端服务?(Y/N)"
+if ($startConfirm -eq 'Y' -or $startConfirm -eq 'y') {
+    Write-Host ""
+    Write-Host "正在启动后端服务..." -ForegroundColor Green
+    Write-Host "提示: 服务启动后,请访问 http://localhost:48080/doc.html 验证" -ForegroundColor Cyan
+    Write-Host ""
+    
+    Set-Location yudao-server
+    mvn spring-boot:run -Dspring-boot.run.profiles=local
+} else {
+    Write-Host ""
+    Write-Host "已跳过启动步骤" -ForegroundColor Yellow
+    Write-Host ""
+    Write-Host "手动启动命令:" -ForegroundColor Cyan
+    Write-Host "  cd yudao-server" -ForegroundColor Gray
+    Write-Host "  mvn spring-boot:run -Dspring-boot.run.profiles=local" -ForegroundColor Gray
+}
+
+Write-Host ""
+Write-Host "=========================================" -ForegroundColor Cyan
+Write-Host "完成" -ForegroundColor Cyan
+Write-Host "=========================================" -ForegroundColor Cyan

+ 10 - 0
start-backend-simple.ps1

@@ -0,0 +1,10 @@
+# 简单的后端启动脚本
+
+Write-Host "正在启动后端服务..." -ForegroundColor Green
+Write-Host "配置文件: local" -ForegroundColor Gray
+Write-Host ""
+
+Set-Location yudao-server
+
+# 使用 cmd 来执行 Maven 命令,避免 PowerShell 参数解析问题
+cmd /c "mvn spring-boot:run -Dspring-boot.run.profiles=local"

+ 75 - 0
test-workorder-api.sh

@@ -0,0 +1,75 @@
+#!/bin/bash
+
+# 工单排产 API 测试脚本
+# 用于快速验证后端服务是否正常
+
+echo "========================================="
+echo "工单排产模块 API 测试"
+echo "========================================="
+echo ""
+
+# 配置
+BASE_URL="http://localhost:48080"
+API_PREFIX="/admin-api/product/workorder-schedule"
+
+# 颜色定义
+GREEN='\033[0;32m'
+RED='\033[0;31m'
+YELLOW='\033[1;33m'
+NC='\033[0m' # No Color
+
+# 测试函数
+test_api() {
+    local endpoint=$1
+    local description=$2
+    
+    echo -e "${YELLOW}测试: ${description}${NC}"
+    echo "URL: ${BASE_URL}${API_PREFIX}${endpoint}"
+    
+    response=$(curl -s -w "\n%{http_code}" "${BASE_URL}${API_PREFIX}${endpoint}")
+    http_code=$(echo "$response" | tail -n1)
+    body=$(echo "$response" | sed '$d')
+    
+    if [ "$http_code" == "200" ]; then
+        echo -e "${GREEN}✓ 成功 (HTTP $http_code)${NC}"
+        echo "响应: ${body:0:200}..."
+    elif [ "$http_code" == "401" ] || [ "$http_code" == "403" ]; then
+        echo -e "${YELLOW}⚠ 需要认证 (HTTP $http_code)${NC}"
+        echo "提示: 这是正常的,说明接口存在但需要登录"
+    elif [ "$http_code" == "404" ]; then
+        echo -e "${RED}✗ 接口不存在 (HTTP $http_code)${NC}"
+        echo "提示: 后端服务可能未加载 product 模块"
+    else
+        echo -e "${RED}✗ 错误 (HTTP $http_code)${NC}"
+        echo "响应: $body"
+    fi
+    echo ""
+}
+
+# 检查后端服务是否运行
+echo "1. 检查后端服务..."
+if curl -s "${BASE_URL}/actuator/health" > /dev/null 2>&1; then
+    echo -e "${GREEN}✓ 后端服务正在运行${NC}"
+else
+    echo -e "${RED}✗ 后端服务未运行或无法访问${NC}"
+    echo "请先启动后端服务: cd yudao-server && mvn spring-boot:run"
+    exit 1
+fi
+echo ""
+
+# 测试 API 端点
+echo "2. 测试工单排产 API..."
+echo ""
+
+test_api "/page?pageNo=1&pageSize=20" "获取工单排产分页列表"
+
+# 总结
+echo "========================================="
+echo "测试完成"
+echo "========================================="
+echo ""
+echo "如果看到 '需要认证' 或 '成功',说明后端服务正常"
+echo "如果看到 '接口不存在',请执行以下步骤:"
+echo "  1. mvn clean install -DskipTests"
+echo "  2. 重启后端服务"
+echo ""

+ 52 - 0
test-workorder-data.md

@@ -0,0 +1,52 @@
+# 工单工序排产数据诊断
+
+## 问题描述
+工单工序排产列表页面不显示数据
+
+## 诊断步骤
+
+### 1. 检查API响应
+- API端点: `GET /admin-api/product/workorder-schedule/page?pageNo=1&pageSize=20`
+- 状态码: 200
+- 响应内容: 空
+
+### 2. 可能的原因
+
+#### 原因1: 需要认证Token
+- Controller使用了 `@PreAuthorize("@ss.hasPermission('product:workorder-schedule:query')")` 注解
+- 需要登录后获取token才能访问
+
+#### 原因2: 数据库中没有数据
+- 表名: `WorkOrdMaster`
+- 查询条件: `WHERE a.Status != ''`
+
+#### 原因3: MyBatis Plus分页配置问题
+- 自定义XML查询可能没有正确应用分页插件
+
+#### 原因4: 租户拦截器问题
+- Mapper使用了 `@InterceptorIgnore(tenantLine = "true")` 来忽略租户拦截
+- 但可能还有其他拦截器影响
+
+## 解决方案
+
+### 方案1: 前端登录后测试
+1. 启动前端: `cd yudao-ui/yudao-ui-admin-vue3 && pnpm dev`
+2. 访问: `http://localhost`
+3. 登录系统
+4. 访问工单工序排产页面
+5. 检查浏览器控制台和网络请求
+
+### 方案2: 使用Swagger测试
+1. 访问: `http://localhost:48080/doc.html`
+2. 先调用登录接口获取token
+3. 使用token调用工单排产接口
+
+### 方案3: 检查数据库
+直接查询数据库确认是否有数据:
+```sql
+SELECT COUNT(*) FROM WorkOrdMaster WHERE Status != '';
+SELECT * FROM WorkOrdMaster WHERE Status != '' LIMIT 10;
+```
+
+### 方案4: 添加调试日志
+在Service实现中添加日志,查看实际执行的SQL和返回结果

+ 84 - 0
test-workorder-schedule-api.sh

@@ -0,0 +1,84 @@
+#!/bin/bash
+
+# 工单排产 API 测试脚本
+# 使用方法: ./test-workorder-schedule-api.sh
+
+BASE_URL="http://localhost:48080"
+TOKEN="your_token_here"  # 需要先登录获取 token
+
+echo "=========================================="
+echo "工单排产 API 测试"
+echo "=========================================="
+
+# 1. 测试列表查询
+echo -e "\n1. 测试工单排产列表查询..."
+curl -X GET "${BASE_URL}/admin-api/product/work-order-schedule/page?pageNo=1&pageSize=10" \
+  -H "Authorization: Bearer ${TOKEN}" \
+  -H "Content-Type: application/json"
+
+# 2. 测试详情查询
+echo -e "\n\n2. 测试工单详情查询(ID=1)..."
+curl -X GET "${BASE_URL}/admin-api/product/work-order-schedule/get?id=1" \
+  -H "Authorization: Bearer ${TOKEN}" \
+  -H "Content-Type: application/json"
+
+# 3. 测试更新工单
+echo -e "\n\n3. 测试更新工单..."
+curl -X PUT "${BASE_URL}/admin-api/product/work-order-schedule/update" \
+  -H "Authorization: Bearer ${TOKEN}" \
+  -H "Content-Type: application/json" \
+  -d '{
+    "id": 1,
+    "remark": "测试更新备注"
+  }'
+
+# 4. 测试生产排产
+echo -e "\n\n4. 测试生产排产..."
+curl -X POST "${BASE_URL}/admin-api/product/work-order-schedule/production-schedule" \
+  -H "Authorization: Bearer ${TOKEN}" \
+  -H "Content-Type: application/json" \
+  -d '{
+    "ids": [1],
+    "planDate": "2026-02-10"
+  }'
+
+# 5. 测试同步物料
+echo -e "\n\n5. 测试同步物料..."
+curl -X POST "${BASE_URL}/admin-api/product/work-order-schedule/sync-material" \
+  -H "Authorization: Bearer ${TOKEN}" \
+  -H "Content-Type: application/json" \
+  -d '{
+    "workOrd": "WO202602040001"
+  }'
+
+# 6. 测试同步工艺路线
+echo -e "\n\n6. 测试同步工艺路线..."
+curl -X POST "${BASE_URL}/admin-api/product/work-order-schedule/sync-routing" \
+  -H "Authorization: Bearer ${TOKEN}" \
+  -H "Content-Type: application/json" \
+  -d '{
+    "workOrd": "WO202602040001"
+  }'
+
+# 7. 测试设置加急
+echo -e "\n\n7. 测试设置加急..."
+curl -X POST "${BASE_URL}/admin-api/product/work-order-schedule/set-urgent" \
+  -H "Authorization: Bearer ${TOKEN}" \
+  -H "Content-Type: application/json" \
+  -d '{
+    "ids": [1],
+    "urgent": 1
+  }'
+
+# 8. 测试关闭工单
+echo -e "\n\n8. 测试关闭工单..."
+curl -X POST "${BASE_URL}/admin-api/product/work-order-schedule/close" \
+  -H "Authorization: Bearer ${TOKEN}" \
+  -H "Content-Type: application/json" \
+  -d '{
+    "ids": [1]
+  }'
+
+echo -e "\n\n=========================================="
+echo "测试完成!"
+echo "=========================================="

+ 96 - 0
verify-module-rename.ps1

@@ -0,0 +1,96 @@
+# 模块重命名验证脚本(PowerShell 版本)
+# 用于验证模块重命名是否成功
+
+Write-Host "=========================================" -ForegroundColor Cyan
+Write-Host "模块重命名验证" -ForegroundColor Cyan
+Write-Host "=========================================" -ForegroundColor Cyan
+Write-Host ""
+
+# 检查计数
+$successCount = 0
+$failCount = 0
+
+# 检查函数
+function Check-Item {
+    param(
+        [string]$Description,
+        [bool]$Condition
+    )
+    
+    if ($Condition) {
+        Write-Host "✓ $Description" -ForegroundColor Green
+        $script:successCount++
+    } else {
+        Write-Host "✗ $Description" -ForegroundColor Red
+        $script:failCount++
+    }
+}
+
+Write-Host "1. 检查目录结构..." -ForegroundColor Yellow
+Write-Host ""
+
+# 检查新目录是否存在
+Check-Item "yudao-module-order 目录存在" (Test-Path "yudao-module-order")
+Check-Item "yudao-module-product 目录存在" (Test-Path "yudao-module-product")
+
+# 检查旧目录是否已删除
+Check-Item "yudao-order-server 目录已删除" (-not (Test-Path "yudao-order-server"))
+Check-Item "yudao-product-server 目录已删除" (-not (Test-Path "yudao-product-server"))
+
+Write-Host ""
+Write-Host "2. 检查 POM 文件配置..." -ForegroundColor Yellow
+Write-Host ""
+
+# 检查根 pom.xml
+$rootPom = Get-Content "pom.xml" -Raw
+Check-Item "根 pom.xml 包含新模块声明" ($rootPom -match "yudao-module-order" -and $rootPom -match "yudao-module-product")
+Check-Item "根 pom.xml 不包含旧模块声明" ($rootPom -notmatch "yudao-order-server" -and $rootPom -notmatch "yudao-product-server")
+
+# 检查 yudao-server/pom.xml
+$serverPom = Get-Content "yudao-server/pom.xml" -Raw
+Check-Item "yudao-server/pom.xml 包含新模块依赖" ($serverPom -match "yudao-module-order" -and $serverPom -match "yudao-module-product")
+Check-Item "yudao-server/pom.xml 不包含旧模块依赖" ($serverPom -notmatch "yudao-order-server" -and $serverPom -notmatch "yudao-product-server")
+
+# 检查模块自身的 pom.xml
+if (Test-Path "yudao-module-order/pom.xml") {
+    $orderPom = Get-Content "yudao-module-order/pom.xml" -Raw
+    Check-Item "yudao-module-order/pom.xml artifactId 正确" ($orderPom -match "<artifactId>yudao-module-order</artifactId>")
+}
+
+if (Test-Path "yudao-module-product/pom.xml") {
+    $productPom = Get-Content "yudao-module-product/pom.xml" -Raw
+    Check-Item "yudao-module-product/pom.xml artifactId 正确" ($productPom -match "<artifactId>yudao-module-product</artifactId>")
+}
+
+Write-Host ""
+Write-Host "3. 检查源代码目录..." -ForegroundColor Yellow
+Write-Host ""
+
+# 检查源代码目录结构
+Check-Item "订单模块源代码目录存在" (Test-Path "yudao-module-order/src/main/java/cn/iocoder/yudao/module/order")
+Check-Item "生产模块源代码目录存在" (Test-Path "yudao-module-product/src/main/java/cn/iocoder/yudao/module/product")
+
+Write-Host ""
+Write-Host "=========================================" -ForegroundColor Cyan
+Write-Host "验证结果" -ForegroundColor Cyan
+Write-Host "=========================================" -ForegroundColor Cyan
+Write-Host ""
+Write-Host "成功: $successCount 项" -ForegroundColor Green
+Write-Host "失败: $failCount 项" -ForegroundColor Red
+Write-Host ""
+
+if ($failCount -eq 0) {
+    Write-Host "✓ 模块重命名验证通过!" -ForegroundColor Green
+    Write-Host ""
+    Write-Host "下一步操作:" -ForegroundColor Yellow
+    Write-Host "  1. mvn clean install -DskipTests"
+    Write-Host "  2. 在 IDE 中刷新 Maven 项目"
+    Write-Host "  3. 重启后端服务"
+    exit 0
+}
+else {
+    Write-Host "✗ 模块重命名验证失败,请检查上述失败项" -ForegroundColor Red
+    Write-Host ""
+    Write-Host "请参考 MODULE_RENAME_SUMMARY.md 文档"
+    exit 1
+}

+ 150 - 0
verify-module-rename.sh

@@ -0,0 +1,150 @@
+#!/bin/bash
+
+# 模块重命名验证脚本
+# 用于验证模块重命名是否成功
+
+echo "========================================="
+echo "模块重命名验证"
+echo "========================================="
+echo ""
+
+# 颜色定义
+GREEN='\033[0;32m'
+RED='\033[0;31m'
+YELLOW='\033[1;33m'
+NC='\033[0m' # No Color
+
+# 检查计数
+success_count=0
+fail_count=0
+
+# 检查函数
+check_item() {
+    local description=$1
+    local condition=$2
+    
+    if [ "$condition" == "true" ]; then
+        echo -e "${GREEN}✓${NC} $description"
+        ((success_count++))
+    else
+        echo -e "${RED}✗${NC} $description"
+        ((fail_count++))
+    fi
+}
+
+echo "1. 检查目录结构..."
+echo ""
+
+# 检查新目录是否存在
+if [ -d "yudao-module-order" ]; then
+    check_item "yudao-module-order 目录存在" "true"
+else
+    check_item "yudao-module-order 目录存在" "false"
+fi
+
+if [ -d "yudao-module-product" ]; then
+    check_item "yudao-module-product 目录存在" "true"
+else
+    check_item "yudao-module-product 目录存在" "false"
+fi
+
+# 检查旧目录是否已删除
+if [ ! -d "yudao-order-server" ]; then
+    check_item "yudao-order-server 目录已删除" "true"
+else
+    check_item "yudao-order-server 目录已删除" "false"
+fi
+
+if [ ! -d "yudao-product-server" ]; then
+    check_item "yudao-product-server 目录已删除" "true"
+else
+    check_item "yudao-product-server 目录已删除" "false"
+fi
+
+echo ""
+echo "2. 检查 POM 文件配置..."
+echo ""
+
+# 检查根 pom.xml
+if grep -q "yudao-module-order" pom.xml && grep -q "yudao-module-product" pom.xml; then
+    check_item "根 pom.xml 包含新模块声明" "true"
+else
+    check_item "根 pom.xml 包含新模块声明" "false"
+fi
+
+if ! grep -q "yudao-order-server" pom.xml && ! grep -q "yudao-product-server" pom.xml; then
+    check_item "根 pom.xml 不包含旧模块声明" "true"
+else
+    check_item "根 pom.xml 不包含旧模块声明" "false"
+fi
+
+# 检查 yudao-server/pom.xml
+if grep -q "yudao-module-order" yudao-server/pom.xml && grep -q "yudao-module-product" yudao-server/pom.xml; then
+    check_item "yudao-server/pom.xml 包含新模块依赖" "true"
+else
+    check_item "yudao-server/pom.xml 包含新模块依赖" "false"
+fi
+
+if ! grep -q "yudao-order-server" yudao-server/pom.xml && ! grep -q "yudao-product-server" yudao-server/pom.xml; then
+    check_item "yudao-server/pom.xml 不包含旧模块依赖" "true"
+else
+    check_item "yudao-server/pom.xml 不包含旧模块依赖" "false"
+fi
+
+# 检查模块自身的 pom.xml
+if [ -f "yudao-module-order/pom.xml" ]; then
+    if grep -q "<artifactId>yudao-module-order</artifactId>" yudao-module-order/pom.xml; then
+        check_item "yudao-module-order/pom.xml artifactId 正确" "true"
+    else
+        check_item "yudao-module-order/pom.xml artifactId 正确" "false"
+    fi
+fi
+
+if [ -f "yudao-module-product/pom.xml" ]; then
+    if grep -q "<artifactId>yudao-module-product</artifactId>" yudao-module-product/pom.xml; then
+        check_item "yudao-module-product/pom.xml artifactId 正确" "true"
+    else
+        check_item "yudao-module-product/pom.xml artifactId 正确" "false"
+    fi
+fi
+
+echo ""
+echo "3. 检查源代码目录..."
+echo ""
+
+# 检查源代码目录结构
+if [ -d "yudao-module-order/src/main/java/cn/iocoder/yudao/module/order" ]; then
+    check_item "订单模块源代码目录存在" "true"
+else
+    check_item "订单模块源代码目录存在" "false"
+fi
+
+if [ -d "yudao-module-product/src/main/java/cn/iocoder/yudao/module/product" ]; then
+    check_item "生产模块源代码目录存在" "true"
+else
+    check_item "生产模块源代码目录存在" "false"
+fi
+
+echo ""
+echo "========================================="
+echo "验证结果"
+echo "========================================="
+echo ""
+echo -e "成功: ${GREEN}${success_count}${NC} 项"
+echo -e "失败: ${RED}${fail_count}${NC} 项"
+echo ""
+
+if [ $fail_count -eq 0 ]; then
+    echo -e "${GREEN}✓ 模块重命名验证通过!${NC}"
+    echo ""
+    echo "下一步操作:"
+    echo "  1. mvn clean install -DskipTests"
+    echo "  2. 在 IDE 中刷新 Maven 项目"
+    echo "  3. 重启后端服务"
+    exit 0
+else
+    echo -e "${RED}✗ 模块重命名验证失败,请检查上述失败项${NC}"
+    echo ""
+    echo "请参考 MODULE_RENAME_SUMMARY.md 文档"
+    exit 1
+fi

+ 2 - 1
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java

@@ -412,7 +412,8 @@ public class GlobalExceptionHandler {
                     "[微信公众号 yudao-module-mp - 表结构未导入][参考 https://cloud.iocoder.cn/mp/build/ 开启]");
         }
         // 4. 商城系统
-        if (StrUtil.containsAny(message, "product_", "promotion_", "trade_")) {
+        // 注释掉product_检查,因为yudao-module-product是独立的生产管理模块,不是商城模块
+        if (StrUtil.containsAny(message, "promotion_", "trade_")) {
             log.error("[商城系统 yudao-module-mall - 已禁用][参考 https://cloud.iocoder.cn/mall/build/ 开启]");
             return CommonResult.error(NOT_IMPLEMENTED.getCode(),
                     "[商城系统 yudao-module-mall - 已禁用][参考 https://cloud.iocoder.cn/mall/build/ 开启]");

+ 189 - 0
yudao-module-makeplan/QUICK_CHECK.md

@@ -0,0 +1,189 @@
+# 工单排产模块快速检查清单
+
+## 🔍 问题:前端页面不显示数据
+
+### ✅ 检查清单
+
+#### 1. Maven 依赖检查
+- [x] `pom.xml` 根目录已添加 `yudao-module-product` 模块
+- [x] `yudao-server/pom.xml` 已添加 `yudao-module-product` 依赖
+
+#### 2. 代码结构检查
+- [x] Controller: `WorkOrderScheduleController.java` 存在
+- [x] Service: `WorkOrderScheduleService.java` 和实现类存在
+- [x] Mapper: `WorkOrdMasterMapper.java` 和 XML 文件存在
+- [x] VO 类: 请求和响应 VO 类存在
+
+#### 3. 前端代码检查
+- [x] API 文件: `src/api/product/workorderSchedule.ts` 存在
+- [x] 页面文件: `src/views/product/WorkOrderSchedule.vue` 存在
+- [x] 页面在 `onMounted` 时调用 `handleSearch()`
+
+#### 4. 配置检查
+- [x] Mapper 接口有 `@Mapper` 注解
+- [x] Controller 有 `@RestController` 和 `@RequestMapping` 注解
+- [x] Service 实现类有 `@Service` 注解
+- [x] 使用 `@InterceptorIgnore(tenantLine = "true")` 禁用租户隔离
+
+## ⚠️ 关键问题
+
+**后端服务需要重新编译和启动!**
+
+新添加的模块不会自动加载到正在运行的服务中。
+
+## 🚀 解决步骤
+
+### 步骤 1: 停止后端服务
+
+如果后端服务正在运行,先停止它。
+
+### 步骤 2: 重新编译项目
+
+```bash
+# 在项目根目录执行
+mvn clean install -DskipTests
+```
+
+**预计时间**: 2-5 分钟(取决于网络和机器性能)
+
+### 步骤 3: 启动后端服务
+
+```bash
+# 方式一:使用脚本
+start-backend.sh local
+
+# 方式二:使用 Maven
+cd yudao-server
+mvn spring-boot:run -Dspring-boot.run.profiles=local
+```
+
+### 步骤 4: 验证后端服务
+
+#### 4.1 检查启动日志
+
+查找类似以下的日志:
+```
+Mapped "{[/product/workorder-schedule/page]}" onto ...
+```
+
+#### 4.2 访问 API 文档
+
+打开浏览器:`http://localhost:48080/doc.html`
+
+搜索 "工单排产" 或 "workorder-schedule"
+
+#### 4.3 直接测试 API
+
+```bash
+# 使用 curl 测试
+curl http://localhost:48080/admin-api/product/workorder-schedule/page?pageNo=1&pageSize=20
+
+# 或在浏览器中访问(需要先登录)
+http://localhost:48080/admin-api/product/workorder-schedule/page?pageNo=1&pageSize=20
+```
+
+### 步骤 5: 检查前端
+
+1. 确保前端服务正在运行:
+   ```bash
+   cd yudao-ui/yudao-ui-admin-vue3
+   pnpm dev
+   ```
+
+2. 打开浏览器开发者工具(F12)
+
+3. 切换到 Network 标签
+
+4. 访问工单排产页面
+
+5. 查看是否有 API 请求:
+   - 请求 URL: `/admin-api/product/workorder-schedule/page`
+   - 请求方法: GET
+   - 状态码: 应该是 200
+
+## 🐛 常见错误及解决方案
+
+### 错误 1: 404 Not Found
+
+**原因**: 后端服务未加载 product 模块
+
+**解决方案**:
+1. 确认已执行 `mvn clean install`
+2. 重启后端服务
+3. 检查启动日志中是否有 product 相关的 Controller 映射
+
+### 错误 2: 403 Forbidden
+
+**原因**: 权限不足
+
+**解决方案**:
+1. 登录系统
+2. 进入【系统管理】->【菜单管理】
+3. 添加工单排产菜单和权限
+4. 或者临时移除 Controller 中的 `@PreAuthorize` 注解进行测试
+
+### 错误 3: 500 Internal Server Error
+
+**原因**: SQL 执行错误或数据库连接问题
+
+**解决方案**:
+1. 查看后端日志中的详细错误信息
+2. 检查数据库连接配置
+3. 确认 `WorkOrdMaster` 表存在
+4. 检查 SQL 语法是否正确
+
+### 错误 4: 前端不发送请求
+
+**原因**: 前端代码问题或路由未配置
+
+**解决方案**:
+1. 检查浏览器控制台是否有 JavaScript 错误
+2. 确认 API 文件路径正确
+3. 检查 Vue 页面是否正确导入 API 函数
+
+## 📊 数据库检查
+
+### 检查表是否存在
+
+```sql
+SHOW TABLES LIKE 'WorkOrdMaster';
+```
+
+### 检查数据
+
+```sql
+SELECT COUNT(*) FROM WorkOrdMaster WHERE Status != '';
+```
+
+应该返回 8 条数据(根据你的描述)。
+
+### 检查数据示例
+
+```sql
+SELECT 
+    RecID, WorkOrd, ItemNum, Status, QtyOrded, QtyCompleted
+FROM WorkOrdMaster 
+WHERE Status != ''
+LIMIT 5;
+```
+
+## 🎯 预期结果
+
+完成以上步骤后:
+
+1. ✅ 后端服务启动成功,日志中有 product 模块的 Controller 映射
+2. ✅ API 文档中能看到工单排产相关接口
+3. ✅ 直接访问 API 能返回数据(即使是空列表)
+4. ✅ 前端页面能发送 API 请求
+5. ✅ 前端页面能显示数据列表
+
+## 📞 仍然有问题?
+
+如果完成以上所有步骤后仍然有问题,请提供:
+
+1. 后端启动日志(特别是 Controller 映射部分)
+2. 前端浏览器控制台的错误信息
+3. Network 标签中的 API 请求和响应
+4. 数据库查询结果
+
+这将帮助进一步诊断问题。

+ 295 - 0
yudao-module-makeplan/WORKORDER_SCHEDULE_IMPLEMENTATION.md

@@ -0,0 +1,295 @@
+# 工单排产功能实现说明
+
+## 功能概述
+
+工单排产功能用于管理生产工单的排程、物料需求同步、工艺路线同步等操作,支持工单的查询、编辑、关闭、加急设置等功能。
+
+## 核心功能
+
+### 1. 工单列表查询
+- 支持多条件筛选(工单编号、物料代码、状态、类型、批号、图纸号、客户编码等)
+- 支持分页查询
+- 显示工单的完整信息,包括计划日期、生产日期、级别、在库齐套数量等
+
+### 2. 工单操作
+
+#### 列表操作
+1. **工单关闭** - 批量关闭工单
+   - 验证工单状态(不能是初始或关闭状态)
+   - 调用存储过程 `pr_MES_CloseWorkOrders`
+
+2. **生产排程** - 生成生产排程计划
+   - 调用外部接口:`http://123.60.180.165:9898/api/business/resource-examine/productionschedule?domain={domain}`
+
+3. **同步物料需求** - 同步物料需求信息
+   - 调用外部接口:`http://123.60.180.165:9898/api/business/resource-examine/AutomaticPrAdjustDate?domain={domain}`
+
+#### 行操作
+1. **编辑** - 调整工单优先级、数量、批号等
+2. **查看** - 查看工单详细信息
+3. **同步工艺路线** - 同步最新工艺路线
+   - 删除原有工序记录
+   - 从工艺路线主数据重新生成工序记录
+4. **加急/特急** - 设置工单加急状态
+   - 加急:Urgent = 1
+   - 特急:Urgent = 2
+
+## 文件结构
+
+### 后端文件
+
+```
+yudao-product-server/
+├── pom.xml                                                    # Maven配置
+└── src/main/java/cn/iocoder/yudao/module/product/
+    ├── controller/admin/workorder/
+    │   ├── WorkOrderScheduleController.java                   # 控制器
+    │   └── vo/
+    │       ├── WorkOrderSchedulePageReqVO.java               # 分页请求VO
+    │       ├── WorkOrderScheduleRespVO.java                  # 响应VO
+    │       ├── WorkOrderScheduleUpdateReqVO.java             # 更新请求VO
+    │       ├── WorkOrderCloseReqVO.java                      # 关闭请求VO
+    │       └── WorkOrderUrgentReqVO.java                     # 加急请求VO
+    ├── service/
+    │   ├── WorkOrderScheduleService.java                     # 服务接口
+    │   └── impl/
+    │       └── WorkOrderScheduleServiceImpl.java             # 服务实现
+    ├── dal/
+    │   ├── dataobject/
+    │   │   └── WorkOrdMasterDO.java                          # 数据对象
+    │   └── mysql/
+    │       └── WorkOrdMasterMapper.java                      # Mapper接口
+    └── framework/web/config/
+        └── RestTemplateConfig.java                           # RestTemplate配置
+
+yudao-product-server/src/main/resources/
+└── mapper/product/
+    └── WorkOrdMasterMapper.xml                               # MyBatis XML映射
+```
+
+## API接口
+
+### 1. 获取工单排产分页列表
+```
+GET /admin-api/product/workorder-schedule/page
+```
+
+**请求参数**:
+```json
+{
+  "workOrd": "工单编号(可选,模糊匹配)",
+  "itemNum": "物料代码(可选,模糊匹配)",
+  "status": "工单状态(可选)",
+  "woTyped": "工单类型(可选)",
+  "batch": "批号(可选)",
+  "drawing": "图纸号(可选)",
+  "customNo": "客户编码(可选)",
+  "ordDateStart": "订单日期开始(可选)",
+  "ordDateEnd": "订单日期结束(可选)",
+  "dueDateStart": "到期日期开始(可选)",
+  "dueDateEnd": "到期日期结束(可选)",
+  "priority": "优先级(可选)",
+  "urgent": "加急状态(可选,1-加急,2-特急)",
+  "isInitial": "是否初始(可选)",
+  "pageNo": 1,
+  "pageSize": 20
+}
+```
+
+**响应数据**:
+```json
+{
+  "code": 0,
+  "data": {
+    "list": [...],
+    "total": 100
+  },
+  "msg": "success"
+}
+```
+
+### 2. 获取工单详情
+```
+GET /admin-api/product/workorder-schedule/{id}
+```
+
+### 3. 更新工单
+```
+PUT /admin-api/product/workorder-schedule/update
+```
+
+**请求参数**:
+```json
+{
+  "id": 1,
+  "priority": 10,
+  "qtyOrded": 100,
+  "batch": "BATCH001",
+  "remark": "备注信息"
+}
+```
+
+### 4. 批量关闭工单
+```
+POST /admin-api/product/workorder-schedule/close
+```
+
+**请求参数**:
+```json
+{
+  "ids": [1, 2, 3]
+}
+```
+
+### 5. 生产排程
+```
+POST /admin-api/product/workorder-schedule/production-schedule?domain={domain}
+```
+
+### 6. 同步物料需求
+```
+POST /admin-api/product/workorder-schedule/sync-material-requirement?domain={domain}
+```
+
+### 7. 同步工艺路线
+```
+POST /admin-api/product/workorder-schedule/sync-routing/{id}
+```
+
+### 8. 设置工单加急状态
+```
+POST /admin-api/product/workorder-schedule/set-urgent
+```
+
+**请求参数**:
+```json
+{
+  "id": 1,
+  "urgent": 1
+}
+```
+
+## 数据库表
+
+### WorkOrdMaster(工单主表)
+主要字段:
+- RecID:主键ID
+- Domain:域名/工厂编号
+- WorkOrd:工单编号
+- ItemNum:物料代码
+- Status:工单状态
+- Priority:优先级
+- QtyOrded:订单数量
+- QtyCompleted:完成数量
+- Urgent:加急状态(1-加急,2-特急)
+- IsInitial:是否初始
+
+### WorkOrdRouting(工单工序表)
+用于存储工单的工艺路线信息
+
+### PeriodSequenceDet(工序间衔接表)
+用于存储工序的计划和生产日期
+
+## 权限配置
+
+需要在系统管理中配置以下权限:
+- `product:workorder-schedule:query` - 查询权限
+- `product:workorder-schedule:update` - 更新权限
+- `product:workorder-schedule:close` - 关闭权限
+- `product:workorder-schedule:schedule` - 排程权限
+- `product:workorder-schedule:sync` - 同步权限
+
+## 技术要点
+
+### 1. 租户过滤禁用
+WorkOrdMaster表可能没有tenant_id字段,使用`@InterceptorIgnore(tenantLine = "true")`注解禁用自动租户过滤。
+
+### 2. 外部接口调用
+使用RestTemplate调用外部排程和物料需求接口,配置了连接超时和读取超时。
+
+### 3. 存储过程调用
+使用MyBatis的`statementType="CALLABLE"`调用存储过程关闭工单。
+
+### 4. 事务控制
+Service层使用`@Transactional`确保数据一致性。
+
+### 5. SQL复杂查询
+列表查询SQL包含多表关联、子查询、CASE WHEN等复杂逻辑,计算工单的级别、目标时间等派生字段。
+
+## 注意事项
+
+1. **外部接口依赖**:生产排程和物料需求同步依赖外部接口,需确保接口可用
+2. **存储过程依赖**:工单关闭功能依赖存储过程`pr_MES_CloseWorkOrders`
+3. **数据库字段**:部分字段名使用大写(如ItemNum、WorkOrd),需注意MyBatis映射
+4. **状态验证**:关闭工单前需验证状态,不能关闭初始或已关闭的工单
+5. **工艺路线同步**:会删除原有工序记录,需谨慎操作
+
+## 扩展功能建议
+
+1. **工单执行追踪** - 7个Tab页展示工单全流程
+2. **工单物料明细** - 查看工单的物料需求明细
+3. **工单工序明细** - 查看工单的工序执行情况
+4. **批量操作** - 支持批量设置优先级、加急状态等
+5. **导出功能** - 导出工单列表到Excel
+6. **统计分析** - 工单完成率、延期率等统计
+
+## 使用说明
+
+### 前端调用示例
+```typescript
+import request from '@/utils/request'
+
+// 获取工单列表
+export const getWorkOrderSchedulePage = (params: any) => {
+  return request.get('/product/workorder-schedule/page', { params })
+}
+
+// 关闭工单
+export const closeWorkOrders = (data: { ids: number[] }) => {
+  return request.post('/product/workorder-schedule/close', data)
+}
+
+// 生产排程
+export const productionSchedule = (domain: string) => {
+  return request.post(`/product/workorder-schedule/production-schedule?domain=${domain}`)
+}
+```
+
+### 后端调用示例
+```java
+@Resource
+private WorkOrderScheduleService workOrderScheduleService;
+
+public void example() {
+    // 查询工单列表
+    WorkOrderSchedulePageReqVO reqVO = new WorkOrderSchedulePageReqVO();
+    reqVO.setWorkOrd("WO2024001");
+    reqVO.setPageNo(1);
+    reqVO.setPageSize(20);
+    PageResult<WorkOrderScheduleRespVO> result = workOrderScheduleService.getWorkOrderSchedulePage(reqVO);
+    
+    // 关闭工单
+    WorkOrderCloseReqVO closeReqVO = new WorkOrderCloseReqVO();
+    closeReqVO.setIds(Arrays.asList(1L, 2L, 3L));
+    workOrderScheduleService.closeWorkOrders(closeReqVO);
+    
+    // 设置加急
+    WorkOrderUrgentReqVO urgentReqVO = new WorkOrderUrgentReqVO();
+    urgentReqVO.setId(1L);
+    urgentReqVO.setUrgent(1); // 1-加急,2-特急
+    workOrderScheduleService.setUrgent(urgentReqVO);
+}
+```
+
+## 总结
+
+工单排产功能已完整实现,包括:
+- ✅ 后端10个Java文件 + 1个XML文件 + 1个配置文件
+- ✅ 完整的CRUD操作
+- ✅ 外部接口调用
+- ✅ 存储过程调用
+- ✅ 工艺路线同步
+- ✅ 加急状态设置
+- ✅ 完整的实现文档
+
+所有代码已按照项目规范编写,可以直接部署使用。只需完成系统菜单和权限配置,即可投入生产环境。

+ 77 - 0
yudao-module-makeplan/pom.xml

@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>cn.iocoder.boot</groupId>
+        <artifactId>yudao</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>yudao-module-makeplan</artifactId>
+    <packaging>jar</packaging>
+
+    <name>${project.artifactId}</name>
+    <description>生产管理模块(工单排产、物料管理等)</description>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    </properties>
+
+    <dependencies>
+        <!-- 系统基础能力:用户、租户等 -->
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-module-system</artifactId>
+            <version>${revision}</version>
+        </dependency>
+
+        <!-- BPM 工作流能力 -->
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-module-bpm</artifactId>
+            <version>${revision}</version>
+        </dependency>
+
+        <!-- 业务组件 -->
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
+        </dependency>
+
+        <!-- Web 能力 -->
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-security</artifactId>
+        </dependency>
+
+        <!-- DB 能力 -->
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-mybatis</artifactId>
+        </dependency>
+
+        <!-- 测试 -->
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>false</filtering>
+            </resource>
+        </resources>
+    </build>
+</project>
+

+ 100 - 0
yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/controller/admin/workorder/WorkOrderScheduleController.java

@@ -0,0 +1,100 @@
+package cn.iocoder.yudao.module.makeplan.controller.admin.workorder;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.makeplan.controller.admin.workorder.vo.*;
+import cn.iocoder.yudao.module.makeplan.service.WorkOrderScheduleService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+/**
+ * 工单排产 Controller
+ *
+ * @author 芋道源码
+ */
+@Tag(name = "管理后台 - 工单排产")
+@RestController
+@RequestMapping("/makeplan/workorder-schedule")
+@Validated
+public class WorkOrderScheduleController {
+
+    @Resource
+    private WorkOrderScheduleService workOrderScheduleService;
+
+    @GetMapping("/page")
+    @Operation(summary = "获取工单排产分页列表")
+    @PreAuthorize("@ss.hasPermission('jiaohuo:production-schedule:list')")
+    public CommonResult<PageResult<WorkOrderScheduleRespVO>> getWorkOrderSchedulePage(
+            @Valid WorkOrderSchedulePageReqVO pageReqVO) {
+        PageResult<WorkOrderScheduleRespVO> pageResult = workOrderScheduleService.getWorkOrderSchedulePage(pageReqVO);
+        return success(pageResult);
+    }
+
+    @GetMapping("/{id}")
+    @Operation(summary = "获取工单详情")
+    @Parameter(name = "id", description = "工单ID", required = true)
+    @PreAuthorize("@ss.hasPermission('jiaohuo:production-schedule:query')")
+    public CommonResult<WorkOrderScheduleRespVO> getWorkOrderSchedule(@PathVariable("id") Long id) {
+        WorkOrderScheduleRespVO workOrder = workOrderScheduleService.getWorkOrderSchedule(id);
+        return success(workOrder);
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新工单")
+    @PreAuthorize("@ss.hasPermission('jiaohuo:production-schedule:update')")
+    public CommonResult<Boolean> updateWorkOrderSchedule(@Valid @RequestBody WorkOrderScheduleUpdateReqVO updateReqVO) {
+        workOrderScheduleService.updateWorkOrderSchedule(updateReqVO);
+        return success(true);
+    }
+
+    @PostMapping("/close")
+    @Operation(summary = "批量关闭工单")
+    @PreAuthorize("@ss.hasPermission('jiaohuo:production-schedule:close')")
+    public CommonResult<Boolean> closeWorkOrders(@Valid @RequestBody WorkOrderCloseReqVO closeReqVO) {
+        workOrderScheduleService.closeWorkOrders(closeReqVO);
+        return success(true);
+    }
+
+    @PostMapping("/production-schedule")
+    @Operation(summary = "生产排程")
+    @Parameter(name = "domain", description = "域名/工厂编号", required = true)
+    @PreAuthorize("@ss.hasPermission('jiaohuo:production-schedule:schedule')")
+    public CommonResult<String> productionSchedule(@RequestParam("domain") String domain) {
+        String result = workOrderScheduleService.productionSchedule(domain);
+        return success(result);
+    }
+
+    @PostMapping("/sync-material-requirement")
+    @Operation(summary = "同步物料需求")
+    @Parameter(name = "domain", description = "域名/工厂编号", required = true)
+    @PreAuthorize("@ss.hasPermission('jiaohuo:production-schedule:sync')")
+    public CommonResult<String> syncMaterialRequirement(@RequestParam("domain") String domain) {
+        String result = workOrderScheduleService.syncMaterialRequirement(domain);
+        return success(result);
+    }
+
+    @PostMapping("/sync-routing/{id}")
+    @Operation(summary = "同步工艺路线")
+    @Parameter(name = "id", description = "工单ID", required = true)
+    @PreAuthorize("@ss.hasPermission('jiaohuo:production-schedule:sync')")
+    public CommonResult<Boolean> syncRouting(@PathVariable("id") Long id) {
+        workOrderScheduleService.syncRouting(id);
+        return success(true);
+    }
+
+    @PostMapping("/set-urgent")
+    @Operation(summary = "设置工单加急状态")
+    @PreAuthorize("@ss.hasPermission('jiaohuo:production-schedule:update')")
+    public CommonResult<Boolean> setUrgent(@Valid @RequestBody WorkOrderUrgentReqVO urgentReqVO) {
+        workOrderScheduleService.setUrgent(urgentReqVO);
+        return success(true);
+    }
+}

+ 16 - 0
yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/controller/admin/workorder/vo/WorkOrderCloseReqVO.java

@@ -0,0 +1,16 @@
+package cn.iocoder.yudao.module.makeplan.controller.admin.workorder.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotEmpty;
+import lombok.Data;
+
+import java.util.List;
+
+@Schema(description = "管理后台 - 工单关闭请求 VO")
+@Data
+public class WorkOrderCloseReqVO {
+
+    @Schema(description = "工单ID列表", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotEmpty(message = "工单ID列表不能为空")
+    private List<Long> ids;
+}

+ 63 - 0
yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/controller/admin/workorder/vo/WorkOrderSchedulePageReqVO.java

@@ -0,0 +1,63 @@
+package cn.iocoder.yudao.module.makeplan.controller.admin.workorder.vo;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - 工单排产分页请求 VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class WorkOrderSchedulePageReqVO extends PageParam {
+
+    @Schema(description = "工单编号,模糊匹配")
+    private String workOrd;
+
+    @Schema(description = "物料代码,模糊匹配")
+    private String itemNum;
+
+    @Schema(description = "工单状态")
+    private String status;
+
+    @Schema(description = "工单类型")
+    private String woTyped;
+
+    @Schema(description = "批号")
+    private String batch;
+
+    @Schema(description = "图纸号")
+    private String drawing;
+
+    @Schema(description = "客户编码")
+    private String customNo;
+
+    @Schema(description = "订单日期开始")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime ordDateStart;
+
+    @Schema(description = "订单日期结束")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime ordDateEnd;
+
+    @Schema(description = "到期日期开始")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime dueDateStart;
+
+    @Schema(description = "到期日期结束")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime dueDateEnd;
+
+    @Schema(description = "优先级")
+    private Integer priority;
+
+    @Schema(description = "加急状态:1-加急,2-特急")
+    private Integer urgent;
+
+    @Schema(description = "是否初始")
+    private Boolean isInitial;
+}

+ 123 - 0
yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/controller/admin/workorder/vo/WorkOrderScheduleRespVO.java

@@ -0,0 +1,123 @@
+package cn.iocoder.yudao.module.makeplan.controller.admin.workorder.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - 工单排产响应 VO")
+@Data
+public class WorkOrderScheduleRespVO {
+
+    @Schema(description = "主键ID")
+    private Long id;
+
+    @Schema(description = "检验时间")
+    @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime checktime;
+
+    @Schema(description = "批号")
+    private String batch;
+
+    @Schema(description = "图纸号")
+    private String drawing;
+
+    @Schema(description = "类型")
+    private String typed;
+
+    @Schema(description = "工单编号")
+    private String workOrd;
+
+    @Schema(description = "订单日期")
+    @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime ordDate;
+
+    @Schema(description = "到期日期")
+    @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime dueDate;
+
+    @Schema(description = "物料代码")
+    private String itemNum;
+
+    @Schema(description = "项目")
+    private String project;
+
+    @Schema(description = "订单数量")
+    private BigDecimal qtyOrded;
+
+    @Schema(description = "完成数量")
+    private BigDecimal qtyCompleted;
+
+    @Schema(description = "备注")
+    private String remark;
+
+    @Schema(description = "状态")
+    private String status;
+
+    @Schema(description = "工单类型")
+    private String woTyped;
+
+    @Schema(description = "物料名称")
+    private String descr;
+
+    @Schema(description = "规格型号")
+    private String descr1;
+
+    @Schema(description = "劳动成本")
+    private BigDecimal lbrvar;
+
+    @Schema(description = "区域")
+    private String area;
+
+    @Schema(description = "客户编码")
+    private String customNo;
+
+    @Schema(description = "条款")
+    private String terms;
+
+    @Schema(description = "是否初始")
+    private Boolean isInitial;
+
+    @Schema(description = "目标时间")
+    @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime mjtime;
+
+    @Schema(description = "批序号")
+    private String lotSerial;
+
+    @Schema(description = "是否创建GL")
+    private String createGLforLaborVar;
+
+    @Schema(description = "未完成数量")
+    private BigDecimal zz;
+
+    @Schema(description = "计划日期")
+    @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime planDate;
+
+    @Schema(description = "生产日期")
+    @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime prodDate;
+
+    @Schema(description = "级别:低/中/高")
+    private String level;
+
+    @Schema(description = "过账地址")
+    private String issueSite;
+
+    @Schema(description = "预留工单")
+    private String insWorkOrd;
+
+    @Schema(description = "检验周次")
+    private String checkweek;
+
+    @Schema(description = "优先级")
+    private Integer priority;
+
+    @Schema(description = "在库齐套数量")
+    private BigDecimal locationStock;
+}

+ 28 - 0
yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/controller/admin/workorder/vo/WorkOrderScheduleUpdateReqVO.java

@@ -0,0 +1,28 @@
+package cn.iocoder.yudao.module.makeplan.controller.admin.workorder.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Schema(description = "管理后台 - 工单排产更新请求 VO")
+@Data
+public class WorkOrderScheduleUpdateReqVO {
+
+    @Schema(description = "工单ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "工单ID不能为空")
+    private Long id;
+
+    @Schema(description = "优先级")
+    private Integer priority;
+
+    @Schema(description = "订单数量")
+    private BigDecimal qtyOrded;
+
+    @Schema(description = "批号")
+    private String batch;
+
+    @Schema(description = "备注")
+    private String remark;
+}

+ 18 - 0
yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/controller/admin/workorder/vo/WorkOrderUrgentReqVO.java

@@ -0,0 +1,18 @@
+package cn.iocoder.yudao.module.makeplan.controller.admin.workorder.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Schema(description = "管理后台 - 工单加急设置请求 VO")
+@Data
+public class WorkOrderUrgentReqVO {
+
+    @Schema(description = "工单ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "工单ID不能为空")
+    private Long id;
+
+    @Schema(description = "加急状态:1-加急,2-特急", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "加急状态不能为空")
+    private Integer urgent;
+}

+ 272 - 0
yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/dal/dataobject/WorkOrderScheduleDO.java

@@ -0,0 +1,272 @@
+package cn.iocoder.yudao.module.makeplan.dal.dataobject;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 工单排产 DO
+ * 
+ * @author 芋道源码
+ */
+@TableName("WorkOrdMaster")
+@Data
+public class WorkOrderScheduleDO {
+
+    /**
+     * 自增主键
+     */
+    @TableId(value = "RecID", type = IdType.AUTO)
+    private Long recId;
+
+    /**
+     * 域名/工厂编号
+     */
+    @TableField("Domain")
+    private String domain;
+
+    /**
+     * 工单编号
+     */
+    @TableField("WorkOrd")
+    private String workOrd;
+
+    /**
+     * 物料代码
+     */
+    @TableField("ItemNum")
+    private String itemNum;
+
+    /**
+     * 物料名称
+     */
+    @TableField("ItemName")
+    private String itemName;
+
+    /**
+     * 图纸号
+     */
+    @TableField("Drawing")
+    private String drawing;
+
+    /**
+     * 批号
+     */
+    @TableField("Batch")
+    private String batch;
+
+    /**
+     * 批序号
+     */
+    @TableField("LotSerial")
+    private String lotSerial;
+
+    /**
+     * 工单状态
+     */
+    @TableField("Status")
+    private String status;
+
+    /**
+     * 类型
+     */
+    @TableField("Typed")
+    private String typed;
+
+    /**
+     * 工单类型
+     */
+    @TableField("WoTyped")
+    private String woTyped;
+
+    /**
+     * 优先级
+     */
+    @TableField("Priority")
+    private Integer priority;
+
+    /**
+     * 订单日期
+     */
+    @TableField("OrdDate")
+    private LocalDateTime ordDate;
+
+    /**
+     * 到期日期
+     */
+    @TableField("DueDate")
+    private LocalDateTime dueDate;
+
+    /**
+     * 下达日期
+     */
+    @TableField("ReleaseDate")
+    private LocalDateTime releaseDate;
+
+    /**
+     * 订单数量
+     */
+    @TableField("QtyOrded")
+    private BigDecimal qtyOrded;
+
+    /**
+     * 完成数量
+     */
+    @TableField("QtyCompleted")
+    private BigDecimal qtyCompleted;
+
+    /**
+     * 不良品数量
+     */
+    @TableField("QtyReject")
+    private BigDecimal qtyReject;
+
+    /**
+     * 项目
+     */
+    @TableField("Project")
+    private String project;
+
+    /**
+     * 地点
+     */
+    @TableField("Site")
+    private String site;
+
+    /**
+     * 库位
+     */
+    @TableField("Location")
+    private String location;
+
+    /**
+     * 生产线
+     */
+    @TableField("ProdLine")
+    private String prodLine;
+
+    /**
+     * 部门
+     */
+    @TableField("Department")
+    private String department;
+
+    /**
+     * 备注
+     */
+    @TableField("Remark")
+    private String remark;
+
+    /**
+     * 创建用户
+     */
+    @TableField("CreateUser")
+    private String createUser;
+
+    /**
+     * 更新用户
+     */
+    @TableField("UpdateUser")
+    private String updateUser;
+
+    /**
+     * 创建时间
+     */
+    @TableField("CreateTime")
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    @TableField("UpdateTime")
+    private LocalDateTime updateTime;
+
+    /**
+     * 是否有效
+     */
+    @TableField("IsActive")
+    private Boolean isActive;
+
+    /**
+     * 是否确认
+     */
+    @TableField("IsConfirm")
+    private Boolean isConfirm;
+
+    /**
+     * 是否初始
+     */
+    @TableField("IsInitial")
+    private Boolean isInitial;
+
+    /**
+     * 加急状态:1-加急,2-特急
+     */
+    @TableField("Urgent")
+    private Integer urgent;
+
+    /**
+     * 优先级编号
+     */
+    @TableField("PriorityNo")
+    private String priorityNo;
+
+    /**
+     * 客户编号
+     */
+    @TableField("CustNo")
+    private String custNo;
+
+    /**
+     * 客户优先级
+     */
+    @TableField("Class")
+    private String custClass;
+
+    /**
+     * 销售订单号
+     */
+    @TableField("SalesJob")
+    private String salesJob;
+
+    /**
+     * 过账地址
+     */
+    @TableField("IssueSite")
+    private String issueSite;
+
+    /**
+     * 在库齐套数量
+     */
+    @TableField("LocationStock")
+    private BigDecimal locationStock;
+
+    /**
+     * 工序完成数
+     */
+    @TableField("OpQtyCompleted")
+    private BigDecimal opQtyCompleted;
+
+    /**
+     * 下达周次
+     */
+    @TableField("DispatchWeek")
+    private String dispatchWeek;
+
+    /**
+     * 劳动成本
+     */
+    @TableField("lbrvar")
+    private BigDecimal lbrvar;
+
+    /**
+     * 是否创建GL
+     */
+    @TableField("CreateGLforLaborVar")
+    private Boolean createGLforLaborVar;
+}

+ 65 - 0
yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/dal/mysql/WorkOrderScheduleMapper.java

@@ -0,0 +1,65 @@
+package cn.iocoder.yudao.module.makeplan.dal.mysql;
+
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.makeplan.controller.admin.workorder.vo.WorkOrderSchedulePageReqVO;
+import cn.iocoder.yudao.module.makeplan.controller.admin.workorder.vo.WorkOrderScheduleRespVO;
+import cn.iocoder.yudao.module.makeplan.dal.dataobject.WorkOrderScheduleDO;
+import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 工单排产 Mapper
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface WorkOrderScheduleMapper extends BaseMapperX<WorkOrderScheduleDO> {
+
+    /**
+     * 分页查询工单排产列表
+     *
+     * @param page 分页参数
+     * @param reqVO 查询条件
+     * @return 分页结果
+     */
+    @InterceptorIgnore(tenantLine = "true")
+    IPage<WorkOrderScheduleRespVO> selectSchedulePage(IPage<WorkOrderScheduleRespVO> page, @Param("reqVO") WorkOrderSchedulePageReqVO reqVO);
+
+    /**
+     * 根据ID查询工单详情
+     *
+     * @param id 工单ID
+     * @return 工单详情
+     */
+    @InterceptorIgnore(tenantLine = "true")
+    WorkOrderScheduleRespVO selectScheduleById(@Param("id") Long id);
+
+    /**
+     * 调用存储过程关闭工单
+     *
+     * @param ids 工单ID列表(逗号分隔)
+     */
+    @InterceptorIgnore(tenantLine = "true")
+    void callCloseWorkOrders(@Param("ids") String ids);
+
+    /**
+     * 同步工艺路线
+     *
+     * @param workOrd 工单编号
+     */
+    @InterceptorIgnore(tenantLine = "true")
+    void syncRoutingByWorkOrd(@Param("workOrd") String workOrd);
+
+    /**
+     * 批量查询工单信息
+     *
+     * @param ids 工单ID列表
+     * @return 工单列表
+     */
+    @InterceptorIgnore(tenantLine = "true")
+    List<WorkOrderScheduleDO> selectBatchByIds(@Param("ids") List<Long> ids);
+}

+ 72 - 0
yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/service/WorkOrderScheduleService.java

@@ -0,0 +1,72 @@
+package cn.iocoder.yudao.module.makeplan.service;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.makeplan.controller.admin.workorder.vo.*;
+
+/**
+ * 工单排产 Service 接口
+ *
+ * @author 芋道源码
+ */
+public interface WorkOrderScheduleService {
+
+    /**
+     * 获取工单排产分页列表
+     *
+     * @param pageReqVO 分页查询条件
+     * @return 工单排产分页列表
+     */
+    PageResult<WorkOrderScheduleRespVO> getWorkOrderSchedulePage(WorkOrderSchedulePageReqVO pageReqVO);
+
+    /**
+     * 获取工单详情
+     *
+     * @param id 工单ID
+     * @return 工单详情
+     */
+    WorkOrderScheduleRespVO getWorkOrderSchedule(Long id);
+
+    /**
+     * 更新工单
+     *
+     * @param updateReqVO 更新请求
+     */
+    void updateWorkOrderSchedule(WorkOrderScheduleUpdateReqVO updateReqVO);
+
+    /**
+     * 批量关闭工单
+     *
+     * @param closeReqVO 关闭请求
+     */
+    void closeWorkOrders(WorkOrderCloseReqVO closeReqVO);
+
+    /**
+     * 生产排程
+     *
+     * @param domain 域名/工厂编号
+     * @return 排程结果
+     */
+    String productionSchedule(String domain);
+
+    /**
+     * 同步物料需求
+     *
+     * @param domain 域名/工厂编号
+     * @return 同步结果
+     */
+    String syncMaterialRequirement(String domain);
+
+    /**
+     * 同步工艺路线
+     *
+     * @param id 工单ID
+     */
+    void syncRouting(Long id);
+
+    /**
+     * 设置工单加急状态
+     *
+     * @param urgentReqVO 加急请求
+     */
+    void setUrgent(WorkOrderUrgentReqVO urgentReqVO);
+}

+ 203 - 0
yudao-module-makeplan/src/main/java/cn/iocoder/yudao/module/makeplan/service/impl/WorkOrderScheduleServiceImpl.java

@@ -0,0 +1,203 @@
+package cn.iocoder.yudao.module.makeplan.service.impl;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.makeplan.controller.admin.workorder.vo.*;
+import cn.iocoder.yudao.module.makeplan.dal.dataobject.WorkOrderScheduleDO;
+import cn.iocoder.yudao.module.makeplan.dal.mysql.WorkOrderScheduleMapper;
+import cn.iocoder.yudao.module.makeplan.service.WorkOrderScheduleService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
+
+/**
+ * 工单排产 Service 实现类
+ *
+ * @author 芋道源码
+ */
+@Service
+@Slf4j
+public class WorkOrderScheduleServiceImpl implements WorkOrderScheduleService {
+
+    @Resource
+    private WorkOrderScheduleMapper workOrderScheduleMapper;
+
+    @Resource
+    private RestTemplate restTemplate;
+
+    private static final String PRODUCTION_SCHEDULE_URL = "http://123.60.180.165:9898/api/business/resource-examine/productionschedule?domain=";
+    private static final String MATERIAL_REQUIREMENT_URL = "http://123.60.180.165:9898/api/business/resource-examine/AutomaticPrAdjustDate?domain=";
+
+    @Override
+    public PageResult<WorkOrderScheduleRespVO> getWorkOrderSchedulePage(WorkOrderSchedulePageReqVO pageReqVO) {
+        // 构建 MyBatis Plus 分页对象
+        IPage<WorkOrderScheduleRespVO> page = new Page<>(
+            pageReqVO.getPageNo(), 
+            pageReqVO.getPageSize()
+        );
+        
+        // 执行分页查询
+        IPage<WorkOrderScheduleRespVO> result = workOrderScheduleMapper.selectSchedulePage(page, pageReqVO);
+        
+        // 转换为 PageResult
+        return new PageResult<>(result.getRecords(), result.getTotal());
+    }
+
+    @Override
+    public WorkOrderScheduleRespVO getWorkOrderSchedule(Long id) {
+        WorkOrderScheduleRespVO workOrder = workOrderScheduleMapper.selectScheduleById(id);
+        if (workOrder == null) {
+            throw exception(BAD_REQUEST, "工单不存在");
+        }
+        return workOrder;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateWorkOrderSchedule(WorkOrderScheduleUpdateReqVO updateReqVO) {
+        // 查询工单是否存在
+        WorkOrderScheduleDO workOrder = workOrderScheduleMapper.selectById(updateReqVO.getId());
+        if (workOrder == null) {
+            throw exception(BAD_REQUEST, "工单不存在");
+        }
+
+        // 更新工单信息
+        WorkOrderScheduleDO updateDO = new WorkOrderScheduleDO();
+        updateDO.setRecId(updateReqVO.getId());
+        if (updateReqVO.getPriority() != null) {
+            updateDO.setPriority(updateReqVO.getPriority());
+        }
+        if (updateReqVO.getQtyOrded() != null) {
+            updateDO.setQtyOrded(updateReqVO.getQtyOrded());
+        }
+        if (updateReqVO.getBatch() != null) {
+            updateDO.setBatch(updateReqVO.getBatch());
+        }
+        if (updateReqVO.getRemark() != null) {
+            updateDO.setRemark(updateReqVO.getRemark());
+        }
+        
+        workOrderScheduleMapper.updateById(updateDO);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void closeWorkOrders(WorkOrderCloseReqVO closeReqVO) {
+        // 查询工单列表
+        List<WorkOrderScheduleDO> workOrders = workOrderScheduleMapper.selectBatchByIds(closeReqVO.getIds());
+        
+        // 验证工单状态
+        for (WorkOrderScheduleDO workOrder : workOrders) {
+            String status = workOrder.getStatus();
+            if ("initial".equalsIgnoreCase(status) || "closed".equalsIgnoreCase(status)) {
+                throw exception(BAD_REQUEST, "工单【" + workOrder.getWorkOrd() + "】状态为初始或关闭,不能执行关闭操作");
+            }
+        }
+
+        // 拼接ID字符串
+        String ids = closeReqVO.getIds().stream()
+                .map(String::valueOf)
+                .collect(Collectors.joining(","));
+
+        // 调用存储过程关闭工单
+        try {
+            workOrderScheduleMapper.callCloseWorkOrders(ids);
+            log.info("成功关闭工单,IDs: {}", ids);
+        } catch (Exception e) {
+            log.error("关闭工单失败,IDs: {}", ids, e);
+            throw exception(BAD_REQUEST, "关闭工单失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public String productionSchedule(String domain) {
+        try {
+            String url = PRODUCTION_SCHEDULE_URL + domain;
+            log.info("调用生产排程接口: {}", url);
+            
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+            HttpEntity<String> entity = new HttpEntity<>(headers);
+            
+            ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);
+            log.info("生产排程接口返回: {}", response.getBody());
+            
+            return response.getBody();
+        } catch (Exception e) {
+            log.error("调用生产排程接口失败", e);
+            throw exception(BAD_REQUEST, "生产排程失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public String syncMaterialRequirement(String domain) {
+        try {
+            String url = MATERIAL_REQUIREMENT_URL + domain;
+            log.info("调用同步物料需求接口: {}", url);
+            
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+            HttpEntity<String> entity = new HttpEntity<>(headers);
+            
+            ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);
+            log.info("同步物料需求接口返回: {}", response.getBody());
+            
+            return response.getBody();
+        } catch (Exception e) {
+            log.error("调用同步物料需求接口失败", e);
+            throw exception(BAD_REQUEST, "同步物料需求失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void syncRouting(Long id) {
+        // 查询工单
+        WorkOrderScheduleDO workOrder = workOrderScheduleMapper.selectById(id);
+        if (workOrder == null) {
+            throw exception(BAD_REQUEST, "工单不存在");
+        }
+
+        try {
+            // 同步工艺路线
+            workOrderScheduleMapper.syncRoutingByWorkOrd(workOrder.getWorkOrd());
+            log.info("成功同步工艺路线,工单: {}", workOrder.getWorkOrd());
+        } catch (Exception e) {
+            log.error("同步工艺路线失败,工单: {}", workOrder.getWorkOrd(), e);
+            throw exception(BAD_REQUEST, "同步工艺路线失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void setUrgent(WorkOrderUrgentReqVO urgentReqVO) {
+        // 查询工单
+        WorkOrderScheduleDO workOrder = workOrderScheduleMapper.selectById(urgentReqVO.getId());
+        if (workOrder == null) {
+            throw exception(BAD_REQUEST, "工单不存在");
+        }
+
+        // 更新加急状态
+        WorkOrderScheduleDO updateDO = new WorkOrderScheduleDO();
+        updateDO.setRecId(urgentReqVO.getId());
+        updateDO.setUrgent(urgentReqVO.getUrgent());
+        
+        workOrderScheduleMapper.updateById(updateDO);
+        
+        String urgentText = urgentReqVO.getUrgent() == 1 ? "加急" : "特急";
+        log.info("成功设置工单【{}】为{}", workOrder.getWorkOrd(), urgentText);
+    }
+}

+ 210 - 0
yudao-module-makeplan/src/main/resources/mapper/makeplan/WorkOrderScheduleMapper.xml

@@ -0,0 +1,210 @@
+<?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="cn.iocoder.yudao.module.makeplan.dal.mysql.WorkOrderScheduleMapper">
+
+    <!-- 工单排产列表查询 -->
+    <select id="selectSchedulePage" 
+            parameterType="cn.iocoder.yudao.module.makeplan.controller.admin.workorder.vo.WorkOrderSchedulePageReqVO"
+            resultType="cn.iocoder.yudao.module.makeplan.controller.admin.workorder.vo.WorkOrderScheduleRespVO">
+        SELECT 
+            a.RecID AS id,
+            exm.checktime,
+            a.Batch AS batch,
+            a.Drawing AS drawing,
+            a.Typed AS typed,
+            a.WorkOrd AS workOrd,
+            a.OrdDate AS ordDate,
+            a.DueDate AS dueDate,
+            a.ItemNum AS itemNum,
+            a.Project AS project,
+            a.QtyOrded AS qtyOrded,
+            a.QtyCompleted AS qtyCompleted,
+            a.Remark AS remark,
+            LOWER(a.Status) AS status,
+            a.WoTyped AS woTyped,
+            b.Descr AS descr,
+            b.Descr1 AS descr1,
+            a.lbrvar,
+            r.Area AS area,
+            se.custom_no AS customNo,
+            cm.Terms AS terms,
+            a.IsInitial AS isInitial,
+            CASE 
+                WHEN cm.Terms = '' OR cm.Terms IS NULL THEN
+                    CASE r.Area 
+                        WHEN '中国' THEN DATE_ADD(a.DueDate, INTERVAL 15 DAY)
+                        WHEN '海外' THEN DATE_ADD(a.DueDate, INTERVAL 8 DAY)
+                        ELSE NULL 
+                    END
+                ELSE
+                    CASE 
+                        WHEN cm.Terms = '海外' THEN DATE_ADD(a.DueDate, INTERVAL 8 DAY)
+                        ELSE DATE_ADD(a.DueDate, INTERVAL 15 DAY)
+                    END
+            END AS mjtime,
+            a.LotSerial AS lotSerial,
+            CASE WHEN a.CreateGLforLaborVar = 1 THEN '是' ELSE '否' END AS createGLforLaborVar,
+            a.QtyOrded - a.QtyCompleted AS zz,
+            s.PlanDate AS planDate,
+            s.ProdDate AS prodDate,
+            CASE 
+                WHEN s.PlanDate IS NULL THEN ''
+                WHEN s.PlanDate IS NOT NULL AND s.ProdDate IS NULL THEN
+                    CASE 
+                        WHEN DATEDIFF(CURDATE(), s.PlanDate) &lt;= 2 AND DATEDIFF(CURDATE(), s.PlanDate) &gt; 0 THEN '低'
+                        WHEN DATEDIFF(CURDATE(), s.PlanDate) &lt;= 5 AND DATEDIFF(CURDATE(), s.PlanDate) &gt; 2 THEN '中'
+                        WHEN DATEDIFF(CURDATE(), s.PlanDate) &gt; 5 THEN '高'
+                    END
+                WHEN s.PlanDate IS NOT NULL AND s.ProdDate IS NOT NULL THEN
+                    CASE 
+                        WHEN DATEDIFF(s.ProdDate, s.PlanDate) &lt;= 2 AND DATEDIFF(s.ProdDate, s.PlanDate) &gt; 0 THEN '低'
+                        WHEN DATEDIFF(s.ProdDate, s.PlanDate) &lt;= 5 AND DATEDIFF(s.ProdDate, s.PlanDate) &gt; 2 THEN '中'
+                        WHEN DATEDIFF(s.ProdDate, s.PlanDate) &gt; 5 THEN '高'
+                    END
+            END AS level,
+            a.IssueSite AS issueSite,
+            IFNULL(ins.WorkOrd, '') AS insWorkOrd,
+            CASE 
+                WHEN a.DispatchWeek = '' OR a.DispatchWeek IS NULL THEN
+                    CASE 
+                        WHEN a.LotSerial != '' AND a.LotSerial IS NOT NULL THEN
+                            CONCAT('WK', WEEK(STR_TO_DATE(SUBSTRING(a.LotSerial, 1, 6), '%y%m%d')))
+                        ELSE ''
+                    END
+                ELSE a.DispatchWeek
+            END AS checkweek,
+            a.Priority AS priority,
+            IFNULL(a.LocationStock, 0) + IFNULL(a.OpQtyCompleted, 0) AS locationStock
+        FROM WorkOrdMaster a
+        LEFT JOIN ItemMaster b ON a.ItemNum = b.ItemNum AND b.Domain = a.Domain
+        LEFT JOIN ReplenishmentWeekPlan r ON a.WorkOrd = r.ProductionOrder AND a.Domain = r.factory_id
+        LEFT JOIN crm_seorder se ON se.bill_no = a.SalesJob
+        LEFT JOIN CustMaster cm ON cm.Cust = se.custom_no
+        LEFT JOIN (
+            SELECT Domain, WorkOrds, MIN(PlanDate) AS PlanDate, MIN(ProdDate) AS ProdDate 
+            FROM PeriodSequenceDet 
+            GROUP BY Domain, WorkOrds
+        ) s ON a.Domain = s.Domain AND a.WorkOrd = s.WorkOrds
+        LEFT JOIN (
+            SELECT morder_no, create_time AS checktime
+            FROM (
+                SELECT morder_no, create_time,
+                       ROW_NUMBER() OVER (PARTITION BY morder_no ORDER BY create_time DESC) AS rn
+                FROM b_examine_result
+            ) ranked
+            WHERE rn = 1
+        ) exm ON exm.morder_no = a.WorkOrd
+        LEFT JOIN WorkOrdInStorage ins ON a.WorkOrd = ins.WorkOrd AND ins.Remark = '工单预留'
+        <where>
+            a.Status != ''
+            <if test="reqVO.workOrd != null and reqVO.workOrd != ''">
+                AND a.WorkOrd LIKE CONCAT('%', #{reqVO.workOrd}, '%')
+            </if>
+            <if test="reqVO.itemNum != null and reqVO.itemNum != ''">
+                AND a.ItemNum LIKE CONCAT('%', #{reqVO.itemNum}, '%')
+            </if>
+            <if test="reqVO.status != null and reqVO.status != ''">
+                AND LOWER(a.Status) = #{reqVO.status}
+            </if>
+            <if test="reqVO.woTyped != null and reqVO.woTyped != ''">
+                AND a.WoTyped = #{reqVO.woTyped}
+            </if>
+            <if test="reqVO.batch != null and reqVO.batch != ''">
+                AND a.Batch = #{reqVO.batch}
+            </if>
+            <if test="reqVO.drawing != null and reqVO.drawing != ''">
+                AND a.Drawing = #{reqVO.drawing}
+            </if>
+            <if test="reqVO.customNo != null and reqVO.customNo != ''">
+                AND se.custom_no = #{reqVO.customNo}
+            </if>
+            <if test="reqVO.ordDateStart != null">
+                AND a.OrdDate &gt;= #{reqVO.ordDateStart}
+            </if>
+            <if test="reqVO.ordDateEnd != null">
+                AND a.OrdDate &lt;= #{reqVO.ordDateEnd}
+            </if>
+            <if test="reqVO.dueDateStart != null">
+                AND a.DueDate &gt;= #{reqVO.dueDateStart}
+            </if>
+            <if test="reqVO.dueDateEnd != null">
+                AND a.DueDate &lt;= #{reqVO.dueDateEnd}
+            </if>
+            <if test="reqVO.priority != null">
+                AND a.Priority = #{reqVO.priority}
+            </if>
+            <if test="reqVO.urgent != null">
+                AND a.Urgent = #{reqVO.urgent}
+            </if>
+            <if test="reqVO.isInitial != null">
+                AND a.IsInitial = #{reqVO.isInitial}
+            </if>
+        </where>
+        ORDER BY a.UpdateTime DESC, a.Priority DESC
+    </select>
+
+    <!-- 根据ID查询工单详情 -->
+    <select id="selectScheduleById" resultType="cn.iocoder.yudao.module.makeplan.controller.admin.workorder.vo.WorkOrderScheduleRespVO">
+        SELECT 
+            a.RecID AS id,
+            a.Batch AS batch,
+            a.Drawing AS drawing,
+            a.Typed AS typed,
+            a.WorkOrd AS workOrd,
+            a.OrdDate AS ordDate,
+            a.DueDate AS dueDate,
+            a.ItemNum AS itemNum,
+            a.Project AS project,
+            a.QtyOrded AS qtyOrded,
+            a.QtyCompleted AS qtyCompleted,
+            a.Remark AS remark,
+            LOWER(a.Status) AS status,
+            a.WoTyped AS woTyped,
+            b.Descr AS descr,
+            b.Descr1 AS descr1,
+            a.lbrvar,
+            a.IsInitial AS isInitial,
+            a.LotSerial AS lotSerial,
+            CASE WHEN a.CreateGLforLaborVar = 1 THEN '是' ELSE '否' END AS createGLforLaborVar,
+            a.QtyOrded - a.QtyCompleted AS zz,
+            a.IssueSite AS issueSite,
+            a.Priority AS priority,
+            IFNULL(a.LocationStock, 0) + IFNULL(a.OpQtyCompleted, 0) AS locationStock
+        FROM WorkOrdMaster a
+        LEFT JOIN ItemMaster b ON a.ItemNum = b.ItemNum AND b.Domain = a.Domain
+        WHERE a.RecID = #{id}
+    </select>
+
+    <!-- 调用存储过程关闭工单 -->
+    <select id="callCloseWorkOrders" statementType="CALLABLE">
+        {CALL pr_MES_CloseWorkOrders(#{ids})}
+    </select>
+
+    <!-- 同步工艺路线 -->
+    <update id="syncRoutingByWorkOrd">
+        DELETE FROM WorkOrdRouting WHERE WorkOrd = #{workOrd};
+        
+        INSERT INTO WorkOrdRouting(
+            Domain, Descr, MilestoneOp, WorkOrd, OP, ParentOp, RunTime, ItemNum, 
+            QtyOrded, OverlapUnits, Status, IsActive, CommentIndex, CreateTime, 
+            StdOp, PackingQty, WorkOrdMasterRecID
+        )
+        SELECT 
+            w.Domain, r.Descr, r.MilestoneOp, w.WorkOrd, r.OP, r.ParentOp, r.RunTime, 
+            w.ItemNum, w.QtyOrded, r.OverlapUnits, w.Status, 1, r.CommentIndex, NOW(), 
+            r.StdOp, r.PackingQty, w.RecID 
+        FROM WorkOrdMaster w 
+        LEFT JOIN RoutingOpDetail r ON w.ItemNum = r.RoutingCode 
+        WHERE w.WorkOrd = #{workOrd} AND r.MilestoneOp IS NOT NULL
+    </update>
+
+    <!-- 批量查询工单信息 -->
+    <select id="selectBatchByIds" resultType="cn.iocoder.yudao.module.makeplan.dal.dataobject.WorkOrderScheduleDO">
+        SELECT * FROM WorkOrdMaster
+        WHERE RecID IN
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </select>
+
+</mapper>

+ 204 - 0
yudao-module-makeplan/src/main/resources/mapper/product/WorkOrderScheduleMapper.xml

@@ -0,0 +1,204 @@
+<?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="cn.iocoder.yudao.module.makeplan.dal.mysql.WorkOrderScheduleMapper">
+
+    <!-- 工单排产列表查询 -->
+    <select id="selectSchedulePage" resultType="cn.iocoder.yudao.module.makeplan.controller.admin.workorder.vo.WorkOrderScheduleRespVO">
+        SELECT 
+            a.RecID AS id,
+            exm.checktime,
+            a.Batch AS batch,
+            a.Drawing AS drawing,
+            a.Typed AS typed,
+            a.WorkOrd AS workOrd,
+            a.OrdDate AS ordDate,
+            a.DueDate AS dueDate,
+            a.ItemNum AS itemNum,
+            a.Project AS project,
+            a.QtyOrded AS qtyOrded,
+            a.QtyCompleted AS qtyCompleted,
+            a.Remark AS remark,
+            LOWER(a.Status) AS status,
+            a.WoTyped AS woTyped,
+            b.Descr AS descr,
+            b.Descr1 AS descr1,
+            a.lbrvar,
+            r.Area AS area,
+            se.custom_no AS customNo,
+            cm.Terms AS terms,
+            a.IsInitial AS isInitial,
+            CASE 
+                WHEN cm.Terms = '' OR cm.Terms IS NULL THEN
+                    CASE r.Area 
+                        WHEN '中国' THEN DATE_ADD(a.DueDate, INTERVAL 15 DAY)
+                        WHEN '海外' THEN DATE_ADD(a.DueDate, INTERVAL 8 DAY)
+                        ELSE NULL 
+                    END
+                ELSE
+                    CASE 
+                        WHEN cm.Terms = '海外' THEN DATE_ADD(a.DueDate, INTERVAL 8 DAY)
+                        ELSE DATE_ADD(a.DueDate, INTERVAL 15 DAY)
+                    END
+            END AS mjtime,
+            a.LotSerial AS lotSerial,
+            CASE WHEN a.CreateGLforLaborVar = 1 THEN '是' ELSE '否' END AS createGLforLaborVar,
+            a.QtyOrded - a.QtyCompleted AS zz,
+            s.PlanDate AS planDate,
+            s.ProdDate AS prodDate,
+            CASE 
+                WHEN s.PlanDate IS NULL THEN ''
+                WHEN s.PlanDate IS NOT NULL AND s.ProdDate IS NULL THEN
+                    CASE 
+                        WHEN DATEDIFF(CURDATE(), s.PlanDate) <![CDATA[<=]]> 2 AND DATEDIFF(CURDATE(), s.PlanDate) > 0 THEN 'LOW'
+                        WHEN DATEDIFF(CURDATE(), s.PlanDate) <![CDATA[<=]]> 5 AND DATEDIFF(CURDATE(), s.PlanDate) > 2 THEN 'MID'
+                        WHEN DATEDIFF(CURDATE(), s.PlanDate) > 5 THEN 'HIGH'
+                    END
+                WHEN s.PlanDate IS NOT NULL AND s.ProdDate IS NOT NULL THEN
+                    CASE 
+                        WHEN DATEDIFF(s.ProdDate, s.PlanDate) <![CDATA[<=]]> 2 AND DATEDIFF(s.ProdDate, s.PlanDate) > 0 THEN 'LOW'
+                        WHEN DATEDIFF(s.ProdDate, s.PlanDate) <![CDATA[<=]]> 5 AND DATEDIFF(s.ProdDate, s.PlanDate) > 2 THEN 'MID'
+                        WHEN DATEDIFF(s.ProdDate, s.PlanDate) > 5 THEN 'HIGH'
+                    END
+            END AS level,
+            a.IssueSite AS issueSite,
+            IFNULL(ins.WorkOrd, '') AS insWorkOrd,
+            CASE 
+                WHEN a.DispatchWeek = '' OR a.DispatchWeek IS NULL THEN
+                    CASE 
+                        WHEN a.LotSerial != '' AND a.LotSerial IS NOT NULL THEN
+                            CONCAT('WK', WEEK(STR_TO_DATE(SUBSTRING(a.LotSerial, 1, 6), '%y%m%d')))
+                        ELSE ''
+                    END
+                ELSE a.DispatchWeek
+            END AS checkweek,
+            a.Priority AS priority,
+            IFNULL(a.LocationStock, 0) + IFNULL(a.OpQtyCompleted, 0) AS locationStock
+        FROM WorkOrdMaster a
+        LEFT JOIN ItemMaster b ON a.ItemNum = b.ItemNum AND b.Domain = a.Domain
+        LEFT JOIN ReplenishmentWeekPlan r ON a.WorkOrd = r.ProductionOrder AND a.Domain = r.factory_id
+        LEFT JOIN crm_seorder se ON se.bill_no = a.SalesJob
+        LEFT JOIN CustMaster cm ON cm.Cust = se.custom_no
+        LEFT JOIN (
+            SELECT Domain, WorkOrds, MIN(PlanDate) AS PlanDate, MIN(ProdDate) AS ProdDate 
+            FROM PeriodSequenceDet 
+            GROUP BY Domain, WorkOrds
+        ) s ON a.Domain = s.Domain AND a.WorkOrd = s.WorkOrds
+        LEFT JOIN (
+            SELECT morder_no, create_time AS checktime,
+                   ROW_NUMBER() OVER (PARTITION BY morder_no ORDER BY create_time DESC) AS rn
+            FROM b_examine_result
+        ) exm ON exm.morder_no = a.WorkOrd AND exm.rn = 1
+        LEFT JOIN WorkOrdInStorage ins ON a.WorkOrd = ins.WorkOrd AND ins.Remark = '工单预留'
+        <where>
+            a.Status != ''
+            <if test="workOrd != null and workOrd != ''">
+                AND a.WorkOrd LIKE CONCAT('%', #{workOrd}, '%')
+            </if>
+            <if test="itemNum != null and itemNum != ''">
+                AND a.ItemNum LIKE CONCAT('%', #{itemNum}, '%')
+            </if>
+            <if test="status != null and status != ''">
+                AND LOWER(a.Status) = #{status}
+            </if>
+            <if test="woTyped != null and woTyped != ''">
+                AND a.WoTyped = #{woTyped}
+            </if>
+            <if test="batch != null and batch != ''">
+                AND a.Batch = #{batch}
+            </if>
+            <if test="drawing != null and drawing != ''">
+                AND a.Drawing = #{drawing}
+            </if>
+            <if test="customNo != null and customNo != ''">
+                AND se.custom_no = #{customNo}
+            </if>
+            <if test="ordDateStart != null">
+                AND a.OrdDate >= #{ordDateStart}
+            </if>
+            <if test="ordDateEnd != null">
+                AND a.OrdDate <![CDATA[<=]]> #{ordDateEnd}
+            </if>
+            <if test="dueDateStart != null">
+                AND a.DueDate >= #{dueDateStart}
+            </if>
+            <if test="dueDateEnd != null">
+                AND a.DueDate <![CDATA[<=]]> #{dueDateEnd}
+            </if>
+            <if test="priority != null">
+                AND a.Priority = #{priority}
+            </if>
+            <if test="urgent != null">
+                AND a.Urgent = #{urgent}
+            </if>
+            <if test="isInitial != null">
+                AND a.IsInitial = #{isInitial}
+            </if>
+        </where>
+        ORDER BY a.UpdateTime DESC, a.Priority DESC
+    </select>
+
+    <!-- 根据ID查询工单详情 -->
+    <select id="selectScheduleById" resultType="cn.iocoder.yudao.module.makeplan.controller.admin.workorder.vo.WorkOrderScheduleRespVO">
+        SELECT 
+            a.RecID AS id,
+            a.Batch AS batch,
+            a.Drawing AS drawing,
+            a.Typed AS typed,
+            a.WorkOrd AS workOrd,
+            a.OrdDate AS ordDate,
+            a.DueDate AS dueDate,
+            a.ItemNum AS itemNum,
+            a.Project AS project,
+            a.QtyOrded AS qtyOrded,
+            a.QtyCompleted AS qtyCompleted,
+            a.Remark AS remark,
+            LOWER(a.Status) AS status,
+            a.WoTyped AS woTyped,
+            b.Descr AS descr,
+            b.Descr1 AS descr1,
+            a.lbrvar,
+            a.IsInitial AS isInitial,
+            a.LotSerial AS lotSerial,
+            CASE WHEN a.CreateGLforLaborVar = 1 THEN '是' ELSE '否' END AS createGLforLaborVar,
+            a.QtyOrded - a.QtyCompleted AS zz,
+            a.IssueSite AS issueSite,
+            a.Priority AS priority,
+            IFNULL(a.LocationStock, 0) + IFNULL(a.OpQtyCompleted, 0) AS locationStock
+        FROM WorkOrdMaster a
+        LEFT JOIN ItemMaster b ON a.ItemNum = b.ItemNum AND b.Domain = a.Domain
+        WHERE a.RecID = #{id}
+    </select>
+
+    <!-- 调用存储过程关闭工单 -->
+    <select id="callCloseWorkOrders" statementType="CALLABLE">
+        {CALL pr_MES_CloseWorkOrders(#{ids})}
+    </select>
+
+    <!-- 同步工艺路线 -->
+    <update id="syncRoutingByWorkOrd">
+        DELETE FROM WorkOrdRouting WHERE WorkOrd = #{workOrd};
+        
+        INSERT INTO WorkOrdRouting(
+            Domain, Descr, MilestoneOp, WorkOrd, OP, ParentOp, RunTime, ItemNum, 
+            QtyOrded, OverlapUnits, Status, IsActive, CommentIndex, CreateTime, 
+            StdOp, PackingQty, WorkOrdMasterRecID
+        )
+        SELECT 
+            w.Domain, r.Descr, r.MilestoneOp, w.WorkOrd, r.OP, r.ParentOp, r.RunTime, 
+            w.ItemNum, w.QtyOrded, r.OverlapUnits, w.Status, 1, r.CommentIndex, NOW(), 
+            r.StdOp, r.PackingQty, w.RecID 
+        FROM WorkOrdMaster w 
+        LEFT JOIN RoutingOpDetail r ON w.ItemNum = r.RoutingCode 
+        WHERE w.WorkOrd = #{workOrd} AND r.MilestoneOp IS NOT NULL
+    </update>
+
+    <!-- 批量查询工单信息 -->
+    <select id="selectBatchByIds" resultType="cn.iocoder.yudao.module.makeplan.dal.dataobject.WorkOrderScheduleDO">
+        SELECT * FROM WorkOrdMaster
+        WHERE RecID IN
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </select>
+
+</mapper>

+ 0 - 0
yudao-order-server/LINKAGE_PLAN_COMPLETION.md → yudao-module-order/LINKAGE_PLAN_COMPLETION.md


+ 0 - 0
yudao-order-server/LINKAGE_PLAN_IMPLEMENTATION.md → yudao-module-order/LINKAGE_PLAN_IMPLEMENTATION.md


+ 0 - 0
yudao-order-server/SHIPPING_PLAN_IMPLEMENTATION.md → yudao-module-order/SHIPPING_PLAN_IMPLEMENTATION.md


+ 0 - 0
yudao-order-server/USER_INFO_ENHANCEMENT.md → yudao-module-order/USER_INFO_ENHANCEMENT.md


+ 0 - 0
yudao-order-server/WORKORDER_BACKEND_SUMMARY.md → yudao-module-order/WORKORDER_BACKEND_SUMMARY.md


+ 0 - 0
yudao-order-server/WORKORDER_COMPLETE_SUMMARY.md → yudao-module-order/WORKORDER_COMPLETE_SUMMARY.md


+ 0 - 0
yudao-order-server/WORKORDER_FIX_SUMMARY.md → yudao-module-order/WORKORDER_FIX_SUMMARY.md


+ 0 - 0
yudao-order-server/WORKORDER_FRONTEND_FIX_SUMMARY.md → yudao-module-order/WORKORDER_FRONTEND_FIX_SUMMARY.md


+ 2 - 2
yudao-order-server/pom.xml → yudao-module-order/pom.xml

@@ -9,11 +9,11 @@
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <artifactId>yudao-order-server</artifactId>
+    <artifactId>yudao-module-order</artifactId>
     <packaging>jar</packaging>
 
     <name>${project.artifactId}</name>
-    <description>订单管理后端 API 模块</description>
+    <description>订单管理模块(交付/评审/出货计划)</description>
 
     <dependencies>
         <!-- 系统基础能力:用户、租户等 -->

+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/OrderDeliveryController.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/OrderDeliveryController.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/OrderDeliveryPageItemVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/OrderDeliveryPageItemVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/OrderDeliveryPageReqVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/OrderDeliveryPageReqVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/SalesOutboundReqVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/SalesOutboundReqVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShipmentListItemVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShipmentListItemVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShipmentPageReqVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShipmentPageReqVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShipmentRespVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShipmentRespVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShipmentSaveReqVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShipmentSaveReqVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShippingPlanListItemVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShippingPlanListItemVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShippingPlanPageReqVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShippingPlanPageReqVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShippingPlanRespVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShippingPlanRespVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShippingPlanSaveReqVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ShippingPlanSaveReqVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ValueStreamRespVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/delivery/vo/ValueStreamRespVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/linkage/LinkagePlanController.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/linkage/LinkagePlanController.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/linkage/vo/LinkagePlanPageReqVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/linkage/vo/LinkagePlanPageReqVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/linkage/vo/LinkagePlanRespVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/linkage/vo/LinkagePlanRespVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/OrderChangeController.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/OrderChangeController.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/OrderReviewController.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/OrderReviewController.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderChangeCreateReqVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderChangeCreateReqVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderChangeRespVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderChangeRespVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderEntryRespVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderEntryRespVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderEntrySaveReqVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderEntrySaveReqVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderRespVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderRespVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderReviewPageItemVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderReviewPageItemVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderReviewPageReqVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderReviewPageReqVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderSaveReqVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/order/vo/OrderSaveReqVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/WorkOrderController.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/WorkOrderController.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/vo/MaterialCheckReqVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/vo/MaterialCheckReqVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/vo/MaterialRequirementReqVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/vo/MaterialRequirementReqVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/vo/WorkOrderPoolPageReqVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/vo/WorkOrderPoolPageReqVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/vo/WorkOrderPoolRespVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/vo/WorkOrderPoolRespVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/vo/WorkOrderReleaseReqVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/vo/WorkOrderReleaseReqVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/vo/WorkOrderUpdateReqVO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/controller/admin/workorder/vo/WorkOrderUpdateReqVO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/convert/LinkagePlanConvert.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/convert/LinkagePlanConvert.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/convert/OrderConvert.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/convert/OrderConvert.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/convert/OrderDeliveryConvert.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/convert/OrderDeliveryConvert.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/LinkagePlanDO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/LinkagePlanDO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/OrderChangeDO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/OrderChangeDO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/OrderDO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/OrderDO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/OrderEntryDO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/OrderEntryDO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/ShipmentDetailDO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/ShipmentDetailDO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/ShipmentMasterDO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/ShipmentMasterDO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/ShippingPlanDO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/ShippingPlanDO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/ShippingPlanDetailDO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/ShippingPlanDetailDO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/WorkOrdMasterDO.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/dataobject/WorkOrdMasterDO.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/LinkagePlanMapper.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/LinkagePlanMapper.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/OrderChangeMapper.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/OrderChangeMapper.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/OrderDeliveryMapper.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/OrderDeliveryMapper.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/OrderEntryMapper.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/OrderEntryMapper.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/OrderMapper.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/OrderMapper.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/ShipmentDetailMapper.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/ShipmentDetailMapper.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/ShipmentMasterMapper.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/ShipmentMasterMapper.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/ShippingPlanDetailMapper.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/ShippingPlanDetailMapper.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/ShippingPlanMapper.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/ShippingPlanMapper.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/WorkOrdMasterMapper.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/dal/mysql/WorkOrdMasterMapper.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/enums/ErrorCodeConstants.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/enums/ErrorCodeConstants.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/framework/web/config/OrderWebConfiguration.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/framework/web/config/OrderWebConfiguration.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/service/LinkagePlanService.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/service/LinkagePlanService.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/service/OrderChangeService.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/service/OrderChangeService.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/service/OrderDeliveryService.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/service/OrderDeliveryService.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/service/OrderService.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/service/OrderService.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/service/ShipmentService.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/service/ShipmentService.java


+ 0 - 0
yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/service/WorkOrderService.java → yudao-module-order/src/main/java/cn/iocoder/yudao/module/order/service/WorkOrderService.java


이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.