package com.example.demo.serviceImpl; import cn.hutool.log.AbstractLog; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.write.metadata.WriteSheet; import com.example.demo.Util.ExcelUploadUtil; import com.example.demo.Util.ExecutionContextUtil; import com.example.demo.Util.JWTUtil; import com.example.demo.controller.ConsumeController; import com.example.demo.controller.GoldDetailController; import com.example.demo.controller.RechargeController; import com.example.demo.controller.RefundController; import com.example.demo.domain.entity.Admin; import com.example.demo.domain.entity.Export; import com.example.demo.domain.entity.User; import com.example.demo.domain.export.Goldmingxi; import com.example.demo.domain.vo.*; import com.example.demo.mapper.ExportMapper; import com.example.demo.service.ExportExcelService; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.example.demo.service.AiEmotionService; import com.github.pagehelper.PageInfo; import jakarta.servlet.http.HttpServletRequest; 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.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.*; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.List; @Service @Slf4j public class ExportExcelServiceImpl implements ExportExcelService { private static final ObjectMapper objectMapper = new ObjectMapper(); @Value("${file.upload.url}") private String uploadUrl; //注入AiEmotionService @Autowired private AiEmotionService aiEmotionService; //注入GoldDetailController @Autowired private GoldDetailController goldDetailController; @Autowired private RechargeController rechargeController; @Autowired private RefundController refundController; @Autowired private ConsumeController consumeController; @Autowired private AuthenticationManager authenticationManager; // 每页查询的数据量 private static final int PAGE_SIZE = 1000; @Autowired private ExportMapper exportMapper; @Transactional @Override public Exception handleExcelExportData(String message) throws Exception { System.out.println("明细导出excel数据开始执行:" + message); long sTime = System.currentTimeMillis(); Long recordId = null; String fileName = null; File tempFile = null; OutputStream outputStream = null; ExcelWriter excelWriter = null; try { // 1. 解析JSON任务 JsonNode rootNode = objectMapper.readTree(message); // 2. 获取基本参数 recordId = rootNode.path("recordId").asLong(); JsonNode requestDataNode = rootNode.path("requestData"); JsonNode token = requestDataNode.path("token"); String tokenValue = token.asText(); JsonNode goldDetailNode = requestDataNode.path("goldDetail"); GoldDetail goldDetail = objectMapper.treeToValue(goldDetailNode, GoldDetail.class); // 3. 验证导出记录 AiEmotionExportRecordVO record = validateExportRecord(recordId); if (record == null) return null; //4. 更新状态为处理中 aiEmotionService.updateStatus(recordId, 1, "", "", 0); // 5. 准备Excel文件 fileName = record.getFileName(); // 初始化临时文件(保存到本地临时目录) tempFile = File.createTempFile("export_", ".xlsx"); outputStream = new FileOutputStream(tempFile); // 使用文件输出流 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 从JSON中提取单个值 Date startTime = null; if (goldDetailNode.has("startTime") && goldDetailNode.get("startTime") != null) { String startTimeStr = goldDetailNode.get("startTime").asText(); if (!"null".equalsIgnoreCase(startTimeStr) && !startTimeStr.trim().isEmpty()) { try { startTime = dateFormat.parse(startTimeStr); } catch (ParseException e) { System.err.println("无法解析 startTime: " + startTimeStr); e.printStackTrace(); } } } // 解析 endTime Date endTime = null; if (goldDetailNode.has("endTime") && goldDetailNode.get("endTime") != null) { String endTimeStr = goldDetailNode.get("endTime").asText(); if (!"null".equalsIgnoreCase(endTimeStr) && !endTimeStr.trim().isEmpty()) { try { endTime = dateFormat.parse(endTimeStr); } catch (ParseException e) { System.err.println("无法解析 endTime: " + endTimeStr); e.printStackTrace(); } } } try { // 6. 初始化Excel写入器(指向本地文件流) excelWriter = EasyExcel.write(outputStream, GoldDetail.class).build(); WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build(); // 7. 分页查询并写入数据 Page page = new Page(); page.setGoldDetail(goldDetail); if(goldDetail.getMarkets()==null||goldDetail.getMarkets().isEmpty()){ Admin admin = (Admin) JWTUtil.getUserDetailsList(String.valueOf(tokenValue), Admin.class); List markets = Arrays.asList(StringUtils.split(admin.getMarkets(), ",")); if(!markets.contains("总部")) { page.getGoldDetail().setMarkets(markets); } } page.setPageNum(1); page.setPageSize(5000); Integer totalCount = 0; boolean hasMore = true; while (hasMore) { Result pageResult = goldDetailController.ExcelGoldDetail(page); Integer code = pageResult.getCode(); Object data = pageResult.getData(); if (code == 200) { // 判断 data 是否是 PageInfo 类型 if (!(data instanceof PageInfo)) { log.error("返回数据类型错误,期望 PageInfo,实际为:{}", data.getClass()); hasMore = false; continue; } @SuppressWarnings("unchecked") PageInfo pageInfo = (PageInfo) data; Long total = (long) pageInfo.getTotal(); // 转换为 long List list = pageInfo.getList(); if (list == null || list.isEmpty()) { hasMore = false; } else { // 写入 Excel 数据 excelWriter.write(list, writeSheet); page.setPageNum(page.getPageNum() + 1); totalCount += list.size(); log.info("导出进度 recordId: {}, 已处理: {}条", recordId, totalCount); hasMore = totalCount < total; } } else { hasMore = false; log.error("获取数据失败,状态码: {}", code); } } // 7. 完成Excel写入(所有数据写入后关闭写入器) if (excelWriter != null) { excelWriter.finish(); } if (outputStream != null) { outputStream.flush(); // 确保所有数据写入 outputStream.close(); // 关闭文件流 } // 检查文件是否存在且不为空 if (tempFile != null && tempFile.exists() && tempFile.length() > 0) { // 8. 上传到OSS(读取本地临时文件) // 获取接口的基础 URL String uploadUrl = this.uploadUrl; try { // 1. 创建上传工具实例 ExcelUploadUtil uploadUtil = new ExcelUploadUtil(uploadUrl); // 2. 准备要上传的文件 File excelFile = new File(tempFile.toURI()); try { // 3. 执行上传 String result = uploadUtil.uploadExcel(excelFile, "export/excel/"); // 1. 解析JSON任务 // JsonNode uploadResult = objectMapper.readTree(result); // System.out.println(uploadResult+"11111111111111111111111"); // long code = uploadResult.path("code").asLong(); // String url = String.valueOf(uploadResult.path("data")); // url = url.replace("\"", ""); // if (code == 1) { // // 3. 验证导出记录decodecode // aiEmotionService.updateStatus(recordId, 2, url, "", totalCount); // } else { // //更新失败 // aiEmotionService.updateStatus(recordId, 3, "", url, 0); // } JsonNode uploadResult = objectMapper.readTree(result); long code = uploadResult.path("code").asLong(); String fileUrl = ""; JsonNode dataNode = uploadResult.path("data"); if (dataNode.isObject()) { fileUrl = dataNode.path("url").asText(); } else if (dataNode.isTextual()) { fileUrl = dataNode.asText(); // 如果 data 是直接字符串 URL } log.info("解析到的URL: {}", fileUrl); if (code == 200 && !fileUrl.isEmpty()) { aiEmotionService.updateStatus(recordId, 2, fileUrl, "", totalCount); } else { aiEmotionService.updateStatus(recordId, 3, "", "上传成功但URL为空或解析失败", 0); } } catch (Exception e) { //更新失败 aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); throw new Exception("文件上传云端失败1", e); } } catch (Exception e) { log.error("上传文件失败 recordId: {}, 文件名: {}", recordId, fileName, e); //更新状态为失败 if (recordId != null) { aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); } throw new Exception("文件上传云端失败2", e); } } else { throw new Exception("导出的Excel文件不存在或为空"); } } catch (Exception e) { System.out.println("导出异常" + e.getMessage()); log.error("导出任务处理失败 recordId: {}", recordId, e); // 更新状态为失败 if (recordId != null) { aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); } throw new Exception("导出异常", e); } finally { // 确保资源被关闭 try { if (excelWriter != null) { excelWriter.finish(); } if (outputStream != null) { outputStream.close(); } } catch (Exception e) { log.error("关闭资源失败", e); throw new Exception("excel文件关闭资源失败", e); } } } catch (Exception e) { log.error("导出任务处理失败 recordId: {}", recordId, e); // 更新状态为失败 if (recordId != null) { aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); } System.out.println("<导出失败>" + e.getMessage()); throw new Exception("导出任务处理失败", e); } finally { // 清理临时文件 if (tempFile != null && tempFile.exists()) { try { if (tempFile.delete()) { log.info("临时文件已删除: {}", tempFile.getAbsolutePath()); } else { log.warn("无法删除临时文件: {}", tempFile.getAbsolutePath()); } } catch (Exception e) { log.error("删除临时文件失败", e.getMessage()); throw new Exception("删除临时文件失败", e); } } long eTime = System.currentTimeMillis(); log.info("导出任务完成,耗时: {}毫秒", (eTime - sTime)); } return null; } @Transactional @Override public Exception handleExcel(String message) throws Exception { System.out.println("明细导出excel数据开始执行:" + message); long stTime = System.currentTimeMillis(); Long recordId = null; String fileName = null; File tempFile = null; OutputStream outputStream = null; ExcelWriter excelWriter = null; try { // 1. 解析JSON任务 JsonNode rootNode = objectMapper.readTree(message); // 2. 获取基本参数 recordId = rootNode.path("recordId").asLong(); JsonNode requestDataNode = rootNode.path("requestData"); JsonNode token = requestDataNode.path("token"); String tokenValue = token.asText(); JsonNode userNode = requestDataNode.path("user"); User user = objectMapper.treeToValue(userNode, User.class); // 3. 验证导出记录 AiEmotionExportRecordVO record = validateExportRecord(recordId); if (record == null) return null; //4. 更新状态为处理中 aiEmotionService.updateStatus(recordId, 1, "", "", 0); // 5. 准备Excel文件 fileName = record.getFileName(); // 初始化临时文件(保存到本地临时目录) tempFile = File.createTempFile("export_", ".xlsx"); outputStream = new FileOutputStream(tempFile); // 使用文件输出流 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 从JSON中提取单个值 // String text = requestDataNode.has("text") ? requestDataNode.get("text").asText() : null; // Integer sort = requestDataNode.has("sort") ? requestDataNode.get("sort").asInt() : null; // String field = requestDataNode.has("field") ? requestDataNode.get("field").asText() : null; // String deptId = requestDataNode.has("deptId") ? requestDataNode.get("deptId").asText() : null; Date startTime = null; if (userNode.has("startTime") && userNode.get("startTime") != null) { String startTimeStr = userNode.get("startTime").asText(); if (!"null".equalsIgnoreCase(startTimeStr) && !startTimeStr.trim().isEmpty()) { try { startTime = dateFormat.parse(startTimeStr); } catch (ParseException e) { System.err.println("无法解析 startTime: " + startTimeStr); e.printStackTrace(); } } } // 解析 endTime Date endTime = null; if (userNode.has("endTime") && userNode.get("endTime") != null) { String endTimeStr = userNode.get("endTime").asText(); if (!"null".equalsIgnoreCase(endTimeStr) && !endTimeStr.trim().isEmpty()) { try { endTime = dateFormat.parse(endTimeStr); } catch (ParseException e) { System.err.println("无法解析 endTime: " + endTimeStr); e.printStackTrace(); } } } try { // 6. 初始化Excel写入器(指向本地文件流) excelWriter = EasyExcel.write(outputStream, User.class).build(); WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build(); // 7. 分页查询并写入数据 Page page = new Page(); page.setUser(user); if(user.getMarkets()==null||user.getMarkets().isEmpty()){ Admin admin = (Admin) JWTUtil.getUserDetailsList(String.valueOf(tokenValue), Admin.class); List markets = Arrays.asList(StringUtils.split(admin.getMarkets(), ",")); if(!markets.contains("总部")) { page.getUser().setMarkets(markets); } } page.setPageNum(1); page.setPageSize(5000); Integer totalCount = 0; boolean hasMore = true; while (hasMore) { Result pageResult = goldDetailController.ExcelGold(page); Integer code = pageResult.getCode(); Object data = pageResult.getData(); if (code == 200) { // 判断 data 是否是 PageInfo 类型 if (!(data instanceof PageInfo)) { log.error("返回数据类型错误,期望 PageInfo,实际为:{}", data.getClass()); hasMore = false; continue; } @SuppressWarnings("unchecked") PageInfo pageInfo = (PageInfo) data; Long total = (long) pageInfo.getTotal(); // 转换为 long List list = pageInfo.getList(); if (list == null || list.isEmpty()) { hasMore = false; } else { // 写入 Excel 数据 excelWriter.write(list, writeSheet); page.setPageNum(page.getPageNum() + 1); totalCount += list.size(); log.info("导出进度 recordId: {}, 已处理: {}条", recordId, totalCount); hasMore = totalCount < total; } } else { hasMore = false; log.error("获取数据失败,状态码: {}", code); } } // 7. 完成Excel写入(所有数据写入后关闭写入器) if (excelWriter != null) { excelWriter.finish(); } if (outputStream != null) { outputStream.flush(); // 确保所有数据写入 outputStream.close(); // 关闭文件流 } // 检查文件是否存在且不为空 if (tempFile != null && tempFile.exists() && tempFile.length() > 0) { // 8. 上传到OSS(读取本地临时文件) // 获取接口的基础 URL String uploadUrl = this.uploadUrl; try { // 1. 创建上传工具实例 ExcelUploadUtil uploadUtil = new ExcelUploadUtil(uploadUrl); // 2. 准备要上传的文件 File excelFile = new File(tempFile.toURI()); try { // 3. 执行上传 String result = uploadUtil.uploadExcel(excelFile, "export/excel/"); // 1. 解析JSON任务 // JsonNode uploadResult = objectMapper.readTree(result); // System.out.println(uploadResult+"11111111111111111111111"); // long code = uploadResult.path("code").asLong(); // String url = String.valueOf(uploadResult.path("data")); // url = url.replace("\"", ""); // if (code == 1) { // // 3. 验证导出记录decodecode // aiEmotionService.updateStatus(recordId, 2, url, "", totalCount); // } else { // //更新失败 // aiEmotionService.updateStatus(recordId, 3, "", url, 0); // } JsonNode uploadResult = objectMapper.readTree(result); long code = uploadResult.path("code").asLong(); String fileUrl = ""; JsonNode dataNode = uploadResult.path("data"); if (dataNode.isObject()) { fileUrl = dataNode.path("url").asText(); } else if (dataNode.isTextual()) { fileUrl = dataNode.asText(); // 如果 data 是直接字符串 URL } log.info("解析到的URL: {}", fileUrl); if (code == 200 && !fileUrl.isEmpty()) { aiEmotionService.updateStatus(recordId, 2, fileUrl, "", totalCount); } else { aiEmotionService.updateStatus(recordId, 3, "", "上传成功但URL为空或解析失败", 0); } } catch (Exception e) { //更新失败 aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); throw new Exception("文件上传云端失败1", e); } } catch (Exception e) { log.error("上传文件失败 recordId: {}, 文件名: {}", recordId, fileName, e); //更新状态为失败 if (recordId != null) { aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); } throw new Exception("文件上传云端失败2", e); } } else { throw new Exception("导出的Excel文件不存在或为空"); } } catch (Exception e) { System.out.println("导出异常" + e.getMessage()); log.error("导出任务处理失败 recordId: {}", recordId, e); // 更新状态为失败 if (recordId != null) { aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); } throw new Exception("导出异常", e); } finally { // 确保资源被关闭 try { if (excelWriter != null) { excelWriter.finish(); } if (outputStream != null) { outputStream.close(); } } catch (Exception e) { log.error("关闭资源失败", e); throw new Exception("excel文件关闭资源失败", e); } } } catch (Exception e) { log.error("导出任务处理失败 recordId: {}", recordId, e); // 更新状态为失败 if (recordId != null) { aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); } System.out.println("<导出失败>" + e.getMessage()); throw new Exception("导出任务处理失败", e); } finally { // 清理临时文件 if (tempFile != null && tempFile.exists()) { try { if (tempFile.delete()) { log.info("临时文件已删除: {}", tempFile.getAbsolutePath()); } else { log.warn("无法删除临时文件: {}", tempFile.getAbsolutePath()); } } catch (Exception e) { log.error("删除临时文件失败", e.getMessage()); throw new Exception("删除临时文件失败", e); } } long eTime = System.currentTimeMillis(); log.info("导出任务完成,耗时: {}毫秒", (eTime - stTime)); } return null; } @Transactional @Override public Exception rechargeExcel(String message) throws Exception { System.out.println("明细导出excel数据开始执行:" + message); long startTime = System.currentTimeMillis(); Long recordId = null; String fileName = null; String token = null; File tempFile = null; OutputStream outputStream = null; ExcelWriter excelWriter = null; try { // 1. 解析JSON任务 JsonNode rootNode = objectMapper.readTree(message); // 2. 获取基本参数 recordId = rootNode.path("recordId").asLong(); token = rootNode.path("token").asText(); JsonNode requestDataNode = rootNode.path("requestData"); JsonNode rechargeNode = requestDataNode.path("rechargeUser"); RechargeUser rechargeUser = objectMapper.treeToValue(rechargeNode, RechargeUser.class); // 3. 验证导出记录 AiEmotionExportRecordVO record = validateExportRecord(recordId); if (record == null) return null; //4. 更新状态为处理中 aiEmotionService.updateStatus(recordId, 1, "", "", 0); // 5. 准备Excel文件 fileName = record.getFileName(); // 初始化临时文件(保存到本地临时目录) tempFile = File.createTempFile("export_", ".xlsx"); outputStream = new FileOutputStream(tempFile); // 使用文件输出流 // 从JSON中提取单个值 // String text = requestDataNode.has("text") ? requestDataNode.get("text").asText() : null; // Integer sort = requestDataNode.has("sort") ? requestDataNode.get("sort").asInt() : null; // String field = requestDataNode.has("field") ? requestDataNode.get("field").asText() : null; // String deptId = requestDataNode.has("deptId") ? requestDataNode.get("deptId").asText() : null; try { // 6. 初始化Excel写入器(指向本地文件流) try { excelWriter = EasyExcel.write(outputStream, RechargeUser.class).build(); } catch (Exception e) { log.error("Excel 写入器初始化失败", e); throw new RuntimeException("Excel 写入器初始化失败", e); } WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build(); // 7. 分页查询并写入数据 Page page = new Page(); page.setPageNum(1); page.setPageSize(5000); Integer totalCount = 0; page.setRechargeUser(rechargeUser); boolean hasMore = true; while (hasMore) { try { Authentication authentication = JWTUtil.getAuthenticationFromToken(token, Admin.class); if (authentication != null) { System.out.println("Authentication: " + authentication); SecurityContextHolder.getContext().setAuthentication(authentication); // 存储认证信息 } } catch (Exception e) { e.printStackTrace(); } Result pageResult = rechargeController.selcetBy(page); Integer code = pageResult.getCode(); Object data = pageResult.getData(); if (code == 200) { // 判断 data 是否是 PageInfo 类型 if (!(data instanceof PageInfo)) { log.error("返回数据类型错误,期望 PageInfo,实际为:{}", data.getClass()); hasMore = false; continue; } @SuppressWarnings("unchecked") PageInfo pageInfo = (PageInfo) data; Long total = (long) pageInfo.getTotal(); // 转换为 long List list = pageInfo.getList(); if (list == null || list.isEmpty()) { hasMore = false; } else { // 写入 Excel 数据 excelWriter.write(list, writeSheet); page.setPageNum(page.getPageNum() + 1); totalCount += list.size(); log.info("导出进度 recordId: {}, 已处理: {}条", recordId, totalCount); hasMore = totalCount < total; } } else { hasMore = false; log.error("获取数据失败,状态码: {}", code); } } // 7. 完成Excel写入(所有数据写入后关闭写入器) if (excelWriter != null) { excelWriter.finish(); } if (outputStream != null) { outputStream.flush(); // 确保所有数据写入 outputStream.close(); // 关闭文件流 } // 检查文件是否存在且不为空 if (tempFile != null && tempFile.exists() && tempFile.length() > 0) { // 8. 上传到OSS(读取本地临时文件) // 获取接口的基础 URL String uploadUrl = this.uploadUrl; try { // 1. 创建上传工具实例 ExcelUploadUtil uploadUtil = new ExcelUploadUtil(uploadUrl); // 2. 准备要上传的文件 File excelFile = new File(tempFile.toURI()); try { // 3. 执行上传 String result = uploadUtil.uploadExcel(excelFile, "export/excel/"); // 1. 解析JSON任务 // JsonNode uploadResult = objectMapper.readTree(result); // System.out.println(uploadResult+"11111111111111111111111"); // long code = uploadResult.path("code").asLong(); // String url = String.valueOf(uploadResult.path("data")); // url = url.replace("\"", ""); // if (code == 1) { // // 3. 验证导出记录decodecode // aiEmotionService.updateStatus(recordId, 2, url, "", totalCount); // } else { // //更新失败 // aiEmotionService.updateStatus(recordId, 3, "", url, 0); // } JsonNode uploadResult = objectMapper.readTree(result); long code = uploadResult.path("code").asLong(); String fileUrl = ""; JsonNode dataNode = uploadResult.path("data"); if (dataNode.isObject()) { fileUrl = dataNode.path("url").asText(); } else if (dataNode.isTextual()) { fileUrl = dataNode.asText(); // 如果 data 是直接字符串 URL } log.info("解析到的URL: {}", fileUrl); if (code == 200 && !fileUrl.isEmpty()) { aiEmotionService.updateStatus(recordId, 2, fileUrl, "", totalCount); } else { aiEmotionService.updateStatus(recordId, 3, "", "上传成功但URL为空或解析失败", 0); } } catch (Exception e) { //更新失败 aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); throw new Exception("文件上传云端失败1", e); } } catch (Exception e) { log.error("上传文件失败 recordId: {}, 文件名: {}", recordId, fileName, e); //更新状态为失败 if (recordId != null) { aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); } throw new Exception("文件上传云端失败2", e); } } else { throw new Exception("导出的Excel文件不存在或为空"); } } catch (Exception e) { System.out.println("导出异常" + e.getMessage()); log.error("导出任务处理失败 recordId: {}", recordId, e); // 更新状态为失败 if (recordId != null) { aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); } throw new Exception("导出异常", e); } finally { // 确保资源被关闭 try { if (excelWriter != null) { excelWriter.finish(); } if (outputStream != null) { outputStream.close(); } } catch (Exception e) { log.error("关闭资源失败", e); throw new Exception("excel文件关闭资源失败", e); } } } catch (Exception e) { log.error("导出任务处理失败 recordId: {}", recordId, e); // 更新状态为失败 if (recordId != null) { aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); } System.out.println("<导出失败>" + e.getMessage()); throw new Exception("导出任务处理失败", e); } finally { // 清理临时文件 if (tempFile != null && tempFile.exists()) { try { if (tempFile.delete()) { log.info("临时文件已删除: {}", tempFile.getAbsolutePath()); } else { log.warn("无法删除临时文件: {}", tempFile.getAbsolutePath()); } } catch (Exception e) { log.error("删除临时文件失败", e.getMessage()); throw new Exception("删除临时文件失败", e); } } long endTime = System.currentTimeMillis(); log.info("导出任务完成,耗时: {}毫秒", (endTime - startTime)); } return null; } @Transactional @Override public Exception consumeExcel(String message) throws Exception { System.out.println("明细导出excel数据开始执行:" + message); long startTime = System.currentTimeMillis(); Long recordId = null; String fileName = null; File tempFile = null; String token = null; OutputStream outputStream = null; ExcelWriter excelWriter = null; try { // 1. 解析JSON任务 JsonNode rootNode = objectMapper.readTree(message); // 2. 获取基本参数 recordId = rootNode.path("recordId").asLong(); JsonNode requestDataNode = rootNode.path("requestData"); token = rootNode.path("token").asText(); JsonNode consumeUserNode = requestDataNode.path("consumeUser"); ConsumeUser consumeUser = objectMapper.treeToValue(consumeUserNode, ConsumeUser.class); // 3. 验证导出记录 AiEmotionExportRecordVO record = validateExportRecord(recordId); if (record == null) return null; //4. 更新状态为处理中 aiEmotionService.updateStatus(recordId, 1, "", "", 0); // 5. 准备Excel文件 fileName = record.getFileName(); log.info("到这了---------------------------------------------"); // 初始化临时文件(保存到本地临时目录) tempFile = File.createTempFile("export_", ".xlsx"); outputStream = new FileOutputStream(tempFile); // 使用文件输出流 // 从JSON中提取单个值 try { // 6. 初始化Excel写入器(指向本地文件流) excelWriter = EasyExcel.write(outputStream, ConsumeUser.class).build(); WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build(); // 7. 分页查询并写入数据 Page page = new Page(); page.setPageNum(1); page.setPageSize(5000); page.setConsumeUser(consumeUser); Integer totalCount = 0; boolean hasMore = true; while (hasMore) { try { Authentication authentication = JWTUtil.getAuthenticationFromToken(token, Admin.class); if (authentication != null) { System.out.println("Authentication: " + authentication); SecurityContextHolder.getContext().setAuthentication(authentication); // 存储认证信息 } } catch (Exception e) { e.printStackTrace(); } Result pageResult = consumeController.selectBy(page); Integer code = pageResult.getCode(); Object data = pageResult.getData(); if (code == 200) { // 判断 data 是否是 PageInfo 类型 if (!(data instanceof PageInfo)) { log.error("返回数据类型错误,期望 PageInfo,实际为:{}", data.getClass()); hasMore = false; continue; } @SuppressWarnings("unchecked") PageInfo pageInfo = (PageInfo) data; Long total = (long) pageInfo.getTotal(); // 转换为 long List list = pageInfo.getList(); if (list == null || list.isEmpty()) { hasMore = false; } else { // 写入 Excel 数据 excelWriter.write(list, writeSheet); page.setPageNum(page.getPageNum() + 1); totalCount += list.size(); log.info("导出进度 recordId: {}, 已处理: {}条", recordId, totalCount); hasMore = totalCount < total; } } else { hasMore = false; log.error("获取数据失败,状态码: {}", code); } } // 7. 完成Excel写入(所有数据写入后关闭写入器) if (excelWriter != null) { excelWriter.finish(); } if (outputStream != null) { outputStream.flush(); // 确保所有数据写入 outputStream.close(); // 关闭文件流 } // 检查文件是否存在且不为空 if (tempFile != null && tempFile.exists() && tempFile.length() > 0) { // 8. 上传到OSS(读取本地临时文件) // 获取接口的基础 URL String uploadUrl = this.uploadUrl; try { // 1. 创建上传工具实例 ExcelUploadUtil uploadUtil = new ExcelUploadUtil(uploadUrl); // 2. 准备要上传的文件 File excelFile = new File(tempFile.toURI()); try { // 3. 执行上传 String result = uploadUtil.uploadExcel(excelFile, "export/excel/"); // 1. 解析JSON任务 // JsonNode uploadResult = objectMapper.readTree(result); // System.out.println(uploadResult+"11111111111111111111111"); // long code = uploadResult.path("code").asLong(); // String url = String.valueOf(uploadResult.path("data")); // url = url.replace("\"", ""); // if (code == 1) { // // 3. 验证导出记录decodecode // aiEmotionService.updateStatus(recordId, 2, url, "", totalCount); // } else { // //更新失败 // aiEmotionService.updateStatus(recordId, 3, "", url, 0); // } JsonNode uploadResult = objectMapper.readTree(result); long code = uploadResult.path("code").asLong(); String fileUrl = ""; JsonNode dataNode = uploadResult.path("data"); if (dataNode.isObject()) { fileUrl = dataNode.path("url").asText(); } else if (dataNode.isTextual()) { fileUrl = dataNode.asText(); // 如果 data 是直接字符串 URL } log.info("解析到的URL: {}", fileUrl); if (code == 200 && !fileUrl.isEmpty()) { aiEmotionService.updateStatus(recordId, 2, fileUrl, "", totalCount); } else { aiEmotionService.updateStatus(recordId, 3, "", "上传成功但URL为空或解析失败", 0); } } catch (Exception e) { //更新失败 aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); throw new Exception("文件上传云端失败1", e); } } catch (Exception e) { log.error("上传文件失败 recordId: {}, 文件名: {}", recordId, fileName, e); //更新状态为失败 if (recordId != null) { aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); } throw new Exception("文件上传云端失败2", e); } } else { throw new Exception("导出的Excel文件不存在或为空"); } } catch (Exception e) { System.out.println("导出异常" + e.getMessage()); log.error("导出任务处理失败 recordId: {}", recordId, e); // 更新状态为失败 if (recordId != null) { aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); } throw new Exception("导出异常", e); } finally { // 确保资源被关闭 try { if (excelWriter != null) { excelWriter.finish(); } if (outputStream != null) { outputStream.close(); } } catch (Exception e) { log.error("关闭资源失败", e); throw new Exception("excel文件关闭资源失败", e); } } } catch (Exception e) { log.error("导出任务处理失败 recordId: {}", recordId, e); // 更新状态为失败 if (recordId != null) { aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); } System.out.println("<导出失败>" + e.getMessage()); throw new Exception("导出任务处理失败", e); } finally { // 清理临时文件 if (tempFile != null && tempFile.exists()) { try { if (tempFile.delete()) { log.info("临时文件已删除: {}", tempFile.getAbsolutePath()); } else { log.warn("无法删除临时文件: {}", tempFile.getAbsolutePath()); } } catch (Exception e) { log.error("删除临时文件失败", e.getMessage()); throw new Exception("删除临时文件失败", e); } } long endTime = System.currentTimeMillis(); log.info("导出任务完成,耗时: {}毫秒", (endTime - startTime)); } return null; } @Transactional @Override public Exception refundExcel(String message) throws Exception { System.out.println("明细导出excel数据开始执行:" + message); long startTime = System.currentTimeMillis(); Long recordId = null; String fileName = null; String token = null; File tempFile = null; OutputStream outputStream = null; ExcelWriter excelWriter = null; try { // 1. 解析JSON任务 JsonNode rootNode = objectMapper.readTree(message); // 2. 获取基本参数 recordId = rootNode.path("recordId").asLong(); token = rootNode.path("token").asText(); JsonNode requestDataNode = rootNode.path("requestData"); JsonNode refundUserNode = requestDataNode.path("refundUser"); RefundUser refundUser = objectMapper.treeToValue(refundUserNode, RefundUser.class); // 3. 验证导出记录 AiEmotionExportRecordVO record = validateExportRecord(recordId); if (record == null) return null; //4. 更新状态为处理中 aiEmotionService.updateStatus(recordId, 1, "", "", 0); // 5. 准备Excel文件 fileName = record.getFileName(); // 初始化临时文件(保存到本地临时目录) tempFile = File.createTempFile("export_", ".xlsx"); outputStream = new FileOutputStream(tempFile); // 使用文件输出流 // 从JSON中提取单个值 try { // 6. 初始化Excel写入器(指向本地文件流) excelWriter = EasyExcel.write(outputStream, RefundUser.class).build(); WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build(); // 7. 分页查询并写入数据 Page page = new Page(); page.setPageNum(1); page.setPageSize(5000); page.setRefundUser(refundUser); Integer totalCount = 0; boolean hasMore = true; while (hasMore) { try { Authentication authentication = JWTUtil.getAuthenticationFromToken(token, Admin.class); if (authentication != null) { System.out.println("Authentication: " + authentication); SecurityContextHolder.getContext().setAuthentication(authentication); // 存储认证信息 } } catch (Exception e) { e.printStackTrace(); } Result pageResult = refundController.selcetBy(page); Integer code = pageResult.getCode(); Object data = pageResult.getData(); if (code == 200) { // 判断 data 是否是 PageInfo 类型 if (!(data instanceof PageInfo)) { log.error("返回数据类型错误,期望 PageInfo,实际为:{}", data.getClass()); hasMore = false; continue; } @SuppressWarnings("unchecked") PageInfo pageInfo = (PageInfo) data; Long total = (long) pageInfo.getTotal(); // 转换为 long List list = pageInfo.getList(); if (list == null || list.isEmpty()) { hasMore = false; } else { // 写入 Excel 数据 excelWriter.write(list, writeSheet); page.setPageNum(page.getPageNum() + 1); totalCount += list.size(); log.info("导出进度 recordId: {}, 已处理: {}条", recordId, totalCount); hasMore = totalCount < total; } } else { hasMore = false; log.error("获取数据失败,状态码: {}", code); } } // 7. 完成Excel写入(所有数据写入后关闭写入器) if (excelWriter != null) { excelWriter.finish(); } if (outputStream != null) { outputStream.flush(); // 确保所有数据写入 outputStream.close(); // 关闭文件流 } // 检查文件是否存在且不为空 if (tempFile != null && tempFile.exists() && tempFile.length() > 0) { // 8. 上传到OSS(读取本地临时文件) // 获取接口的基础 URL String uploadUrl = this.uploadUrl; try { // 1. 创建上传工具实例 ExcelUploadUtil uploadUtil = new ExcelUploadUtil(uploadUrl); // 2. 准备要上传的文件 File excelFile = new File(tempFile.toURI()); try { // 3. 执行上传 String result = uploadUtil.uploadExcel(excelFile, "export/excel/"); // 1. 解析JSON任务 // JsonNode uploadResult = objectMapper.readTree(result); // System.out.println(uploadResult+"11111111111111111111111"); // long code = uploadResult.path("code").asLong(); // String url = String.valueOf(uploadResult.path("data")); // url = url.replace("\"", ""); // if (code == 1) { // // 3. 验证导出记录decodecode // aiEmotionService.updateStatus(recordId, 2, url, "", totalCount); // } else { // //更新失败 // aiEmotionService.updateStatus(recordId, 3, "", url, 0); // } JsonNode uploadResult = objectMapper.readTree(result); long code = uploadResult.path("code").asLong(); String fileUrl = ""; JsonNode dataNode = uploadResult.path("data"); if (dataNode.isObject()) { fileUrl = dataNode.path("url").asText(); } else if (dataNode.isTextual()) { fileUrl = dataNode.asText(); // 如果 data 是直接字符串 URL } log.info("解析到的URL: {}", fileUrl); if (code == 200 && !fileUrl.isEmpty()) { aiEmotionService.updateStatus(recordId, 2, fileUrl, "", totalCount); } else { aiEmotionService.updateStatus(recordId, 3, "", "上传成功但URL为空或解析失败", 0); } } catch (Exception e) { //更新失败 aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); throw new Exception("文件上传云端失败1", e); } } catch (Exception e) { log.error("上传文件失败 recordId: {}, 文件名: {}", recordId, fileName, e); //更新状态为失败 if (recordId != null) { aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); } throw new Exception("文件上传云端失败2", e); } } else { throw new Exception("导出的Excel文件不存在或为空"); } } catch (Exception e) { System.out.println("导出异常" + e.getMessage()); log.error("导出任务处理失败 recordId: {}", recordId, e); // 更新状态为失败 if (recordId != null) { aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); } throw new Exception("导出异常", e); } finally { // 确保资源被关闭 try { if (excelWriter != null) { excelWriter.finish(); } if (outputStream != null) { outputStream.close(); } } catch (Exception e) { log.error("关闭资源失败", e); throw new Exception("excel文件关闭资源失败", e); } } } catch (Exception e) { log.error("导出任务处理失败 recordId: {}", recordId, e); // 更新状态为失败 if (recordId != null) { aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); } System.out.println("<导出失败>" + e.getMessage()); throw new Exception("导出任务处理失败", e); } finally { // 清理临时文件 if (tempFile != null && tempFile.exists()) { try { if (tempFile.delete()) { log.info("临时文件已删除: {}", tempFile.getAbsolutePath()); } else { log.warn("无法删除临时文件: {}", tempFile.getAbsolutePath()); } } catch (Exception e) { log.error("删除临时文件失败", e.getMessage()); throw new Exception("删除临时文件失败", e); } } long endTime = System.currentTimeMillis(); log.info("导出任务完成,耗时: {}毫秒", (endTime - startTime)); } return null; } @Override public List getExcel(Export export) { List list = exportMapper.getExportRecord(export.getAccount(),export.getType()); System.out.println(list+"-------------------------------"); return list; } /** * 验证导出记录 */ private AiEmotionExportRecordVO validateExportRecord(Long recordId) throws Exception { AiEmotionExportRecordVO record = aiEmotionService.getRecordById(recordId); AbstractLog log = null; if (record == null) { log.error("导出记录不存在 recordId: {}", recordId); return null; } // 检查是否已经处理过 if (record.getState() != 0) { log.warn("导出记录已处理 recordId: {}, status: {}", recordId, record.getState()); return null; } return record; } /** * 初始化excel文件 * @param os * @param exportType * @return */ private ExcelWriter initExcelWriter(OutputStream os, String exportType) { switch (exportType) { case "user": return EasyExcel.write(os, Goldmingxi.class) .inMemory(Boolean.TRUE) .build(); default: throw new IllegalArgumentException("不支持的导出类型: " + exportType); } } /** * 初始化excel文件 * @param os * @param exportType * @return */ private ExcelWriter ExcelWriter(OutputStream os, String exportType) { switch (exportType) { case "user": return EasyExcel.write(os, User.class) .inMemory(Boolean.TRUE) .build(); default: throw new IllegalArgumentException("不支持的导出类型: " + exportType); } } /** * 初始化excel文件 * @param os * @param exportType * @return */ private ExcelWriter RechargeExcelWriter(OutputStream os, String exportType) { switch (exportType) { case "user": return EasyExcel.write(os, RechargeUser.class) .inMemory(Boolean.TRUE) .build(); default: throw new IllegalArgumentException("不支持的导出类型: " + exportType); } } /** * 初始化excel文件 * @param os * @param exportType * @return */ private ExcelWriter ConExcelWriter(OutputStream os, String exportType) { switch (exportType) { case "user": return EasyExcel.write(os, ConsumeUser.class) .inMemory(Boolean.TRUE) .build(); default: throw new IllegalArgumentException("不支持的导出类型: " + exportType); } }/** * 初始化excel文件 * @param os * @param exportType * @return */ private ExcelWriter RefundExcelWriter(OutputStream os, String exportType) { switch (exportType) { case "user": return EasyExcel.write(os, RefundUser.class) .inMemory(Boolean.TRUE) .build(); default: throw new IllegalArgumentException("不支持的导出类型: " + exportType); } } }