diff --git a/urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/costfee/CostFeeController.java b/urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/costfee/CostFeeController.java index c4ef24d..24d7c31 100644 --- a/urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/costfee/CostFeeController.java +++ b/urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/costfee/CostFeeController.java @@ -1,378 +1,378 @@ -package com.zteits.urbanops.module.garden.controller.admin.costfee; - -import com.zteits.urbanops.framework.common.pojo.CommonResult; -import com.zteits.urbanops.framework.excel.core.util.ExcelUtils; -import com.zteits.urbanops.module.garden.controller.admin.costfee.vo.WaterFeeImport; -import com.zteits.urbanops.module.garden.enums.TemplateEnum; -import com.zteits.urbanops.module.garden.service.costfee.CostFeeService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.servlet.http.HttpServletResponse; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.io.ClassPathResource; -import org.springframework.util.CollectionUtils; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.reflect.Method; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.*; - -import static com.zteits.urbanops.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST; -import static com.zteits.urbanops.framework.common.pojo.CommonResult.success; - -/** - * 人机材公共处理控制器 - * 处理Excel导入预览、提交等功能 - */ -@Tag(name = "管理后台 - 人机材批量导入") -@RestController -@RequestMapping("/costfee") -@Slf4j -public class CostFeeController{ - - @Autowired - private CostFeeService costFeeService; - - // 静态资源服务器基础URL(从配置文件读取) - @Value("${static.resource.server.url}") - private String staticResourceServerUrl; - - @Value("${static.resource.server.enable}") - private Boolean staticResourceServerenable; - - // Excel文件校验相关 - private static final List ALLOWED_EXCEL_SUFFIX = Arrays.asList(".xlsx", ".xlsm"); - private static final String EXCEL_MIME_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; - private static final String EXCEL_MIME_TYPE_XLS = "application/vnd.ms-excel"; - - /** - * 导入模板下载 - */ - @GetMapping("/get-import-template") - @Operation(summary = "获得导入用户模板") - public void importTemplate(HttpServletResponse response, - @RequestParam("templateName") String templateName) throws IOException { - // 参数校验 - if (templateName == null || templateName.trim().isEmpty()) { - response.sendError(HttpServletResponse.SC_BAD_REQUEST, "模板名称不能为空"); - return; - } - - // 模板类型校验 - TemplateEnum template = TemplateEnum.getByCode(templateName); - if (template == null) { - response.sendError(HttpServletResponse.SC_BAD_REQUEST, "未知的模板类型: " + templateName); - return; - } - - if (staticResourceServerenable) { - // 构建完整的静态服务器URL(确保路径正确) - String serverUrl = staticResourceServerUrl; - if (serverUrl != null && !serverUrl.endsWith("/")) { - serverUrl += "/"; // 确保URL以/结尾,避免拼接错误 - } - - String encodedFileName = URLEncoder.encode(template.getName().split("\\.")[0], StandardCharsets.UTF_8.name()); - - String templateFileName = encodedFileName + "." + template.getName().split("\\.")[1]; - - String templateUrl = serverUrl + templateFileName; // 包含templates目录 - - // 方式1:重定向到静态资源服务器 - response.sendRedirect(templateUrl); - } else { - String templateFileName = templateName + "." + template.getName().split("\\.")[1]; - - // 写入模板文件到响应 - writeTemplateToResponse(response, template.getName(), templateFileName); - } - } - - - /** - * Excel文件上传预览 - */ - @PostMapping("/preview") - @Operation(summary = "文件上传") - public CommonResult previewExcel(@RequestParam("file") MultipartFile file, - @RequestParam("templateName") String templateName) { - // 基础参数校验 - if (templateName == null || templateName.trim().isEmpty()) { - return CommonResult.error(BAD_REQUEST, "模板名称不能为空"); - - } - // 模板类型校验 - TemplateEnum template = TemplateEnum.getByCode(templateName); - if (template == null) { - return CommonResult.error(BAD_REQUEST, "未知的模板类型"); - } - String suffix = template.getName().split("\\.")[1]; - // 文件有效性校验 - if (!isValidExcelFile(file)) { - return CommonResult.error(BAD_REQUEST, "请上传有效的Excel文件"); - } - //部门信息缓存,校验正确性使用 - - - // 解析Excel并获取数据 - ImportResult result = parseExcelFile(file, template); - - // 需预览的数据存入Redis并返回批次ID - if (result.isNeedPreview()) { - if (CollectionUtils.isEmpty(result.getDataList())) { - return CommonResult.error(BAD_REQUEST, "导入的Excel文件不能为空"); - - } - String batchId = costFeeService.saveDataToRedis(result.getDataList(), templateName); - Map resultMap = new HashMap<>(2); - resultMap.put("batchId", batchId); - resultMap.put("totalCount", result.getDataList().size()); - resultMap.put("templateName",templateName); - return success(resultMap); - } - // 无需预览的直接返回数据 - return success(result.getDataList()); - } - - - /** - * 分页获取预览数据 - */ - @GetMapping("/preview-data") - @Operation(summary = "批量上传分页预览") - public CommonResult getPreviewData(@RequestParam("batchId") String batchId, - @RequestParam("templateName") String templateName, - @RequestParam(value = "page", defaultValue = "1") int page, - @RequestParam(value = "size", defaultValue = "100000") int size) { - - - // 参数校验 - if (batchId == null || batchId.trim().isEmpty()) { - return CommonResult.error(BAD_REQUEST, "批次ID不能为空"); - } - if (templateName == null || templateName.trim().isEmpty()) { - return CommonResult.error(BAD_REQUEST, "模板名称不能为空"); - - } - if (TemplateEnum.getByCode(templateName) == null) { - return CommonResult.error(BAD_REQUEST, "未知的模板类型"); - - } - try { - //if (page < 1 || size < 1 || size > 100) { // 限制每页最大100条,避免过大 - // return AjaxResult.error("分页参数无效(page≥1,1≤size≤100)"); - //} - - // 模板类型校验 - TemplateEnum template = TemplateEnum.getByCode(templateName); - Class importClass = template.getImportClass(); // 从枚举获取导入类,避免switch - - // 从Redis获取分页数据 - PageResult pageResult = costFeeService.getPagedDataFromRedis(batchId, templateName, page, size, importClass); - return CommonResult.success(pageResult); - } catch (Exception e) { - log.error("获取预览数据失败", e); - throw new RuntimeException(e); - } - } - - - /** - * 提交导入数据到数据库 - */ - @PostMapping("/submit") - @Operation(summary = "批次保存") - public CommonResult submitImport(@RequestParam("batchId") String batchId, - @RequestParam("templateName") String templateName, - @RequestParam("operator") String operator) { - // 参数校验 - if (batchId == null || batchId.trim().isEmpty()) { - return CommonResult.error(BAD_REQUEST, "批次ID不能为空"); - } - if (templateName == null || templateName.trim().isEmpty()) { - return CommonResult.error(BAD_REQUEST, "模板名称不能为空"); - - } - if (TemplateEnum.getByCode(templateName) == null) { - return CommonResult.error(BAD_REQUEST, "未知的模板类型"); - - } - if (operator == null || operator.trim().isEmpty()) { - return CommonResult.error(BAD_REQUEST, "操作人不能为空"); - } - int count = costFeeService.submitImport(batchId, templateName, operator); - return CommonResult.success("导入成功,共" + count + "条数据"); - } - - /** - * 写入模板文件到响应流 - */ - private void writeTemplateToResponse(HttpServletResponse response, String filename, String templatePath) throws IOException { - // 设置响应头 - response.setContentType(EXCEL_MIME_TYPE); - response.setCharacterEncoding("UTF-8"); - String encodedFileName = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+", "%20"); - response.setHeader("Content-Disposition", "attachment;filename=" + encodedFileName); - response.setHeader("Cache-Control", "no-store"); // 禁止缓存 - - // 读取模板文件并写入响应 - try (InputStream in = new ClassPathResource("template/" + templatePath).getInputStream(); - OutputStream out = response.getOutputStream()) { - - byte[] buffer = new byte[4096]; - int bytesRead; - while ((bytesRead = in.read(buffer)) != -1) { - out.write(buffer, 0, bytesRead); - } - out.flush(); - } - } - - - /** - * 校验Excel文件有效性(后缀+MIME类型) - */ - private boolean isValidExcelFile(MultipartFile file) { - if (file == null || file.isEmpty()) { - return false; - } - String fileName = file.getOriginalFilename(); - if (fileName == null) { - return false; - } - - // 校验文件后缀 - boolean validSuffix = ALLOWED_EXCEL_SUFFIX.stream() - .anyMatch(suffix -> fileName.toLowerCase().endsWith(suffix)); - if (!validSuffix) { - return false; - } - - // 4. 校验MIME类型(兼容可能带参数的MIME类型,如charset) - String contentType = file.getContentType(); - if (contentType == null) { - return false; - } - // 处理MIME类型可能带参数的情况(如"application/xxx;charset=UTF-8") - String baseContentType = contentType.split(";")[0].trim(); - // 3. 匹配预设的Excel MIME类型(.xlsx/.xlsm或.xls) - return EXCEL_MIME_TYPE.equals(baseContentType) - || baseContentType.startsWith(EXCEL_MIME_TYPE_XLS); - } - - - /** - * 解析Excel文件并返回导入结果 - */ - @SuppressWarnings("unchecked") - private ImportResult parseExcelFile(MultipartFile file, TemplateEnum template){ - // 获取模板对应的导入类 - Class importClass = (Class) template.getImportClass(); - List dataList = null; - try { - // 解析Excel(从指定行开始读取) - dataList = ExcelUtils.read(file, importClass, template.getStartIndex()); - if (dataList == null) { - dataList = Collections.emptyList(); - } - // 关键:移除最后一行(以“说明”开头的行) - removeLastLineIfStartWithExplain(dataList, importClass); - // 基础数据校验(非空、格式等) - costFeeService.validateImportData(dataList, template); - - } catch (IOException e) { - log.error(e.getMessage()); - } - return new ImportResult<>(dataList, template.isNeedPreview()); - } - /** - * 移除列表最后一行(若该行第一列内容以“说明”开头) - * @param dataList Excel解析后的实体类列表 - * @param clazz 实体类字节码(用于反射获取第一列字段值) - * @param 泛型:Excel对应的实体类 - */ - private void removeLastLineIfStartWithExplain(List dataList, Class clazz) { - // 1. 跳过空列表/元素数<1的情况,避免索引越界 - if (CollectionUtils.isEmpty(dataList)) { - return; - } - - // 2. 获取最后一个元素(正确索引:size()-1) - T lastItem = dataList.get(dataList.size() - 1); - if (Objects.isNull(lastItem)) { - return; - } - - // 3. 反射获取「第一列字段的值」(核心:Excel列对应实体类的字段,假设第一列字段名是 firstColumn,需根据实际调整) - String firstColumnValue = getFirstColumnValue(lastItem, clazz); - if (Objects.isNull(firstColumnValue)) { - return; - } - - // 4. 匹配“说明”(trim() 避免空格干扰,如“ 说明:xxx”) - if (firstColumnValue.trim().startsWith("说明")) { - // 移除最后一个元素(正确索引:size()-1) - dataList.remove(dataList.size() - 1); - } - } - - /** - * 反射获取实体类的「第一列字段值」(需根据你的Excel列配置调整字段名) - * @param item 实体类对象(Excel一行数据) - * @param clazz 实体类字节码 - * @return 第一列的字符串值(null 表示无值) - */ - private String getFirstColumnValue(T item, Class clazz) { - try { - String firstColumnFieldName = ""; - if (WaterFeeImport.class.isAssignableFrom(clazz)) { - firstColumnFieldName = "feeMonth"; - } else { - return null; - } - - // 反射获取 getter 方法() - String getterMethodName = "get" + firstColumnFieldName.substring(0, 1).toUpperCase() + firstColumnFieldName.substring(1); - Method getterMethod = clazz.getDeclaredMethod(getterMethodName); - - // 执行 getter 方法获取字段值 - Object value = getterMethod.invoke(item); - return value == null ? null : value.toString(); - } catch (Exception e) { - // 反射失败(字段名错误、无getter方法),打印日志不抛异常,避免影响整体流程 - log.warn("获取Excel第一列字段值失败,实体类:{}", clazz.getName(), e); - return null; - } - } - - /** - * 导入结果封装 - */ - @Data - @AllArgsConstructor - private static class ImportResult { - private List dataList; - private boolean needPreview; - } - - /** - * 分页结果封装 - */ - @Data - @AllArgsConstructor - public static class PageResult { - private int page; - private int size; - private int total; - private List data; - } -} +//package com.zteits.urbanops.module.garden.controller.admin.costfee; +// +//import com.zteits.urbanops.framework.common.pojo.CommonResult; +//import com.zteits.urbanops.framework.excel.core.util.ExcelUtils; +//import com.zteits.urbanops.module.garden.controller.admin.costfee.vo.WaterFeeImport; +//import com.zteits.urbanops.module.garden.enums.TemplateEnum; +//import com.zteits.urbanops.module.garden.service.costfee.CostFeeService; +//import io.swagger.v3.oas.annotations.Operation; +//import io.swagger.v3.oas.annotations.tags.Tag; +//import jakarta.servlet.http.HttpServletResponse; +//import lombok.AllArgsConstructor; +//import lombok.Data; +//import lombok.extern.slf4j.Slf4j; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.core.io.ClassPathResource; +//import org.springframework.util.CollectionUtils; +//import org.springframework.web.bind.annotation.*; +//import org.springframework.web.multipart.MultipartFile; +// +//import java.io.IOException; +//import java.io.InputStream; +//import java.io.OutputStream; +//import java.lang.reflect.Method; +//import java.net.URLEncoder; +//import java.nio.charset.StandardCharsets; +//import java.util.*; +// +//import static com.zteits.urbanops.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST; +//import static com.zteits.urbanops.framework.common.pojo.CommonResult.success; +// +///** +// * 人机材公共处理控制器 +// * 处理Excel导入预览、提交等功能 +// */ +//@Tag(name = "管理后台 - 人机材批量导入") +//@RestController +//@RequestMapping("/costfee") +//@Slf4j +//public class CostFeeController{ +// +// @Autowired +// private CostFeeService costFeeService; +// +// // 静态资源服务器基础URL(从配置文件读取) +// @Value("${static.resource.server.url}") +// private String staticResourceServerUrl; +// +// @Value("${static.resource.server.enable}") +// private Boolean staticResourceServerenable; +// +// // Excel文件校验相关 +// private static final List ALLOWED_EXCEL_SUFFIX = Arrays.asList(".xlsx", ".xlsm"); +// private static final String EXCEL_MIME_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; +// private static final String EXCEL_MIME_TYPE_XLS = "application/vnd.ms-excel"; +// +// /** +// * 导入模板下载 +// */ +// @GetMapping("/get-import-template") +// @Operation(summary = "获得导入用户模板") +// public void importTemplate(HttpServletResponse response, +// @RequestParam("templateName") String templateName) throws IOException { +// // 参数校验 +// if (templateName == null || templateName.trim().isEmpty()) { +// response.sendError(HttpServletResponse.SC_BAD_REQUEST, "模板名称不能为空"); +// return; +// } +// +// // 模板类型校验 +// TemplateEnum template = TemplateEnum.getByCode(templateName); +// if (template == null) { +// response.sendError(HttpServletResponse.SC_BAD_REQUEST, "未知的模板类型: " + templateName); +// return; +// } +// +// if (staticResourceServerenable) { +// // 构建完整的静态服务器URL(确保路径正确) +// String serverUrl = staticResourceServerUrl; +// if (serverUrl != null && !serverUrl.endsWith("/")) { +// serverUrl += "/"; // 确保URL以/结尾,避免拼接错误 +// } +// +// String encodedFileName = URLEncoder.encode(template.getName().split("\\.")[0], StandardCharsets.UTF_8.name()); +// +// String templateFileName = encodedFileName + "." + template.getName().split("\\.")[1]; +// +// String templateUrl = serverUrl + templateFileName; // 包含templates目录 +// +// // 方式1:重定向到静态资源服务器 +// response.sendRedirect(templateUrl); +// } else { +// String templateFileName = templateName + "." + template.getName().split("\\.")[1]; +// +// // 写入模板文件到响应 +// writeTemplateToResponse(response, template.getName(), templateFileName); +// } +// } +// +// +// /** +// * Excel文件上传预览 +// */ +// @PostMapping("/preview") +// @Operation(summary = "文件上传") +// public CommonResult previewExcel(@RequestParam("file") MultipartFile file, +// @RequestParam("templateName") String templateName) { +// // 基础参数校验 +// if (templateName == null || templateName.trim().isEmpty()) { +// return CommonResult.error(BAD_REQUEST, "模板名称不能为空"); +// +// } +// // 模板类型校验 +// TemplateEnum template = TemplateEnum.getByCode(templateName); +// if (template == null) { +// return CommonResult.error(BAD_REQUEST, "未知的模板类型"); +// } +// String suffix = template.getName().split("\\.")[1]; +// // 文件有效性校验 +// if (!isValidExcelFile(file)) { +// return CommonResult.error(BAD_REQUEST, "请上传有效的Excel文件"); +// } +// //部门信息缓存,校验正确性使用 +// +// +// // 解析Excel并获取数据 +// ImportResult result = parseExcelFile(file, template); +// +// // 需预览的数据存入Redis并返回批次ID +// if (result.isNeedPreview()) { +// if (CollectionUtils.isEmpty(result.getDataList())) { +// return CommonResult.error(BAD_REQUEST, "导入的Excel文件不能为空"); +// +// } +// String batchId = costFeeService.saveDataToRedis(result.getDataList(), templateName); +// Map resultMap = new HashMap<>(2); +// resultMap.put("batchId", batchId); +// resultMap.put("totalCount", result.getDataList().size()); +// resultMap.put("templateName",templateName); +// return success(resultMap); +// } +// // 无需预览的直接返回数据 +// return success(result.getDataList()); +// } +// +// +// /** +// * 分页获取预览数据 +// */ +// @GetMapping("/preview-data") +// @Operation(summary = "批量上传分页预览") +// public CommonResult getPreviewData(@RequestParam("batchId") String batchId, +// @RequestParam("templateName") String templateName, +// @RequestParam(value = "page", defaultValue = "1") int page, +// @RequestParam(value = "size", defaultValue = "100000") int size) { +// +// +// // 参数校验 +// if (batchId == null || batchId.trim().isEmpty()) { +// return CommonResult.error(BAD_REQUEST, "批次ID不能为空"); +// } +// if (templateName == null || templateName.trim().isEmpty()) { +// return CommonResult.error(BAD_REQUEST, "模板名称不能为空"); +// +// } +// if (TemplateEnum.getByCode(templateName) == null) { +// return CommonResult.error(BAD_REQUEST, "未知的模板类型"); +// +// } +// try { +// //if (page < 1 || size < 1 || size > 100) { // 限制每页最大100条,避免过大 +// // return AjaxResult.error("分页参数无效(page≥1,1≤size≤100)"); +// //} +// +// // 模板类型校验 +// TemplateEnum template = TemplateEnum.getByCode(templateName); +// Class importClass = template.getImportClass(); // 从枚举获取导入类,避免switch +// +// // 从Redis获取分页数据 +// PageResult pageResult = costFeeService.getPagedDataFromRedis(batchId, templateName, page, size, importClass); +// return CommonResult.success(pageResult); +// } catch (Exception e) { +// log.error("获取预览数据失败", e); +// throw new RuntimeException(e); +// } +// } +// +// +// /** +// * 提交导入数据到数据库 +// */ +// @PostMapping("/submit") +// @Operation(summary = "批次保存") +// public CommonResult submitImport(@RequestParam("batchId") String batchId, +// @RequestParam("templateName") String templateName, +// @RequestParam("operator") String operator) { +// // 参数校验 +// if (batchId == null || batchId.trim().isEmpty()) { +// return CommonResult.error(BAD_REQUEST, "批次ID不能为空"); +// } +// if (templateName == null || templateName.trim().isEmpty()) { +// return CommonResult.error(BAD_REQUEST, "模板名称不能为空"); +// +// } +// if (TemplateEnum.getByCode(templateName) == null) { +// return CommonResult.error(BAD_REQUEST, "未知的模板类型"); +// +// } +// if (operator == null || operator.trim().isEmpty()) { +// return CommonResult.error(BAD_REQUEST, "操作人不能为空"); +// } +// int count = costFeeService.submitImport(batchId, templateName, operator); +// return CommonResult.success("导入成功,共" + count + "条数据"); +// } +// +// /** +// * 写入模板文件到响应流 +// */ +// private void writeTemplateToResponse(HttpServletResponse response, String filename, String templatePath) throws IOException { +// // 设置响应头 +// response.setContentType(EXCEL_MIME_TYPE); +// response.setCharacterEncoding("UTF-8"); +// String encodedFileName = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+", "%20"); +// response.setHeader("Content-Disposition", "attachment;filename=" + encodedFileName); +// response.setHeader("Cache-Control", "no-store"); // 禁止缓存 +// +// // 读取模板文件并写入响应 +// try (InputStream in = new ClassPathResource("template/" + templatePath).getInputStream(); +// OutputStream out = response.getOutputStream()) { +// +// byte[] buffer = new byte[4096]; +// int bytesRead; +// while ((bytesRead = in.read(buffer)) != -1) { +// out.write(buffer, 0, bytesRead); +// } +// out.flush(); +// } +// } +// +// +// /** +// * 校验Excel文件有效性(后缀+MIME类型) +// */ +// private boolean isValidExcelFile(MultipartFile file) { +// if (file == null || file.isEmpty()) { +// return false; +// } +// String fileName = file.getOriginalFilename(); +// if (fileName == null) { +// return false; +// } +// +// // 校验文件后缀 +// boolean validSuffix = ALLOWED_EXCEL_SUFFIX.stream() +// .anyMatch(suffix -> fileName.toLowerCase().endsWith(suffix)); +// if (!validSuffix) { +// return false; +// } +// +// // 4. 校验MIME类型(兼容可能带参数的MIME类型,如charset) +// String contentType = file.getContentType(); +// if (contentType == null) { +// return false; +// } +// // 处理MIME类型可能带参数的情况(如"application/xxx;charset=UTF-8") +// String baseContentType = contentType.split(";")[0].trim(); +// // 3. 匹配预设的Excel MIME类型(.xlsx/.xlsm或.xls) +// return EXCEL_MIME_TYPE.equals(baseContentType) +// || baseContentType.startsWith(EXCEL_MIME_TYPE_XLS); +// } +// +// +// /** +// * 解析Excel文件并返回导入结果 +// */ +// @SuppressWarnings("unchecked") +// private ImportResult parseExcelFile(MultipartFile file, TemplateEnum template){ +// // 获取模板对应的导入类 +// Class importClass = (Class) template.getImportClass(); +// List dataList = null; +// try { +// // 解析Excel(从指定行开始读取) +// dataList = ExcelUtils.read(file, importClass, template.getStartIndex()); +// if (dataList == null) { +// dataList = Collections.emptyList(); +// } +// // 关键:移除最后一行(以“说明”开头的行) +// removeLastLineIfStartWithExplain(dataList, importClass); +// // 基础数据校验(非空、格式等) +// costFeeService.validateImportData(dataList, template); +// +// } catch (IOException e) { +// log.error(e.getMessage()); +// } +// return new ImportResult<>(dataList, template.isNeedPreview()); +// } +// /** +// * 移除列表最后一行(若该行第一列内容以“说明”开头) +// * @param dataList Excel解析后的实体类列表 +// * @param clazz 实体类字节码(用于反射获取第一列字段值) +// * @param 泛型:Excel对应的实体类 +// */ +// private void removeLastLineIfStartWithExplain(List dataList, Class clazz) { +// // 1. 跳过空列表/元素数<1的情况,避免索引越界 +// if (CollectionUtils.isEmpty(dataList)) { +// return; +// } +// +// // 2. 获取最后一个元素(正确索引:size()-1) +// T lastItem = dataList.get(dataList.size() - 1); +// if (Objects.isNull(lastItem)) { +// return; +// } +// +// // 3. 反射获取「第一列字段的值」(核心:Excel列对应实体类的字段,假设第一列字段名是 firstColumn,需根据实际调整) +// String firstColumnValue = getFirstColumnValue(lastItem, clazz); +// if (Objects.isNull(firstColumnValue)) { +// return; +// } +// +// // 4. 匹配“说明”(trim() 避免空格干扰,如“ 说明:xxx”) +// if (firstColumnValue.trim().startsWith("说明")) { +// // 移除最后一个元素(正确索引:size()-1) +// dataList.remove(dataList.size() - 1); +// } +// } +// +// /** +// * 反射获取实体类的「第一列字段值」(需根据你的Excel列配置调整字段名) +// * @param item 实体类对象(Excel一行数据) +// * @param clazz 实体类字节码 +// * @return 第一列的字符串值(null 表示无值) +// */ +// private String getFirstColumnValue(T item, Class clazz) { +// try { +// String firstColumnFieldName = ""; +// if (WaterFeeImport.class.isAssignableFrom(clazz)) { +// firstColumnFieldName = "feeMonth"; +// } else { +// return null; +// } +// +// // 反射获取 getter 方法() +// String getterMethodName = "get" + firstColumnFieldName.substring(0, 1).toUpperCase() + firstColumnFieldName.substring(1); +// Method getterMethod = clazz.getDeclaredMethod(getterMethodName); +// +// // 执行 getter 方法获取字段值 +// Object value = getterMethod.invoke(item); +// return value == null ? null : value.toString(); +// } catch (Exception e) { +// // 反射失败(字段名错误、无getter方法),打印日志不抛异常,避免影响整体流程 +// log.warn("获取Excel第一列字段值失败,实体类:{}", clazz.getName(), e); +// return null; +// } +// } +// +// /** +// * 导入结果封装 +// */ +// @Data +// @AllArgsConstructor +// private static class ImportResult { +// private List dataList; +// private boolean needPreview; +// } +// +// /** +// * 分页结果封装 +// */ +// @Data +// @AllArgsConstructor +// public static class PageResult { +// private int page; +// private int size; +// private int total; +// private List data; +// } +//} diff --git a/urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/costfee/CostFeeService.java b/urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/costfee/CostFeeService.java index f106863..cd6cf6e 100644 --- a/urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/costfee/CostFeeService.java +++ b/urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/costfee/CostFeeService.java @@ -1,64 +1,64 @@ -package com.zteits.urbanops.module.garden.service.costfee; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.zteits.urbanops.module.garden.controller.admin.costfee.CostFeeController; -import com.zteits.urbanops.module.garden.enums.TemplateEnum; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -/** - * @Classname ICostFeeService - * @Description 模板导入公共接口 - * @Date 2025/7/20 15:10 - * @Created by wangqian - */ -public interface CostFeeService { - - /** - * @Author wangqian - * @Description 导入数据保存redis - * @Date 2025/7/20 15:36 - * @Param dataList - * @param templateName - * @Return java.lang.String - */ - public String saveDataToRedis(List dataList, String templateName); - - /** - * @Author wangqian - * @Description 导入数据保存到数据库 - * @Date 2025/7/20 15:36 - * @Param batchId - * @param templateName - * @param operator - * @Return int - */ - public int submitImport(String batchId, String templateName, String operator); - - /** - * @Author wangqian - * @Description 预览分页查询 - * @Date 2025/7/20 15:36 - * @Param batchId - * @param templateName - * @param page - * @param size - * @param clazz - * @Return com.servicemanager.project.costfee.controller.CostFeeController.PageResult - */ - public CostFeeController.PageResult getPagedDataFromRedis(String batchId, String templateName, - int page, int size, Class clazz) throws IOException; - - /** - * @Author wangqian - * @Description 导入内容校验 - * @Date 2025/11/24 8:40 - * @Param dataList - * @param template - * @Return void - */ - public void validateImportData(List dataList, TemplateEnum template); - -} +//package com.zteits.urbanops.module.garden.service.costfee; +// +//import com.fasterxml.jackson.core.JsonProcessingException; +//import com.zteits.urbanops.module.garden.controller.admin.costfee.CostFeeController; +//import com.zteits.urbanops.module.garden.enums.TemplateEnum; +// +//import java.io.IOException; +//import java.util.List; +//import java.util.Map; +// +///** +// * @Classname ICostFeeService +// * @Description 模板导入公共接口 +// * @Date 2025/7/20 15:10 +// * @Created by wangqian +// */ +//public interface CostFeeService { +// +// /** +// * @Author wangqian +// * @Description 导入数据保存redis +// * @Date 2025/7/20 15:36 +// * @Param dataList +// * @param templateName +// * @Return java.lang.String +// */ +// public String saveDataToRedis(List dataList, String templateName); +// +// /** +// * @Author wangqian +// * @Description 导入数据保存到数据库 +// * @Date 2025/7/20 15:36 +// * @Param batchId +// * @param templateName +// * @param operator +// * @Return int +// */ +// public int submitImport(String batchId, String templateName, String operator); +// +// /** +// * @Author wangqian +// * @Description 预览分页查询 +// * @Date 2025/7/20 15:36 +// * @Param batchId +// * @param templateName +// * @param page +// * @param size +// * @param clazz +// * @Return com.servicemanager.project.costfee.controller.CostFeeController.PageResult +// */ +// public CostFeeController.PageResult getPagedDataFromRedis(String batchId, String templateName, +// int page, int size, Class clazz) throws IOException; +// +// /** +// * @Author wangqian +// * @Description 导入内容校验 +// * @Date 2025/11/24 8:40 +// * @Param dataList +// * @param template +// * @Return void +// */ +// public void validateImportData(List dataList, TemplateEnum template); +// +//}