From 1b2f1eb44d9f0de6b9238cfe314988a95c87344a Mon Sep 17 00:00:00 2001
From: zouyu <2723363702@qq.com>
Date: 星期四, 02 四月 2026 13:37:15 +0800
Subject: [PATCH] 绩效管理:工时汇总对接MES数据&人员考勤调整

---
 inspect-server/src/main/java/com/ruoyi/inspect/task/SyncStaffAttendanceRecordSchedule.java                 |    5 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/api/mes/MesApiUtils.java                                 |  150 +++++++++++
 inspect-server/src/main/java/com/ruoyi/inspect/util/HourDiffCalculator.java                                |   37 ++
 performance-server/src/main/java/com/ruoyi/performance/service/impl/AuxiliaryOriginalHoursServiceImpl.java |   82 ++++++
 ruoyi-common/src/main/java/com/ruoyi/common/utils/api/mes/model/WorkingHoursRecordSumVO.java               |  103 +++++++
 /dev/null                                                                                                  |  102 -------
 inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffAttendanceTrackingRecordServiceImpl.java  |   29 +
 performance-server/src/main/java/com/ruoyi/performance/dto/AuxiliaryAllDto.java                            |   92 ++++++
 inspect-server/src/main/java/com/ruoyi/inspect/aspect/MoveLocationAfterPushMesStockAspect.java             |    4 
 performance-server/src/main/java/com/ruoyi/performance/service/AuxiliaryOriginalHoursService.java          |    2 
 performance-server/src/main/java/com/ruoyi/performance/controller/AuxiliaryOriginalHoursController.java    |    7 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/api/mes/model/WorkingHoursRecordTotalVO.java             |   84 ++++++
 inspect-server/src/main/java/com/ruoyi/inspect/util/TimeDiffCalculator.java                                |   62 ++++
 13 files changed, 626 insertions(+), 133 deletions(-)

diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/aspect/MoveLocationAfterPushMesStockAspect.java b/inspect-server/src/main/java/com/ruoyi/inspect/aspect/MoveLocationAfterPushMesStockAspect.java
index 1cf7d14..524e5d5 100644
--- a/inspect-server/src/main/java/com/ruoyi/inspect/aspect/MoveLocationAfterPushMesStockAspect.java
+++ b/inspect-server/src/main/java/com/ruoyi/inspect/aspect/MoveLocationAfterPushMesStockAspect.java
@@ -4,11 +4,9 @@
 import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.ruoyi.basic.pojo.IfsInventoryQuantity;
-import com.ruoyi.common.config.mes.MesConfig;
-import com.ruoyi.common.config.mes.MesProperties;
 import com.ruoyi.common.numgen.NumberGenerator;
 import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.common.utils.api.MesApiUtils;
+import com.ruoyi.common.utils.api.mes.MesApiUtils;
 import com.ruoyi.inspect.pojo.IfsSplitOrderRecord;
 import com.ruoyi.inspect.service.IfsSplitOrderRecordService;
 import lombok.extern.slf4j.Slf4j;
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffAttendanceTrackingRecordServiceImpl.java b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffAttendanceTrackingRecordServiceImpl.java
index 99d2aaf..27a6c78 100644
--- a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffAttendanceTrackingRecordServiceImpl.java
+++ b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffAttendanceTrackingRecordServiceImpl.java
@@ -19,6 +19,7 @@
 import com.ruoyi.inspect.pojo.StaffAttendanceTrackingRecord;
 import com.ruoyi.inspect.service.StaffAttendanceTrackingRecordService;
 import com.ruoyi.inspect.util.HourDiffCalculator;
+import com.ruoyi.inspect.util.TimeDiffCalculator;
 import com.ruoyi.inspect.vo.StaffAttendanceVO;
 import com.ruoyi.inspect.vo.StaffClockInVO;
 import com.ruoyi.performance.dto.PerformanceShiftMapDto;
@@ -90,6 +91,11 @@
     private final static List<String> syncDeviceCode = Arrays.asList("1001538", "1001539", "1001540", "1001541",
             "1001626", "1001627", "1001628", "1001629");
 
+    /**
+     * 涓婄彮鏃堕棿鍒ゅ畾杈圭晫灏忔椂鏁�
+     */
+    private final static long WORK_TIME_BOUNDARY = 2L;
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean syncAttendanceRecord(LocalDateTime startDate, LocalDateTime endDate) {
@@ -140,9 +146,6 @@
     public IPage<StaffAttendanceVO> pageAttendanceRecord(Page<StaffAttendanceTrackingRecord> page,
             StaffAttendanceDTO staffAttendanceDTO) {
         // 鏌ヨ鎵撳崱璁板綍
-        System.out.println(staffAttendanceDTO.getStartDate());
-        System.out.println(staffAttendanceDTO.getEndDate());
-        System.out.println(ObjectUtils.allNotNull(staffAttendanceDTO.getStartDate(),staffAttendanceDTO.getEndDate()));
         Wrapper<StaffAttendanceTrackingRecord> queryWrapper = Wrappers.<StaffAttendanceTrackingRecord>lambdaQuery()
                 .eq(StaffAttendanceTrackingRecord::getEnableReport, Boolean.TRUE)
                 .between(ObjectUtils.allNotNull(staffAttendanceDTO.getStartDate(),staffAttendanceDTO.getEndDate()),
@@ -181,10 +184,6 @@
                 LocalTime currentShiftStartTime = LocalTime.parse(p.getStartTime(), HHmm);
                 LocalDateTime currentShiftStartDateTime = LocalDateTime.of(p.getWorkTime().toLocalDate(),
                         currentShiftStartTime);
-                // 褰撳墠鐝缁撴潫鏃堕棿
-                LocalTime currentShiftEndTime = LocalTime.parse(p.getEndTime(), HHmm);
-                LocalDateTime currentShiftEndDateTime = LocalDateTime.of(endDateTime.toLocalDate(),
-                        currentShiftEndTime);
                 // 涓嬩竴鐝寮�濮嬫椂闂�
                 LocalDateTime nextShiftStartDateTime = getShiftStartDateTime(i + 1, performanceShifts,
                         startDateTime.plusDays(1L));
@@ -192,15 +191,21 @@
                     // 濡傛灉灏忔椂宸负璐熸暟锛岃〃绀鸿法澶╋紝缁撴潫鏃堕棿闇�鍔犱竴
                     endDateTime = endDateTime.plusDays(1L);
                 }
+                // 褰撳墠鐝缁撴潫鏃堕棿
+                LocalTime currentShiftEndTime = LocalTime.parse(p.getEndTime(), HHmm);
+                LocalDateTime currentShiftEndDateTime = LocalDateTime.of(endDateTime.toLocalDate(),
+                        currentShiftEndTime);
                 // 杩囨护鍑哄綋鍓嶄汉鍛樺綋鍓嶇彮娆$殑杩�/鍑鸿褰�
                 LocalDateTime workDateTime = null;
                 LocalDateTime offWorkDateTime = null;
                 List<StaffAttendanceTrackingRecord> enterRecords = filterAttendanceRecord(p.getPersonCode(),
                         EnterOrExitType.ENTER.getValue(), startDateTime, endDateTime, recordList);
+                //涓婄彮鏃堕棿鍒ゅ畾杈圭晫
+                LocalDateTime boundaryTime = currentShiftStartDateTime.minusHours(WORK_TIME_BOUNDARY);
                 if (!enterRecords.isEmpty()) {
                     // 涓婄彮鏃堕棿鍜岀姸鎬�
                     StaffAttendanceTrackingRecord enterRecord = enterRecords.stream()
-                            .filter(s -> !s.getSwingTime().isAfter(currentShiftStartDateTime))
+                            .filter(s -> !s.getSwingTime().isAfter(currentShiftStartDateTime) && !s.getSwingTime().isBefore(boundaryTime))
                             .max(Comparator.comparing(StaffAttendanceTrackingRecord::getSwingTime))
                             .orElse(new StaffAttendanceTrackingRecord());
                     if (BeanUtil.isEmpty(enterRecord)) {
@@ -244,14 +249,16 @@
 
                 }
                 if (ObjectUtils.allNotNull(workDateTime, offWorkDateTime)) {
-                    vo.setActualWorkHours(HourDiffCalculator.getHourDiff(workDateTime.toLocalTime().format(HHmm),
-                            offWorkDateTime.toLocalTime().format(HHmm)));
+                    vo.setActualWorkHours(TimeDiffCalculator.getHourDiff(workDateTime,
+                            offWorkDateTime));
                 }
                 // 璧嬪��
                 vo.setShiftId(p.getShift());
                 vo.setPersonCode(p.getPersonCode());
                 vo.setPersonName(p.getUserName());
-                vo.setPlannedWorkHours(hourDiff);
+                //搴斿嫟鏃堕暱
+                double plannedWorkHours = Math.abs(hourDiff);
+                vo.setPlannedWorkHours(plannedWorkHours);
                 vo.setSwingDate(startDateTime);
                 vo.setWorkDateTime(workDateTime);
                 vo.setOffWorkDateTime(offWorkDateTime);
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/task/SyncStaffAttendanceRecordSchedule.java b/inspect-server/src/main/java/com/ruoyi/inspect/task/SyncStaffAttendanceRecordSchedule.java
index 3d595ed..fc95b46 100644
--- a/inspect-server/src/main/java/com/ruoyi/inspect/task/SyncStaffAttendanceRecordSchedule.java
+++ b/inspect-server/src/main/java/com/ruoyi/inspect/task/SyncStaffAttendanceRecordSchedule.java
@@ -23,12 +23,13 @@
     private StaffAttendanceTrackingRecordService trackingRecordService;
 
 
-    @Scheduled(cron = "0 0 1 * * ?")
+    @Scheduled(cron = "0 0 */12 * * ?")
     public void sync() {
         log.info("--------鍚屾鑰冨嫟璁板綍瀹氭椂浠诲姟寮�濮�--------");
         LocalDate yesterday = LocalDate.now(ZoneId.of("Asia/Shanghai")).minusDays(1L);
+        LocalDate now = LocalDate.now(ZoneId.of("Asia/Shanghai"));
         LocalDateTime startTime = LocalDateTime.of(yesterday, LocalTime.MIN);
-        LocalDateTime endTime = LocalDateTime.of(yesterday, LocalTime.MAX);
+        LocalDateTime endTime = LocalDateTime.of(now, LocalTime.MAX);
         trackingRecordService.syncAttendanceRecord(startTime,endTime);
         log.info("--------鍚屾鑰冨嫟璁板綍瀹氭椂浠诲姟缁撴潫--------");
     }
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/util/HourDiffCalculator.java b/inspect-server/src/main/java/com/ruoyi/inspect/util/HourDiffCalculator.java
index 687645e..425c559 100644
--- a/inspect-server/src/main/java/com/ruoyi/inspect/util/HourDiffCalculator.java
+++ b/inspect-server/src/main/java/com/ruoyi/inspect/util/HourDiffCalculator.java
@@ -2,6 +2,8 @@
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
 import java.util.Objects;
 import java.util.regex.Pattern;
 
@@ -39,6 +41,41 @@
         return hourDiff.doubleValue();
     }
 
+    public static void main(String[] args) {
+        System.out.println(getHourDiff("07:38","19:26"));
+        LocalDateTime localDateTime = LocalDateTime.of(2026, 3, 30, 7, 38);
+        LocalDateTime localDateTime2 = LocalDateTime.of(2026, 3, 30, 19, 26);
+        System.out.println(getTimeDifference(localDateTime,localDateTime2));
+    }
+
+    /**
+     * 璁$畻涓や釜鏃堕棿鐨勫樊鍊硷紝杩斿洖 澶�:鏃�:鍒�:绉掞紙姣忎綅涓や綅鏁帮紝鏀寔璺ㄥぉ锛�
+     * @param startTime 寮�濮嬫椂闂�
+     * @param endTime   缁撴潫鏃堕棿
+     * @return 鏍煎紡鍖栧悗鐨勬椂闂村樊锛堜緥锛�01澶� 01鏃� 30鍒� 05绉掞級
+     */
+    public static String getTimeDifference(LocalDateTime startTime, LocalDateTime endTime) {
+        // 1. 璁$畻涓や釜鏃堕棿鐨�**鎬绘绉掑樊**锛堢粷瀵瑰�硷紝閬垮厤鏃堕棿椤哄簭闂锛�
+        long totalMillis = Math.abs(ChronoUnit.MILLIS.between(startTime, endTime));
+
+        // 2. 瀹氫箟鏃堕棿鍗曚綅甯搁噺锛堟绉掞級
+        final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;  // 1澶�
+        final long MILLIS_PER_HOUR = 60 * 60 * 1000;       // 1灏忔椂
+        final long MILLIS_PER_MINUTE = 60 * 1000;          // 1鍒嗛挓
+        final long MILLIS_PER_SECOND = 1000;               // 1绉�
+
+        // 3. 鎷嗗垎 澶┿�佹椂銆佸垎銆佺
+        long days = totalMillis / MILLIS_PER_DAY;
+        long remainingMillis = totalMillis % MILLIS_PER_DAY;
+        long hours = remainingMillis / MILLIS_PER_HOUR;
+        remainingMillis %= MILLIS_PER_HOUR;
+        long minutes = remainingMillis / MILLIS_PER_MINUTE;
+        long seconds = remainingMillis / MILLIS_PER_SECOND;
+
+        // 4. 鏍煎紡鍖栵細%02d = 鏁存暟琛ラ浂鍒颁袱浣嶆暟锛堟牳蹇冿紒婊¤冻绮剧‘鍒颁袱浣嶆暟瑕佹眰锛�
+        return String.format("%02d澶� %02d鏃� %02d鍒� %02d绉�", days, hours, minutes, seconds);
+    }
+
     /**
      * 鏍¢獙鏃堕棿鏍煎紡鏄惁涓篐H:mm
      */
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/util/TimeDiffCalculator.java b/inspect-server/src/main/java/com/ruoyi/inspect/util/TimeDiffCalculator.java
new file mode 100644
index 0000000..a7e0e83
--- /dev/null
+++ b/inspect-server/src/main/java/com/ruoyi/inspect/util/TimeDiffCalculator.java
@@ -0,0 +1,62 @@
+package com.ruoyi.inspect.util;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.Duration;
+import java.time.LocalDateTime;
+
+/**
+ * LocalDateTime 鏃堕棿宸绠楀伐鍏�
+ * 鍔熻兘锛氫紶鍏ヤ袱涓椂闂达紝杩斿洖淇濈暀涓や綅灏忔暟鐨勬椂闂村樊锛堝ぉ/灏忔椂/鍒嗛挓/绉掞級
+ */
+public class TimeDiffCalculator {
+
+    // 绾崇鎹㈢畻甯搁噺锛堟渶绮剧‘鐨勬椂闂村崟浣嶏紝鏃犵簿搴︿涪澶憋級
+    private static final long NANOS_PER_DAY = 24L * 60 * 60 * 1000000000;
+    private static final long NANOS_PER_HOUR = 60L * 60 * 1000000000;
+    private static final long NANOS_PER_MINUTE = 60L * 1000000000;
+    private static final long NANOS_PER_SECOND = 1000000000L;
+
+    /**
+     * 璁$畻 澶╂暟 宸紝淇濈暀涓や綅灏忔暟
+     */
+    public static double getDayDiff(LocalDateTime start, LocalDateTime end) {
+        return calculateDiff(start, end, NANOS_PER_DAY);
+    }
+
+    /**
+     * 璁$畻 灏忔椂 宸紝淇濈暀涓や綅灏忔暟
+     */
+    public static double getHourDiff(LocalDateTime start, LocalDateTime end) {
+        return calculateDiff(start, end, NANOS_PER_HOUR);
+    }
+
+    /**
+     * 璁$畻 鍒嗛挓 宸紝淇濈暀涓や綅灏忔暟
+     */
+    public static double getMinuteDiff(LocalDateTime start, LocalDateTime end) {
+        return calculateDiff(start, end, NANOS_PER_MINUTE);
+    }
+
+    /**
+     * 璁$畻 绉� 宸紝淇濈暀涓や綅灏忔暟
+     */
+    public static double getSecondDiff(LocalDateTime start, LocalDateTime end) {
+        return calculateDiff(start, end, NANOS_PER_SECOND);
+    }
+
+    /**
+     * 缁熶竴璁$畻閫昏緫锛堟娊绂诲叕鍏变唬鐮侊級
+     * @param unitNanos 鐩爣鍗曚綅瀵瑰簲鐨勭撼绉掓暟
+     */
+    private static double calculateDiff(LocalDateTime start, LocalDateTime end, long unitNanos) {
+        // 1. 璁$畻鏃堕棿宸紝鍙栫粷瀵瑰��
+        Duration duration = Duration.between(start, end).abs();
+        // 2. 绾崇杞珺igDecimal锛岀簿纭绠�
+        BigDecimal totalNanos = new BigDecimal(duration.toNanos());
+        BigDecimal unit = new BigDecimal(unitNanos);
+        // 3. 闄ゆ硶杩愮畻锛屼繚鐣�2浣嶅皬鏁帮紝鍥涜垗浜斿叆
+        return totalNanos.divide(unit, 2, RoundingMode.HALF_UP).doubleValue();
+    }
+
+}
\ No newline at end of file
diff --git a/performance-server/src/main/java/com/ruoyi/performance/controller/AuxiliaryOriginalHoursController.java b/performance-server/src/main/java/com/ruoyi/performance/controller/AuxiliaryOriginalHoursController.java
index 62e128b..da5320e 100644
--- a/performance-server/src/main/java/com/ruoyi/performance/controller/AuxiliaryOriginalHoursController.java
+++ b/performance-server/src/main/java/com/ruoyi/performance/controller/AuxiliaryOriginalHoursController.java
@@ -41,4 +41,11 @@
     public Result selectAuxiliaryAllByMonth(AuxiliaryOriginalHoursLookDto dto){
         return Result.success(auxiliaryOriginalHoursService.selectAuxiliaryAllByMonth(dto));
     }
+
+    @ApiOperation(value = "瀵煎嚭宸ユ椂姹囨��")
+    @GetMapping("/exportWorkHoursTotal")
+    public void exportWorkHoursTotal(HttpServletResponse response,AuxiliaryOriginalHoursLookDto dto){
+        auxiliaryOriginalHoursService.exportWorkHoursTotal(response,dto);
+    }
+
 }
diff --git a/performance-server/src/main/java/com/ruoyi/performance/dto/AuxiliaryAllDto.java b/performance-server/src/main/java/com/ruoyi/performance/dto/AuxiliaryAllDto.java
index 88fadc0..ccbfe31 100644
--- a/performance-server/src/main/java/com/ruoyi/performance/dto/AuxiliaryAllDto.java
+++ b/performance-server/src/main/java/com/ruoyi/performance/dto/AuxiliaryAllDto.java
@@ -1,5 +1,7 @@
 package com.ruoyi.performance.dto;
 
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Data;
@@ -18,22 +20,88 @@
 @NoArgsConstructor
 public class AuxiliaryAllDto {
 
-    @ApiModelProperty("浜ч噺宸ユ椂")
-    private BigDecimal yieldHour;
-
-    @ApiModelProperty("杈呭姪宸ユ椂")
-    private BigDecimal subsidiaryHour;
-
-    @ApiModelProperty("鎬诲伐鏃�")
-    private BigDecimal totalHour;
-
+    @ExcelIgnore
     @ApiModelProperty("浜哄憳id")
     private Integer userId;
 
-    @ApiModelProperty("濮撳悕")
-    private String userName;
-
+    @ExcelIgnore
     @ApiModelProperty("鏈堜唤")
     private String month;
 
+    @ExcelProperty(value = {"搴忓彿","搴忓彿"},index = 0)
+    @ApiModelProperty("瀵煎嚭搴忓彿")
+    private Integer excelIndex;
+
+    @ExcelProperty(value = {"濮撳悕","濮撳悕"},index = 1)
+    @ApiModelProperty("濮撳悕")
+    private String userName;
+
+    @ExcelProperty(value = {"鑰愪笣鍩烳ES","宸ュ簭缁╂晥"},index = 2)
+    @ApiModelProperty("宸ュ簭缁╂晥-鑰愪笣鍩�")
+    private BigDecimal operationPerformanceByNS = BigDecimal.ZERO;
+
+    @ExcelProperty(value = {"鑰愪笣鍩烳ES","鎴愬搧缁╂晥"},index = 3)
+    @ApiModelProperty("鎴愬搧缁╂晥-鑰愪笣鍩�")
+    private BigDecimal productPerformanceByNS = BigDecimal.ZERO;
+
+    @ExcelProperty(value = {"鑰愪笣鍩烳ES","宸℃缁╂晥"},index = 4)
+    @ApiModelProperty("宸℃缁╂晥-鑰愪笣鍩�")
+    private BigDecimal onsiteInspWageByNS = BigDecimal.ZERO;
+
+    @ExcelProperty(value = {"鑰愪笣鍩烳ES","鏉傚伐宸ヨ祫"},index = 5)
+    @ApiModelProperty("鏉傚伐宸ヨ祫-鑰愪笣鍩�")
+    private BigDecimal handymanWageByNS = BigDecimal.ZERO;
+
+    @ExcelProperty(value = {"绉戞妧鍩烳ES","宸ュ簭缁╂晥"},index = 6)
+    @ApiModelProperty("宸ュ簭缁╂晥-绉戞妧鍩�")
+    private BigDecimal operationPerformanceByKJ = BigDecimal.ZERO;
+
+    @ExcelProperty(value = {"绉戞妧鍩烳ES","鎴愬搧缁╂晥"},index = 7)
+    @ApiModelProperty("鎴愬搧缁╂晥-绉戞妧鍩�")
+    private BigDecimal productPerformanceByKJ = BigDecimal.ZERO;
+
+    @ExcelProperty(value = {"绉戞妧鍩烳ES","宸℃缁╂晥"},index = 8)
+    @ApiModelProperty("宸℃缁╂晥-绉戞妧鍩�")
+    private BigDecimal onsiteInspWageByKJ = BigDecimal.ZERO;
+
+    @ExcelProperty(value = {"绉戞妧鍩烳ES","鏉傚伐宸ヨ祫"},index = 9)
+    @ApiModelProperty("鏉傚伐宸ヨ祫-绉戞妧鍩�")
+    private BigDecimal handymanWageByKJ = BigDecimal.ZERO;
+
+    @ExcelProperty(value = {"MES姹囨��","宸ュ簭缁╂晥"},index = 10)
+    @ApiModelProperty("宸ュ簭缁╂晥-绉戞妧鍩�")
+    private BigDecimal operationPerformance = BigDecimal.ZERO;
+
+    @ExcelProperty(value = {"MES姹囨��","鎴愬搧缁╂晥"},index = 11)
+    @ApiModelProperty("鎴愬搧缁╂晥-绉戞妧鍩�")
+    private BigDecimal productPerformance = BigDecimal.ZERO;
+
+    @ExcelProperty(value = {"MES姹囨��","宸℃缁╂晥"},index = 12)
+    @ApiModelProperty("宸℃缁╂晥-绉戞妧鍩�")
+    private BigDecimal onsiteInspWage = BigDecimal.ZERO;
+
+    @ExcelProperty(value = {"MES姹囨��","鏉傚伐宸ヨ祫"},index = 13)
+    @ApiModelProperty("鏉傚伐宸ヨ祫-绉戞妧鍩�")
+    private BigDecimal handymanWage = BigDecimal.ZERO;
+
+    @ExcelProperty(value = {"LIMS","浜ч噺宸ユ椂"},index = 14)
+    @ApiModelProperty("浜ч噺宸ユ椂")
+    private BigDecimal yieldHour;
+
+    @ExcelProperty(value = {"LIMS","杈呭姪宸ユ椂"},index = 15)
+    @ApiModelProperty("杈呭姪宸ユ椂")
+    private BigDecimal subsidiaryHour;
+
+    @ExcelProperty(value = {"LIMS","鎬诲伐鏃�"},index = 16)
+    @ApiModelProperty("鎬诲伐鏃�")
+    private BigDecimal totalHour;
+
+    public AuxiliaryAllDto(BigDecimal yieldHour, BigDecimal subsidiaryHour, BigDecimal totalHour, Integer userId, String userName, String month) {
+        this.yieldHour = yieldHour;
+        this.subsidiaryHour = subsidiaryHour;
+        this.totalHour = totalHour;
+        this.userId = userId;
+        this.userName = userName;
+        this.month = month;
+    }
 }
diff --git a/performance-server/src/main/java/com/ruoyi/performance/service/AuxiliaryOriginalHoursService.java b/performance-server/src/main/java/com/ruoyi/performance/service/AuxiliaryOriginalHoursService.java
index 05dd08c..aeba842 100644
--- a/performance-server/src/main/java/com/ruoyi/performance/service/AuxiliaryOriginalHoursService.java
+++ b/performance-server/src/main/java/com/ruoyi/performance/service/AuxiliaryOriginalHoursService.java
@@ -27,4 +27,6 @@
      * @return
      */
     List<AuxiliaryAllDto> selectAuxiliaryAllByMonth(AuxiliaryOriginalHoursLookDto dto);
+
+    void exportWorkHoursTotal(HttpServletResponse response, AuxiliaryOriginalHoursLookDto dto);
 }
diff --git a/performance-server/src/main/java/com/ruoyi/performance/service/impl/AuxiliaryOriginalHoursServiceImpl.java b/performance-server/src/main/java/com/ruoyi/performance/service/impl/AuxiliaryOriginalHoursServiceImpl.java
index dd22d6c..9aef08d 100644
--- a/performance-server/src/main/java/com/ruoyi/performance/service/impl/AuxiliaryOriginalHoursServiceImpl.java
+++ b/performance-server/src/main/java/com/ruoyi/performance/service/impl/AuxiliaryOriginalHoursServiceImpl.java
@@ -2,6 +2,7 @@
 
 import com.alibaba.excel.EasyExcel;
 import com.alibaba.excel.ExcelWriter;
+import com.alibaba.excel.support.ExcelTypeEnum;
 import com.alibaba.excel.write.metadata.WriteSheet;
 import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -11,9 +12,16 @@
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.core.domain.entity.User;
+import com.ruoyi.common.enums.ContractType;
+import com.ruoyi.common.enums.StaffSkillLevelType;
 import com.ruoyi.common.exception.base.BaseException;
+import com.ruoyi.common.utils.api.mes.MesApiUtils;
+import com.ruoyi.common.utils.api.mes.model.WorkingHoursRecordSumVO;
+import com.ruoyi.common.utils.api.mes.model.WorkingHoursRecordTotalVO;
+import com.ruoyi.common.utils.excel.EasyExcelUtils;
+import com.ruoyi.common.utils.excel.FullCustomAutoWidthHandler;
+import com.ruoyi.common.utils.excel.HeaderContentRowHeightHandler;
 import com.ruoyi.performance.dto.AuxiliaryAllDto;
-import com.ruoyi.performance.dto.AuxiliaryCorrectionHoursDto;
 import com.ruoyi.performance.dto.AuxiliaryOriginalHoursDto;
 import com.ruoyi.performance.dto.AuxiliaryOriginalHoursLookDto;
 import com.ruoyi.performance.mapper.AuxiliaryCorrectionHoursMapper;
@@ -23,8 +31,10 @@
 import com.ruoyi.performance.pojo.AuxiliaryCorrectionHours;
 import com.ruoyi.performance.service.AuxiliaryOriginalHoursService;
 import com.ruoyi.system.mapper.UserMapper;
-import org.apache.commons.math3.analysis.function.Power;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.ss.usermodel.IndexedColors;
 import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
@@ -33,11 +43,14 @@
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
+@Slf4j
 @Service
 public class AuxiliaryOriginalHoursServiceImpl implements AuxiliaryOriginalHoursService {
 
@@ -55,6 +68,9 @@
 
     @Resource
     AuxiliaryCorrectionHoursMapper auxiliaryCorrectionHoursMapper;
+
+    @Autowired
+    private MesApiUtils mesApiUtils;
 
     @Override
     public IPage<AuxiliaryOriginalHoursDto> selectAuxiliaryOriginalHours(Page page, AuxiliaryOriginalHoursLookDto auxiliaryOriginalHoursLookDto) {
@@ -231,7 +247,18 @@
         dto.setAssistBeginDate(beginDate);
         dto.setAssistEndDate(endDate);
 
-
+        //鏌ヨKJNS鍜孼TNS鍩熺殑MES缁╂晥鏁版嵁
+        Map<String, Object> params = new HashMap<>();
+        params.put("year",date.getYear());
+        params.put("month",date.getMonthValue());
+        List<WorkingHoursRecordTotalVO> hoursRecordSumByNS = new ArrayList<>();
+        List<WorkingHoursRecordTotalVO> hoursRecordSumByKJ = new ArrayList<>();
+        try {
+            hoursRecordSumByNS = mesApiUtils.getCheckWorkingHoursRecordSum(ContractType.ZTNS.getValue(), params);
+            hoursRecordSumByKJ = mesApiUtils.getCheckWorkingHoursRecordSum(ContractType.KJNS.getValue(), params);
+        }catch (Exception e){
+            log.error("宸ユ椂姹囨�绘煡璇㈠紓甯革細{}",e.getMessage());
+        }
         // 鏌ヨ浜ч噺宸ユ椂
         List<AuxiliaryAllDto> auxiliaryAllDtos = auxiliaryOutputWorkingHoursMapper.selectAuxiliaryAllByMonth(dto, userIds);
 
@@ -257,11 +284,60 @@
             BigDecimal total = (auxiliaryAllDto.getYieldHour() != null ? auxiliaryAllDto.getYieldHour() : BigDecimal.ZERO)
                     .add(auxiliaryAllDto.getSubsidiaryHour() != null ? auxiliaryAllDto.getSubsidiaryHour() : BigDecimal.ZERO);
             auxiliaryAllDto.setTotalHour(total);
+            if(!hoursRecordSumByNS.isEmpty()){
+                WorkingHoursRecordTotalVO totalVOByNS = hoursRecordSumByNS.stream().filter(f -> StringUtils.equals(f.getChecker(), auxiliaryAllDto.getUserName())).findFirst().orElse(null);
+                if(ObjectUtils.isNotNull(totalVOByNS)){
+                    auxiliaryAllDto.setHandymanWageByNS(totalVOByNS.getHandymanWage());
+                    auxiliaryAllDto.setOnsiteInspWageByNS(totalVOByNS.getOnsiteInspWage());
+                    auxiliaryAllDto.setOperationPerformanceByNS(totalVOByNS.getOperationPerformance());
+                    auxiliaryAllDto.setProductPerformanceByNS(totalVOByNS.getProductPerformance());
+                }
+            }
+            if(!hoursRecordSumByKJ.isEmpty()){
+                WorkingHoursRecordTotalVO totalVOByKJ = hoursRecordSumByKJ.stream().filter(f -> StringUtils.equals(f.getChecker(), auxiliaryAllDto.getUserName())).findFirst().orElse(null);
+                if(ObjectUtils.isNotNull(totalVOByKJ)){
+                    auxiliaryAllDto.setHandymanWageByKJ(totalVOByKJ.getHandymanWage());
+                    auxiliaryAllDto.setOnsiteInspWageByKJ(totalVOByKJ.getOnsiteInspWage());
+                    auxiliaryAllDto.setOperationPerformanceByKJ(totalVOByKJ.getOperationPerformance());
+                    auxiliaryAllDto.setProductPerformanceByKJ(totalVOByKJ.getProductPerformance());
+                }
+            }
         }
 
         return auxiliaryAllDtos;
     }
 
+    @Override
+    public void exportWorkHoursTotal(HttpServletResponse response, AuxiliaryOriginalHoursLookDto dto) {
+        response.reset();
+        try {
+            //1.缁勮鏁版嵁
+            AtomicInteger excelIndex = new AtomicInteger(1);
+            List<AuxiliaryAllDto> auxiliaryAllDtos = selectAuxiliaryAllByMonth(dto);
+            auxiliaryAllDtos.forEach(a->{
+                a.setExcelIndex(excelIndex.getAndIncrement());
+                a.setOperationPerformance(a.getOperationPerformanceByKJ().add(a.getOperationPerformanceByNS()));//宸ュ簭缁╂晥姹囨��
+                a.setOnsiteInspWage(a.getOnsiteInspWageByKJ().add(a.getOnsiteInspWageByNS()));//宸℃缁╂晥姹囨��
+                a.setProductPerformance(a.getProductPerformanceByKJ().add(a.getProductPerformanceByNS()));//鎴愬搧缁╂晥姹囨��
+                a.setHandymanWage(a.getHandymanWageByKJ().add(a.getHandymanWageByNS()));//鏉傚伐宸ヨ祫
+            });
+            //2.瀵煎嚭
+            String fileName = "涓ぉ鑰愪笣璐ㄩ噺閮ㄥ伐鏃舵眹鎬�"+ ExcelTypeEnum.XLSX;
+            fileName =  URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
+            response.setContentType("application/vnd.ms-excel");
+            response.setHeader("Cache-Control", "no-cache");
+            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
+            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
+            EasyExcel.write(response.getOutputStream())
+                    .head(AuxiliaryAllDto.class)
+                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
+                    .sheet("Sheet 1")
+                    .doWrite(auxiliaryAllDtos);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     private Map<String, AuxiliaryOriginalHoursDto> getData(List<Map<String, Object>> objectMaps, String type) {
         Map<String, AuxiliaryOriginalHoursDto> dtoMap = new HashMap<>();
         for (Map<String, Object> objectMap : objectMaps) {
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/api/MesApiUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/api/MesApiUtils.java
deleted file mode 100644
index 72d7fe5..0000000
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/api/MesApiUtils.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package com.ruoyi.common.utils.api;
-
-import cn.hutool.http.HttpRequest;
-import cn.hutool.json.JSONObject;
-import cn.hutool.json.JSONUtil;
-import com.ruoyi.common.config.mes.MesConfig;
-import com.ruoyi.common.config.mes.MesProperties;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-
-@Slf4j
-@Component
-public class MesApiUtils {
-
-    @Autowired
-    private MesConfig mesConfig;
-
-    /**
-     * 鏍规嵁宸ュ巶鍩熷洖鍘籱es閰嶇疆
-     * @param contract
-     * @return
-     */
-    public MesProperties getMesPropertiesByContract(String contract){
-        return mesConfig.getProps().stream().filter(f-> org.apache.commons.lang3.StringUtils.equals(f.getContract(),contract)).findFirst().orElse(new MesProperties());
-    }
-
-    /**
-     * 鑾峰彇token璇锋眰閾炬帴
-     * @return
-     */
-    private String getAuthTokenUrl(String ip) {
-        return ip + "/auth/oauth/token?randomStr=blockPuzzle&grant_type=password";
-    }
-
-    /**
-     * 鏂板瀹炴椂搴撳瓨璇锋眰閾炬帴
-     * @return
-     */
-    private String getBatchAddStockUrl(String ip){
-        return ip + "/mes/stock/batchAddStock";
-    }
-
-    /**
-     * 鑾峰彇mes绯荤粺token
-     * @return 鎺ュ彛鍝嶅簲缁撴灉
-     */
-    public String getToken(MesProperties mesProperties){
-        try{
-            Map<String,Object> bodyMap = new HashMap<>();
-            bodyMap.put("username",mesProperties.getUser());
-            String bodyStr = "username="+mesProperties.getUser()+"&password="+mesProperties.getPassword();
-            String response = HttpRequest.post(getAuthTokenUrl(mesProperties.getIp()))
-                    .header("Authorization", "Basic cGlnOnBpZw==")
-                    .header("Content-Type", "application/x-www-form-urlencoded")
-                    .body(bodyStr,"application/x-www-form-urlencoded").execute().body();
-            JSONObject responseObj = JSONUtil.parseObj(response);
-            if(Objects.nonNull(responseObj.getStr("access_token"))){
-                return "Bearer " + responseObj.getStr("access_token");
-            }else{
-                throw new RuntimeException(responseObj.getStr("msg"));
-            }
-        }catch (Exception e){
-            e.printStackTrace();
-            throw new RuntimeException("鑾峰彇MES绯荤粺token鎺ュ彛寮傚父:"+e.getMessage());
-        }
-    }
-
-    /**
-     * mes鏂板瀹炴椂搴撳瓨鎺ュ彛
-     * @param contract 宸ュ巶鍩�
-     * @param requestJsonStr 璇锋眰鍙傛暟json瀛楃涓�
-     * @return 鎺ュ彛鍝嶅簲缁撴灉
-     */
-    public boolean batchAddStock(String contract,String requestJsonStr){
-        try{
-            MesProperties mesProperties = getMesPropertiesByContract(contract);
-            String response = HttpRequest.post(getBatchAddStockUrl(mesProperties.getIp()))
-                    .header("Authorization", getToken(mesProperties))
-                    .header("Content-Type", "application/json")
-                    .body(requestJsonStr)
-                    .execute()
-                    .body();
-            JSONObject entries = JSONUtil.parseObj(response);
-            if(entries.getInt("code")==0){
-                return true;
-            }else{
-                throw new RuntimeException("銆�"+contract+"銆戝悓姝ュ埌MES澶辫触锛�"+entries.getStr("msg"));
-            }
-        }catch (Exception e){
-            e.printStackTrace();
-            throw new RuntimeException("銆�"+contract+"銆戝悓姝ES瀹炴椂搴撳瓨鎺ュ彛寮傚父:"+e.getMessage());
-        }
-    }
-
-}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/api/mes/MesApiUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/api/mes/MesApiUtils.java
new file mode 100644
index 0000000..336c06f
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/api/mes/MesApiUtils.java
@@ -0,0 +1,150 @@
+package com.ruoyi.common.utils.api.mes;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.http.HttpRequest;
+import com.alibaba.fastjson.JSONObject;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.ruoyi.common.config.mes.MesConfig;
+import com.ruoyi.common.config.mes.MesProperties;
+import com.ruoyi.common.utils.api.mes.model.WorkingHoursRecordSumVO;
+import com.ruoyi.common.utils.api.mes.model.WorkingHoursRecordTotalVO;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+@Slf4j
+@Component
+public class MesApiUtils {
+
+    @Autowired
+    private MesConfig mesConfig;
+
+    /**
+     * 鏍规嵁宸ュ巶鍩熷洖鍘籱es閰嶇疆
+     * @param contract
+     * @return
+     */
+    public MesProperties getMesPropertiesByContract(String contract){
+        return mesConfig.getProps().stream().filter(f-> org.apache.commons.lang3.StringUtils.equals(f.getContract(),contract)).findFirst().orElse(new MesProperties());
+    }
+
+    /**
+     * 鑾峰彇token璇锋眰閾炬帴
+     * @return
+     */
+    private String getAuthTokenUrl(String ip) {
+        return ip + "/auth/oauth/token?randomStr=blockPuzzle&grant_type=password";
+    }
+
+    /**
+     * 鏂板瀹炴椂搴撳瓨璇锋眰閾炬帴
+     * @return
+     */
+    private String getBatchAddStockUrl(String ip){
+        return ip + "/mes/stock/batchAddStock";
+    }
+
+    /**
+     * 妫�娴嬪伐鏃剁粺璁℃煡璇㈣姹傞摼鎺�
+     * @return
+     */
+    private String getCheckWorkingHoursRecordSumUrl(String ip){
+        return ip + "/mes/checkWorkingHoursRecord/getCheckWorkingHoursRecordSum";
+    }
+
+
+
+    /**
+     * 鑾峰彇mes绯荤粺token
+     * @return 鎺ュ彛鍝嶅簲缁撴灉
+     */
+    public String getToken(MesProperties mesProperties){
+        try{
+            String bodyStr = "username="+mesProperties.getUser()+"&password="+mesProperties.getPassword();
+            String response = HttpRequest.post(getAuthTokenUrl(mesProperties.getIp()))
+                    .header("Authorization", "Basic cGlnOnBpZw==")
+                    .header("Content-Type", "application/x-www-form-urlencoded")
+                    .body(bodyStr,"application/x-www-form-urlencoded").execute().body();
+            JSONObject responseObj = JSONObject.parseObject(response);
+            if(Objects.nonNull(responseObj.getString("access_token"))){
+                return "Bearer " + responseObj.getString("access_token");
+            }else{
+                throw new RuntimeException(responseObj.getString("msg"));
+            }
+        }catch (Exception e){
+            throw new RuntimeException("鑾峰彇MES绯荤粺token鎺ュ彛寮傚父:"+e.getMessage());
+        }
+    }
+
+    /**
+     * mes鏂板瀹炴椂搴撳瓨鎺ュ彛
+     * @param contract 宸ュ巶鍩�
+     * @param requestJsonStr 璇锋眰鍙傛暟json瀛楃涓�
+     * @return 鎺ュ彛鍝嶅簲缁撴灉
+     */
+    public boolean batchAddStock(String contract,String requestJsonStr){
+        try{
+            MesProperties mesProperties = getMesPropertiesByContract(contract);
+            String response = HttpRequest.post(getBatchAddStockUrl(mesProperties.getIp()))
+                    .header("Authorization", getToken(mesProperties))
+                    .header("Content-Type", "application/json")
+                    .body(requestJsonStr)
+                    .execute()
+                    .body();
+            JSONObject entries = JSONObject.parseObject(response);
+            if(entries.getInteger("code")==0){
+                return true;
+            }else{
+                throw new RuntimeException("銆�"+contract+"銆戝悓姝ュ埌MES澶辫触锛�"+entries.getString("msg"));
+            }
+        }catch (Exception e){
+            throw new RuntimeException("銆�"+contract+"銆戝悓姝ES瀹炴椂搴撳瓨鎺ュ彛寮傚父:"+e.getMessage());
+        }
+    }
+
+    /**
+     * 妫�娴嬪伐鏃剁粺璁℃煡璇�
+     * @return
+     */
+    public List<WorkingHoursRecordTotalVO> getCheckWorkingHoursRecordSum(String contract,Map<String,Object> params){
+        try {
+            MesProperties mesProperties = getMesPropertiesByContract(contract);
+            String response = HttpRequest.get(getCheckWorkingHoursRecordSumUrl(mesProperties.getIp()))
+                    .header("Authorization", getToken(mesProperties))
+                    .header("Content-Type", "application/x-www-form-urlencoded")
+                    .form(params)
+                    .execute()
+                    .body();
+            JSONObject entries = JSONObject.parseObject(response);
+            if(entries.getInteger("code")==0){
+                List<WorkingHoursRecordTotalVO> totalVOS = new ArrayList<>();
+                List<WorkingHoursRecordSumVO> parseObject = JSONObject.parseObject(entries.getString("data"), new TypeReference<List<WorkingHoursRecordSumVO>>() {}.getType());
+                parseObject.forEach(p->{
+                    WorkingHoursRecordSumVO.WorkHoursVO monthTotal = p.getWorkingHours().stream().filter(f -> StringUtils.equals(f.getDutyDate(), "鏈堝害姹囨��")).findFirst().orElse(null);
+                    WorkingHoursRecordTotalVO totalVO = new WorkingHoursRecordTotalVO();
+                    if(ObjectUtils.isNotEmpty(monthTotal)){
+                        BeanUtil.copyProperties(monthTotal,totalVO);
+                    }
+                    totalVO.setYear(p.getYear());
+                    totalVO.setMonth(p.getMonth());
+                    totalVO.setChecker(p.getChecker());
+                    totalVOS.add(totalVO);
+                });
+                return totalVOS;
+            }else{
+                throw new RuntimeException("銆�"+contract+"銆戞媺鍙朚ES妫�娴嬪伐鏃跺け璐ワ細"+entries.getString("msg"));
+            }
+        }catch (Exception e){
+            throw new RuntimeException("銆�"+contract+"銆戞媺鍙朚ES妫�娴嬪伐鏃舵帴鍙e紓甯革細"+e.getMessage());
+        }
+    }
+
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/api/mes/model/WorkingHoursRecordSumVO.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/api/mes/model/WorkingHoursRecordSumVO.java
new file mode 100644
index 0000000..5000579
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/api/mes/model/WorkingHoursRecordSumVO.java
@@ -0,0 +1,103 @@
+package com.ruoyi.common.utils.api.mes.model;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 鍚屾mes妫�娴嬪伐鏃跺搷搴斿璞�
+ */
+@Data
+public class WorkingHoursRecordSumVO {
+
+    /**
+     * 骞翠唤
+     */
+    @ApiModelProperty("骞翠唤")
+    private Integer year;
+
+    /**
+     * 鏈堜唤
+     */
+    @ApiModelProperty("鏈堜唤")
+    private Integer month;
+
+    /**
+     * 妫�娴嬩汉
+     */
+    @ApiModelProperty("妫�娴嬩汉")
+    private String checker;
+
+    /**
+     * 妫�娴嬩汉id
+     */
+    @ApiModelProperty("妫�娴嬩汉id")
+    private Long staffId;
+
+    /**
+     * 宸ユ椂鍒楄〃
+     */
+    @ApiModelProperty("宸ユ椂鍒楄〃")
+    private List<WorkHoursVO> workingHours;
+
+    @Data
+    public static class WorkHoursVO {
+
+        /**
+         * 鏃ユ湡
+         */
+        @ApiModelProperty("鏃ユ湡")
+        private String dutyDate;
+
+        /**
+         * 宸ュ簭鍒嗗��
+         */
+        @ApiModelProperty("宸ュ簭鍒嗗��")
+        private BigDecimal operationScore;
+
+        /**
+         * 宸ュ簭缁╂晥
+         */
+        @ApiModelProperty("宸ュ簭缁╂晥")
+        private BigDecimal operationPerformance;
+
+        /**
+         * 鎴愬搧鍒嗗��
+         */
+        @ApiModelProperty("鎴愬搧鍒嗗��")
+        private BigDecimal productScore;
+
+        /**
+         * 鎴愬搧缁╂晥
+         */
+        @ApiModelProperty("鎴愬搧缁╂晥")
+        private BigDecimal productPerformance;
+
+        /**
+         * 鏉傚伐宸ユ椂
+         */
+        @ApiModelProperty("鏉傚伐宸ユ椂")
+        private BigDecimal handymanHours;
+
+        /**
+         * 鏉傚伐宸ヨ祫
+         */
+        @ApiModelProperty("鏉傚伐宸ヨ祫")
+        private BigDecimal handymanWage;
+
+        /**
+         * 宸℃宸ヨ祫
+         */
+        @ApiModelProperty("宸℃宸ヨ祫")
+        private BigDecimal onsiteInspWage;
+
+        /**
+         * 姹囨��
+         */
+        @ApiModelProperty("姹囨��")
+        private BigDecimal total;
+    }
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/api/mes/model/WorkingHoursRecordTotalVO.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/api/mes/model/WorkingHoursRecordTotalVO.java
new file mode 100644
index 0000000..5220af6
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/api/mes/model/WorkingHoursRecordTotalVO.java
@@ -0,0 +1,84 @@
+package com.ruoyi.common.utils.api.mes.model;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class WorkingHoursRecordTotalVO {
+
+
+    /**
+     * 骞翠唤
+     */
+    @ApiModelProperty("骞翠唤")
+    private Integer year;
+
+    /**
+     * 鏈堜唤
+     */
+    @ApiModelProperty("鏈堜唤")
+    private Integer month;
+
+    /**
+     * 妫�娴嬩汉
+     */
+    @ApiModelProperty("妫�娴嬩汉")
+    private String checker;
+
+    /**
+     * 鏃ユ湡
+     */
+    @ApiModelProperty("鏃ユ湡")
+    private String dutyDate;
+
+    /**
+     * 宸ュ簭鍒嗗��
+     */
+    @ApiModelProperty("宸ュ簭鍒嗗��")
+    private BigDecimal operationScore;
+
+    /**
+     * 宸ュ簭缁╂晥
+     */
+    @ApiModelProperty("宸ュ簭缁╂晥")
+    private BigDecimal operationPerformance;
+
+    /**
+     * 鎴愬搧鍒嗗��
+     */
+    @ApiModelProperty("鎴愬搧鍒嗗��")
+    private BigDecimal productScore;
+
+    /**
+     * 鎴愬搧缁╂晥
+     */
+    @ApiModelProperty("鎴愬搧缁╂晥")
+    private BigDecimal productPerformance;
+
+    /**
+     * 鏉傚伐宸ユ椂
+     */
+    @ApiModelProperty("鏉傚伐宸ユ椂")
+    private BigDecimal handymanHours;
+
+    /**
+     * 鏉傚伐宸ヨ祫
+     */
+    @ApiModelProperty("鏉傚伐宸ヨ祫")
+    private BigDecimal handymanWage;
+
+    /**
+     * 宸℃宸ヨ祫
+     */
+    @ApiModelProperty("宸℃宸ヨ祫")
+    private BigDecimal onsiteInspWage;
+
+    /**
+     * 姹囨��
+     */
+    @ApiModelProperty("姹囨��")
+    private BigDecimal total;
+
+}

--
Gitblit v1.9.3