From b754e3ffc095dd79aac5a66cdcd47aff4fde6db3 Mon Sep 17 00:00:00 2001 From: zt Date: Mon, 22 Sep 2025 22:57:43 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SubUserSalaryDetailController.java | 10 +++-- .../contractor/excel/DynamicSalaryData.java | 3 +- .../excel/DynamicSalaryListener.java | 44 ++++++++++++++----- .../contractor/excel/SalaryExcelReader.java | 4 +- .../impl/SubUserSalaryDetailServiceImpl.java | 1 + .../impl/BusAttendanceServiceImpl.java | 2 +- 6 files changed, 45 insertions(+), 19 deletions(-) diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/controller/SubUserSalaryDetailController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/controller/SubUserSalaryDetailController.java index 8ee8e3c7..92770a5b 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/controller/SubUserSalaryDetailController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/controller/SubUserSalaryDetailController.java @@ -6,6 +6,7 @@ import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import org.dromara.common.core.domain.R; import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.common.idempotent.annotation.RepeatSubmit; import org.dromara.common.log.annotation.Log; import org.dromara.common.log.enums.BusinessType; import org.dromara.common.mybatis.core.page.PageQuery; @@ -25,6 +26,7 @@ import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.util.List; +import java.util.concurrent.TimeUnit; /** * 员工每日工资 @@ -87,10 +89,10 @@ public class SubUserSalaryDetailController extends BaseController { } @PutMapping("/import") - public R importData(@RequestParam("file") MultipartFile file, - @RequestParam("month") String month) { - subUserSalaryDetailService.importData(file, month); - return R.ok(); + @RepeatSubmit(interval = 1, timeUnit = TimeUnit.MINUTES,message = "正在导入,请勿重复提交") + public R importData(@RequestParam("file") MultipartFile file) { + subUserSalaryDetailService.importData(file, null); + return R.ok(true); } @GetMapping("/detailList") diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/excel/DynamicSalaryData.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/excel/DynamicSalaryData.java index 744d6d49..0af5117a 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/excel/DynamicSalaryData.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/excel/DynamicSalaryData.java @@ -16,7 +16,8 @@ public class DynamicSalaryData { private String idCard; // 身份证号 private Double total; // 合计出勤天数 private String isLeave; // 是否离场(未离场/已离场) - private String signature; // 签字(可选) + private String signature; + private String month;// 签字(可选) // 动态日期考勤:key=完整日期(如“2025-09-01”),value=考勤状态(0=未出勤,1=出勤) private Map dailyAttendance = new LinkedHashMap<>(); diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/excel/DynamicSalaryListener.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/excel/DynamicSalaryListener.java index a8f2e54c..8d6ebdc6 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/excel/DynamicSalaryListener.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/excel/DynamicSalaryListener.java @@ -3,6 +3,7 @@ package org.dromara.contractor.excel; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.exception.ServiceException; import org.dromara.common.utils.IdCardEncryptorUtil; import java.time.LocalDate; @@ -13,7 +14,7 @@ import java.util.Map; @Slf4j public class DynamicSalaryListener extends AnalysisEventListener> { private final List allAttendanceList; - private final String month; + private String month; private static final int DATE_COL_START_INDEX = 3; // 日期列起始索引(第4列) private int dateColEndIndex; private final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); @@ -21,22 +22,37 @@ public class DynamicSalaryListener extends AnalysisEventListener allAttendanceList, String month) { + public DynamicSalaryListener(List allAttendanceList) { this.allAttendanceList = allAttendanceList; - this.month = month; - // 月份格式校验 - try { - LocalDate.parse(month + "-01", dateFormatter); - } catch (Exception e) { - throw new IllegalArgumentException("月份格式错误!需传入yyyy-MM格式(如2025-09)"); - } } @Override public void invokeHeadMap(Map headMap, AnalysisContext context) { - // 仅处理固定行号的表头,且仅初始化1次 + + // 处理第一行标题,提取月份 int currentRowIndex = context.readRowHolder().getRowIndex(); + if (currentRowIndex == 0) { // 第一行标题 + // 从标题中提取月份,如"建筑施工企业现场人员工资表(2025年09月)" + String title = getCellValue(headMap, 0); + if (title != null && title.contains("(") && title.contains(")")) { + try { + // 提取年月部分,如"2025-09" + // 转换为yyyy-MM格式,如"2025-09" + + this.month = title.substring(title.indexOf("(") + 1, title.indexOf(")")); + // 校验格式 + LocalDate.parse(this.month + "-01", dateFormatter); + log.info("从标题行解析到月份:{}", this.month); + } catch (Exception e) { + throw new ServiceException("未解析到年月"); + } + } + return; + } + + + // 仅处理固定行号的表头,且仅初始化1次 if (currentRowIndex != FIXED_HEAD_ROW_NUMBER || isHeadInitialized) { return; } @@ -68,6 +84,10 @@ public class DynamicSalaryListener extends AnalysisEventListener rowData, AnalysisContext context) { + // 确保month已初始化 + if (this.month == null || this.month.isEmpty()) { + throw new RuntimeException("月份信息未正确解析,请检查Excel标题格式"); + } // 【核心优化:强化无效行过滤】 // 1. 获取第1列(序号)和第2列(姓名)的值,用于判断是否为有效数据行 String serialNumberStr = getCellValue(rowData, 0); @@ -99,7 +119,7 @@ public class DynamicSalaryListener extends AnalysisEventListener readAllAttendanceByStream(InputStream inputStream, String month) { List allAttendanceList = new ArrayList<>(); - DynamicSalaryListener listener = new DynamicSalaryListener(allAttendanceList, month); + DynamicSalaryListener listener = new DynamicSalaryListener(allAttendanceList); try ( // 1. 构建Excel读取器:读取源为 InputStream,全局设置表头行号 @@ -60,7 +60,7 @@ public class SalaryExcelReader { public static List readAllAttendance(String excelFilePath, String month) { List allAttendanceList = new ArrayList<>(); - DynamicSalaryListener listener = new DynamicSalaryListener(allAttendanceList, month); + DynamicSalaryListener listener = new DynamicSalaryListener(allAttendanceList); try ( // 【核心修改1:在读取器初始化时就全局设置表头行号】 diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/impl/SubUserSalaryDetailServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/impl/SubUserSalaryDetailServiceImpl.java index d575e9bc..a1d44d63 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/impl/SubUserSalaryDetailServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/impl/SubUserSalaryDetailServiceImpl.java @@ -549,6 +549,7 @@ public class SubUserSalaryDetailServiceImpl extends ServiceImpl> dataMap = dataList.stream().collect(Collectors.toMap(vo -> idCardEncryptorUtil.encrypt(vo.getIdCard()), DynamicSalaryData::getDailyAttendance)); Set cards = dataMap.keySet(); + month = dataList.getFirst().getMonth(); YearMonth parse = YearMonth.parse(month, DateTimeFormatter.ofPattern("yyyy-MM")); LocalDate start = parse.atDay(1); LocalDate end = parse.atEndOfMonth(); diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceServiceImpl.java index 5c3f5b9e..0e160a73 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceServiceImpl.java @@ -1252,7 +1252,7 @@ public class BusAttendanceServiceImpl extends ServiceImpl