Browse Source

自动终评

ouyj 3 months ago
parent
commit
d137153f56
1 changed files with 379 additions and 0 deletions
  1. 379 0
      ygtx-gxt/src/main/java/com/ygtx/gxt/task/OrderScoreAutoFinalTask.java

+ 379 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/task/OrderScoreAutoFinalTask.java

@@ -0,0 +1,379 @@
+package com.ygtx.gxt.task;
+
+import com.ygtx.common.core.domain.entity.SysUser;
+import com.ygtx.common.core.domain.model.LoginUser;
+import com.ygtx.common.utils.DateUtils;
+import com.ygtx.framework.web.service.SysPermissionService;
+import com.ygtx.gxt.domain.*;
+import com.ygtx.gxt.service.IGxtOrderScoreService;
+import com.ygtx.gxt.service.IGxtRepairOrderFlowService;
+import com.ygtx.gxt.service.IGxtRepairOrderService;
+import com.ygtx.gxt.service.IGxtWorkOrderFlowService;
+import com.ygtx.gxt.service.IGxtWorkOrderService;
+import com.ygtx.system.mapper.SysUserMapper;
+import com.ygtx.system.service.ISysConfigService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * 工单自动终评任务
+ * 每小时执行,对复评超过24小时但未终评的维修工单和维保工单进行自动终评
+ *
+ * @author ouyj
+ * @date 2026-01-23
+ */
+@EnableScheduling
+@Component("orderScoreAutoFinalTask")
+public class OrderScoreAutoFinalTask {
+
+    private static final Logger log = LoggerFactory.getLogger(OrderScoreAutoFinalTask.class);
+
+    @Autowired
+    private IGxtRepairOrderService repairOrderService;
+
+    @Autowired
+    private IGxtRepairOrderFlowService repairOrderFlowService;
+
+    @Autowired
+    private IGxtWorkOrderService workOrderService;
+
+    @Autowired
+    private IGxtWorkOrderFlowService workOrderFlowService;
+
+    @Autowired
+    private IGxtOrderScoreService orderScoreService;
+
+    @Autowired
+    private SysUserMapper userMapper;
+
+    @Autowired
+    private SysPermissionService permissionService;
+
+    @Autowired
+    private ISysConfigService configService;
+
+    /**
+     * 每小时执行定时任务
+     * 查找复评超过24小时但未终评的维修工单和维保工单,并进行自动终评
+     */
+    public void autoFinalOrders() {
+        log.info("开始执行工单自动终评任务");
+        
+        // 设置系统用户上下文
+        setSystemUserContext();
+        
+        try {
+            // 处理维修工单的自动终评
+            processRepairOrders();
+
+            // 处理维保工单的自动终评
+            processWorkOrders();
+
+        } catch (Exception e) {
+            log.error("执行工单自动终评任务时发生异常", e);
+        }
+    }
+
+    /**
+     * 处理维修工单的自动终评
+     */
+    private void processRepairOrders() {
+        try {
+            // 构造查询条件:待终评状态的工单
+            GxtRepairOrder queryOrder = new GxtRepairOrder();
+            queryOrder.setScoringStatus("to_final"); // 待终评状态
+            List<GxtRepairOrder> orders = repairOrderService.selectGxtRepairOrderList(queryOrder);
+
+            int finalCount = 0;
+            for (GxtRepairOrder order : orders) {
+                // 检查是否满足自动终评条件(复评超过24小时)
+                //if (shouldAutoFinalRepairOrder(order)) {
+                    // 执行自动终评操作
+                    autoFinalRepairOrder(order);
+                    finalCount++;
+                //}
+            }
+
+            log.info("维修工单自动终评任务执行完成,共处理 {} 个工单", finalCount);
+        } catch (Exception e) {
+            log.error("处理维修工单自动终评时发生异常", e);
+        }
+    }
+
+    /**
+     * 处理维保工单的自动终评
+     */
+    private void processWorkOrders() {
+        try {
+            // 构造查询条件:待终评状态的维保工单
+            GxtWorkOrder queryOrder = new GxtWorkOrder();
+            queryOrder.setScoringStatus("to_final"); // 待终评状态
+            List<GxtWorkOrder> orders = workOrderService.selectGxtWorkOrderList(queryOrder);
+
+            int finalCount = 0;
+            for (GxtWorkOrder order : orders) {
+                // 检查是否满足自动终评条件(复评超过24小时)
+                //if (shouldAutoFinalWorkOrder(order)) {
+                    // 执行自动终评操作
+                    autoFinalWorkOrder(order);
+                    finalCount++;
+                //}
+            }
+
+            log.info("维保工单自动终评任务执行完成,共处理 {} 个工单", finalCount);
+        } catch (Exception e) {
+            log.error("处理维保工单自动终评时发生异常", e);
+        }
+    }
+
+    /**
+     * 判断维修工单是否满足自动终评条件
+     * 条件:处于待终评状态且超过配置的小时数,默认24小时
+     *
+     * @param order 维修工单
+     * @return 是否满足自动终评条件
+     */
+    private boolean shouldAutoFinalRepairOrder(GxtRepairOrder order) {
+        Date toFinalStatusTime = null;
+        
+        // 通过查询工单流转记录获取进入待终评状态的时间
+        GxtRepairOrderFlow flowQuery = new GxtRepairOrderFlow();
+        flowQuery.setOrderId(order.getId());
+        flowQuery.setActionType("reviewRating");
+        List<GxtRepairOrderFlow> flows = repairOrderFlowService.selectGxtRepairOrderFlowList(flowQuery);
+
+        if (!flows.isEmpty()) {
+            // 获取最后一次进入待终评状态的时间
+            toFinalStatusTime = flows.get(flows.size() - 1).getActionTime();
+        }
+
+        if (toFinalStatusTime == null) {
+            return false;
+        }
+
+        // 从配置中获取终评超时小时数,如果配置为空则默认24小时
+        String hoursStr = configService.selectConfigByKey("gxt.orderScore.autoFinalHours");
+        int finalHours = 24; // 默认24小时
+        if (hoursStr != null && !hoursStr.trim().isEmpty()) {
+            try {
+                finalHours = Integer.parseInt(hoursStr.trim());
+            } catch (NumberFormatException e) {
+                log.warn("配置的自动终评小时数不是有效数字,使用默认值24小时: {}", hoursStr);
+            }
+        }
+
+        // 检查进入待终评状态的时间是否已超过配置的小时数
+        Date now = DateUtils.getNowDate();
+        Date finalTimeThreshold = DateUtils.addHours(toFinalStatusTime, finalHours);
+
+        return now.after(finalTimeThreshold);
+    }
+
+    /**
+     * 判断维保工单是否满足自动终评条件
+     * 条件:处于待终评状态且超过配置的小时数,默认24小时
+     *
+     * @param order 维保工单
+     * @return 是否满足自动终评条件
+     */
+    private boolean shouldAutoFinalWorkOrder(GxtWorkOrder order) {
+        Date toFinalStatusTime = null;
+        
+        // 通过查询工单流转记录获取进入待终评状态的时间
+        GxtWorkOrderFlow flowQuery = new GxtWorkOrderFlow();
+        flowQuery.setOrderId(order.getId());
+        flowQuery.setActionType("reviewRating");
+        List<GxtWorkOrderFlow> flows = workOrderFlowService.selectGxtWorkOrderFlowList(flowQuery);
+
+        if (!flows.isEmpty()) {
+            // 获取最后一次进入待终评状态的时间
+            toFinalStatusTime = flows.get(flows.size() - 1).getActionTime();
+        }
+
+        if (toFinalStatusTime == null) {
+            return false;
+        }
+
+        // 从配置中获取终评超时小时数,如果配置为空则默认24小时
+        String hoursStr = configService.selectConfigByKey("gxt.orderScore.autoFinalHours");
+        int finalHours = 24; // 默认24小时
+        if (hoursStr != null && !hoursStr.trim().isEmpty()) {
+            try {
+                finalHours = Integer.parseInt(hoursStr.trim());
+            } catch (NumberFormatException e) {
+                log.warn("配置的自动终评小时数不是有效数字,使用默认值24小时: {}", hoursStr);
+            }
+        }
+
+        // 检查进入待终评状态的时间是否已超过配置的小时数
+        Date now = DateUtils.getNowDate();
+        Date finalTimeThreshold = DateUtils.addHours(toFinalStatusTime, finalHours);
+
+        return now.after(finalTimeThreshold);
+    }
+
+    /**
+     * 对维修工单进行自动终评操作
+     *
+     * @param order 需要终评的工单
+     */
+    private void autoFinalRepairOrder(GxtRepairOrder order) {
+        try {
+            // 获取工单的人员评分信息
+            List<GxtRepairOrderPerson> orderPersons = repairOrderService.selectRepairOrderPersonListByOrderId(order.getId());
+            
+            // 创建评分信息对象
+            OrderScoreInfo orderScoreInfo = new OrderScoreInfo();
+            orderScoreInfo.setId(order.getId());
+            orderScoreInfo.setOrderType(1); // 维修工单
+            orderScoreInfo.setWorkOrderProjectNo(order.getWorkOrderProjectNo());
+            
+            // 复制原工单的评分状态和类型信息
+            //orderScoreInfo.setMaintenanceType(order.getMaintenanceType());
+            orderScoreInfo.setFinalCoefficient(order.getFinalCoefficient() != null ? order.getFinalCoefficient() : BigDecimal.ONE); // 系数设为1
+            
+            // 如果有重启时间,这可能影响最终的状态
+            //orderScoreInfo.setRestartTime(order.getRestartTime());
+            
+            // 设置人员评分列表
+            if (orderPersons != null && !orderPersons.isEmpty()) {
+                List<OrderScorePerson> scorePersons = orderPersons.stream().map(person -> {
+                    OrderScorePerson scorePerson = new OrderScorePerson();
+                    scorePerson.setId(person.getId());
+                    scorePerson.setUserId(person.getUserId());
+                    scorePerson.setNickName(person.getNickName());
+                    
+                    // 使用复评分作为终评分和总评分
+                    Double reviewScore = person.getReviewScore();
+                    scorePerson.setFinalScore(reviewScore);
+
+                    Double totalScore = (person.getTotalScore() != null) ? person.getTotalScore() : reviewScore;
+                    scorePerson.setTotalScore(totalScore != null ? totalScore : 0.0);
+                    
+                    // 保留原有的运行得分和停机扣分
+                    scorePerson.setRunScore(person.getRunScore());
+                    scorePerson.setStopScore(person.getStopScore());
+                    
+                    return scorePerson;
+                }).collect(Collectors.toList());
+                
+                orderScoreInfo.setScorePersonList(scorePersons);
+            } else {
+                // 如果没有人员评分信息,则创建一个空列表,避免空指针异常
+                orderScoreInfo.setScorePersonList(new ArrayList<>());
+            }
+
+            // 调用现有的终评方法
+            int result = orderScoreService.finalEvaluation(orderScoreInfo);
+            
+            if (result > 0) {
+                log.info("工单 {} 已成功自动终评", order.getWorkOrderProjectNo());
+            } else {
+                log.warn("工单 {} 自动终评失败", order.getWorkOrderProjectNo());
+            }
+        } catch (Exception e) {
+            log.error("自动终评工单 {} 时发生异常", order.getWorkOrderProjectNo(), e);
+        }
+    }
+
+    /**
+     * 对维保工单进行自动终评操作
+     *
+     * @param order 需要终评的工单
+     */
+    private void autoFinalWorkOrder(GxtWorkOrder order) {
+        try {
+            // 获取工单的人员评分信息
+            List<GxtWorkOrderPerson> orderPersons = workOrderService.selectWorkOrderPersonListByOrderId(order.getId());
+            
+            // 创建评分信息对象
+            OrderScoreInfo orderScoreInfo = new OrderScoreInfo();
+            orderScoreInfo.setId(order.getId());
+            orderScoreInfo.setOrderType(2); // 维保工单
+            orderScoreInfo.setWorkOrderProjectNo(order.getWorkOrderProjectNo());
+            
+            // 复制原工单的评分状态和类型信息
+            //orderScoreInfo.setInspectionType(order.getInspectionType());
+            //orderScoreInfo.setItemCompletionFactor(order.getItemCompletionFactor()); // 系数设为1
+            
+            // 如果有重启时间,这可能影响最终的状态
+            //orderScoreInfo.setRestartTime(order.getRestartTime());
+            
+            // 设置人员评分列表
+            if (orderPersons != null && !orderPersons.isEmpty()) {
+                List<OrderScorePerson> scorePersons = orderPersons.stream().map(person -> {
+                    OrderScorePerson scorePerson = new OrderScorePerson();
+                    scorePerson.setId(person.getId());
+                    scorePerson.setUserId(person.getUserId());
+                    scorePerson.setNickName(person.getNickName());
+                    
+                    // 使用复评分作为终评分和总评分
+                    Double reviewScore = person.getReviewScore();
+                    scorePerson.setFinalScore(reviewScore);
+
+                    Double totalScore = (person.getTotalScore() != null) ? person.getTotalScore() : reviewScore;
+                    scorePerson.setTotalScore(totalScore != null ? totalScore : 0.0);
+                    
+                    // 保留原有的运行得分和停机扣分
+                    scorePerson.setRunScore(person.getRunScore());
+                    scorePerson.setStopScore(person.getStopScore());
+                    
+                    return scorePerson;
+                }).collect(Collectors.toList());
+                
+                orderScoreInfo.setScorePersonList(scorePersons);
+            } else {
+                // 如果没有人员评分信息,则创建一个空列表,避免空指针异常
+                orderScoreInfo.setScorePersonList(new ArrayList<>());
+            }
+
+            // 调用现有的终评方法
+            int result = orderScoreService.finalEvaluation(orderScoreInfo);
+            
+            if (result > 0) {
+                log.info("工单 {} 已成功自动终评", order.getWorkOrderProjectNo());
+            } else {
+                log.warn("工单 {} 自动终评失败", order.getWorkOrderProjectNo());
+            }
+        } catch (Exception e) {
+            log.error("自动终评工单 {} 时发生异常", order.getWorkOrderProjectNo(), e);
+        }
+    }
+
+    /**
+     * 设置系统用户上下文,用于自动操作
+     */
+    private void setSystemUserContext() {
+        try {
+            // 获取admin用户信息
+            SysUser userAdmin = userMapper.selectUserByUserName("admin");
+            if (userAdmin != null) {
+                Set<String> permissions = permissionService.getMenuPermission(userAdmin);
+                LoginUser loginUser = new LoginUser(userAdmin, permissions);
+
+                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
+                        loginUser,
+                        null,
+                        loginUser.getAuthorities()
+                );
+
+                SecurityContextHolder.getContext().setAuthentication(authentication);
+            }
+        } catch (Exception e) {
+            log.error("设置系统用户上下文失败", e);
+        }
+    }
+}