瀏覽代碼

工单连续运行得分

ouyj 3 月之前
父節點
當前提交
390ba21da6

+ 13 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/domain/OrderScorePerson.java

@@ -1,5 +1,7 @@
 package com.ygtx.gxt.domain;
 
+import com.ygtx.common.annotation.Excel;
+
 /**
  * 工单评分人员信息DTO
  * 
@@ -43,6 +45,9 @@ public class OrderScorePerson {
     /** 总分 */
     private Double totalScore;
 
+    /** 运行得分 */
+    private Double runScore;
+
     public Long getId() {
         return id;
     }
@@ -138,4 +143,12 @@ public class OrderScorePerson {
     public void setTotalScore(Double totalScore) {
         this.totalScore = totalScore;
     }
+
+    public Double getRunScore() {
+        return runScore;
+    }
+
+    public void setRunScore(Double runScore) {
+        this.runScore = runScore;
+    }
 }

+ 13 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/mapper/GxtRepairOrderMapper.java

@@ -92,4 +92,17 @@ public interface GxtRepairOrderMapper
     public GxtOrderData selectHomePageData(@Param("userId") Long userId,@Param("monthPeriod") String monthPeriod);
 
     public List<GxtUserScore> selectHomePageRank(GxtUserScore gxtUserScore);
+    
+    /**
+     * 查询设备最近的维修工单
+     *
+     * @return 维修工单集合
+     */
+    public List<GxtRepairOrder> selectLatestGxtRepairOrderByDeviceId(@Param("pcsDeviceId") Long pcsDeviceId, @Param("limit") Integer limit);
+    
+    public List<GxtRepairOrder> selectGxtRepairOrderByDeviceIdWithCondition(@Param("pcsDeviceId") Long pcsDeviceId, 
+        @Param("workOrderStatus") String workOrderStatus, 
+        @Param("excludeStatus") boolean excludeStatus, 
+        @Param("orderByField") String orderByField, 
+        @Param("limit") Integer limit);
 }

+ 13 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/mapper/GxtWorkOrderMapper.java

@@ -102,4 +102,17 @@ public interface GxtWorkOrderMapper {
     public int updateGxtWorkOrderByDeferred(GxtWorkOrder gxtWorkOrder);
 
     public List<GxtOrderData> selectHomePageWorkOrderList(GxtOrderData gxtOrderData);
+    
+    /**
+     * 查询设备最近的维保工单
+     *
+     * @return 维保工单集合
+     */
+    public List<GxtWorkOrder> selectLatestGxtWorkOrderByDeviceId(@Param("pcsDeviceId") Long pcsDeviceId, @Param("limit") Integer limit);
+    
+    public List<GxtWorkOrder> selectGxtWorkOrderByDeviceIdWithCondition(@Param("pcsDeviceId") Long pcsDeviceId, 
+        @Param("workOrderStatus") String workOrderStatus, 
+        @Param("excludeStatus") boolean excludeStatus, 
+        @Param("orderByField") String orderByField, 
+        @Param("limit") Integer limit);
 }

+ 21 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/service/IGxtRepairOrderService.java

@@ -218,4 +218,25 @@ public interface IGxtRepairOrderService
     public int invalidateGxtRepairOrder(GxtRepairOrder gxtRepairOrder);
 
     public int returnGxtRepairOrder(GxtRepairOrder gxtRepairOrder);
+    
+    /**
+     * 查询设备最近的维修工单
+     *
+     * @param pcsDeviceId 设备ID
+     * @param limit 限制数量
+     * @return 维修工单集合
+     */
+    public List<GxtRepairOrder> selectLatestGxtRepairOrderByDeviceId(Long pcsDeviceId, Integer limit);
+    
+    /**
+     * 根据状态和排序字段查询设备相关的维修工单
+     *
+     * @param pcsDeviceId 设备ID
+     * @param workOrderStatus 工单状态
+     * @param excludeStatus 是否排除指定状态
+     * @param orderByField 排序字段
+     * @param limit 限制数量
+     * @return 维修工单集合
+     */
+    public List<GxtRepairOrder> selectGxtRepairOrderByDeviceIdWithCondition(Long pcsDeviceId, String workOrderStatus, boolean excludeStatus, String orderByField, Integer limit);
 }

+ 21 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/service/IGxtWorkOrderService.java

@@ -246,4 +246,25 @@ public interface IGxtWorkOrderService {
      * @return
      */
     public int shutdownOrder(GxtWorkOrder gxtWorkOrder);
+    
+    /**
+     * 查询设备最近的维保工单
+     *
+     * @param pcsDeviceId 设备ID
+     * @param limit 限制数量
+     * @return 维保工单集合
+     */
+    public List<GxtWorkOrder> selectLatestGxtWorkOrderByDeviceId(Long pcsDeviceId, Integer limit);
+    
+    /**
+     * 根据状态和排序字段查询设备相关的维保工单
+     *
+     * @param pcsDeviceId 设备ID
+     * @param workOrderStatus 工单状态
+     * @param excludeStatus 是否排除指定状态
+     * @param orderByField 排序字段
+     * @param limit 限制数量
+     * @return 维保工单集合
+     */
+    public List<GxtWorkOrder> selectGxtWorkOrderByDeviceIdWithCondition(Long pcsDeviceId, String workOrderStatus, boolean excludeStatus, String orderByField, Integer limit);
 }

+ 26 - 8
ygtx-gxt/src/main/java/com/ygtx/gxt/service/impl/GxtOrderScoreServiceImpl.java

@@ -708,7 +708,10 @@ public class GxtOrderScoreServiceImpl implements IGxtOrderScoreService {
                         repairPerson.setReviewScore(person.getReviewScore());
                         //repairPerson.setScore(person.getReviewScore() != null ? BigDecimal.valueOf(person.getReviewScore()) : null);
                         repairPerson.setTotalScore(person.getTotalScore());
-                        repairPerson.setScore(person.getTotalScore() != null ? BigDecimal.valueOf(person.getTotalScore()) : null);
+                        // 计算总分时考虑runScore
+                        Double calculatedScore = (person.getTotalScore() != null ? person.getTotalScore() : 0.0) + 
+                                          (person.getRunScore() != null ? person.getRunScore() : 0.0);
+                        repairPerson.setScore(calculatedScore != 0.0 ? BigDecimal.valueOf(calculatedScore) : null);
                         personList.add(repairPerson);
                     }
                     gxtRepairOrderService.updateRepairOrderPersonList(personList);
@@ -805,7 +808,10 @@ public class GxtOrderScoreServiceImpl implements IGxtOrderScoreService {
                         workPerson.setReviewScore(person.getReviewScore());
                         //workPerson.setScore(person.getReviewScore() != null ? BigDecimal.valueOf(person.getReviewScore()) : null);
                         workPerson.setTotalScore(person.getTotalScore());
-                        workPerson.setScore(person.getTotalScore() != null ? BigDecimal.valueOf(person.getTotalScore()) : null);
+                        // 计算总分时考虑runScore
+                        Double calculatedScore = (person.getTotalScore() != null ? person.getTotalScore() : 0.0) + 
+                                          (person.getRunScore() != null ? person.getRunScore() : 0.0);
+                        workPerson.setScore(calculatedScore != 0.0 ? BigDecimal.valueOf(calculatedScore) : null);
                         personList.add(workPerson);
                     }
                     gxtWorkOrderService.updateWorkOrderPersonList(personList);
@@ -879,7 +885,10 @@ public class GxtOrderScoreServiceImpl implements IGxtOrderScoreService {
                         repairPerson.setId(person.getId());
                         repairPerson.setFinalScore(person.getFinalScore());
                         repairPerson.setTotalScore(person.getTotalScore());
-                        repairPerson.setScore(person.getTotalScore() != null ? BigDecimal.valueOf(person.getTotalScore()) : null);
+                        // 计算总分时考虑runScore
+                        Double calculatedScore = (person.getTotalScore() != null ? person.getTotalScore() : 0.0) + 
+                                          (person.getRunScore() != null ? person.getRunScore() : 0.0);
+                        repairPerson.setScore(calculatedScore != 0.0 ? BigDecimal.valueOf(calculatedScore) : null);
                         personList.add(repairPerson);
                     }
                     gxtRepairOrderService.updateRepairOrderPersonList(personList);
@@ -956,7 +965,10 @@ public class GxtOrderScoreServiceImpl implements IGxtOrderScoreService {
                         workPerson.setFinalScore(person.getFinalScore());
                         //workPerson.setScore(person.getFinalScore() != null ? BigDecimal.valueOf(person.getFinalScore()) : null);
                         workPerson.setTotalScore(person.getTotalScore());
-                        workPerson.setScore(person.getTotalScore() != null ? BigDecimal.valueOf(person.getTotalScore()) : null);
+                        // 计算总分时考虑runScore
+                        Double calculatedScore = (person.getTotalScore() != null ? person.getTotalScore() : 0.0) + 
+                                          (person.getRunScore() != null ? person.getRunScore() : 0.0);
+                        workPerson.setScore(calculatedScore != 0.0 ? BigDecimal.valueOf(calculatedScore) : null);
                         personList.add(workPerson);
                     }
                     gxtWorkOrderService.updateWorkOrderPersonList(personList);
@@ -1307,8 +1319,11 @@ public class GxtOrderScoreServiceImpl implements IGxtOrderScoreService {
                             // 使用userName进行匹配
                             if (sysUser != null && sysUser.getUserName() != null && sysUser.getUserName().equals(userScore.getUserName())) {
                                 // 更新维修工单总分
-                                BigDecimal repairScore = (orderPerson.getScore() != null) ?
-                                        orderPerson.getScore(): BigDecimal.ZERO;
+                                // 从score中扣减runScore,避免重复计算
+                                BigDecimal baseScore = (orderPerson.getScore() != null) ? orderPerson.getScore() : BigDecimal.ZERO;
+                                BigDecimal runScore = (orderPerson.getRunScore() != null) ? 
+                                        BigDecimal.valueOf(orderPerson.getRunScore()) : BigDecimal.ZERO;
+                                BigDecimal repairScore = baseScore.subtract(runScore);
 
                                 BigDecimal currentRepairTotal = (userScore.getRepairTotalScore() != null) ?
                                         userScore.getRepairTotalScore() : BigDecimal.ZERO;
@@ -1387,8 +1402,11 @@ public class GxtOrderScoreServiceImpl implements IGxtOrderScoreService {
                             // 使用userName进行匹配
                             if (sysUser != null && sysUser.getUserName() != null && sysUser.getUserName().equals(userScore.getUserName())) {
                                 // 更新维保工单总分
-                                BigDecimal maintenanceScore = (orderPerson.getScore() != null) ?
-                                        orderPerson.getScore() : BigDecimal.ZERO;
+                                // 从score中扣减runScore,避免重复计算
+                                BigDecimal baseScore = (orderPerson.getScore() != null) ? orderPerson.getScore() : BigDecimal.ZERO;
+                                BigDecimal runScore = (orderPerson.getRunScore() != null) ? 
+                                        BigDecimal.valueOf(orderPerson.getRunScore()) : BigDecimal.ZERO;
+                                BigDecimal maintenanceScore = baseScore.subtract(runScore);
 
                                 BigDecimal currentMaintenanceTotal = (userScore.getMaintenanceTotalScore() != null) ?
                                         userScore.getMaintenanceTotalScore() : BigDecimal.ZERO;

+ 10 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/service/impl/GxtRepairOrderServiceImpl.java

@@ -2171,4 +2171,14 @@ public class GxtRepairOrderServiceImpl implements IGxtRepairOrderService
         List<GxtRepairOrder> list = selectGxtRepairOrderList(repairOrder);
         return list.size();
     }
+
+    @Override
+    public List<GxtRepairOrder> selectLatestGxtRepairOrderByDeviceId(Long pcsDeviceId, Integer limit) {
+        return gxtRepairOrderMapper.selectLatestGxtRepairOrderByDeviceId(pcsDeviceId, limit);
+    }
+    
+    @Override
+    public List<GxtRepairOrder> selectGxtRepairOrderByDeviceIdWithCondition(Long pcsDeviceId, String workOrderStatus, boolean excludeStatus, String orderByField, Integer limit) {
+        return gxtRepairOrderMapper.selectGxtRepairOrderByDeviceIdWithCondition(pcsDeviceId, workOrderStatus, excludeStatus, orderByField, limit);
+    }
 }

+ 9 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/service/impl/GxtWorkOrderServiceImpl.java

@@ -2155,4 +2155,13 @@ public class GxtWorkOrderServiceImpl implements IGxtWorkOrderService
         return result;
     }
 
+    @Override
+    public List<GxtWorkOrder> selectLatestGxtWorkOrderByDeviceId(Long pcsDeviceId, Integer limit) {
+        return gxtWorkOrderMapper.selectLatestGxtWorkOrderByDeviceId(pcsDeviceId, limit);
+    }
+    
+    @Override
+    public List<GxtWorkOrder> selectGxtWorkOrderByDeviceIdWithCondition(Long pcsDeviceId, String workOrderStatus, boolean excludeStatus, String orderByField, Integer limit) {
+        return gxtWorkOrderMapper.selectGxtWorkOrderByDeviceIdWithCondition(pcsDeviceId, workOrderStatus, excludeStatus, orderByField, limit);
+    }
 }

+ 676 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/task/EquipmentSafeOperationRewardTask.java

@@ -0,0 +1,676 @@
+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.common.utils.SecurityUtils;
+import com.ygtx.common.utils.spring.SpringUtils;
+import com.ygtx.framework.web.service.SysPermissionService;
+import com.ygtx.gxt.domain.*;
+import com.ygtx.gxt.mapper.GxtRepairOrderMapper;
+import com.ygtx.gxt.mapper.GxtWorkOrderMapper;
+import com.ygtx.gxt.service.IGxtEquipmentService;
+import com.ygtx.gxt.service.IGxtMonthScoreService;
+import com.ygtx.gxt.service.IGxtRepairOrderService;
+import com.ygtx.gxt.service.IGxtSafeOperationRewardService;
+import com.ygtx.gxt.service.IGxtUserScoreService;
+import com.ygtx.gxt.service.IGxtWorkOrderService;
+import com.ygtx.system.mapper.SysUserMapper;
+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.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * 设备连续安全运行奖励任务
+ * 每天0点执行一次,对符合安全运行天数的设备进行奖励分值发放
+ *
+ * @author ouyj
+ * @date 2026-01-08
+ */
+@EnableScheduling
+@Component("equipmentSafeOperationRewardTask")
+public class EquipmentSafeOperationRewardTask {
+
+    private static final Logger log = LoggerFactory.getLogger(EquipmentSafeOperationRewardTask.class);
+
+    @Autowired
+    private IGxtEquipmentService equipmentService;
+
+    @Autowired
+    private IGxtRepairOrderService repairOrderService;
+
+    @Autowired
+    private IGxtWorkOrderService workOrderService;
+
+    @Autowired
+    private IGxtSafeOperationRewardService safeOperationRewardService;
+
+    @Autowired
+    private IGxtMonthScoreService monthScoreService;
+
+    @Autowired
+    private IGxtUserScoreService userScoreService;
+
+    @Autowired
+    private SysUserMapper userMapper;
+
+    @Autowired
+    private SysPermissionService permissionService;
+
+    // 限制每次查询的最大工单数量,防止数据量过大导致性能问题
+    private static final int MAX_ORDERS_PER_QUERY = 1;
+
+    /**
+     * 每天凌晨0点执行定时任务
+     * 循环设备表GxtEquipment,计算连续安全运行奖励
+     */
+    //@Scheduled(cron = "0 0 0 * * ?") // 每天凌晨0点执行一次
+    public void processSafeOperationRewards() {
+        log.info("开始执行设备连续安全运行奖励任务");
+
+        // 设置系统用户上下文
+        setSystemUserContext();
+
+        try {
+            // 查询所有设备
+            GxtEquipment equipmentQuery = new GxtEquipment();
+            List<GxtEquipment> equipments = equipmentService.selectGxtEquipmentList(equipmentQuery);
+
+            int processedCount = 0;
+            for (GxtEquipment equipment : equipments) {
+                try {
+                    processEquipmentSafeOperationReward(equipment);
+                    processedCount++;
+                } catch (Exception e) {
+                    log.error("处理设备 {} 连续安全运行奖励时发生异常", equipment.getEquipmentCode(), e);
+                }
+            }
+
+            log.info("设备连续安全运行奖励任务执行完成,共处理 {} 个设备", processedCount);
+        } catch (Exception e) {
+            log.error("执行设备连续安全运行奖励任务时发生异常", e);
+        }
+    }
+
+    /**
+     * 处理单个设备的连续安全运行奖励
+     * 
+     * @param equipment 设备信息
+     */
+    private void processEquipmentSafeOperationReward(GxtEquipment equipment) {
+        log.debug("开始处理设备 {} 的连续安全运行奖励", equipment.getEquipmentCode());
+        
+       /* // 第一次查询:查询workOrderStatus为archived的工单,按restartTime降序排序
+        List<GxtRepairOrder> archivedRepairOrders = repairOrderService.selectGxtRepairOrderByDeviceIdWithCondition(
+            equipment.getEquipmentId(), "archived", false, "restartTime", MAX_ORDERS_PER_QUERY);
+
+        List<GxtWorkOrder> archivedWorkOrders = workOrderService.selectGxtWorkOrderByDeviceIdWithCondition(
+            equipment.getEquipmentId(), "archived", false, "restartTime", MAX_ORDERS_PER_QUERY);*/
+
+        // 第一次查询:查询workOrderStatus不等于invalid的工单,按restartTime降序排序
+        List<GxtRepairOrder> archivedRepairOrders = repairOrderService.selectGxtRepairOrderByDeviceIdWithCondition(
+                equipment.getEquipmentId(), "invalid", true, "restartTime", MAX_ORDERS_PER_QUERY);
+
+        List<GxtWorkOrder> archivedWorkOrders = workOrderService.selectGxtWorkOrderByDeviceIdWithCondition(
+                equipment.getEquipmentId(), "invalid", true, "restartTime", MAX_ORDERS_PER_QUERY);
+        
+        // 第二次查询:维修工单workOrderStatus不等于invalid,按occurTime降序排序;维保工单workOrderStatus不等于invalid,按pauseTime降序排序
+        List<GxtRepairOrder> activeRepairOrders = repairOrderService.selectGxtRepairOrderByDeviceIdWithCondition(
+            equipment.getEquipmentId(), "invalid", true, "occurTime", MAX_ORDERS_PER_QUERY);
+        
+        List<GxtWorkOrder> activeWorkOrders = workOrderService.selectGxtWorkOrderByDeviceIdWithCondition(
+            equipment.getEquipmentId(), "invalid", true, "pauseTime", MAX_ORDERS_PER_QUERY);
+
+        // 合并两次查询的结果,一次性处理所有数据,找出关键时间点和相关工单
+        ProcessedTimeData processedData = processTimeData(archivedRepairOrders, archivedWorkOrders, activeRepairOrders, activeWorkOrders);
+        
+        if (processedData.latestRestartTime == null) {
+            log.debug("设备 {} 未找到任何restartTime数据,跳过处理", equipment.getEquipmentCode());
+            return; // 必须最少能找到任意的GxtRepairOrder或者GxtWorkOrder当中的其中一个,否则数据不完整,不用再继续后面的步骤
+        }
+
+        /*if (processedData.latestOccurOrPauseTime == null) {
+            log.debug("设备 {} 未找到任何occurTime或pauseTime数据,跳过处理", equipment.getEquipmentCode());
+            return; // 必须最少能找到任意的GxtRepairOrder或者GxtWorkOrder当中的其中一个,否则数据不完整,不用再继续后面的步骤
+        }*/
+
+        // 检查是否在安全运行中
+        if (processedData.latestOccurOrPauseTime != null && processedData.latestRestartTime.before(processedData.latestOccurOrPauseTime)) {
+            log.debug("设备 {} 的最新occurTime/pauseTime({})比restartTime({})晚,不在安全运行中", 
+                equipment.getEquipmentCode(), processedData.latestOccurOrPauseTime, processedData.latestRestartTime);
+            return;
+        }
+
+        // 计算安全运行天数
+        int daysBetween = DateUtils.differentDaysByMillisecond(DateUtils.getNowDate(), processedData.latestRestartTime);
+        if (daysBetween <= 0) {
+            log.debug("设备 {} 安全运行天数为 {} 天,无需奖励", equipment.getEquipmentCode(), daysBetween);
+            return;
+        }
+
+        // 获取奖励配置
+        GxtSafeOperationReward rewardQuery = new GxtSafeOperationReward();
+        rewardQuery.setStatus(0);
+        List<GxtSafeOperationReward> rewardConfigs = safeOperationRewardService.selectGxtSafeOperationRewardList(rewardQuery);
+        if (rewardConfigs.isEmpty()) {
+            log.warn("未找到任何启用的安全运行奖励配置");
+            return;
+        }
+
+        // 按照safeDuration升序排序
+        rewardConfigs.sort(Comparator.comparingInt(GxtSafeOperationReward::getSafeDuration));
+
+        // 获取对应的奖励配置
+        GxtSafeOperationReward applicableReward = getApplicableRewardConfig(rewardConfigs, daysBetween);
+        if (applicableReward == null) {
+            log.debug("设备 {} 运行天数 {} 未找到对应的安全运行奖励配置", equipment.getEquipmentCode(), daysBetween);
+            return;
+        }
+
+        // 使用预处理的数据进行奖励处理
+        if (processedData.relatedRepairOrder != null) {
+            // 如果对应的工单是GxtRepairOrder,则获取的是unplannedMaintenanceScore的值
+            BigDecimal rewardScore = applicableReward.getUnplannedMaintenanceScore();
+            if (rewardScore != null && rewardScore.compareTo(BigDecimal.ZERO) > 0) {
+                log.info("设备 {} 安全运行 {} 天,奖励维修工单 {} 维修奖励分值 {}", 
+                    equipment.getEquipmentCode(), daysBetween, processedData.relatedRepairOrder.getWorkOrderProjectNo(), rewardScore);
+                
+                // 然后在获取这个工单所对应的人员数据,对这些人员进行加分操作
+                updatePersonRunScoreForRepairOrder(processedData.relatedRepairOrder, rewardScore);
+                // 更新月度统计数据
+                updateMonthlyScoreDataForRunScore(processedData.relatedRepairOrder, rewardScore);
+            }
+        } else if (processedData.relatedWorkOrder != null) {
+            // 如果对应的工单是GxtWorkOrder,则获取的是plannedMaintenanceScore的值
+            BigDecimal rewardScore = applicableReward.getPlannedMaintenanceScore();
+            if (rewardScore != null && rewardScore.compareTo(BigDecimal.ZERO) > 0) {
+                log.info("设备 {} 安全运行 {} 天,奖励维保工单 {} 计划检修奖励分值 {}", 
+                    equipment.getEquipmentCode(), daysBetween, processedData.relatedWorkOrder.getWorkOrderProjectNo(), rewardScore);
+                
+                // 然后在获取这个工单所对应的人员数据,对这些人员进行加分操作
+                updatePersonRunScoreForWorkOrder(processedData.relatedWorkOrder, rewardScore);
+                // 更新月度统计数据
+                updateMonthlyScoreDataForRunScore(processedData.relatedWorkOrder, rewardScore);
+            }
+        } else {
+            log.warn("设备 {} 未找到对应的工单信息", equipment.getEquipmentCode());
+        }
+    }
+
+    /**
+     * 更新月度统计数据以反映运行得分奖励
+     * 
+     * @param repairOrder 维修工单
+     * @param rewardScore 奖励分数
+     */
+    private void updateMonthlyScoreDataForRunScore(GxtRepairOrder repairOrder, BigDecimal rewardScore) {
+        try {
+            // 使用当前日期所在的月份(因为奖励是在当前时间发放的)
+            SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM");
+            String monthPeriod = sdf.format(new Date());
+
+            // 获取场站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) {
+                // 更新用户评分统计
+                updateUserScoresForRunScore(monthScore, repairOrder, rewardScore);
+            }
+        } catch (Exception e) {
+            log.error("更新维修工单 {} 的月度统计数据时发生异常", repairOrder.getWorkOrderProjectNo(), e);
+        }
+    }
+
+    /**
+     * 更新月度统计数据以反映运行得分奖励
+     * 
+     * @param workOrder 维保工单
+     * @param rewardScore 奖励分数
+     */
+    private void updateMonthlyScoreDataForRunScore(GxtWorkOrder workOrder, BigDecimal rewardScore) {
+        try {
+            // 使用当前日期所在的月份(因为奖励是在当前时间发放的)
+            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM");
+            String monthPeriod = sdf.format(new Date());
+
+            // 获取场站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) {
+                // 更新用户评分统计
+                updateUserScoresForRunScore(monthScore, workOrder, rewardScore);
+            }
+        } catch (Exception e) {
+            log.error("更新维保工单 {} 的月度统计数据时发生异常", workOrder.getWorkOrderProjectNo(), e);
+        }
+    }
+
+    /**
+     * 更新用户评分统计以反映运行得分奖励
+     * 
+     * @param monthScore 月度统计信息
+     * @param order 维修工单
+     * @param rewardScore 奖励分数
+     */
+    private void updateUserScoresForRunScore(GxtMonthScore monthScore, GxtRepairOrder order, BigDecimal rewardScore) {
+        try {
+            List<GxtRepairOrderPerson> persons = order.getRepairOrderPersonList();
+            if (persons == null || persons.isEmpty()) {
+                // 如果工单中的人员列表为空,尝试从数据库查询
+                persons = repairOrderService.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(rewardScore);
+                        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);
+
+                        log.debug("更新用户 {} 月度统计得分: {} -> {}", person.getNickName(), currentRepairTotal, newRepairScore);
+                    } else {
+                        // 没有找到记录,创建新记录
+                        GxtUserScore newUserScore = new GxtUserScore();
+                        newUserScore.setMonthScoreId(monthScore.getId());
+                        newUserScore.setUserName(sysUser.getUserName());
+                        newUserScore.setNickName(person.getNickName());
+                        newUserScore.setMonthPeriod(monthScore.getMonthPeriod());
+                        
+                        // 设置维修工单得分
+                        BigDecimal repairScore = rewardScore;
+                        newUserScore.setRepairTotalScore(rewardScore);
+                        
+                        // 维保得分默认为0
+                        newUserScore.setMaintenanceTotalScore(BigDecimal.ZERO);
+                        newUserScore.setFinalScore(rewardScore);
+                        newUserScore.setStatus(0);
+                        newUserScore.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserName());
+                        newUserScore.setCreateTime(new Date());
+                        // 插入新记录
+                        userScoreService.insertGxtUserScore(newUserScore);
+                        
+                        log.debug("创建用户 {} 月度统计得分: {}", person.getNickName(), repairScore);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            log.error("更新维修工单人员月度统计数据时发生异常", e);
+        }
+    }
+
+    /**
+     * 更新用户评分统计以反映运行得分奖励
+     * 
+     * @param monthScore 月度统计信息
+     * @param order 维保工单
+     * @param rewardScore 奖励分数
+     */
+    private void updateUserScoresForRunScore(GxtMonthScore monthScore, GxtWorkOrder order, BigDecimal rewardScore) {
+        try {
+            List<GxtWorkOrderPerson> persons = order.getWorkOrderPersonList();
+            if (persons == null || persons.isEmpty()) {
+                // 如果工单中的人员列表为空,尝试从数据库查询
+                persons = workOrderService.selectWorkOrderPersonListByOrderId(order.getId());
+            }
+
+            if (persons != null) {
+                for (GxtWorkOrderPerson 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 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;
+
+                        BigDecimal finalScore = repairScore.add(newMaintenanceScore);
+                        userScore.setFinalScore(finalScore);
+                        userScore.setUpdateBy(SecurityUtils.getLoginUser().getUser().getUserName());
+                        userScore.setUpdateTime(new Date());
+                        
+                        userScoreService.updateGxtUserScore(userScore);
+                        
+                        log.debug("更新用户 {} 月度统计得分: {} -> {}", person.getNickName(), currentMaintenanceTotal, newMaintenanceScore);
+                    } else {
+                        // 没有找到记录,创建新记录
+                        GxtUserScore newUserScore = new GxtUserScore();
+                        newUserScore.setMonthScoreId(monthScore.getId());
+                        newUserScore.setUserName(sysUser.getUserName());
+                        newUserScore.setNickName(person.getNickName());
+                        newUserScore.setMonthPeriod(monthScore.getMonthPeriod());
+                        
+                        // 设置维保工单得分
+                        BigDecimal maintenanceScore = rewardScore;
+                        newUserScore.setMaintenanceTotalScore(maintenanceScore);
+                        
+                        // 维修得分默认为0
+                        newUserScore.setRepairTotalScore(BigDecimal.ZERO);
+                        newUserScore.setFinalScore(maintenanceScore);
+                        newUserScore.setStatus(0);
+                        newUserScore.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserName());
+                        newUserScore.setCreateTime(new Date());
+                        // 插入新记录
+                        userScoreService.insertGxtUserScore(newUserScore);
+                        
+                        log.debug("创建用户 {} 月度统计得分: {}", person.getNickName(), maintenanceScore);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            log.error("更新维保工单人员月度统计数据时发生异常", e);
+        }
+    }
+
+    /**
+     * 处理时间数据,一次性计算所有必要的时间点和相关工单
+     */
+    private ProcessedTimeData processTimeData(List<GxtRepairOrder> archivedRepairOrders, List<GxtWorkOrder> archivedWorkOrders, 
+                                              List<GxtRepairOrder> activeRepairOrders, List<GxtWorkOrder> activeWorkOrders) {
+        ProcessedTimeData data = new ProcessedTimeData();
+        
+        // 获取最新的restartTime数据和对应的工单(从归档工单中查找)
+        // 由于查询时已按restartTime降序排序,所以取第一个非空元素即可
+        if (!archivedRepairOrders.isEmpty()) {
+            GxtRepairOrder firstOrder = archivedRepairOrders.get(0);
+            if (firstOrder.getRestartTime() != null) {
+                data.latestRestartTime = firstOrder.getRestartTime();
+                data.relatedRepairOrder = firstOrder; // 记录相关维修工单
+                data.relatedWorkOrder = null; // 清除可能之前设置的维保工单
+            }
+        }
+
+        if (!archivedWorkOrders.isEmpty()) {
+            GxtWorkOrder firstOrder = archivedWorkOrders.get(0);
+            if (firstOrder.getRestartTime() != null && 
+                (data.latestRestartTime == null || firstOrder.getRestartTime().after(data.latestRestartTime))) {
+                data.latestRestartTime = firstOrder.getRestartTime();
+                data.relatedWorkOrder = firstOrder; // 记录相关维保工单
+                data.relatedRepairOrder = null; // 清除可能之前设置的维修工单
+            }
+        }
+
+        // 获取最新的occurTime或pauseTime数据(从活动工单中查找)
+        // 由于查询时已按相应时间字段降序排序,所以取第一个非空元素即可
+        if (!activeRepairOrders.isEmpty()) {
+            GxtRepairOrder firstOrder = activeRepairOrders.get(0);
+            if (firstOrder.getOccurTime() != null) {
+                data.latestOccurOrPauseTime = firstOrder.getOccurTime();
+            }
+        }
+
+        if (!activeWorkOrders.isEmpty()) {
+            GxtWorkOrder firstOrder = activeWorkOrders.get(0);
+            if (firstOrder.getPauseTime() != null && 
+                (data.latestOccurOrPauseTime == null || firstOrder.getPauseTime().after(data.latestOccurOrPauseTime))) {
+                data.latestOccurOrPauseTime = firstOrder.getPauseTime();
+            }
+        }
+
+        return data;
+    }
+
+    /**
+     * 根据安全运行天数获取适用的奖励配置
+     * 
+     * @param rewardConfigs 奖励配置列表
+     * @param daysBetween 安全运行天数
+     * @return 适用的奖励配置
+     */
+    private GxtSafeOperationReward getApplicableRewardConfig(List<GxtSafeOperationReward> rewardConfigs, int daysBetween) {
+        GxtSafeOperationReward applicableReward = null;
+
+        for (GxtSafeOperationReward config : rewardConfigs) {
+            if (config.getSafeDuration() <= daysBetween) {
+                applicableReward = config;
+            } else {
+                // 因为已经按safeDuration升序排序,所以第一个大于daysBetween的配置就是边界
+                break;
+            }
+        }
+
+        return applicableReward;
+    }
+
+    /**
+     * 为维修工单人员更新运行得分
+     * 
+     * @param repairOrder 维修工单
+     * @param rewardScore 奖励分数
+     */
+    private void updatePersonRunScoreForRepairOrder(GxtRepairOrder repairOrder, BigDecimal rewardScore) {
+        try {
+            List<GxtRepairOrderPerson> persons = repairOrder.getRepairOrderPersonList();
+            if (persons == null || persons.isEmpty()) {
+                // 如果工单中的人员列表为空,尝试从数据库查询
+                persons = repairOrderService.selectRepairOrderPersonListByOrderId(repairOrder.getId());
+            }
+
+            if (persons == null || persons.isEmpty()) {
+                log.warn("维修工单 {} 没有找到相关人员", repairOrder.getWorkOrderProjectNo());
+                return;
+            }
+
+            List<GxtRepairOrderPerson> updatedPersons = new ArrayList<>();
+            for (GxtRepairOrderPerson person : persons) {
+                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());
+                
+                updatedPersons.add(updatedPerson);
+                
+                log.debug("维修工单 {} 人员 {} 运行得分更新: {} -> {}",
+                    repairOrder.getWorkOrderProjectNo(), person.getNickName(), currentRunScore, newRunScore );
+            }
+
+            // 批量更新人员得分
+            int result = repairOrderService.updateRepairOrderPersonList(updatedPersons);
+            log.info("维修工单 {} 共更新 {} 名人员的运行得分和总得分", repairOrder.getWorkOrderProjectNo(), updatedPersons.size());
+
+            /*double totalScore = persons.stream()
+                    .mapToDouble(person -> person.getTotalScore() != null ? person.getTotalScore() : 0.0)
+                    .sum();
+            repairOrder.setScore(new BigDecimal(String.valueOf(totalScore)));
+
+            repairOrderService.updateGxtRepairOrderForScore(repairOrder);*/
+        } catch (Exception e) {
+            log.error("更新维修工单 {} 人员运行得分时发生异常", repairOrder.getWorkOrderProjectNo(), e);
+        }
+    }
+
+    /**
+     * 为维保工单人员更新运行得分
+     * 
+     * @param workOrder 维保工单
+     * @param rewardScore 奖励分数
+     */
+    private void updatePersonRunScoreForWorkOrder(GxtWorkOrder workOrder, BigDecimal rewardScore) {
+        try {
+            List<GxtWorkOrderPerson> persons = workOrder.getWorkOrderPersonList();
+            if (persons == null || persons.isEmpty()) {
+                // 如果工单中的人员列表为空,尝试从数据库查询
+                persons = workOrderService.selectWorkOrderPersonListByOrderId(workOrder.getId());
+            }
+
+            if (persons == null || persons.isEmpty()) {
+                log.warn("维保工单 {} 没有找到相关人员", workOrder.getWorkOrderProjectNo());
+                return;
+            }
+
+            List<GxtWorkOrderPerson> updatedPersons = new ArrayList<>();
+            for (GxtWorkOrderPerson person : persons) {
+                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());
+                
+                updatedPersons.add(updatedPerson);
+                
+                log.debug("维保工单 {} 人员 {} 运行得分更新: {} -> {}",
+                    workOrder.getWorkOrderProjectNo(), person.getNickName(), currentRunScore, newRunScore);
+            }
+
+            // 批量更新人员得分
+            int result = workOrderService.updateWorkOrderPersonList(updatedPersons);
+            log.info("维保工单 {} 共更新 {} 名人员的运行得分和总得分", workOrder.getWorkOrderProjectNo(), updatedPersons.size());
+
+            /*double totalScore = persons.stream()
+                    .mapToDouble(person -> person.getTotalScore() != null ? person.getTotalScore() : 0.0)
+                    .sum();
+            workOrder.setScore(new BigDecimal(String.valueOf(totalScore)));
+
+            workOrderService.updateGxtWorkOrderForScore(workOrder);*/
+        } catch (Exception e) {
+            log.error("更新维保工单 {} 人员运行得分时发生异常", workOrder.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);
+        }
+    }
+
+    /**
+     * 存储处理后的时间数据
+     */
+    private static class ProcessedTimeData {
+        Date latestRestartTime;           // 最新的重启时间
+        Date latestOccurOrPauseTime;      // 最新的故障或暂停时间
+        GxtRepairOrder relatedRepairOrder; // 相关的维修工单
+        GxtWorkOrder relatedWorkOrder;    // 相关的维保工单
+    }
+}

+ 39 - 0
ygtx-gxt/src/main/resources/mapper/gxt/GxtRepairOrderMapper.xml

@@ -915,4 +915,43 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         ORDER BY
             IFNULL(us.final_score,0) DESC
     </select>
+
+    <select id="selectLatestGxtRepairOrderByDeviceId" parameterType="map" resultMap="GxtRepairOrderResult">
+        <include refid="selectGxtRepairOrderVo"/>
+        <where>
+            <if test="pcsDeviceId != null"> and pcs_device_id = #{pcsDeviceId}</if>
+            <if test="limit != null and limit > 0"> 
+                ORDER BY create_time DESC LIMIT #{limit}
+            </if>
+        </where>
+    </select>
+    
+    <select id="selectGxtRepairOrderByDeviceIdWithCondition" parameterType="map" resultMap="GxtRepairOrderResult">
+        <include refid="selectGxtRepairOrderVo"/>
+        <where>
+            <if test="pcsDeviceId != null"> and pcs_device_id = #{pcsDeviceId}</if>
+            <if test="workOrderStatus != null and workOrderStatus != ''">
+                <if test="excludeStatus">
+                    and work_order_status != #{workOrderStatus}
+                </if>
+                <if test="!excludeStatus">
+                    and work_order_status = #{workOrderStatus}
+                </if>
+            </if>
+        </where>
+        <choose>
+            <when test="orderByField != null and orderByField == 'occurTime'">
+                ORDER BY occur_time DESC
+            </when>
+            <when test="orderByField != null and orderByField == 'restartTime'">
+                ORDER BY restart_time DESC
+            </when>
+            <otherwise>
+                ORDER BY create_time DESC
+            </otherwise>
+        </choose>
+        <if test="limit != null and limit > 0"> 
+            LIMIT #{limit}
+        </if>
+    </select>
 </mapper>

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

@@ -44,7 +44,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <select id="selectGxtUserScoreList" parameterType="GxtUserScore" resultMap="GxtUserScoreResult">
         <include refid="selectGxtUserScoreVo"/>
         <where>  
-            <if test="userName != null  and userName != ''"> and user_name like concat('%', #{userName}, '%')</if>
+            <if test="userName != null  and userName != ''"> and user_name = #{userName}</if>
             <if test="nickName != null  and nickName != ''"> and nick_name like concat('%', #{nickName}, '%')</if>
             <if test="monthPeriod != null  and monthPeriod != ''"> and month_period = #{monthPeriod}</if>
             <if test="monthScoreId != null"> and month_score_id = #{monthScoreId}</if>

+ 39 - 0
ygtx-gxt/src/main/resources/mapper/gxt/GxtWorkOrderMapper.xml

@@ -826,4 +826,43 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             </otherwise>
         </choose>
     </select>
+
+    <select id="selectLatestGxtWorkOrderByDeviceId" parameterType="map" resultMap="GxtWorkOrderResult">
+        <include refid="selectGxtWorkOrderVo"/>
+        <where>
+            <if test="pcsDeviceId != null"> and pcs_device_id = #{pcsDeviceId}</if>
+            <if test="limit != null and limit > 0"> 
+                ORDER BY create_time DESC LIMIT #{limit}
+            </if>
+        </where>
+    </select>
+    
+    <select id="selectGxtWorkOrderByDeviceIdWithCondition" parameterType="map" resultMap="GxtWorkOrderResult">
+        <include refid="selectGxtWorkOrderVo"/>
+        <where>
+            <if test="pcsDeviceId != null"> and pcs_device_id = #{pcsDeviceId}</if>
+            <if test="workOrderStatus != null and workOrderStatus != ''">
+                <if test="excludeStatus">
+                    and work_order_status != #{workOrderStatus}
+                </if>
+                <if test="!excludeStatus">
+                    and work_order_status = #{workOrderStatus}
+                </if>
+            </if>
+        </where>
+        <choose>
+            <when test="orderByField != null and orderByField == 'pauseTime'">
+                ORDER BY pause_time DESC
+            </when>
+            <when test="orderByField != null and orderByField == 'restartTime'">
+                ORDER BY restart_time DESC
+            </when>
+            <otherwise>
+                ORDER BY create_time DESC
+            </otherwise>
+        </choose>
+        <if test="limit != null and limit > 0"> 
+            LIMIT #{limit}
+        </if>
+    </select>
 </mapper>

+ 24 - 14
ygtx-ui/src/views/gxt/orderScore/index.vue

@@ -307,7 +307,7 @@
                     <span>{{ scope.row.finalScore !== null && scope.row.finalScore !== undefined ? parseFloat(scope.row.finalScore).toFixed(2) : '' }}</span>
                   </template>
                 </el-table-column>-->
-                <!-- 额外工分和分 - 仅当维修工单且有额外工作总结时显示 -->
+                <!-- 额外工分和工单得分 - 仅当维修工单且有额外工作总结时显示 -->
                 <el-table-column 
                   label="额外工分" 
                   align="center" 
@@ -319,7 +319,7 @@
                   </template>
                 </el-table-column>
                 <el-table-column 
-                  label="总分" 
+                  label="工单得分"
                   align="center" 
                   prop="totalScore" 
                   v-if="viewForm.orderType === 1 && viewForm.extraWork && viewForm.extraWork.trim() !== ''" 
@@ -328,6 +328,16 @@
                     <span>{{ scope.row.totalScore !== null && scope.row.totalScore !== undefined ? parseFloat(scope.row.totalScore).toFixed(2) : '' }}</span>
                   </template>
                 </el-table-column>
+                <el-table-column
+                    label="奖励得分"
+                    align="center"
+                    prop="runScore"
+                    v-if="viewForm.restartTime !== null && viewForm.restartTime !== undefined"
+                    style="width: 33%;">
+                  <template #default="scope">
+                    <span>{{ scope.row.runScore !== null && scope.row.runScore !== undefined ? parseFloat(scope.row.runScore).toFixed(2) : '' }}</span>
+                  </template>
+                </el-table-column>
               </el-table>
             </el-form-item>
           </el-col>
@@ -472,7 +482,7 @@
                   @change="updateTotalScore(scope.row)"/>
               </template>
             </el-table-column>
-            <!-- 额外工分和分 - 仅当维修工单且有额外工作总结时显示 -->
+            <!-- 额外工分和工单得分 - 仅当维修工单且有额外工作总结时显示 -->
             <el-table-column 
               label="额外工分" 
               align="center" 
@@ -492,7 +502,7 @@
               </template>
             </el-table-column>
             <el-table-column 
-              label="总分" 
+              label="工单得分"
               align="center" 
               prop="totalScore" 
               v-if="selfEvaluationForm.orderType === 1 && selfEvaluationForm.extraWork && selfEvaluationForm.extraWork.trim() !== ''" 
@@ -509,7 +519,7 @@
                 />
               </template>
             </el-table-column>
-            <!-- 额外工分和分 - 仅当维保工单且维保类型包含其他/其它时显示 -->
+            <!-- 额外工分和工单得分 - 仅当维保工单且维保类型包含其他/其它时显示 -->
             <el-table-column 
               label="额外工分" 
               align="center" 
@@ -529,7 +539,7 @@
               </template>
             </el-table-column>
             <el-table-column 
-              label="总分" 
+              label="工单得分"
               align="center" 
               prop="totalScore" 
               v-if="selfEvaluationForm.orderType === 2 && hasOtherOrQitaInspectionType()" 
@@ -764,7 +774,7 @@
                 <el-input v-model="scope.row.reviewScore" style="width: 100%;" :readonly="isEditScore"/>
               </template>
             </el-table-column>
-            <!-- 额外工分和分 - 仅当维修工单且有额外工作总结时显示 -->
+            <!-- 额外工分和工单得分 - 仅当维修工单且有额外工作总结时显示 -->
             <el-table-column 
               label="额外工分" 
               align="center" 
@@ -784,7 +794,7 @@
               </template>
             </el-table-column>
             <el-table-column 
-              label="总分" 
+              label="工单得分"
               align="center" 
               prop="totalScore" 
               v-if="reviewForm.orderType === 1 && reviewForm.extraWork && reviewForm.extraWork.trim() !== ''" 
@@ -801,7 +811,7 @@
                 />
               </template>
             </el-table-column>
-            <!-- 额外工分和分 - 仅当维保工单且维保类型包含其他/其它时显示 -->
+            <!-- 额外工分和工单得分 - 仅当维保工单且维保类型包含其他/其它时显示 -->
             <el-table-column 
               label="额外工分" 
               align="center" 
@@ -821,7 +831,7 @@
               </template>
             </el-table-column>
             <el-table-column 
-              label="总分" 
+              label="工单得分"
               align="center" 
               prop="totalScore" 
               v-if="reviewForm.orderType === 2 && hasOtherOrQitaInspectionType()" 
@@ -1000,7 +1010,7 @@
                     />
                   </template>
                 </el-table-column>
-                <!-- 额外工分和分 - 仅当维修工单且有额外工作总结时显示 -->
+                <!-- 额外工分和工单得分 - 仅当维修工单且有额外工作总结时显示 -->
                 <el-table-column 
                   label="额外工分" 
                   align="center" 
@@ -1016,7 +1026,7 @@
                   </template>
                 </el-table-column>
                 <el-table-column 
-                  label="总分" 
+                  label="工单得分"
                   align="center" 
                   prop="totalScore" 
                   v-if="hasExtraWork()" 
@@ -1029,7 +1039,7 @@
                     />
                   </template>
                 </el-table-column>
-                <!-- 额外工分和分 - 仅当维保工单且维保类型包含其他/其它时显示 -->
+                <!-- 额外工分和工单得分 - 仅当维保工单且维保类型包含其他/其它时显示 -->
                 <el-table-column 
                   label="额外工分" 
                   align="center" 
@@ -1045,7 +1055,7 @@
                   </template>
                 </el-table-column>
                 <el-table-column 
-                  label="总分" 
+                  label="工单得分"
                   align="center" 
                   prop="totalScore" 
                   v-if="finalEvaluationForm.orderType === 2 && hasOtherOrQitaInspectionType()"