Commit 767330ab93432aeb8e4f3d073ea0adb6e63d3cee
1 parent
f9cf2428
feat(adopt): 增强客户同步功能并支持Excel文件处理
- 为 fullySyncCustomer 接口增加路径参数以支持多租户管道配置 - 添加对 Excel 文件(xls 和 xlsx)的解析与处理逻辑 - 引入 Apache POI 依赖用于读取电子表格数据 - 新增 ExcelUtils 工具类实现表格数据转换为 Map 列表 - 在 ReceiveMessageCO 中将 systemType 类型从枚举改为字符串 - 更新 controller 和 service 方法签名以传递更多上下文信息 - 添加文件格式校验及空文件名校验防止非法输入 - 优化代码结构并增强异常处理机制确保服务稳定性
Showing
7 changed files
with
113 additions
and
11 deletions
pom.xml
| ... | ... | @@ -34,6 +34,7 @@ |
| 34 | 34 | <mybatis-plus.version>3.5.14</mybatis-plus.version> |
| 35 | 35 | <!-- 工具类库 --> |
| 36 | 36 | <lombok.version>1.18.42</lombok.version> |
| 37 | + <poi.version>5.5.0</poi.version> | |
| 37 | 38 | </properties> |
| 38 | 39 | |
| 39 | 40 | <dependencyManagement> |
| ... | ... | @@ -69,6 +70,16 @@ |
| 69 | 70 | <artifactId>mysql-connector-j</artifactId> |
| 70 | 71 | <version>${mysql-connector.version}</version> |
| 71 | 72 | </dependency> |
| 73 | + <dependency> | |
| 74 | + <groupId>org.apache.poi</groupId> | |
| 75 | + <artifactId>poi</artifactId> | |
| 76 | + <version>${poi.version}</version> | |
| 77 | + </dependency> | |
| 78 | + <dependency> | |
| 79 | + <groupId>org.apache.poi</groupId> | |
| 80 | + <artifactId>poi-ooxml</artifactId> | |
| 81 | + <version>${poi.version}</version> | |
| 82 | + </dependency> | |
| 72 | 83 | </dependencies> |
| 73 | 84 | </dependencyManagement> |
| 74 | 85 | ... | ... |
tax-adopt/pom.xml
| ... | ... | @@ -8,14 +8,23 @@ |
| 8 | 8 | <artifactId>tax-agent</artifactId> |
| 9 | 9 | <version>${revision}</version> |
| 10 | 10 | </parent> |
| 11 | + <artifactId>tax-adopt</artifactId> | |
| 12 | + | |
| 11 | 13 | <dependencies> |
| 12 | 14 | <dependency> |
| 13 | 15 | <groupId>com.diligrp</groupId> |
| 14 | 16 | <artifactId>tax-central</artifactId> |
| 15 | 17 | <version>${revision}</version> |
| 16 | 18 | </dependency> |
| 19 | + <dependency> | |
| 20 | + <groupId>org.apache.poi</groupId> | |
| 21 | + <artifactId>poi</artifactId> | |
| 22 | + </dependency> | |
| 23 | + <dependency> | |
| 24 | + <groupId>org.apache.poi</groupId> | |
| 25 | + <artifactId>poi-ooxml</artifactId> | |
| 26 | + </dependency> | |
| 17 | 27 | </dependencies> |
| 18 | 28 | |
| 19 | - <artifactId>tax-adopt</artifactId> | |
| 20 | 29 | |
| 21 | -</project> | |
| 22 | 30 | \ No newline at end of file |
| 31 | +</project> | ... | ... |
tax-adopt/src/main/java/com/diligrp/tax/adopt/api/AdoptMessageController.java
| ... | ... | @@ -3,6 +3,7 @@ package com.diligrp.tax.adopt.api; |
| 3 | 3 | import com.diligrp.tax.adopt.model.ReceiveMessageCO; |
| 4 | 4 | import com.diligrp.tax.adopt.service.AdoptMessageService; |
| 5 | 5 | import com.diligrp.tax.central.message.Message; |
| 6 | +import jakarta.validation.constraints.NotNull; | |
| 6 | 7 | import lombok.AllArgsConstructor; |
| 7 | 8 | import org.springframework.web.bind.annotation.*; |
| 8 | 9 | import org.springframework.web.multipart.MultipartFile; |
| ... | ... | @@ -18,15 +19,31 @@ public class AdoptMessageController { |
| 18 | 19 | private final AdoptMessageService adoptMessageService; |
| 19 | 20 | |
| 20 | 21 | |
| 22 | + /** | |
| 23 | + * 接收消息 | |
| 24 | + * | |
| 25 | + * @param receiveMessageCO 接收消息 | |
| 26 | + * @return {@link Message }<{@link ? }> | |
| 27 | + */ | |
| 21 | 28 | @PostMapping("/message") |
| 22 | 29 | public Message<?> receiveMessage(@RequestBody ReceiveMessageCO receiveMessageCO) { |
| 23 | 30 | adoptMessageService.convertMessage(receiveMessageCO); |
| 24 | 31 | return Message.success(); |
| 25 | 32 | } |
| 26 | 33 | |
| 27 | - @PostMapping("/fullySyncCustomer") | |
| 28 | - public Message<?> fullySyncCustomer(@RequestPart("file")MultipartFile file) { | |
| 29 | - adoptMessageService.fullySyncCustomer(file); | |
| 34 | + /** | |
| 35 | + * 完全同步客户 | |
| 36 | + * | |
| 37 | + * @param file 文件 | |
| 38 | + * @return {@link Message }<{@link ? }> | |
| 39 | + */ | |
| 40 | + @PostMapping("/fullySyncCustomer/{group}/{entity}/{pipelineCode}/{documentType}") | |
| 41 | + public Message<?> fullySyncCustomer(@RequestPart("file") @NotNull MultipartFile file, | |
| 42 | + @PathVariable("group") String group, | |
| 43 | + @PathVariable("entity") String entity, | |
| 44 | + @PathVariable("pipelineCode") String pipelineCode, | |
| 45 | + @PathVariable("documentType") String documentType) { | |
| 46 | + adoptMessageService.fullySyncCustomer(file, group, entity, pipelineCode, documentType); | |
| 30 | 47 | return Message.success(); |
| 31 | 48 | } |
| 32 | 49 | } | ... | ... |
tax-adopt/src/main/java/com/diligrp/tax/adopt/model/ReceiveMessageCO.java
tax-adopt/src/main/java/com/diligrp/tax/adopt/service/AdoptMessageService.java
| 1 | 1 | package com.diligrp.tax.adopt.service; |
| 2 | 2 | |
| 3 | 3 | import com.diligrp.tax.adopt.model.ReceiveMessageCO; |
| 4 | +import jakarta.validation.constraints.NotNull; | |
| 4 | 5 | import org.springframework.web.multipart.MultipartFile; |
| 5 | 6 | |
| 6 | 7 | /** |
| ... | ... | @@ -9,6 +10,8 @@ import org.springframework.web.multipart.MultipartFile; |
| 9 | 10 | public interface AdoptMessageService { |
| 10 | 11 | |
| 11 | 12 | /** |
| 13 | + * 转换消息 | |
| 14 | + * | |
| 12 | 15 | * @param receiveMessageCO 接收消息 |
| 13 | 16 | */ |
| 14 | 17 | void convertMessage(ReceiveMessageCO receiveMessageCO); |
| ... | ... | @@ -16,7 +19,11 @@ public interface AdoptMessageService { |
| 16 | 19 | /** |
| 17 | 20 | * 完全同步客户 |
| 18 | 21 | * |
| 19 | - * @param file | |
| 22 | + * @param file 文件 | |
| 23 | + * @param group 群 | |
| 24 | + * @param entity 实体 | |
| 25 | + * @param pipelineCode 管道代码 | |
| 26 | + * @param documentType | |
| 20 | 27 | */ |
| 21 | - void fullySyncCustomer(MultipartFile file); | |
| 28 | + void fullySyncCustomer(@NotNull MultipartFile file, String group, String entity, String pipelineCode, String documentType); | |
| 22 | 29 | } | ... | ... |
tax-adopt/src/main/java/com/diligrp/tax/adopt/service/impl/AdoptMessageServiceImpl.java
| ... | ... | @@ -2,19 +2,25 @@ package com.diligrp.tax.adopt.service.impl; |
| 2 | 2 | |
| 3 | 3 | import com.diligrp.tax.adopt.model.ReceiveMessageCO; |
| 4 | 4 | import com.diligrp.tax.adopt.service.AdoptMessageService; |
| 5 | +import com.diligrp.tax.adopt.util.ExcelUtils; | |
| 5 | 6 | import com.diligrp.tax.central.exception.TaxAgentServiceException; |
| 6 | 7 | import com.diligrp.tax.central.model.PipelineBusinessKeyword; |
| 7 | 8 | import com.diligrp.tax.central.model.TenantPipeline; |
| 8 | 9 | import com.diligrp.tax.central.service.ITaxPipelineBusinessKeywordService; |
| 9 | 10 | import com.diligrp.tax.central.service.ITaxTenantService; |
| 11 | +import com.diligrp.tax.central.type.TaxSystemType; | |
| 10 | 12 | import com.diligrp.tax.central.utils.AdoptUtils; |
| 11 | 13 | import com.diligrp.tax.central.utils.JsonUtils; |
| 12 | 14 | import lombok.AllArgsConstructor; |
| 15 | +import org.apache.commons.io.FilenameUtils; | |
| 16 | +import org.apache.poi.hssf.usermodel.HSSFWorkbook; | |
| 17 | +import org.apache.poi.xssf.usermodel.XSSFWorkbook; | |
| 13 | 18 | import org.springframework.amqp.rabbit.core.RabbitTemplate; |
| 14 | 19 | import org.springframework.stereotype.Service; |
| 15 | 20 | import org.springframework.util.CollectionUtils; |
| 16 | 21 | import org.springframework.web.multipart.MultipartFile; |
| 17 | 22 | |
| 23 | +import java.io.IOException; | |
| 18 | 24 | import java.util.List; |
| 19 | 25 | import java.util.Map; |
| 20 | 26 | import java.util.Optional; |
| ... | ... | @@ -46,14 +52,38 @@ public class AdoptMessageServiceImpl implements AdoptMessageService { |
| 46 | 52 | Map<String, Object> map = AdoptUtils.handleAdopt(pipelineBusinessKeywords, json); |
| 47 | 53 | receiveMessageCO.setMsgBody(map); |
| 48 | 54 | Optional<TenantPipeline> byTenantAndPipelineCode = taxTenantService.findByTenantAndPipelineCode(receiveMessageCO.getGroup(), receiveMessageCO.getEntity(), receiveMessageCO.getPipelineCode()); |
| 49 | - byTenantAndPipelineCode.ifPresent(tenantPipeline -> receiveMessageCO.setSystemType(tenantPipeline.getSystemType())); | |
| 55 | + byTenantAndPipelineCode.ifPresent(tenantPipeline -> receiveMessageCO.setSystemType(tenantPipeline.getSystemType().code)); | |
| 50 | 56 | // 发送mq |
| 51 | 57 | String messageJson = JsonUtils.toJsonString(receiveMessageCO); |
| 52 | 58 | rabbitTemplate.convertAndSend(NORMAL_EXCHANGE, NORMAL_ROUTING, messageJson); |
| 53 | 59 | } |
| 54 | 60 | |
| 55 | 61 | @Override |
| 56 | - public void fullySyncCustomer(MultipartFile file) { | |
| 57 | - | |
| 62 | + public void fullySyncCustomer(MultipartFile file, String group, String entity, String pipelineCode, String documentType) { | |
| 63 | + try (var inputStream = file.getInputStream()) { | |
| 64 | + Optional.ofNullable(file.getOriginalFilename()).orElseThrow(() -> new TaxAgentServiceException(TaxSystemType.MISSING_BUSINESS_INFORMATION, "未找到文件")); | |
| 65 | + String originalFilename = file.getOriginalFilename(); | |
| 66 | + String extension = FilenameUtils.getExtension(originalFilename).toLowerCase(); | |
| 67 | + var book = switch (extension) { | |
| 68 | + case "xlsx" -> new XSSFWorkbook(inputStream); | |
| 69 | + case "xls" -> new HSSFWorkbook(inputStream); | |
| 70 | + default -> throw new TaxAgentServiceException(TaxSystemType.BUSINESS_MATCHES_ARE_INCORRECT, "未支持的文件格式"); | |
| 71 | + }; | |
| 72 | + List<Map<String, Object>> list = ExcelUtils.processSheet(book); | |
| 73 | + Optional<TenantPipeline> pipelineOptional = taxTenantService.findByTenantAndPipelineCode(group, entity, pipelineCode); | |
| 74 | + TenantPipeline pipeline = pipelineOptional.orElseThrow(() -> new TaxAgentServiceException(TaxSystemType.NO_MATCHING_SET_OF_ACCOUNTS_FOUND, "未找到匹配账套")); | |
| 75 | + list.forEach(map -> { | |
| 76 | + ReceiveMessageCO receiveMessageCO = new ReceiveMessageCO(); | |
| 77 | + receiveMessageCO.setMsgBody(map); | |
| 78 | + receiveMessageCO.setGroup(group); | |
| 79 | + receiveMessageCO.setEntity(entity); | |
| 80 | + receiveMessageCO.setPipelineCode(pipelineCode); | |
| 81 | + receiveMessageCO.setSystemType(pipeline.getSystemType().code); | |
| 82 | + receiveMessageCO.setDocumentType(documentType); | |
| 83 | + rabbitTemplate.convertAndSend(NORMAL_EXCHANGE, NORMAL_ROUTING, JsonUtils.toJsonString(receiveMessageCO)); | |
| 84 | + }); | |
| 85 | + } catch (IOException e) { | |
| 86 | + throw new TaxAgentServiceException(e.getMessage()); | |
| 87 | + } | |
| 58 | 88 | } |
| 59 | 89 | } | ... | ... |
tax-adopt/src/main/java/com/diligrp/tax/adopt/util/ExcelUtils.java
0 → 100644
| 1 | +package com.diligrp.tax.adopt.util; | |
| 2 | + | |
| 3 | +import com.diligrp.tax.central.exception.TaxAgentServiceException; | |
| 4 | +import com.diligrp.tax.central.type.TaxSystemType; | |
| 5 | +import org.apache.poi.ss.usermodel.Workbook; | |
| 6 | + | |
| 7 | +import java.util.*; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * @Author: zhangmeiyang | |
| 11 | + * @CreateTime: 2025-11-19 15:11 | |
| 12 | + * @Version: todo | |
| 13 | + */ | |
| 14 | +public class ExcelUtils { | |
| 15 | + public static List<Map<String, Object>> processSheet(Workbook book) { | |
| 16 | + var res = new ArrayList<Map<String, Object>>(); | |
| 17 | + Optional.ofNullable(book).orElseThrow(() -> new TaxAgentServiceException(TaxSystemType.ABNORMAL_PARAMETERS, "文件转换异常")); | |
| 18 | + book.sheetIterator().forEachRemaining(sheet -> sheet.rowIterator().forEachRemaining(row -> { | |
| 19 | + var map = new HashMap<String, Object>(); | |
| 20 | + row.cellIterator().forEachRemaining(cell -> map.put(cell.getStringCellValue(), cell.getStringCellValue())); | |
| 21 | + res.add(map); | |
| 22 | + })); | |
| 23 | + return res; | |
| 24 | + } | |
| 25 | +} | ... | ... |