zouyu
2026-04-14 948194840fc18c00617cbf3cf72f9e81bb0ee5b3
人员考勤调整:导出区分年度和月度
已添加2个文件
已重命名1个文件
已修改5个文件
94 ■■■■ 文件已修改
cnas-device/src/main/java/com/ruoyi/device/pojo/Device.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-device/src/main/java/com/ruoyi/device/utils/DataAcquisition.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/dto/StaffAttendanceDTO.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffAttendanceTrackingRecordServiceImpl.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/resources/mapper/InsOrderMapper.xml 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/resources/static/staff_attendance_month_template.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/resources/static/staff_attendance_year_template.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/enums/StaffAttendanceReportType.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-device/src/main/java/com/ruoyi/device/pojo/Device.java
@@ -126,6 +126,9 @@
    @ApiModelProperty("数采-db,mdb文件名称")
    private String dbFileName;
    @ApiModelProperty("数采-db,末尾追加sql语句")
    private String lastSql;
    @ApiModelProperty("被授权人")
    private String authorizedPerson;
cnas-device/src/main/java/com/ruoyi/device/utils/DataAcquisition.java
@@ -84,6 +84,7 @@
        String dbFileName = StringUtils.isNotBlank(device.getDbFileName())?device.getDbFileName():"";
        String colorTag = StringUtils.isNotBlank(cableTag)?cableTag:"";
        String lotBatchNoStr = StringUtils.isNotBlank(lotBatchNo)?lotBatchNo:"";
        String lastSql = StringUtils.isNotBlank(device.getLastSql())?device.getLastSql():"";
        String http = HTTP + ip + GETFILE +
                "?filePath=" + device.getCollectUrl() +
                "&fileExtension=" + device.getFileType() +
@@ -96,6 +97,7 @@
                "&dbPassword=" + dbPassword +
                "&lotBatchNo=" + lotBatchNoStr +
                "&cableTag=" + colorTag +
                "&lastSql=" + lastSql +
                "&dbTable=" + dbTable;
        System.out.println("请求的 URL: " + http);
        String result = null;
inspect-server/src/main/java/com/ruoyi/inspect/dto/StaffAttendanceDTO.java
@@ -84,4 +84,10 @@
    @ApiModelProperty("下班记录id")
    private Long offWorkDataId;
    /**
     * è€ƒå‹¤å¯¼å‡ºç»´åº¦(year/month)
     */
    @ApiModelProperty("考勤导出维度(year/month)")
    private String attendanceReportType;
}
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffAttendanceTrackingRecordServiceImpl.java
@@ -3,7 +3,9 @@
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
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.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -12,6 +14,7 @@
import com.google.common.util.concurrent.AtomicDouble;
import com.ruoyi.common.enums.ClockInState;
import com.ruoyi.common.enums.EnterOrExitType;
import com.ruoyi.common.enums.StaffAttendanceReportType;
import com.ruoyi.common.enums.SyncStatus;
import com.ruoyi.common.utils.api.icc.IccApiUtil;
import com.ruoyi.common.utils.api.icc.model.GetResultPageRequest;
@@ -81,6 +84,8 @@
    private DateTimeFormatter HHmm = DateTimeFormatter.ofPattern("HH:mm");
    private DateTimeFormatter yyyMMddHHmmss = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private DateTimeFormatter yyyMMStr = DateTimeFormatter.ofPattern("yyyyå¹´MM月dd日");
    /** è´¨é‡éƒ¨id */
    private final static String deptIds = "6";
@@ -420,9 +425,9 @@
            for (int i = 0; i < userIdKeys.size(); i++) {
                List<PerformanceShiftMapDto> shiftMapDtos = groupByUserId.get(userIdKeys.get(i));
                StaffAttendanceExcelData attendanceExcelData = new StaffAttendanceExcelData();
                attendanceExcelData.setExcelIndex(i+1);
                List<String> shiftList = new ArrayList<>();
                attendanceExcelData.setPersonName(shiftMapDtos.get(0).getUserName());
                attendanceExcelData.setExcelIndex(i+1);
                AtomicInteger holidayCount = new AtomicInteger(0);//休息天数
                AtomicInteger personalLeaveCount = new AtomicInteger(0);//事假天数
                AtomicInteger annualLeaveCount = new AtomicInteger(0);//年假天数
@@ -469,11 +474,16 @@
                            }
                        }
                    }
                    if(StringUtils.isNotBlank(shiftMapDto.getAnnotationText())){
                        annotationTextList.add(new StaffAttendanceAnnotationTextExcelData(i,j,shiftMapDto.getAnnotationText()));
                    //月度统计才插入批注数据
                    if(StringUtils.isNoneBlank(staffAttendanceDTO.getAttendanceReportType()) && StringUtils.equals(staffAttendanceDTO.getAttendanceReportType(), StaffAttendanceReportType.MONTH.name())){
                        if(StringUtils.isNotBlank(shiftMapDto.getAnnotationText())){
                            annotationTextList.add(new StaffAttendanceAnnotationTextExcelData(i,j,shiftMapDto.getAnnotationText()));
                        }
                    }
                }
                attendanceExcelData.setShiftList(shiftList);
                if(StringUtils.isNoneBlank(staffAttendanceDTO.getAttendanceReportType()) && StringUtils.equals(staffAttendanceDTO.getAttendanceReportType(), StaffAttendanceReportType.MONTH.name())){
                    attendanceExcelData.setShiftList(shiftList);
                }
                attendanceExcelData.setAttendanceDayCount(attendanceDayCount.get());
                attendanceExcelData.setAttendanceWorkHourCount(attendanceWorkHourCount.get());
                //班次考勤天数
@@ -493,13 +503,19 @@
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            InputStream resourceAsStream = buildAttendanceTemplate(attendanceDateList);
            EasyExcel.write(response.getOutputStream())
                    .withTemplate(resourceAsStream)
                    .registerWriteHandler(new CommentWriteHandler(excelData, annotationTextList))
                    .relativeHeadRowIndex(4)
                    .sheet()
                    .doFill(excelData);
            InputStream resourceAsStream = buildAttendanceTemplate(attendanceDateList,staffAttendanceDTO.getAttendanceReportType());
            try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(resourceAsStream).registerWriteHandler(new CommentWriteHandler(excelData, annotationTextList)).relativeHeadRowIndex(4).build()) {
                WriteSheet writeSheet = EasyExcel.writerSheet().build();
                excelWriter.fill(excelData, writeSheet);
                if(StringUtils.equals(staffAttendanceDTO.getAttendanceReportType(),StaffAttendanceReportType.YEAR.name())){
                    String startDate = staffAttendanceDTO.getStartDate().format(yyyMMStr);
                    String endDate = staffAttendanceDTO.getEndDate().format(yyyMMStr);
                    Map<String, String> dateMap = new HashMap<>();
                    dateMap.put("startDate",startDate);
                    dateMap.put("endDate",endDate);
                    excelWriter.fill(dateMap, writeSheet);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
@@ -518,20 +534,28 @@
        for (LocalDate currentDate = startDate; !currentDate.isAfter(endDate); currentDate = currentDate.plusDays(1)) {
            attendanceDateList.add(currentDate);
        }
        if (attendanceDateList.size() > 31) {
        if (attendanceDateList.size() > 31 && StringUtils.equals(staffAttendanceDTO.getAttendanceReportType(),StaffAttendanceReportType.MONTH.name())) {
            throw new IllegalArgumentException("导出时间范围不能超过31天");
        }
        return attendanceDateList;
    }
    private InputStream buildAttendanceTemplate(List<LocalDate> attendanceDateList) throws IOException {
        try (InputStream templateStream = this.getClass().getResourceAsStream("/static/staff_attendance_template.xlsx");
                Workbook workbook = WorkbookFactory.create(templateStream);
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            Sheet sheet = workbook.getSheetAt(0);
            fillAttendanceHeader(sheet, attendanceDateList);
            workbook.write(outputStream);
            return new ByteArrayInputStream(outputStream.toByteArray());
    private InputStream buildAttendanceTemplate(List<LocalDate> attendanceDateList,String attendanceReportType) throws IOException {
        String templateName = "/static/staff_attendance_month_template.xlsx";
        if(StringUtils.equals(attendanceReportType,StaffAttendanceReportType.YEAR.name())){
            templateName = "/static/staff_attendance_year_template.xlsx";
        }
        try (InputStream templateStream = this.getClass().getResourceAsStream(templateName)) {
            assert templateStream != null;
            try (Workbook workbook = WorkbookFactory.create(templateStream);
                 ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
                Sheet sheet = workbook.getSheetAt(0);
                if(StringUtils.equals(attendanceReportType,StaffAttendanceReportType.MONTH.name())){
                    fillAttendanceHeader(sheet, attendanceDateList);
                }
                workbook.write(outputStream);
                return new ByteArrayInputStream(outputStream.toByteArray());
            }
        } catch (Exception e) {
            throw new IOException("构建考勤导出模板失败", e);
        }
inspect-server/src/main/resources/mapper/InsOrderMapper.xml
@@ -396,13 +396,18 @@
                     io2.entrust_code,
                     io2.test_quantity,
                     io2.ins_state,
                     sto.color AS part_color,
                     CASE
                      WHEN pp.color IS NOT NULL
                      THEN pp.color
                      ELSE sto.color
                     END  part_color,
                     JSON_OBJECT(
                             'sample_name', io2.sample_view,
                             'entrust_code', io2.entrust_code
                     )                                                 labelBarCode
              from ins_order io2
                LEFT JOIN ins_sample isa ON io2.id = isa.ins_order_id
                LEFT JOIN product_part pp ON pp.part_no = io2.part_no COLLATE utf8mb4_general_ci
                LEFT JOIN structure_test_object_part sto ON sto.part_no = io2.part_no COLLATE utf8mb4_general_ci
              where type_source = -1
              GROUP BY io2.id) a
inspect-server/src/main/resources/static/staff_attendance_month_template.xlsx
Binary files differ
inspect-server/src/main/resources/static/staff_attendance_year_template.xlsx
Binary files differ
ruoyi-common/src/main/java/com/ruoyi/common/enums/StaffAttendanceReportType.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
package com.ruoyi.common.enums;
/**
 * äººå‘˜è€ƒå‹¤å¯¼å‡ºç»´åº¦æžšä¸¾(year/month)
 */
public enum StaffAttendanceReportType {
    YEAR,
    MONTH
}