Browse Source

feat:生产工单派工相关接口

lumaojun 2 tuần trước cách đây
mục cha
commit
4765c38788

+ 61 - 0
easydo-mes/src/main/java/easydo/technology/controller/ProductOrderDispatchController.java

@@ -0,0 +1,61 @@
+package easydo.technology.controller;
+
+import easydo.technology.model.vo.DispatchVO;
+import easydo.technology.service.ProductOrderDispatchService;
+import easydo.technology.utils.SecurityUtils;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.Map;
+
+/**
+ * 生产派工报工控制器
+ */
+@RestController
+@RequestMapping("/productOrderDispatch")
+public class ProductOrderDispatchController {
+
+    @Resource
+    private ProductOrderDispatchService productOrderDispatchService;
+
+    /**
+     * 分页查询派工记录
+     */
+    @RequestMapping(value = "/getPage")
+    public Object getPage(@RequestBody Map<String, Object> map) throws Exception {
+        Map<String, Object> result = productOrderDispatchService.getPage(map);
+        return new ResponseEntity<>(result, HttpStatus.OK);
+    }
+
+    /**
+     * 工单派工
+     */
+    @RequestMapping(value = "/dispatch")
+    public Object dispatch(@RequestBody DispatchVO vo) throws Exception {
+        // 校验用户登录状态
+        Long userId = SecurityUtils.getCurrentUserId();
+        if (userId == null) {
+            return new ResponseEntity<>("用户请先登录", HttpStatus.UNAUTHORIZED);
+        }
+
+        String result = productOrderDispatchService.dispatch(vo);
+        return new ResponseEntity<>(result, HttpStatus.OK);
+    }
+
+    /**
+     * 查询工单派工统计
+     */
+    @RequestMapping(value = "/getDispatchSummary")
+    public Object getDispatchSummary(@RequestBody Map<String, Object> map) throws Exception {
+        String orderId = (String) map.get("orderId");
+        if (orderId == null || orderId.trim().isEmpty()) {
+            return new ResponseEntity<>("orderId 不能为空", HttpStatus.BAD_REQUEST);
+        }
+        Map<String, Object> result = productOrderDispatchService.getDispatchSummary(orderId);
+        return new ResponseEntity<>(result, HttpStatus.OK);
+    }
+}

+ 5 - 0
easydo-mes/src/main/java/easydo/technology/enums/MESEnum.java

@@ -78,6 +78,11 @@ public enum MESEnum {
     PRODUCT_ORDER_OF_PRIORITY_HIGH("high", "高"),
     PRODUCT_ORDER_OF_PRIORITY_MEDIUM("medium", "中"),
     PRODUCT_ORDER_OF_PRIORITY_LOW("low", "低"),
+
+    PRODUCT_ORDER_DISPATCH_OF_STATUS_PENDING("pending", "待开始"),
+    PRODUCT_ORDER_DISPATCH_OF_STATUS_PROCESSING("processing", "进行中"),
+    PRODUCT_ORDER_DISPATCH_OF_STATUS_COMPLETED("completed", "已完成"),
+    PRODUCT_ORDER_DISPATCH_OF_STATUS_REWORK("rework", "待返工"),
     
     PURCHASE_PLAN_OF_STATUS_PENDING("pending", "待进行"),
     PURCHASE_PLAN_OF_STATUS_PROCESSING("processing", "进行中"),

+ 45 - 0
easydo-mes/src/main/java/easydo/technology/model/DispatchUserItem.java

@@ -0,0 +1,45 @@
+package easydo.technology.model;
+
+import easydo.technology.annotation.NotTableField;
+import easydo.technology.system.model.SysUser;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.math.BigDecimal;
+
+/**
+ * 派工人员子表
+ * 表名: dispatch_user_item
+ * 用于记录每个派工记录关联的操作工
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class DispatchUserItem extends CommonModel {
+    private String id;
+    private String dispatchId;  // 关联 product_order_dispatch 表的 id
+    private Long userId;        // 操作工ID
+    
+    // 以下字段为冗余字段,方便后续扩展每个用户的派工数据
+    private String orderId;
+    private String beginTime;
+    private String endTime;
+    private String status;
+    private String routeId;
+    private String bomId;
+    private String stageId;
+    private BigDecimal readyTimeHour;
+    private BigDecimal processNum;
+    private BigDecimal processTimeHour;
+    private BigDecimal moveTimeHour;
+    private BigDecimal moveNum;
+    private Integer orderNum;
+    private Boolean isReview;
+    private Boolean isReport;
+    private Boolean isRound;
+    private String tenantId;
+    private String createTime;
+    private Long createId;
+
+    @NotTableField
+    private SysUser user;  // 关联的用户信息
+}

+ 48 - 0
easydo-mes/src/main/java/easydo/technology/model/ProductOrderDispatch.java

@@ -0,0 +1,48 @@
+package easydo.technology.model;
+
+import easydo.technology.annotation.NotTableField;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 生产派工主表
+ * 表名: product_order_dispatch
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ProductOrderDispatch extends CommonModel {
+    private String id;
+    private String orderId;
+    private String beginTime;
+    private String endTime;
+    private String status;
+    private String routeId;
+    private String bomId;
+    private String stageId;
+    private BigDecimal readyTimeHour;
+    private BigDecimal processNum;
+    private BigDecimal processTimeHour;
+    private BigDecimal moveTimeHour;
+    private BigDecimal moveNum;
+    private Integer orderNum;
+    private Boolean isReview;
+    private Boolean isReport;
+    private Boolean isRound;
+    private String tenantId;
+    private String createTime;
+    private Long createId;
+
+    @NotTableField
+    private ProductOrder productOrder;
+    @NotTableField
+    private ProductOrderBom productOrderBom;
+    @NotTableField
+    private ProcessStage stage;
+    @NotTableField
+    private ProcessRoute route;
+    @NotTableField
+    private List<DispatchUserItem> userItems;  // 关联的派工人员列表
+}

+ 25 - 0
easydo-mes/src/main/java/easydo/technology/model/vo/DispatchVO.java

@@ -0,0 +1,25 @@
+package easydo.technology.model.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 派工请求VO
+ */
+@Data
+public class DispatchVO {
+    private String orderId;              // 工单ID
+    private String bomId;                // BOM ID(必填)
+    private List<DispatchItem> items;    // 派工明细列表
+
+    @Data
+    public static class DispatchItem {
+        private String id;               // 派工ID(有值=修改/删除,无值=新增)
+        private String stageId;          // 工序ID
+        private List<Long> userIds;      // 操作工ID列表(支持多个用户)
+        private Integer orderNum;        // 派工数量
+        private String beginTime;        // 计划开始时间
+        private String endTime;          // 计划结束时间
+    }
+}

+ 84 - 0
easydo-mes/src/main/java/easydo/technology/model/vo/ProductOrderDispatchVO.java

@@ -0,0 +1,84 @@
+package easydo.technology.model.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 派工记录查询返回VO
+ * 只包含前端需要的字段
+ */
+@Data
+public class ProductOrderDispatchVO {
+    private String id;
+    private String orderId;
+    private String bomId;
+    private String stageId;
+    private String routeId;
+    private Integer orderNum;
+    private BigDecimal processNum;
+    private BigDecimal processTimeHour;
+    private BigDecimal readyTimeHour;
+    private BigDecimal moveNum;
+    private BigDecimal moveTimeHour;
+    private String status;
+    private Boolean isReport;
+    private Boolean isReview;
+    private Boolean isRound;
+    private String beginTime;
+    private String endTime;
+    private String createTime;
+    private String tenantId;
+    
+    // 关联对象(简化)
+    private SimpleProductOrder productOrder;
+    private SimpleProductOrderBom productOrderBom;
+    private SimpleStage stage;
+    private List<SimpleDispatchUserItem> userItems;
+    
+    @Data
+    public static class SimpleProductOrder {
+        private String id;
+        private String code;
+        private String name;
+    }
+    
+    @Data
+    public static class SimpleProductOrderBom {
+        private String id;
+        private String bomId;
+        private Double number;
+        private SimpleProductBom productBom;
+    }
+    
+    @Data
+    public static class SimpleProductBom {
+        private String id;
+        private String bomCode;
+        private String materialName;
+    }
+    
+    @Data
+    public static class SimpleStage {
+        private String id;
+        private String name;
+        private String code;
+    }
+    
+    @Data
+    public static class SimpleDispatchUserItem {
+        private String id;
+        private Long userId;
+        private String status;
+        private Boolean isReport;
+        private Boolean isReview;
+        private SimpleUser user;
+    }
+    
+    @Data
+    public static class SimpleUser {
+        private Long id;
+        private String username;
+    }
+}

+ 23 - 0
easydo-mes/src/main/java/easydo/technology/service/ProductOrderDispatchService.java

@@ -0,0 +1,23 @@
+package easydo.technology.service;
+
+import easydo.technology.model.vo.DispatchVO;
+
+import java.util.Map;
+
+public interface ProductOrderDispatchService {
+    
+    /**
+     * 分页查询派工记录
+     */
+    Map<String, Object> getPage(Map<String, Object> map) throws Exception;
+    
+    /**
+     * 工单派工
+     */
+    String dispatch(DispatchVO vo) throws Exception;
+    
+    /**
+     * 查询工单的派工统计(每道工序已派工/未派工数量)
+     */
+    Map<String, Object> getDispatchSummary(String orderId) throws Exception;
+}

+ 440 - 0
easydo-mes/src/main/java/easydo/technology/service/impl/ProductOrderDispatchServiceImpl.java

@@ -0,0 +1,440 @@
+package easydo.technology.service.impl;
+
+import easydo.technology.components.JdbcClient;
+import easydo.technology.enums.MESEnum;
+import easydo.technology.exception.BizException;
+import easydo.technology.model.*;
+import easydo.technology.model.vo.DispatchVO;
+import easydo.technology.model.vo.ProductOrderDispatchVO;
+import easydo.technology.service.ProductOrderDispatchService;
+import easydo.technology.system.model.SysUser;
+import easydo.technology.utils.SecurityUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class ProductOrderDispatchServiceImpl implements ProductOrderDispatchService {
+
+    @Resource
+    private JdbcClient jdbcClient;
+    @Resource
+    private DataSource dataSource;
+
+    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Map<String, Object> getPage(Map<String, Object> map) throws Exception {
+        Connection connection = dataSource.getConnection();
+        try {
+            // 查询派工记录分页数据
+            Map<String, Object> result = jdbcClient.getJdbcPage(map, ProductOrderDispatch.class, connection);
+            List<ProductOrderDispatch> list = (List<ProductOrderDispatch>) result.get("records");
+            
+            if (list == null || list.isEmpty()) {
+                return result;
+            }
+
+            // 转换为 VO 对象
+            List<ProductOrderDispatchVO> voList = new ArrayList<>();
+            for (ProductOrderDispatch model : list) {
+                ProductOrderDispatchVO vo = new ProductOrderDispatchVO();
+                
+                // 复制主要字段
+                vo.setId(model.getId());
+                vo.setOrderId(model.getOrderId());
+                vo.setBomId(model.getBomId());
+                vo.setStageId(model.getStageId());
+                vo.setRouteId(model.getRouteId());
+                vo.setOrderNum(model.getOrderNum());
+                vo.setProcessNum(model.getProcessNum());
+                vo.setProcessTimeHour(model.getProcessTimeHour());
+                vo.setReadyTimeHour(model.getReadyTimeHour());
+                vo.setMoveNum(model.getMoveNum());
+                vo.setMoveTimeHour(model.getMoveTimeHour());
+                vo.setStatus(model.getStatus());
+                vo.setIsReport(model.getIsReport());
+                vo.setIsReview(model.getIsReview());
+                vo.setIsRound(model.getIsRound());
+                vo.setBeginTime(model.getBeginTime());
+                vo.setEndTime(model.getEndTime());
+                vo.setCreateTime(model.getCreateTime());
+                vo.setTenantId(model.getTenantId());
+                
+                // 查询并设置工单信息
+                if (model.getOrderId() != null) {
+                    ProductOrder orderParam = new ProductOrder();
+                    orderParam.setId(model.getOrderId());
+                    ProductOrder order = jdbcClient.getJdbcModelById(orderParam, connection);
+                    if (order != null) {
+                        ProductOrderDispatchVO.SimpleProductOrder simpleOrder = new ProductOrderDispatchVO.SimpleProductOrder();
+                        simpleOrder.setId(order.getId());
+                        simpleOrder.setCode(order.getCode());
+                        simpleOrder.setName(order.getName());
+                        vo.setProductOrder(simpleOrder);
+                    }
+                }
+                
+                // 查询并设置工序信息
+                if (model.getStageId() != null) {
+                    ProcessStage stageParam = new ProcessStage();
+                    stageParam.setId(model.getStageId());
+                    ProcessStage stage = jdbcClient.getJdbcModelById(stageParam, connection);
+                    if (stage != null) {
+                        ProductOrderDispatchVO.SimpleStage simpleStage = new ProductOrderDispatchVO.SimpleStage();
+                        simpleStage.setId(stage.getId());
+                        simpleStage.setName(stage.getName());
+                        simpleStage.setCode(stage.getCode());
+                        vo.setStage(simpleStage);
+                    }
+                }
+                
+                // 查询并设置 BOM 信息
+                if (model.getBomId() != null) {
+                    ProductOrderBom bomParam = new ProductOrderBom();
+                    bomParam.setId(model.getBomId());
+                    ProductOrderBom bom = jdbcClient.getJdbcModelById(bomParam, connection);
+                    
+                    if (bom != null) {
+                        ProductOrderDispatchVO.SimpleProductOrderBom simpleBom = new ProductOrderDispatchVO.SimpleProductOrderBom();
+                        simpleBom.setId(bom.getId());
+                        simpleBom.setBomId(bom.getBomId());
+                        simpleBom.setNumber(bom.getNumber());
+                        
+                        // 查询产品 BOM 信息
+                        if (bom.getBomId() != null) {
+                            ProductBom productBomParam = new ProductBom();
+                            productBomParam.setId(bom.getBomId());
+                            ProductBom productBom = jdbcClient.getJdbcModelById(productBomParam, connection);
+                            if (productBom != null) {
+                                ProductOrderDispatchVO.SimpleProductBom simpleProductBom = new ProductOrderDispatchVO.SimpleProductBom();
+                                simpleProductBom.setId(productBom.getId());
+                                simpleProductBom.setBomCode(productBom.getBomCode());
+                                simpleProductBom.setMaterialName(productBom.getMaterialName());
+                                simpleBom.setProductBom(simpleProductBom);
+                            }
+                        }
+                        
+                        vo.setProductOrderBom(simpleBom);
+                    }
+                }
+                
+                // 查询并设置派工人员列表
+                DispatchUserItem userItemParam = new DispatchUserItem();
+                userItemParam.setDispatchId(model.getId());
+                List<DispatchUserItem> userItems = jdbcClient.getJdbcList(userItemParam, connection);
+                if (userItems != null && !userItems.isEmpty()) {
+                    List<ProductOrderDispatchVO.SimpleDispatchUserItem> simpleUserItems = new ArrayList<>();
+                    for (DispatchUserItem item : userItems) {
+                        ProductOrderDispatchVO.SimpleDispatchUserItem simpleItem = new ProductOrderDispatchVO.SimpleDispatchUserItem();
+                        simpleItem.setId(item.getId());
+                        simpleItem.setUserId(item.getUserId());
+                        simpleItem.setStatus(item.getStatus());
+                        simpleItem.setIsReport(item.getIsReport());
+                        simpleItem.setIsReview(item.getIsReview());
+                        
+                        // 查询用户信息
+                        if (item.getUserId() != null) {
+                            SysUser userParam = new SysUser();
+                            userParam.setId(item.getUserId());
+                            SysUser user = jdbcClient.getJdbcModelById(userParam, connection);
+                            if (user != null) {
+                                ProductOrderDispatchVO.SimpleUser simpleUser = new ProductOrderDispatchVO.SimpleUser();
+                                simpleUser.setId(user.getId());
+                                simpleUser.setUsername(user.getUsername());
+                                simpleItem.setUser(simpleUser);
+                            }
+                        }
+                        
+                        simpleUserItems.add(simpleItem);
+                    }
+                    vo.setUserItems(simpleUserItems);
+                }
+                
+                voList.add(vo);
+            }
+            
+            // 替换 records
+            result.put("records", voList);
+            return result;
+        } catch (Exception e) {
+            throw new BizException(e.getMessage());
+        } finally {
+            connection.close();
+        }
+    }
+
+    @Override
+    public String dispatch(DispatchVO vo) throws Exception {
+        Long userId = SecurityUtils.getCurrentUserId();
+        if (userId == null) {
+            throw new BizException("用户未登录");
+        }
+
+        Connection connection = dataSource.getConnection();
+        connection.setAutoCommit(false);
+        try {
+            // 1. 校验工单是否存在
+            ProductOrder orderParam = new ProductOrder();
+            orderParam.setId(vo.getOrderId());
+            ProductOrder order = jdbcClient.getJdbcModelById(orderParam, connection);
+            if (order == null) {
+                throw new BizException("工单不存在");
+            }
+
+            // 2. 获取租户ID
+            String tenantId = order.getTenantId();
+            
+            // 3. 校验 bomId 必填
+            if (vo.getBomId() == null || vo.getBomId().isEmpty()) {
+                throw new BizException("bomId 不能为空");
+            }
+            
+            // 4. 查询 BOM 并获取 routeId
+            ProductOrderBom bomParam = new ProductOrderBom();
+            bomParam.setId(vo.getBomId());
+            ProductOrderBom bom = jdbcClient.getJdbcModelById(bomParam, connection);
+            if (bom == null) {
+                throw new BizException("BOM不存在");
+            }
+            
+            // 从 BOM 获取 routeId
+            String routeId = bom.getRouteId();
+            if (routeId == null || routeId.isEmpty()) {
+                throw new BizException("BOM 未关联工艺路线");
+            }
+
+            // 5. 按明细处理:新增 / 修改 / 删除
+            if (vo.getItems() != null && !vo.getItems().isEmpty()) {
+                for (DispatchVO.DispatchItem item : vo.getItems()) {
+                    boolean hasId = item.getId() != null && !item.getId().trim().isEmpty();
+                    boolean deleteOnly = hasId
+                            && (item.getStageId() == null || item.getStageId().trim().isEmpty())
+                            && (item.getUserIds() == null || item.getUserIds().isEmpty())
+                            && item.getOrderNum() == null
+                            && (item.getBeginTime() == null || item.getBeginTime().trim().isEmpty())
+                            && (item.getEndTime() == null || item.getEndTime().trim().isEmpty());
+
+                    // 删除:仅传派工id
+                    if (deleteOnly) {
+                        ProductOrderDispatch deleteParam = new ProductOrderDispatch();
+                        deleteParam.setId(item.getId());
+                        ProductOrderDispatch existDispatch = jdbcClient.getJdbcModelById(deleteParam, connection);
+                        if (existDispatch == null) {
+                            throw new BizException("派工记录不存在: " + item.getId());
+                        }
+                        if (!vo.getOrderId().equals(existDispatch.getOrderId())) {
+                            throw new BizException("派工记录与工单不匹配: " + item.getId());
+                        }
+
+                        // 先删子表
+                        DispatchUserItem removeUserItemParam = new DispatchUserItem();
+                        removeUserItemParam.setDispatchId(item.getId());
+                        jdbcClient.jdbcRemove(removeUserItemParam, connection);
+
+                        // 再删主表
+                        ProductOrderDispatch removeDispatchParam = new ProductOrderDispatch();
+                        removeDispatchParam.setId(item.getId());
+                        jdbcClient.jdbcRemoveById(removeDispatchParam, connection);
+                        continue;
+                    }
+
+                    // 新增/修改都需要完整基础字段
+                    if (item.getStageId() == null || item.getStageId().trim().isEmpty()) {
+                        throw new BizException("工序不能为空");
+                    }
+                    if (item.getUserIds() == null || item.getUserIds().isEmpty()) {
+                        throw new BizException("派工人员不能为空");
+                    }
+
+                    // 校验工序是否存在
+                    ProcessStage stageParam = new ProcessStage();
+                    stageParam.setId(item.getStageId());
+                    ProcessStage stage = jdbcClient.getJdbcModelById(stageParam, connection);
+                    if (stage == null) {
+                        throw new BizException("工序不存在: " + item.getStageId());
+                    }
+
+                    if (hasId) {
+                        // 修改:传派工id + 修改字段
+                        ProductOrderDispatch updateParam = new ProductOrderDispatch();
+                        updateParam.setId(item.getId());
+                        ProductOrderDispatch existDispatch = jdbcClient.getJdbcModelById(updateParam, connection);
+                        if (existDispatch == null) {
+                            throw new BizException("派工记录不存在: " + item.getId());
+                        }
+                        if (!vo.getOrderId().equals(existDispatch.getOrderId())) {
+                            throw new BizException("派工记录与工单不匹配: " + item.getId());
+                        }
+
+                        existDispatch.setRouteId(routeId);
+                        existDispatch.setBomId(vo.getBomId());
+                        existDispatch.setStageId(item.getStageId());
+                        existDispatch.setOrderNum(item.getOrderNum());
+                        existDispatch.setBeginTime(item.getBeginTime());
+                        existDispatch.setEndTime(item.getEndTime());
+                        jdbcClient.jdbcUpdateById(existDispatch, connection);
+
+                        // 子表先删后插,确保人员同步
+                        DispatchUserItem removeUserItemParam = new DispatchUserItem();
+                        removeUserItemParam.setDispatchId(item.getId());
+                        jdbcClient.jdbcRemove(removeUserItemParam, connection);
+
+                        for (Long userIdItem : item.getUserIds()) {
+                            DispatchUserItem userItem = new DispatchUserItem();
+                            userItem.setDispatchId(existDispatch.getId());
+                            userItem.setOrderId(vo.getOrderId());
+                            userItem.setUserId(userIdItem);
+                            userItem.setBomId(vo.getBomId());
+                            userItem.setStageId(item.getStageId());
+                            userItem.setOrderNum(item.getOrderNum());
+                            userItem.setBeginTime(item.getBeginTime());
+                            userItem.setEndTime(item.getEndTime());
+                            userItem.setStatus(existDispatch.getStatus());
+                            userItem.setIsReport(false);
+                            userItem.setIsReview(false);
+                            userItem.setIsRound(false);
+                            userItem.setTenantId(tenantId);
+                            userItem.setCreateId(userId);
+                            userItem.setCreateTime(LocalDateTime.now().format(FORMATTER));
+                            jdbcClient.jdbcInsert(userItem, connection);
+                        }
+                    } else {
+                        // 新增:不传派工id
+                        ProductOrderDispatch dispatch = new ProductOrderDispatch();
+                        dispatch.setOrderId(vo.getOrderId());
+                        dispatch.setRouteId(routeId);
+                        dispatch.setBomId(vo.getBomId());
+                        dispatch.setStageId(item.getStageId());
+                        dispatch.setOrderNum(item.getOrderNum());
+                        dispatch.setBeginTime(item.getBeginTime());
+                        dispatch.setEndTime(item.getEndTime());
+                        dispatch.setStatus(MESEnum.PRODUCT_ORDER_DISPATCH_OF_STATUS_PENDING.getValue());
+                        dispatch.setIsReport(false);
+                        dispatch.setIsReview(false);
+                        dispatch.setIsRound(false);
+                        dispatch.setTenantId(tenantId);
+                        dispatch.setCreateId(userId);
+                        dispatch.setCreateTime(LocalDateTime.now().format(FORMATTER));
+
+                        jdbcClient.jdbcInsert(dispatch, connection);
+
+                        for (Long userIdItem : item.getUserIds()) {
+                            DispatchUserItem userItem = new DispatchUserItem();
+                            userItem.setDispatchId(dispatch.getId());
+                            userItem.setOrderId(vo.getOrderId());
+                            userItem.setUserId(userIdItem);
+                            userItem.setBomId(vo.getBomId());
+                            userItem.setStageId(item.getStageId());
+                            userItem.setOrderNum(item.getOrderNum());
+                            userItem.setBeginTime(item.getBeginTime());
+                            userItem.setEndTime(item.getEndTime());
+                            userItem.setStatus(MESEnum.PRODUCT_ORDER_DISPATCH_OF_STATUS_PENDING.getValue());
+                            userItem.setIsReport(false);
+                            userItem.setIsReview(false);
+                            userItem.setIsRound(false);
+                            userItem.setTenantId(tenantId);
+                            userItem.setCreateId(userId);
+                            userItem.setCreateTime(LocalDateTime.now().format(FORMATTER));
+                            jdbcClient.jdbcInsert(userItem, connection);
+                        }
+                    }
+                }
+            }
+
+            // 6. 更新工单状态为进行中(如果当前是待进行状态)
+            if (MESEnum.PRODUCT_ORDER_OF_STATUS_PENDING.getValue().equals(order.getStatus())) {
+                order.setStatus(MESEnum.PRODUCT_ORDER_OF_STATUS_PROCESSING.getValue());
+                jdbcClient.jdbcUpdateById(order, connection);
+            }
+
+            connection.commit();
+            return "派工处理成功";
+        } catch (Exception e) {
+            connection.rollback();
+            throw new BizException(e.getMessage());
+        } finally {
+            connection.close();
+        }
+    }
+
+    @Override
+    public Map<String, Object> getDispatchSummary(String orderId) throws Exception {
+        Connection connection = dataSource.getConnection();
+        try {
+            // 1. 查询该工单的所有派工记录(从主表 product_order_dispatch)
+            ProductOrderDispatch dispatchParam = new ProductOrderDispatch();
+            dispatchParam.setOrderId(orderId);
+            List<ProductOrderDispatch> dispatchList = jdbcClient.getJdbcList(dispatchParam, connection);
+            
+            // 2. 组装派工记录列表
+            List<Map<String, Object>> dispatches = new ArrayList<>();
+            
+            if (dispatchList != null) {
+                for (ProductOrderDispatch dispatch : dispatchList) {
+                    Map<String, Object> dispatchInfo = new HashMap<>();
+                    
+                    // 基本字段
+                    dispatchInfo.put("id", dispatch.getId());
+                    dispatchInfo.put("orderId", dispatch.getOrderId());
+                    dispatchInfo.put("bomId", dispatch.getBomId());
+                    dispatchInfo.put("stageId", dispatch.getStageId());
+                    dispatchInfo.put("routeId", dispatch.getRouteId());
+                    dispatchInfo.put("orderNum", dispatch.getOrderNum());
+                    dispatchInfo.put("processNum", dispatch.getProcessNum());
+                    dispatchInfo.put("processTimeHour", dispatch.getProcessTimeHour());
+                    dispatchInfo.put("readyTimeHour", dispatch.getReadyTimeHour());
+                    dispatchInfo.put("moveNum", dispatch.getMoveNum());
+                    dispatchInfo.put("moveTimeHour", dispatch.getMoveTimeHour());
+                    dispatchInfo.put("status", dispatch.getStatus());
+                    dispatchInfo.put("isReport", dispatch.getIsReport());
+                    dispatchInfo.put("isReview", dispatch.getIsReview());
+                    dispatchInfo.put("isRound", dispatch.getIsRound());
+                    dispatchInfo.put("beginTime", dispatch.getBeginTime());
+                    dispatchInfo.put("endTime", dispatch.getEndTime());
+                    dispatchInfo.put("createTime", dispatch.getCreateTime());
+                    
+                    // 3. 查询关联的用户信息(从子表 dispatch_user_item)
+                    DispatchUserItem userItemParam = new DispatchUserItem();
+                    userItemParam.setDispatchId(dispatch.getId());
+                    List<DispatchUserItem> userItems = jdbcClient.getJdbcList(userItemParam, connection);
+                    
+                    List<Map<String, Object>> users = new ArrayList<>();
+                    if (userItems != null) {
+                        for (DispatchUserItem userItem : userItems) {
+                            SysUser userParam = new SysUser();
+                            userParam.setId(userItem.getUserId());
+                            SysUser user = jdbcClient.getJdbcModelById(userParam, connection);
+                            
+                            Map<String, Object> userInfo = new HashMap<>();
+                            userInfo.put("userId", userItem.getUserId());
+                            userInfo.put("userName", user != null ? user.getUsername() : "");
+                            users.add(userInfo);
+                        }
+                    }
+                    
+                    dispatchInfo.put("users", users);
+                    dispatches.add(dispatchInfo);
+                }
+            }
+            
+            Map<String, Object> result = new HashMap<>();
+            result.put("dispatches", dispatches);
+            
+            return result;
+        } catch (Exception e) {
+            throw new BizException(e.getMessage());
+        } finally {
+            connection.close();
+        }
+    }
+}

+ 34 - 1
easydo-mes/src/main/java/easydo/technology/service/impl/ProductOrderServiceImpl.java

@@ -6,11 +6,13 @@ import easydo.technology.exception.BizException;
 import easydo.technology.model.*;
 import easydo.technology.service.FlowNoService;
 import easydo.technology.service.ProductOrderService;
+import easydo.technology.utils.StringUtil;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import javax.sql.DataSource;
 import java.sql.Connection;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -58,7 +60,30 @@ public class ProductOrderServiceImpl implements ProductOrderService {
                         if (orderBom.getRouteId() != null) {
                             ProcessRoute routeParam = new ProcessRoute();
                             routeParam.setId(orderBom.getRouteId());
-                            orderBom.setProcessRoute(jdbcClient.getJdbcModelById(routeParam, connection));
+                            ProcessRoute route = jdbcClient.getJdbcModelById(routeParam, connection);
+                            
+                            // 4.1.1) 查询工艺路线的工序明细列表(按 order_num 排序)
+                            if (route != null) {
+                                Map<String, Object> detailQueryMap = new HashMap<>();
+                                detailQueryMap.put("routeId", route.getId());
+                                detailQueryMap.put("orderBy", "orderNum_asc");
+                                List<ProcessRouteDetail> detailList = jdbcClient.getJdbcList(detailQueryMap, ProcessRouteDetail.class, connection);
+                                
+                                // 补齐每个工序明细的工序信息
+                                if (detailList != null) {
+                                    for (ProcessRouteDetail detail : detailList) {
+                                        if (detail.getStageId() != null) {
+                                            ProcessStage stageParam = new ProcessStage();
+                                            stageParam.setId(detail.getStageId());
+                                            detail.setStage(jdbcClient.getJdbcModelById(stageParam, connection));
+                                        }
+                                    }
+                                }
+                                
+                                route.setDetailList(detailList);
+                            }
+                            
+                            orderBom.setProcessRoute(route);
                         }
                         // 4.2) 质检方案
                         if (orderBom.getInspectProgramId() != null) {
@@ -161,6 +186,14 @@ public class ProductOrderServiceImpl implements ProductOrderService {
                 }
             }
 
+            // 6) 若工单关联了生产计划,则将对应生产计划状态更新为 processing
+            if (StringUtil.isNotEmpty(model.getPlanId())) {
+                ProductPlan productPlan = new ProductPlan();
+                productPlan.setId(model.getPlanId());
+                productPlan.setStatus(MESEnum.PRODUCT_PLAN_OF_STATUS_PROCESSING.getValue());
+                jdbcClient.jdbcUpdateById(productPlan, connection);
+            }
+
             connection.commit();
             return model;
         } catch (Exception e) {