From 5366d13f91face2f202806875eb6e958c17e3728 Mon Sep 17 00:00:00 2001 From: junzhangfm Date: Wed, 1 Apr 2026 14:06:01 +0800 Subject: [PATCH] =?UTF-8?q?2026-4-1=E6=8F=90=E4=BA=A4=EF=BC=9Apdf=E5=AF=BC?= =?UTF-8?q?=E5=87=BA=E5=92=8C=E4=B8=8B=E8=BD=BD=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../grid/controller/DnerEventController.java | 16 ++--- .../DnerEventExportRecordController.java | 45 ++++++++++++++ .../grid/entity/DnerEventExportRecord.java | 12 ++++ .../service/DnerEventExportRecordService.java | 14 ----- ....java => IDnerEventAttachmentService.java} | 2 +- .../IDnerEventExportRecordService.java | 32 ++++++++++ ...entService.java => IDnerEventService.java} | 2 +- .../impl/DnerEventAttachmentServiceImpl.java | 49 ++-------------- .../DnerEventExportRecordServiceImpl.java | 47 ++++++++++++++- .../service/impl/DnerEventServiceImpl.java | 8 +-- .../power/grid/utils/FileDownloadUtil.java | 58 +++++++++++++++++++ src/main/resources/application.yml | 6 +- src/main/resources/sql/20260313-DDL-002.sql | 5 +- 13 files changed, 214 insertions(+), 82 deletions(-) create mode 100644 src/main/java/com/southern/power/grid/controller/DnerEventExportRecordController.java delete mode 100644 src/main/java/com/southern/power/grid/service/DnerEventExportRecordService.java rename src/main/java/com/southern/power/grid/service/{DnerEventAttachmentService.java => IDnerEventAttachmentService.java} (85%) create mode 100644 src/main/java/com/southern/power/grid/service/IDnerEventExportRecordService.java rename src/main/java/com/southern/power/grid/service/{DnerEventService.java => IDnerEventService.java} (94%) create mode 100644 src/main/java/com/southern/power/grid/utils/FileDownloadUtil.java diff --git a/src/main/java/com/southern/power/grid/controller/DnerEventController.java b/src/main/java/com/southern/power/grid/controller/DnerEventController.java index 0745cf0..94ba7aa 100644 --- a/src/main/java/com/southern/power/grid/controller/DnerEventController.java +++ b/src/main/java/com/southern/power/grid/controller/DnerEventController.java @@ -3,8 +3,8 @@ package com.southern.power.grid.controller; import com.southern.power.grid.common.Result; import com.southern.power.grid.entity.DnerEvent; import com.southern.power.grid.entity.DnerEventVO; -import com.southern.power.grid.service.DnerEventAttachmentService; -import com.southern.power.grid.service.DnerEventService; +import com.southern.power.grid.service.IDnerEventAttachmentService; +import com.southern.power.grid.service.IDnerEventService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import org.springframework.http.ResponseEntity; @@ -25,10 +25,10 @@ import java.util.List; public class DnerEventController { @Autowired - private DnerEventService dnerEventService; + private IDnerEventService dnerEventService; @Autowired - private DnerEventAttachmentService dnerEventAttachmentService; + private IDnerEventAttachmentService dnerEventAttachmentService; /** * 新增事件 @@ -55,14 +55,6 @@ public class DnerEventController { return Result.success(dnerEventService.updateById(event)); } - /** - * 根据ID查询事件 - */ - @GetMapping("/get/{id}") - public DnerEvent getById(@PathVariable Long id) { - return dnerEventService.getById(id); - } - /** * 查询所有事件 */ diff --git a/src/main/java/com/southern/power/grid/controller/DnerEventExportRecordController.java b/src/main/java/com/southern/power/grid/controller/DnerEventExportRecordController.java new file mode 100644 index 0000000..d417733 --- /dev/null +++ b/src/main/java/com/southern/power/grid/controller/DnerEventExportRecordController.java @@ -0,0 +1,45 @@ +package com.southern.power.grid.controller; + +import com.southern.power.grid.common.Result; +import com.southern.power.grid.service.IDnerEventExportRecordService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +/** + * 事件导出记录 - Controller层 + * + * @Author junzhangfm + * @Date 2026-04-01 + */ +@RestController +@RequestMapping("/api/v1/export") +public class DnerEventExportRecordController { + @Autowired + private IDnerEventExportRecordService dnerEventExportRecordService; + + /** + * 上传导出的图表文件 + * + * @param file 文件 + * @param eventId 事件ID + * @return 结果 + */ + @PostMapping("/upload") + public Result updateExportRecord(@RequestParam("file") MultipartFile file, + @RequestParam("eventId") Long eventId) { + return Result.success(dnerEventExportRecordService.updateExportRecord(file, eventId)); + } + + /** + * 下载模板 + * + * @return 结果 + */ + @GetMapping("/download/{id}") + public ResponseEntity download(@PathVariable String id) { + return dnerEventExportRecordService.download(id); + } +} diff --git a/src/main/java/com/southern/power/grid/entity/DnerEventExportRecord.java b/src/main/java/com/southern/power/grid/entity/DnerEventExportRecord.java index 5abd493..b603020 100644 --- a/src/main/java/com/southern/power/grid/entity/DnerEventExportRecord.java +++ b/src/main/java/com/southern/power/grid/entity/DnerEventExportRecord.java @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; +import lombok.experimental.Accessors; import java.time.LocalDateTime; @@ -16,6 +17,7 @@ import java.time.LocalDateTime; **/ @Data @TableName("dner_event_export_record") +@Accessors(chain = true) public class DnerEventExportRecord { /** @@ -54,4 +56,14 @@ public class DnerEventExportRecord { * 导出文件类型 */ private String fileType; + + /** + * 存储在本地的唯一文件名 + */ + private String storedFileName; + + /** + * 文件大小(字节) + */ + private Long fileSize; } \ No newline at end of file diff --git a/src/main/java/com/southern/power/grid/service/DnerEventExportRecordService.java b/src/main/java/com/southern/power/grid/service/DnerEventExportRecordService.java deleted file mode 100644 index ff0211b..0000000 --- a/src/main/java/com/southern/power/grid/service/DnerEventExportRecordService.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.southern.power.grid.service; - -import com.baomidou.mybatisplus.extension.service.IService; -import com.southern.power.grid.entity.DnerEventExportRecord; - -/** - * 事件导出记录 服务接口 - * - * @author: junzhangfm - * @date: 2026/3/23 - **/ -public interface DnerEventExportRecordService extends IService { - -} diff --git a/src/main/java/com/southern/power/grid/service/DnerEventAttachmentService.java b/src/main/java/com/southern/power/grid/service/IDnerEventAttachmentService.java similarity index 85% rename from src/main/java/com/southern/power/grid/service/DnerEventAttachmentService.java rename to src/main/java/com/southern/power/grid/service/IDnerEventAttachmentService.java index adb75f4..9024113 100644 --- a/src/main/java/com/southern/power/grid/service/DnerEventAttachmentService.java +++ b/src/main/java/com/southern/power/grid/service/IDnerEventAttachmentService.java @@ -11,7 +11,7 @@ import org.springframework.http.ResponseEntity; * @author: junzhangfm * @date: 2026/3/23 **/ -public interface DnerEventAttachmentService extends IService { +public interface IDnerEventAttachmentService extends IService { /** * 下载附件 diff --git a/src/main/java/com/southern/power/grid/service/IDnerEventExportRecordService.java b/src/main/java/com/southern/power/grid/service/IDnerEventExportRecordService.java new file mode 100644 index 0000000..02af3d5 --- /dev/null +++ b/src/main/java/com/southern/power/grid/service/IDnerEventExportRecordService.java @@ -0,0 +1,32 @@ +package com.southern.power.grid.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.southern.power.grid.entity.DnerEventExportRecord; +import org.springframework.core.io.Resource; +import org.springframework.http.ResponseEntity; +import org.springframework.web.multipart.MultipartFile; + +/** + * 事件导出记录 服务接口 + * + * @author: junzhangfm + * @date: 2026/3/23 + **/ +public interface IDnerEventExportRecordService extends IService { + /** + * 上传导出记录 + * + * @param file 导出文件 + * @param eventId 事件ID + * @return 结果 + */ + Boolean updateExportRecord(MultipartFile file, Long eventId); + + /** + * 通过导出记录ID下载导出文件 + * + * @param id 导出记录ID + * @return 响应体 + */ + ResponseEntity download(String id); +} diff --git a/src/main/java/com/southern/power/grid/service/DnerEventService.java b/src/main/java/com/southern/power/grid/service/IDnerEventService.java similarity index 94% rename from src/main/java/com/southern/power/grid/service/DnerEventService.java rename to src/main/java/com/southern/power/grid/service/IDnerEventService.java index 4f393de..549f0c8 100644 --- a/src/main/java/com/southern/power/grid/service/DnerEventService.java +++ b/src/main/java/com/southern/power/grid/service/IDnerEventService.java @@ -15,7 +15,7 @@ import java.util.List; * @author: junzhangfm * @date: 2026/3/23 **/ -public interface DnerEventService extends IService { +public interface IDnerEventService extends IService { /** * 查询事件列表 * diff --git a/src/main/java/com/southern/power/grid/service/impl/DnerEventAttachmentServiceImpl.java b/src/main/java/com/southern/power/grid/service/impl/DnerEventAttachmentServiceImpl.java index fb89ccc..15672bb 100644 --- a/src/main/java/com/southern/power/grid/service/impl/DnerEventAttachmentServiceImpl.java +++ b/src/main/java/com/southern/power/grid/service/impl/DnerEventAttachmentServiceImpl.java @@ -3,19 +3,12 @@ package com.southern.power.grid.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.southern.power.grid.dao.DnerEventAttachmentMapper; import com.southern.power.grid.entity.DnerEventAttachment; -import com.southern.power.grid.service.DnerEventAttachmentService; -import org.springframework.core.io.FileSystemResource; +import com.southern.power.grid.service.IDnerEventAttachmentService; +import com.southern.power.grid.utils.FileDownloadUtil; import org.springframework.core.io.Resource; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import java.io.File; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; - import org.springframework.stereotype.Service; /** @@ -27,7 +20,7 @@ import org.springframework.stereotype.Service; @Service public class DnerEventAttachmentServiceImpl extends ServiceImpl - implements DnerEventAttachmentService { + implements IDnerEventAttachmentService { @Override public ResponseEntity downloadExcel(Long attachmentId) { @@ -36,40 +29,6 @@ public class DnerEventAttachmentServiceImpl if (attachment == null) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null); } - - // 2. 获取文件真实路径 - String filePath = attachment.getFilePath(); - File file = new File(filePath); - - // 3. 校验文件是否存在 - if (!file.exists()) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null); - } - - // 4. 封装文件资源 - Resource resource = new FileSystemResource(file); - - // 5. 处理中文名下载乱码(关键!) - String originalFilename = attachment.getFileName(); - String encodeFileName = null; - try { - encodeFileName = URLEncoder.encode(originalFilename, StandardCharsets.UTF_8.toString()) - .replace("+", "%20"); - } catch (UnsupportedEncodingException e) { - log.error("URLEncoder.encode error!"); - throw new RuntimeException(e); - } - - // 6. 构建响应头 - HttpHeaders headers = new HttpHeaders(); - headers.add(HttpHeaders.CONTENT_DISPOSITION, - "attachment; filename=\"" + encodeFileName + "\"; filename*=UTF-8''" + encodeFileName); - - // 7. 返回文件流 - return ResponseEntity.ok() - .headers(headers) - .contentType(MediaType.APPLICATION_OCTET_STREAM) - .contentLength(file.length()) - .body(resource); + return FileDownloadUtil.downLoad(attachment.getFilePath(), attachment.getFileName()); } } diff --git a/src/main/java/com/southern/power/grid/service/impl/DnerEventExportRecordServiceImpl.java b/src/main/java/com/southern/power/grid/service/impl/DnerEventExportRecordServiceImpl.java index 0ec7b2c..d2a449e 100644 --- a/src/main/java/com/southern/power/grid/service/impl/DnerEventExportRecordServiceImpl.java +++ b/src/main/java/com/southern/power/grid/service/impl/DnerEventExportRecordServiceImpl.java @@ -3,8 +3,19 @@ package com.southern.power.grid.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.southern.power.grid.dao.DnerEventExportRecordMapper; import com.southern.power.grid.entity.DnerEventExportRecord; -import com.southern.power.grid.service.DnerEventExportRecordService; +import com.southern.power.grid.service.IDnerEventExportRecordService; +import com.southern.power.grid.utils.FileDownloadUtil; +import com.southern.power.grid.utils.FileUploadUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.time.LocalDateTime; /** * 事件导出记录 服务实现类 @@ -13,8 +24,40 @@ import org.springframework.stereotype.Service; * @date: 2026/3/23 **/ @Service +@Slf4j public class DnerEventExportRecordServiceImpl extends ServiceImpl - implements DnerEventExportRecordService { + implements IDnerEventExportRecordService { + @Value("${file.upload.pdf-path}") + private String uploadPath; + + @Override + public Boolean updateExportRecord(MultipartFile file, Long eventId) { + // 1. 获取文件信息 + String originalFilename = file.getOriginalFilename(); + String suffix = FileUploadUtil.getFileSuffix(originalFilename); + String storedFilename = FileUploadUtil.generateUniqueFileName(suffix); + String absolutePath = uploadPath + storedFilename; + // 2. 保存到本地 + try { + FileUploadUtil.saveFile(file, absolutePath); + } catch (IOException e) { + log.error("updateExportRecord saveFile error!"); + throw new RuntimeException(e); + } + // 3、入库 + return save(new DnerEventExportRecord().setEventId(eventId).setExportTime(LocalDateTime.now()).setExporter("admin") + .setFileName(originalFilename).setFilePath(absolutePath).setFileType(suffix) + .setStoredFileName(storedFilename).setFileSize(file.getSize())); + } + + @Override + public ResponseEntity download(String id) { + DnerEventExportRecord record = getById(id); + if (record == null) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null); + } + return FileDownloadUtil.downLoad(record.getFilePath(), record.getFileName()); + } } \ No newline at end of file diff --git a/src/main/java/com/southern/power/grid/service/impl/DnerEventServiceImpl.java b/src/main/java/com/southern/power/grid/service/impl/DnerEventServiceImpl.java index 65d3ecd..c6d4983 100644 --- a/src/main/java/com/southern/power/grid/service/impl/DnerEventServiceImpl.java +++ b/src/main/java/com/southern/power/grid/service/impl/DnerEventServiceImpl.java @@ -5,8 +5,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.southern.power.grid.dao.*; import com.southern.power.grid.entity.*; -import com.southern.power.grid.service.DnerEventAttachmentService; -import com.southern.power.grid.service.DnerEventService; +import com.southern.power.grid.service.IDnerEventAttachmentService; +import com.southern.power.grid.service.IDnerEventService; import com.southern.power.grid.service.IFileService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -34,7 +34,7 @@ import java.util.stream.Collectors; @Service @Slf4j public class DnerEventServiceImpl extends ServiceImpl - implements DnerEventService { + implements IDnerEventService { @Autowired private DnerEventMapper dnerEventMapper; @@ -54,7 +54,7 @@ public class DnerEventServiceImpl extends ServiceImpl listVO() { diff --git a/src/main/java/com/southern/power/grid/utils/FileDownloadUtil.java b/src/main/java/com/southern/power/grid/utils/FileDownloadUtil.java new file mode 100644 index 0000000..436f0c9 --- /dev/null +++ b/src/main/java/com/southern/power/grid/utils/FileDownloadUtil.java @@ -0,0 +1,58 @@ +package com.southern.power.grid.utils; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +/** + * 文件下载工具类 + * + * @Author junzhangfm + * @Date 2026-04-01 + */ +@Slf4j +public class FileDownloadUtil { + + public static ResponseEntity downLoad(String filePath, String filename) { + File file = new File(filePath); + + // 校验文件是否存在 + if (!file.exists()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null); + } + + // 4. 封装文件资源 + Resource resource = new FileSystemResource(file); + + // 5. 处理中文名下载乱码(关键!) + String encodeFileName = null; + try { + encodeFileName = URLEncoder.encode(filename, StandardCharsets.UTF_8.toString()) + .replace("+", "%20"); + } catch (UnsupportedEncodingException e) { + log.error("URLEncoder.encode error!"); + throw new RuntimeException(e); + } + + // 6. 构建响应头 + HttpHeaders headers = new HttpHeaders(); + headers.add(HttpHeaders.CONTENT_DISPOSITION, + "attachment; filename=\"" + encodeFileName + "\"; filename*=UTF-8''" + encodeFileName); + + // 7. 返回文件流 + return ResponseEntity.ok() + .headers(headers) + .contentType(MediaType.APPLICATION_OCTET_STREAM) + .contentLength(file.length()) + .body(resource); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 65a0602..6f4dad5 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -9,7 +9,7 @@ spring: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/south_power_grid?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true username: root - password: Root@123456 + password: 123456 hikari: connection-timeout: 30000 validation-timeout: 5000 @@ -27,8 +27,10 @@ spring: # 自定义本地文件存储路径(绝对路径,不要放在项目里!) file: upload: - path: E:/springboot-uploads/excel/ # Windows + path: D:/springboot-uploads/excel/ # Windows + pdf-path: D:/springboot-uploads/pdf/ # Windows # path: /home/springboot/uploads/excel/ # Linux + # pdf-path: /home/springboot/uploads/pdf/ # Linux import: batch-size: 500 # 批量导入大小 diff --git a/src/main/resources/sql/20260313-DDL-002.sql b/src/main/resources/sql/20260313-DDL-002.sql index d97fc2f..cbe9458 100644 --- a/src/main/resources/sql/20260313-DDL-002.sql +++ b/src/main/resources/sql/20260313-DDL-002.sql @@ -1,3 +1,6 @@ ALTER TABLE pmds_qxj_city_weather MODIFY COLUMN `prediction_time` int COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '预报时效,小时'; -ALTER TABLE pmds_qxj_city_weather COMMENT = '地区天气预报表'; \ No newline at end of file +ALTER TABLE pmds_qxj_city_weather COMMENT = '地区天气预报表'; +ALTER TABLE dner_event_export_record + ADD `stored_file_name` VARCHAR(255) NOT NULL COMMENT '存储在本地的唯一文件名', + ADD `file_size` BIGINT NOT NULL COMMENT '文件大小(字节)';