Parcourir la source

工单操作过程奖励完善、扣分增加

ouyj il y a 2 mois
Parent
commit
a0ad5bd50d

+ 16 - 1
ygtx-gxt/src/main/java/com/ygtx/gxt/service/IGxtRepairOrderService.java

@@ -294,5 +294,20 @@ public interface IGxtRepairOrderService
      * @return 满足条件的维修工单集合
      */
     public List<GxtRepairOrder> selectRepairOrdersByRestartTime(Long equipmentId);
-    
+
+    /**
+     * 处理挂起工单的奖励数据补全
+     * 当设备维修工单的恢复时间与故障发生时间间隔不超过30分钟时,
+     * 需将关联的GxtOrderScoreDetail记录状态由1改为0,并补全人员运行得分及月度统计数据更新
+     *
+     * @param repairOrder 维修工单
+     */
+    public void processSuspendedOrderRewardData(GxtRepairOrder repairOrder);
+
+    /**
+     * 补全待结单工单的扣分数据
+     *
+     * @param repairOrder 维修工单
+     */
+    public void completePendingOrderDeductionData(GxtRepairOrder repairOrder);
 }

+ 693 - 3
ygtx-gxt/src/main/java/com/ygtx/gxt/service/impl/GxtRepairOrderServiceImpl.java

@@ -6,6 +6,7 @@ import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.text.SimpleDateFormat;
 import java.time.LocalTime;
 import java.time.YearMonth;
 import java.time.format.DateTimeFormatter;
@@ -23,20 +24,22 @@ import com.ygtx.common.utils.DictUtils;
 import com.ygtx.common.core.domain.entity.SysDept;
 import com.ygtx.framework.aspectj.DataScopeAspect;
 import com.ygtx.gxt.domain.*;
+import com.ygtx.system.mapper.SysUserMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import com.ygtx.gxt.mapper.GxtEquipmentMapper;
 import com.ygtx.gxt.mapper.GxtOrderPersonMapper;
-import com.ygtx.gxt.service.IGxtUserOperatorHistoryService;
+import com.ygtx.gxt.service.*;
 import com.ygtx.system.domain.SysPost;
 import com.ygtx.system.domain.SysPostHomePage;
 import com.ygtx.system.service.*;
 import com.ygtx.gxt.mapper.GxtRepairOrderPersonMapper;
+import com.ygtx.gxt.mapper.GxtWorkOrderPersonMapper;
 import com.ygtx.system.service.ISysUserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 import com.ygtx.gxt.mapper.GxtRepairOrderMapper;
-import com.ygtx.gxt.service.IGxtRepairOrderService;
-import com.ygtx.gxt.service.IGxtRepairOrderFlowService;
 import com.ygtx.common.annotation.DataScope;
 import com.ygtx.common.core.domain.entity.SysRole;
 import com.ygtx.common.core.domain.entity.SysUser;
@@ -55,6 +58,7 @@ import javax.sql.DataSource;
 @Service
 public class GxtRepairOrderServiceImpl implements IGxtRepairOrderService
 {
+    private static final Logger log = LoggerFactory.getLogger(GxtRepairOrderServiceImpl.class);
     @Autowired
     private GxtRepairOrderMapper gxtRepairOrderMapper;
 
@@ -94,6 +98,27 @@ public class GxtRepairOrderServiceImpl implements IGxtRepairOrderService
 
     @Autowired
     private GxtOrderPersonMapper orderPersonMapper;
+    
+    @Autowired
+    private IGxtWorkOrderService gxtWorkOrderService;
+    
+    @Autowired  
+    private IGxtOrderScoreDetailService gxtOrderScoreDetailService;
+    
+    @Autowired
+    private IGxtMonthScoreService monthScoreService;
+    
+    @Autowired
+    private IGxtUserScoreService userScoreService;
+    
+    @Autowired
+    private IGxtSafeOperationRewardService safeOperationRewardService;
+    
+    @Autowired
+    private GxtWorkOrderPersonMapper gxtWorkOrderPersonMapper;
+
+    @Autowired
+    private SysUserMapper userMapper;
 
     /**
      * 查询维修工单
@@ -1144,6 +1169,22 @@ public class GxtRepairOrderServiceImpl implements IGxtRepairOrderService
             flow.setActionTime(DateUtils.getNowDate());
             flow.setActionRemark("维修工单已自评。维修人员:"+memberNames);
             gxtRepairOrderFlowService.insertGxtRepairOrderFlow(flow);
+
+            if(oldOrder.getRestartTime() != null){
+                Date restartTime = oldOrder.getRestartTime();
+                Date occurTime = oldOrder.getOccurTime();
+                if (restartTime != null && occurTime != null) {
+                    long timeDiffMinutes = (restartTime.getTime() - occurTime.getTime()) / (1000 * 60);
+                    // 如果时间差小于等于30分钟,原来挂停的工单分数明细生效,奖励生效并补全数据
+                    if (timeDiffMinutes <= 30) {
+                        // 处理挂起工单的奖励数据补全
+                        processSuspendedOrderRewardData(gxtRepairOrder);
+                    }
+                }
+            }
+
+            //完善扣分数据
+            completePendingOrderDeductionData(gxtRepairOrder);
         }
         return result;
     }
@@ -1187,6 +1228,19 @@ public class GxtRepairOrderServiceImpl implements IGxtRepairOrderService
             flow.setActionTime(DateUtils.getNowDate());
             flow.setActionRemark("工单复启");
             gxtRepairOrderFlowService.insertGxtRepairOrderFlow(flow);
+
+            long timeDiffMinutes = 0;
+            if(oldOrder.getRestartTime() != null){
+                Date restartTime = oldOrder.getRestartTime();
+                Date occurTime = oldOrder.getOccurTime();
+                if (restartTime != null && occurTime != null) {
+                    timeDiffMinutes = (restartTime.getTime() - occurTime.getTime()) / (1000 * 60);
+                }
+            }
+            if("2".equals(gxtRepairOrder.getResetMethod()) || ("1".equals(gxtRepairOrder.getResetMethod()) && oldOrder.getRestartTime() != null && timeDiffMinutes <= 30)){
+                // 处理挂起工单的奖励数据补全
+                processSuspendedOrderRewardData(gxtRepairOrder);
+            }
         }
         return result;
     }
@@ -1250,6 +1304,28 @@ public class GxtRepairOrderServiceImpl implements IGxtRepairOrderService
                 flowArchive.setActionRemark("工单归档");
                 gxtRepairOrderFlowService.insertGxtRepairOrderFlow(flowArchive);
             }
+
+            long timeDiffMinutes = 0;
+            Date restartTime = gxtRepairOrder.getRestartTime();
+            Date occurTime = oldOrder.getOccurTime();
+            timeDiffMinutes = (restartTime.getTime() - occurTime.getTime()) / (1000 * 60);
+            // 判断是否需要处理挂起工单的奖励数据补全
+            boolean shouldProcessReward = false;
+            
+            if (gxtRepairOrder.getRepairMethod() != null) {
+                if ("1".equals(gxtRepairOrder.getRepairMethod())) {
+                    //正常维修:只要时间差不超过30分钟就需要处理
+                    shouldProcessReward =  timeDiffMinutes <= 30;
+                } else if ("2".equals(gxtRepairOrder.getRepairMethod())) {
+                    // 复位启机:需要resetMethod为"1"人工复位且时间差不超过30分钟
+                    shouldProcessReward = ("1".equals(gxtRepairOrder.getResetMethod()) && timeDiffMinutes <= 30);
+                }
+            }
+            
+            if (shouldProcessReward) {
+                // 处理挂起工单的奖励数据补全
+                processSuspendedOrderRewardData(gxtRepairOrder);
+            }
         }
         return result;
     }
@@ -2317,5 +2393,619 @@ public class GxtRepairOrderServiceImpl implements IGxtRepairOrderService
     public List<GxtRepairOrder> selectRepairOrdersByRestartTime(Long equipmentId) {
         return gxtRepairOrderMapper.selectRepairOrdersByRestartTime(equipmentId);
     }
+
+    /**
+     * 处理挂起工单的奖励数据补全
+     * 当设备维修工单的恢复时间与故障发生时间间隔不超过30分钟时,
+     * 需将关联的GxtOrderScoreDetail记录状态由1改为0,并补全人员运行得分及月度统计数据更新
+     * 
+     * @param repairOrder 维修工单
+     */
+    @Override
+    public void processSuspendedOrderRewardData(GxtRepairOrder repairOrder) {
+        //获取相关联的GxtOrderScoreDetail列表,获取方法是根据orderCodeRelate为当前工单编码以及status值为1的,获取到后依次修改status为0,
+        GxtOrderScoreDetail gxtOrderScoreDetail = new GxtOrderScoreDetail();
+        gxtOrderScoreDetail.setOrderCodeRelate(repairOrder.getWorkOrderProjectNo());
+        gxtOrderScoreDetail.setScoreType(2);
+        gxtOrderScoreDetail.setStatus(1);
+        List<GxtOrderScoreDetail> scoreDetails = gxtOrderScoreDetailService.selectGxtOrderScoreDetailList(gxtOrderScoreDetail);
+        if (!scoreDetails.isEmpty()) {
+            // 依次修改status为0
+            for (GxtOrderScoreDetail detail : scoreDetails) {
+                detail.setStatus(0);
+                gxtOrderScoreDetailService.updateGxtOrderScoreDetail(detail);
+                // 根据orderType判断工单类型并执行相应操作
+                if (detail.getOrderType() != null) {
+                    if (detail.getOrderType() == 1) {
+                        // 维修工单处理
+                        processRepairOrderRunScore(detail);
+                    } else if (detail.getOrderType() == 2) {
+                        // 维保工单处理
+                        processWorkOrderRunScore(detail);
+                    }
+                }
+            }
+        }
+    }
+
+    private void processRepairOrderRunScore(GxtOrderScoreDetail detail) {
+        // 获取奖励分数
+        BigDecimal rewardScore = detail.getRunScore();
+        if (rewardScore == null || rewardScore.compareTo(BigDecimal.ZERO) <= 0) {
+            return;
+        }
+
+        // 获取对应的维修工单
+        GxtRepairOrder repairOrder = gxtRepairOrderMapper.selectGxtRepairOrderById(detail.getOrderId());
+        if (repairOrder == null) {
+            return;
+        }
+
+        // 更新维修工单人员运行得分
+        updatePersonRunScoreForRepairOrderSingle(detail, rewardScore);
+
+        // 更新月度统计数据
+        updateMonthlyScoreDataForRunScoreSingle(detail, repairOrder, rewardScore);
+    }
+    
+    /**
+     * 处理维保工单运行得分
+     * 对应EquipmentSafeOperationRewardTask中的updatePersonRunScoreForWorkOrder和updateMonthlyScoreDataForRunScore
+     * 
+     * @param detail 工单个人分数明细
+     */
+    private void processWorkOrderRunScore(GxtOrderScoreDetail detail) {
+        // 获取奖励分数
+        BigDecimal rewardScore = detail.getRunScore();
+        if (rewardScore == null || rewardScore.compareTo(BigDecimal.ZERO) <= 0) {
+            return;
+        }
+
+        // 获取对应的维保工单
+        GxtWorkOrder workOrder = gxtWorkOrderService.selectGxtWorkOrderById(detail.getOrderId());
+        if (workOrder == null) {
+            return;
+        }
+
+        // 更新维保工单人员运行得分
+        updatePersonRunScoreForWorkOrderSingle(detail, rewardScore);
+
+        // 更新月度统计数据
+        updateMonthlyScoreDataForRunScoreSingle(detail, workOrder, rewardScore);
+
+    }
+    
+    /**
+     * 更新单个维修工单人员的运行得分
+     * 
+     * @param detail 工单个人分数明细
+     * @param rewardScore 奖励分数
+     */
+    private void updatePersonRunScoreForRepairOrderSingle(GxtOrderScoreDetail detail, BigDecimal rewardScore) {
+        // 查询对应的工单人员
+        GxtRepairOrderPerson personSearch = new GxtRepairOrderPerson();
+        personSearch.setUserId(detail.getUserId());
+        personSearch.setOrderId(detail.getOrderId());
+        List<GxtRepairOrderPerson> personList = gxtRepairOrderPersonMapper.selectGxtRepairOrderPersonList(personSearch);
+        GxtRepairOrderPerson person = null;
+        if (personList == null || personList.isEmpty()) {
+            return;
+        }
+        person = personList.get(0);
+        // 更新运行得分
+        Double currentRunScore = person.getRunScore();
+        Double newRunScore = (currentRunScore != null ? currentRunScore : 0.0) + rewardScore.doubleValue();
+
+        GxtRepairOrderPerson updatedPerson = new GxtRepairOrderPerson();
+        updatedPerson.setId(person.getId());
+        updatedPerson.setRunScore(newRunScore);
+        updatedPerson.setScore(person.getScore() != null ? person.getScore().add(rewardScore) : rewardScore);
+        updatedPerson.setUpdateBy(SecurityUtils.getLoginUser().getUser().getUserName());
+        updatedPerson.setUpdateTime(new Date());
+
+        gxtRepairOrderPersonMapper.updateGxtRepairOrderPerson(updatedPerson);
+    }
+    
+    /**
+     * 更新单个维保工单人员的运行得分
+     * 
+     * @param detail 工单个人分数明细
+     * @param rewardScore 奖励分数
+     */
+    private void updatePersonRunScoreForWorkOrderSingle(GxtOrderScoreDetail detail, BigDecimal rewardScore) {
+        // 查询对应的工单人员
+        GxtWorkOrderPerson personSearch = new GxtWorkOrderPerson();
+        personSearch.setUserId(detail.getUserId());
+        personSearch.setOrderId(detail.getOrderId());
+        List<GxtWorkOrderPerson> personList = gxtWorkOrderPersonMapper.selectGxtWorkOrderPersonList(personSearch);
+        GxtWorkOrderPerson person = null;
+        if (personList == null || personList.isEmpty()) {
+            return;
+        }
+        person = personList.get(0);
+        // 更新运行得分
+        Double currentRunScore = person.getRunScore();
+        Double newRunScore = (currentRunScore != null ? currentRunScore : 0.0) + rewardScore.doubleValue();
+
+        GxtWorkOrderPerson updatedPerson = new GxtWorkOrderPerson();
+        updatedPerson.setId(person.getId());
+        updatedPerson.setRunScore(newRunScore);
+        updatedPerson.setScore(person.getScore() != null ? person.getScore().add(rewardScore) : rewardScore);
+        updatedPerson.setUpdateBy(SecurityUtils.getLoginUser().getUser().getUserName());
+        updatedPerson.setUpdateTime(new Date());
+
+        gxtWorkOrderPersonMapper.updateGxtWorkOrderPerson(updatedPerson);
+    }
+    
+    /**
+     * 更新单个人员的月度统计数据(维修工单版本)
+     * 
+     * @param detail 工单个人分数明细
+     * @param repairOrder 维修工单
+     * @param rewardScore 奖励分数
+     */
+    private void updateMonthlyScoreDataForRunScoreSingle(GxtOrderScoreDetail detail, GxtRepairOrder repairOrder, BigDecimal rewardScore) {
+         // 使用当前日期所在的月份
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
+        String monthPeriod = sdf.format(detail.getCreateTime());
+
+        // 获取场站ID
+        Long deptId = repairOrder.getPcsStationPid();
+
+        // 获取月度统计信息
+        GxtMonthScore queryScore = new GxtMonthScore();
+        queryScore.setDeptId(deptId);
+        queryScore.setMonthPeriod(monthPeriod);
+        List<GxtMonthScore> scoreList = monthScoreService.selectGxtMonthScoreList(queryScore);
+        GxtMonthScore monthScore = null;
+        if (!scoreList.isEmpty()) {
+            monthScore = scoreList.get(0);
+        }
+
+        if (monthScore == null) {
+            // 如果没有月度统计记录,创建新的记录
+            monthScore = new GxtMonthScore();
+            monthScore.setDeptId(deptId);
+            monthScore.setMonthPeriod(monthPeriod);
+            monthScore.setStatus(0); // 初始状态
+            monthScore.setPersionId(SecurityUtils.getUserId());
+            monthScore.setCreateBy(SecurityUtils.getUsername());
+            monthScore.setCreateTime(new Date());
+            monthScoreService.insertGxtMonthScore(monthScore);
+
+            // 重新查询刚插入的记录
+            scoreList = monthScoreService.selectGxtMonthScoreList(queryScore);
+            if (!scoreList.isEmpty()) {
+                monthScore = scoreList.get(0);
+            }
+        }
+
+        if (monthScore != null) {
+            // 更新用户评分统计
+            updateUserScoreForRunScoreSingle(monthScore, detail, rewardScore);
+        }
+    }
+    
+    /**
+     * 更新单个人员的月度统计数据(维保工单版本)
+     * 
+     * @param detail 工单个人分数明细
+     * @param workOrder 维保工单
+     * @param rewardScore 奖励分数
+     */
+    private void updateMonthlyScoreDataForRunScoreSingle(GxtOrderScoreDetail detail, GxtWorkOrder workOrder, BigDecimal rewardScore) {
+        // 使用当前日期所在的月份
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
+        String monthPeriod = sdf.format(detail.getCreateTime());
+
+        // 获取场站ID
+        Long deptId = workOrder.getPcsStationPid();
+
+        // 获取月度统计信息
+        GxtMonthScore queryScore = new GxtMonthScore();
+        queryScore.setDeptId(deptId);
+        queryScore.setMonthPeriod(monthPeriod);
+        List<GxtMonthScore> scoreList = monthScoreService.selectGxtMonthScoreList(queryScore);
+        GxtMonthScore monthScore = null;
+        if (!scoreList.isEmpty()) {
+            monthScore = scoreList.get(0);
+        }
+
+        if (monthScore == null) {
+            // 如果没有月度统计记录,创建新的记录
+            monthScore = new GxtMonthScore();
+            monthScore.setDeptId(deptId);
+            monthScore.setMonthPeriod(monthPeriod);
+            monthScore.setStatus(0); // 初始状态
+            monthScore.setPersionId(SecurityUtils.getUserId());
+            monthScore.setCreateBy(SecurityUtils.getUsername());
+            monthScore.setCreateTime(new Date());
+            monthScoreService.insertGxtMonthScore(monthScore);
+
+            // 重新查询刚插入的记录
+            scoreList = monthScoreService.selectGxtMonthScoreList(queryScore);
+            if (!scoreList.isEmpty()) {
+                monthScore = scoreList.get(0);
+            }
+        }
+
+        if (monthScore != null) {
+            // 更新用户评分统计
+            updateUserScoreForRunScoreSingle(monthScore, detail, rewardScore);
+        }
+    }
+    
+    /**
+     * 更新单个用户的运行得分统计
+     * 
+     * @param monthScore 月度统计信息
+     * @param detail 工单个人分数明细
+     * @param rewardScore 奖励分数
+     */
+    private void updateUserScoreForRunScoreSingle(GxtMonthScore monthScore, GxtOrderScoreDetail detail, BigDecimal rewardScore) {
+        // 根据userId查询用户信息
+        SysUser sysUser = sysUserService.selectUserById(detail.getUserId());
+        if (sysUser == null) {
+            return;
+        }
+
+        // 使用userName、monthPeriod、monthScoreId精确查询用户评分记录
+        GxtUserScore userScoreQuery = new GxtUserScore();
+        userScoreQuery.setUserName(sysUser.getUserName());
+        userScoreQuery.setMonthPeriod(monthScore.getMonthPeriod());
+        userScoreQuery.setMonthScoreId(monthScore.getId());
+        List<GxtUserScore> userScores = userScoreService.selectGxtUserScoreList(userScoreQuery);
+
+        if (!userScores.isEmpty()) {
+            // 找到现有记录,直接更新
+            GxtUserScore userScore = userScores.get(0);
+
+            // 根据orderType决定更新哪个字段
+            if (detail.getOrderType() != null && detail.getOrderType() == 1) {
+                // 维修工单:更新repairTotalScore
+                BigDecimal currentRepairTotal = (userScore.getRepairTotalScore() != null) ?
+                        userScore.getRepairTotalScore() : BigDecimal.ZERO;
+                BigDecimal newRepairScore = currentRepairTotal.add(rewardScore);
+                userScore.setRepairTotalScore(newRepairScore);
+
+                // 维保得分保持不变
+                BigDecimal maintenanceScore = (userScore.getMaintenanceTotalScore() != null) ?
+                        userScore.getMaintenanceTotalScore() : BigDecimal.ZERO;
+                userScore.setMaintenanceTotalScore(maintenanceScore);
+
+                // 更新最终评分 = 维修得分 + 维保得分
+                BigDecimal finalScore = newRepairScore.add(maintenanceScore);
+                userScore.setFinalScore(finalScore);
+            } else if (detail.getOrderType() != null && detail.getOrderType() == 2) {
+                // 维保工单:更新maintenanceTotalScore
+                BigDecimal currentMaintenanceTotal = (userScore.getMaintenanceTotalScore() != null) ?
+                        userScore.getMaintenanceTotalScore() : BigDecimal.ZERO;
+                BigDecimal newMaintenanceScore = currentMaintenanceTotal.add(rewardScore);
+                userScore.setMaintenanceTotalScore(newMaintenanceScore);
+
+                // 维修得分保持不变
+                BigDecimal repairScore = (userScore.getRepairTotalScore() != null) ?
+                        userScore.getRepairTotalScore() : BigDecimal.ZERO;
+                userScore.setRepairTotalScore(repairScore);
+
+                // 更新最终评分 = 维修得分 + 维保得分
+                BigDecimal finalScore = repairScore.add(newMaintenanceScore);
+                userScore.setFinalScore(finalScore);
+            }
+
+            userScore.setUpdateBy(SecurityUtils.getLoginUser().getUser().getUserName());
+            userScore.setUpdateTime(new Date());
+            userScoreService.updateGxtUserScore(userScore);
+
+        } else {
+            // 没有找到记录,创建新记录
+            GxtUserScore newUserScore = new GxtUserScore();
+            newUserScore.setMonthScoreId(monthScore.getId());
+            newUserScore.setUserName(sysUser.getUserName());
+            newUserScore.setNickName(detail.getNickName());
+            newUserScore.setMonthPeriod(monthScore.getMonthPeriod());
+
+            // 根据orderType决定初始化哪个字段
+            if (detail.getOrderType() != null && detail.getOrderType() == 1) {
+                // 维修工单
+                newUserScore.setRepairTotalScore(rewardScore);
+                newUserScore.setMaintenanceTotalScore(BigDecimal.ZERO);
+                newUserScore.setFinalScore(rewardScore);
+            } else if (detail.getOrderType() != null && detail.getOrderType() == 2) {
+                // 维保工单
+                newUserScore.setMaintenanceTotalScore(rewardScore);
+                newUserScore.setRepairTotalScore(BigDecimal.ZERO);
+                newUserScore.setFinalScore(rewardScore);
+            }
+
+            newUserScore.setStatus(0);
+            newUserScore.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserName());
+            newUserScore.setCreateTime(new Date());
+            // 插入新记录
+            userScoreService.insertGxtUserScore(newUserScore);
+        }
+    }
+
+    /**
+     * 补全待结单工单的扣分数据
+     *
+     * @param repairOrder 维修工单
+     */
+    @Override
+    public void completePendingOrderDeductionData(GxtRepairOrder repairOrder) {
+        // 查询当前工单对应的GxtOrderScoreDetail且状态为1的数据(挂起状态)
+        GxtOrderScoreDetail queryDetail = new GxtOrderScoreDetail();
+        queryDetail.setOrderId(repairOrder.getId());
+        queryDetail.setOrderType(1); // 维修工单
+        queryDetail.setStatus(1); // 挂起状态
+        queryDetail.setScoreType(3); // 停机扣分
+
+        List<GxtOrderScoreDetail> scoreDetails = gxtOrderScoreDetailService.selectGxtOrderScoreDetailList(queryDetail);
+
+        if (scoreDetails == null || scoreDetails.isEmpty()) {
+            return; // 没有找到需要补全的扣分数据
+        }
+
+        // 获取工单所有人员列表
+        List<GxtRepairOrderPerson> allPersons = selectRepairOrderPersonListByOrderId(repairOrder.getId());
+        if (allPersons == null || allPersons.isEmpty()) {
+            return; // 没有找到工单人员
+        }
+
+        repairOrder.setRepairOrderPersonList(allPersons);
+        
+        // 累加所有扣分记录的stopScore
+        BigDecimal totalDeduction = BigDecimal.ZERO;
+        for (GxtOrderScoreDetail detail : scoreDetails) {
+            if (detail.getStopScore() != null && detail.getStopScore().compareTo(BigDecimal.ZERO) < 0) {
+                totalDeduction = totalDeduction.add(detail.getStopScore());
+            }
+        }
+        
+        if (totalDeduction.compareTo(BigDecimal.ZERO) >= 0) {
+            return; // 没有有效的扣分记录
+        }
+
+        // 计算每人平均扣分
+        int personCount = allPersons.size();
+        BigDecimal perPersonDeduction = totalDeduction.divide(new BigDecimal(personCount), 10, BigDecimal.ROUND_HALF_UP);
+        
+        // 根据小数位数决定最终结果
+        if (perPersonDeduction.scale() > 6) {
+            perPersonDeduction = perPersonDeduction.setScale(6, BigDecimal.ROUND_HALF_UP);
+        }
+
+        // 一次性更新所有人员
+        List<GxtRepairOrderPerson> personsToUpdate = new ArrayList<>();
+        
+        for (GxtRepairOrderPerson person : allPersons) {
+            GxtRepairOrderPerson updatedPerson = new GxtRepairOrderPerson();
+            updatedPerson.setId(person.getId());
+            
+            // 正确累加停机扣分
+            Double currentStopScore = person.getStopScore();
+            Double newStopScore = (currentStopScore != null ? currentStopScore : 0.0) + perPersonDeduction.doubleValue();
+            updatedPerson.setStopScore(newStopScore);
+            
+            // 正确累加总分
+            updatedPerson.setScore(person.getScore() != null ? person.getScore().add(perPersonDeduction) : perPersonDeduction);
+            
+            updatedPerson.setUpdateBy(SecurityUtils.getLoginUser().getUser().getUserName());
+            updatedPerson.setUpdateTime(new Date());
+            
+            personsToUpdate.add(updatedPerson);
+        }
+        
+        // 批量更新人员得分
+        updateRepairOrderPersonList(personsToUpdate);
+        
+        // 逐条处理月度统计数据(保持时间准确性)
+        for (GxtOrderScoreDetail detail : scoreDetails) {
+            if (detail.getStopScore() != null && detail.getStopScore().compareTo(BigDecimal.ZERO) < 0) {
+                // 使用每条记录的实际创建时间
+                updateMonthlyScoreDataForStopScore(repairOrder, detail.getStopScore(), detail.getCreateTime());
+                
+                // 为这条记录添加个人明细
+                int detailPersonCount = allPersons.size();
+                BigDecimal detailPerPersonDeduction = detail.getStopScore().divide(new BigDecimal(detailPersonCount), 10, BigDecimal.ROUND_HALF_UP);
+                if (detailPerPersonDeduction.scale() > 6) {
+                    detailPerPersonDeduction = detailPerPersonDeduction.setScale(6, BigDecimal.ROUND_HALF_UP);
+                }
+                addOrderScoreDetailsForStopScoreRepair(repairOrder, allPersons, detailPerPersonDeduction, 3, detail.getCreateTime());
+            }
+        }
+    }
+
+    /**
+     * 更新月度统计数据以反映停机扣分,使用工单归档时间确定月份
+     *
+     * @param repairOrder 维修工单
+     * @param deductionScore 扣分分数
+     * @param scoreTime 扣分时间
+     */
+    private void updateMonthlyScoreDataForStopScore(GxtRepairOrder repairOrder, BigDecimal deductionScore, Date scoreTime) {
+        // 使用归档时间所在的月份
+        java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM");
+        String monthPeriod = sdf.format(scoreTime);
+
+        // 获取场站ID
+        Long deptId = repairOrder.getPcsStationPid();
+
+        // 获取月度统计信息
+        GxtMonthScore queryScore = new GxtMonthScore();
+        queryScore.setDeptId(deptId);
+        queryScore.setMonthPeriod(monthPeriod);
+        List<GxtMonthScore> scoreList = monthScoreService.selectGxtMonthScoreList(queryScore);
+        GxtMonthScore monthScore = null;
+        if (!scoreList.isEmpty()) {
+            monthScore = scoreList.get(0);
+        }
+
+        if (monthScore == null) {
+            // 如果没有月度统计记录,创建新的记录
+            monthScore = new GxtMonthScore();
+            monthScore.setDeptId(deptId);
+            monthScore.setMonthPeriod(monthPeriod);
+            monthScore.setStatus(0); // 初始状态
+            monthScore.setPersionId(SecurityUtils.getUserId());
+            monthScore.setCreateBy(SecurityUtils.getUsername());
+            monthScore.setCreateTime(new Date());
+            monthScoreService.insertGxtMonthScore(monthScore);
+
+            // 重新查询刚插入的记录
+            scoreList = monthScoreService.selectGxtMonthScoreList(queryScore);
+            if (!scoreList.isEmpty()) {
+                monthScore = scoreList.get(0);
+            }
+        }
+
+        if (monthScore != null) {
+            // 更新用户评分统计
+            updateUserScoresForStopScore(monthScore, repairOrder, deductionScore);
+        }
+    }
+
+    /**
+     * 更新用户评分统计以反映停机扣分
+     * 
+     * @param monthScore 月度统计信息
+     * @param order 维修工单
+     * @param deductionScore 扣分分数
+     */
+    private void updateUserScoresForStopScore(GxtMonthScore monthScore, GxtRepairOrder order, BigDecimal deductionScore) {
+        List<GxtRepairOrderPerson> persons = order.getRepairOrderPersonList();
+        if (persons == null || persons.isEmpty()) {
+            // 如果工单中的人员列表为空,尝试从数据库查询
+            persons = selectRepairOrderPersonListByOrderId(order.getId());
+        }
+
+        if (persons != null) {
+            for (GxtRepairOrderPerson person : persons) {
+                Long userId = person.getUserId();
+                SysUser sysUser = userMapper.selectUserById(userId);
+                // 使用userName、monthPeriod、monthScoreId精确查询用户评分记录
+                GxtUserScore userScoreQuery = new GxtUserScore();
+                userScoreQuery.setUserName(sysUser.getUserName());
+                userScoreQuery.setMonthPeriod(monthScore.getMonthPeriod());
+                userScoreQuery.setMonthScoreId(monthScore.getId());
+                List<GxtUserScore> userScores = userScoreService.selectGxtUserScoreList(userScoreQuery);
+
+                if (!userScores.isEmpty()) {
+                    // 找到现有记录,直接更新
+                    GxtUserScore userScore = userScores.get(0);
+                    BigDecimal currentRepairTotal = (userScore.getRepairTotalScore() != null) ?
+                            userScore.getRepairTotalScore() : BigDecimal.ZERO;
+
+                    BigDecimal newRepairScore = currentRepairTotal.add(deductionScore);
+                    userScore.setRepairTotalScore(newRepairScore);
+
+                    // 更新最终评分
+                    BigDecimal maintenanceScore = (userScore.getMaintenanceTotalScore() != null) ?
+                            userScore.getMaintenanceTotalScore() : BigDecimal.ZERO;
+
+                    BigDecimal finalScore = maintenanceScore.add(newRepairScore);
+                    userScore.setFinalScore(finalScore);
+                    userScore.setUpdateBy(SecurityUtils.getLoginUser().getUser().getUserName());
+                    userScore.setUpdateTime(new Date());
+
+                    userScoreService.updateGxtUserScore(userScore);
+                } else {
+                    // 没有找到记录,创建新记录
+                    GxtUserScore newUserScore = new GxtUserScore();
+                    newUserScore.setMonthScoreId(monthScore.getId());
+                    newUserScore.setUserName(sysUser.getUserName());
+                    newUserScore.setNickName(person.getNickName());
+                    newUserScore.setMonthPeriod(monthScore.getMonthPeriod());
+
+                    // 设置维修工单得分
+                    BigDecimal repairScore = deductionScore;
+                    newUserScore.setRepairTotalScore(repairScore);
+
+                    // 维保得分默认为0
+                    newUserScore.setMaintenanceTotalScore(BigDecimal.ZERO);
+                    newUserScore.setFinalScore(deductionScore);
+                    newUserScore.setStatus(0);
+                    newUserScore.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserName());
+                    newUserScore.setCreateTime(new Date());
+                    // 插入新记录
+                    userScoreService.insertGxtUserScore(newUserScore);
+
+                }
+            }
+        }
+    }
+
+    /**
+     * 更新人员停机扣分并添加个人分数明细数据
+     * 
+     * @param repairOrder 维修工单
+     * @param persons 人员列表
+     * @param deductionScore 扣分分数
+     * @param createTime 创建时间(用于月度统计)
+     */
+    private void updatePersonStopScoreAndAddDetails(GxtRepairOrder repairOrder, List<GxtRepairOrderPerson> persons, 
+                                                   BigDecimal deductionScore, Date createTime) {
+        if (persons == null || persons.isEmpty()) {
+            return;
+        }
+
+        List<GxtRepairOrderPerson> updatedPersons = new ArrayList<>();
+        for (GxtRepairOrderPerson person : persons) {
+            Double currentStopScore = person.getStopScore();
+            Double newStopScore = (currentStopScore != null ? currentStopScore : 0.0) + deductionScore.doubleValue();
+
+            GxtRepairOrderPerson updatedPerson = new GxtRepairOrderPerson();
+            updatedPerson.setId(person.getId());
+            updatedPerson.setStopScore(newStopScore);
+            updatedPerson.setScore(person.getScore() != null ? person.getScore().add(deductionScore) : deductionScore);
+            updatedPerson.setUpdateBy(SecurityUtils.getLoginUser().getUser().getUserName());
+            updatedPerson.setUpdateTime(new Date());
+
+            updatedPersons.add(updatedPerson);
+        }
+
+        // 批量更新人员得分
+        int result = updateRepairOrderPersonList(updatedPersons);
+
+        // 更新月度统计数据
+        updateMonthlyScoreDataForStopScore(repairOrder, deductionScore, createTime);
+
+        // 添加工单个人分数明细数据
+        addOrderScoreDetailsForStopScoreRepair(repairOrder, persons, deductionScore, 3, createTime); // 3代表停机扣分
+    }
     
+    /**
+     * 添加停机扣分的工单个人分数明细数据
+     *
+     * @param repairOrder    维修工单
+     * @param persons        更新的人员列表
+     * @param deductionScore 扣分分数
+     * @param scoreType      分数类型
+     * @param createTime     创建时间
+     */
+    private void addOrderScoreDetailsForStopScoreRepair(GxtRepairOrder repairOrder, List<GxtRepairOrderPerson> persons, 
+                                                       BigDecimal deductionScore, int scoreType, Date createTime) {
+        for (GxtRepairOrderPerson person : persons) {
+            GxtOrderScoreDetail detail = new GxtOrderScoreDetail();
+
+            // 设置基础信息
+            detail.setUserId(person.getUserId());
+            detail.setNickName(person.getNickName());
+            detail.setOrderType(1); // 维修工单
+
+            // 设置工单相关信息
+            detail.setOrderId(repairOrder.getId());
+            detail.setOrderCode(repairOrder.getWorkOrderProjectNo());
+
+            // 设置分数类型和分数
+            detail.setScoreType(scoreType); // 停机扣分
+            detail.setScore(deductionScore);
+            detail.setStopScore(deductionScore);
+
+            detail.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserName());
+            detail.setCreateTime(createTime != null ? createTime : new Date());
+            // 保存到数据库
+            gxtOrderScoreDetailService.insertGxtOrderScoreDetail(detail);
+        }
+    }
 }

+ 37 - 5
ygtx-gxt/src/main/java/com/ygtx/gxt/task/EquipmentSafeOperationRewardTask.java

@@ -1234,8 +1234,20 @@ public class EquipmentSafeOperationRewardTask {
                 persons = repairOrderService.selectRepairOrderPersonListByOrderId(repairOrder.getId());
             }
 
+            // 过滤出isLeader等于1的人员
+            if (persons != null && !persons.isEmpty()) {
+                List<GxtRepairOrderPerson> leaderPersons = new ArrayList<>();
+                for (GxtRepairOrderPerson person : persons) {
+                    if (person.getIsLeader() != null && person.getIsLeader() == 1) {
+                        leaderPersons.add(person);
+                        break;
+                    }
+                }
+                persons = leaderPersons;
+            }
+
             if (persons == null || persons.isEmpty()) {
-                log.warn("待结单维修工单 {} 没有找到相关人员", repairOrder.getWorkOrderProjectNo());
+                log.warn("待结单维修工单 {} 没有找到工作负责人", repairOrder.getWorkOrderProjectNo());
                 return;
             }
 
@@ -1471,22 +1483,42 @@ public class EquipmentSafeOperationRewardTask {
             log.info("工单 {} 安全运行 {} 天,总奖励 {} 分,{} 人参与,人均奖励 {} 分",
                 workOrderProjectNo, safeDays, rewardScore, personCount, perPersonReward);
             String repairMethod = lastBreakOrder != null ? lastBreakOrder.getRepairMethod() : null;
+            boolean handelPre = false;
+            long timeDiffMinutes = 0;
+            if (lastBreakOrder != null) {
+                if(lastBreakOrder.getRestartTime() == null){
+                    handelPre = true;
+                }else{
+                    Date restartTimeBreak = lastBreakOrder.getRestartTime();
+                    Date occurTimeBreak = lastBreakOrder.getOccurTime();
+                    timeDiffMinutes = (restartTimeBreak.getTime() - occurTimeBreak.getTime()) / (1000 * 60);
+                }
+            }
+
             // 更新人员得分
             if (orderType == 1) {
                 // 如果repairMethod为空
                 if (repairMethod == null || repairMethod.trim().isEmpty()) {
                     handleOrderWithoutRepairMethod(order, perPersonReward, lastBreakOrder);
                 }else{
-                    updatePersonRunScoreForRepairOrder((GxtRepairOrder) order, perPersonReward);
-                    updateMonthlyScoreDataForRunScore((GxtRepairOrder) order, perPersonReward);
+                    if(handelPre){
+                        handleOrderWithoutRepairMethod(order, perPersonReward, lastBreakOrder);
+                    }else if(timeDiffMinutes <= 30){
+                        updatePersonRunScoreForRepairOrder((GxtRepairOrder) order, perPersonReward);
+                        updateMonthlyScoreDataForRunScore((GxtRepairOrder) order, perPersonReward);
+                    }
                 }
             } else if (orderType == 2) {
                 // 如果repairMethod为空
                 if (lastBreakOrder != null && (repairMethod == null || repairMethod.trim().isEmpty())) {
                     handleOrderWithoutRepairMethod(order, perPersonReward, lastBreakOrder);
                 }else{
-                    updatePersonRunScoreForWorkOrder((GxtWorkOrder) order, perPersonReward);
-                    updateMonthlyScoreDataForRunScore((GxtWorkOrder) order, perPersonReward);
+                    if(handelPre){
+                        handleOrderWithoutRepairMethod(order, perPersonReward, lastBreakOrder);
+                    }else if(timeDiffMinutes <= 30){
+                        updatePersonRunScoreForWorkOrder((GxtWorkOrder) order, perPersonReward);
+                        updateMonthlyScoreDataForRunScore((GxtWorkOrder) order, perPersonReward);
+                    }
                 }
             }
         } catch (Exception e) {

+ 20 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/task/OrderAutoFinalizeTask.java

@@ -5,6 +5,7 @@ import com.ygtx.common.utils.DateUtils;
 import com.ygtx.gxt.domain.*;
 import com.ygtx.gxt.mapper.*;
 import com.ygtx.gxt.mapper.source.GxtMisInfoMapper;
+import com.ygtx.gxt.service.IGxtRepairOrderService;
 import com.ygtx.system.mapper.SysUserMapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -12,6 +13,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.stereotype.Component;
 
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -51,6 +53,9 @@ public class OrderAutoFinalizeTask {
     @Autowired
     private GxtWorkOrderPersonMapper workOrderPersonMapper;
 
+    @Autowired
+    private IGxtRepairOrderService gxtRepairOrderService;
+
     /**
      * 每小时执行定时任务
      * 查找状态为assigned或to_finish且接单时间、停机时间、恢复运行时间不为空的工单
@@ -224,6 +229,21 @@ public class OrderAutoFinalizeTask {
                     flow.setCreateBy("admin");
                     flow.setCreateTime(DateUtils.getNowDate());
                     gxtRepairOrderFlowMapper.insertGxtRepairOrderFlow(flow);
+
+                    if(repairOrder.getRestartTime() != null){
+                        Date restartTime = repairOrder.getRestartTime();
+                        Date occurTime = repairOrder.getOccurTime();
+                        if (restartTime != null && occurTime != null) {
+                            long timeDiffMinutes = (restartTime.getTime() - occurTime.getTime()) / (1000 * 60);
+                            // 如果时间差小于等于30分钟,原来挂停的工单分数明细生效,奖励生效并补全数据
+                            if (timeDiffMinutes <= 30) {
+                                // 处理挂起工单的奖励数据补全
+                                gxtRepairOrderService.processSuspendedOrderRewardData(repairOrder);
+                                //处理扣分数据
+                                gxtRepairOrderService.completePendingOrderDeductionData(repairOrder);
+                            }
+                        }
+                    }
                 }
             }
         }

+ 1 - 0
ygtx-gxt/src/main/resources/mapper/gxt/GxtOrderScoreDetailMapper.xml

@@ -45,6 +45,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="stopScore != null "> and stop_score = #{stopScore}</if>
             <if test="status != null "> and status = #{status}</if>
             <if test="createTimeReal != null "> and create_time_real = #{createTimeReal}</if>
+            <if test="orderCodeRelate != null  and orderCodeRelate != ''"> and order_code_relate = #{orderCodeRelate}</if>
         </where>
     </select>
     

+ 6 - 12
ygtx-gxt/src/main/resources/mapper/gxt/GxtRepairOrderMapper.xml

@@ -1071,19 +1071,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             t.repair_method IS NULL
             OR
             -- 条件2: repair_method不为空且满足特定条件
-            (
-              (
-                -- 处理方式为正常维修
-                t.repair_method = '1'
-                OR
-                -- 处理方式为复位启机且复位方式为人工复位
-                (t.repair_method = '2' AND t.reset_method = '1')
-              )
-              AND t.restart_time IS NOT NULL
-              AND TIMESTAMPDIFF(MINUTE, t.restart_time, t.occur_time) > 30
-            )
+            -- 处理方式为正常维修
+            t.repair_method = '1'
+            OR
+            -- 处理方式为复位启机且复位方式为人工复位
+            (t.repair_method = '2' AND t.reset_method = '1')
           )
-        ORDER BY t.occur_time DESC limit 1
+        ORDER BY t.occur_time DESC,t.id DESC limit 1
     </select>