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,6 +34,7 @@ | ||
| 34 | <mybatis-plus.version>3.5.14</mybatis-plus.version> | 34 | <mybatis-plus.version>3.5.14</mybatis-plus.version> |
| 35 | <!-- 工具类库 --> | 35 | <!-- 工具类库 --> |
| 36 | <lombok.version>1.18.42</lombok.version> | 36 | <lombok.version>1.18.42</lombok.version> |
| 37 | + <poi.version>5.5.0</poi.version> | ||
| 37 | </properties> | 38 | </properties> |
| 38 | 39 | ||
| 39 | <dependencyManagement> | 40 | <dependencyManagement> |
| @@ -69,6 +70,16 @@ | @@ -69,6 +70,16 @@ | ||
| 69 | <artifactId>mysql-connector-j</artifactId> | 70 | <artifactId>mysql-connector-j</artifactId> |
| 70 | <version>${mysql-connector.version}</version> | 71 | <version>${mysql-connector.version}</version> |
| 71 | </dependency> | 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 | </dependencies> | 83 | </dependencies> |
| 73 | </dependencyManagement> | 84 | </dependencyManagement> |
| 74 | 85 |
tax-adopt/pom.xml
| @@ -8,14 +8,23 @@ | @@ -8,14 +8,23 @@ | ||
| 8 | <artifactId>tax-agent</artifactId> | 8 | <artifactId>tax-agent</artifactId> |
| 9 | <version>${revision}</version> | 9 | <version>${revision}</version> |
| 10 | </parent> | 10 | </parent> |
| 11 | + <artifactId>tax-adopt</artifactId> | ||
| 12 | + | ||
| 11 | <dependencies> | 13 | <dependencies> |
| 12 | <dependency> | 14 | <dependency> |
| 13 | <groupId>com.diligrp</groupId> | 15 | <groupId>com.diligrp</groupId> |
| 14 | <artifactId>tax-central</artifactId> | 16 | <artifactId>tax-central</artifactId> |
| 15 | <version>${revision}</version> | 17 | <version>${revision}</version> |
| 16 | </dependency> | 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 | </dependencies> | 27 | </dependencies> |
| 18 | 28 | ||
| 19 | - <artifactId>tax-adopt</artifactId> | ||
| 20 | 29 | ||
| 21 | -</project> | ||
| 22 | \ No newline at end of file | 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,6 +3,7 @@ package com.diligrp.tax.adopt.api; | ||
| 3 | import com.diligrp.tax.adopt.model.ReceiveMessageCO; | 3 | import com.diligrp.tax.adopt.model.ReceiveMessageCO; |
| 4 | import com.diligrp.tax.adopt.service.AdoptMessageService; | 4 | import com.diligrp.tax.adopt.service.AdoptMessageService; |
| 5 | import com.diligrp.tax.central.message.Message; | 5 | import com.diligrp.tax.central.message.Message; |
| 6 | +import jakarta.validation.constraints.NotNull; | ||
| 6 | import lombok.AllArgsConstructor; | 7 | import lombok.AllArgsConstructor; |
| 7 | import org.springframework.web.bind.annotation.*; | 8 | import org.springframework.web.bind.annotation.*; |
| 8 | import org.springframework.web.multipart.MultipartFile; | 9 | import org.springframework.web.multipart.MultipartFile; |
| @@ -18,15 +19,31 @@ public class AdoptMessageController { | @@ -18,15 +19,31 @@ public class AdoptMessageController { | ||
| 18 | private final AdoptMessageService adoptMessageService; | 19 | private final AdoptMessageService adoptMessageService; |
| 19 | 20 | ||
| 20 | 21 | ||
| 22 | + /** | ||
| 23 | + * 接收消息 | ||
| 24 | + * | ||
| 25 | + * @param receiveMessageCO 接收消息 | ||
| 26 | + * @return {@link Message }<{@link ? }> | ||
| 27 | + */ | ||
| 21 | @PostMapping("/message") | 28 | @PostMapping("/message") |
| 22 | public Message<?> receiveMessage(@RequestBody ReceiveMessageCO receiveMessageCO) { | 29 | public Message<?> receiveMessage(@RequestBody ReceiveMessageCO receiveMessageCO) { |
| 23 | adoptMessageService.convertMessage(receiveMessageCO); | 30 | adoptMessageService.convertMessage(receiveMessageCO); |
| 24 | return Message.success(); | 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 | return Message.success(); | 47 | return Message.success(); |
| 31 | } | 48 | } |
| 32 | } | 49 | } |
tax-adopt/src/main/java/com/diligrp/tax/adopt/model/ReceiveMessageCO.java
| @@ -42,5 +42,8 @@ public class ReceiveMessageCO { | @@ -42,5 +42,8 @@ public class ReceiveMessageCO { | ||
| 42 | */ | 42 | */ |
| 43 | private Map<String, Object> msgBody; | 43 | private Map<String, Object> msgBody; |
| 44 | 44 | ||
| 45 | - private SystemType systemType; | 45 | + /** |
| 46 | + * 系统类型 | ||
| 47 | + */ | ||
| 48 | + private String systemType; | ||
| 46 | } | 49 | } |
tax-adopt/src/main/java/com/diligrp/tax/adopt/service/AdoptMessageService.java
| 1 | package com.diligrp.tax.adopt.service; | 1 | package com.diligrp.tax.adopt.service; |
| 2 | 2 | ||
| 3 | import com.diligrp.tax.adopt.model.ReceiveMessageCO; | 3 | import com.diligrp.tax.adopt.model.ReceiveMessageCO; |
| 4 | +import jakarta.validation.constraints.NotNull; | ||
| 4 | import org.springframework.web.multipart.MultipartFile; | 5 | import org.springframework.web.multipart.MultipartFile; |
| 5 | 6 | ||
| 6 | /** | 7 | /** |
| @@ -9,6 +10,8 @@ import org.springframework.web.multipart.MultipartFile; | @@ -9,6 +10,8 @@ import org.springframework.web.multipart.MultipartFile; | ||
| 9 | public interface AdoptMessageService { | 10 | public interface AdoptMessageService { |
| 10 | 11 | ||
| 11 | /** | 12 | /** |
| 13 | + * 转换消息 | ||
| 14 | + * | ||
| 12 | * @param receiveMessageCO 接收消息 | 15 | * @param receiveMessageCO 接收消息 |
| 13 | */ | 16 | */ |
| 14 | void convertMessage(ReceiveMessageCO receiveMessageCO); | 17 | void convertMessage(ReceiveMessageCO receiveMessageCO); |
| @@ -16,7 +19,11 @@ public interface AdoptMessageService { | @@ -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,19 +2,25 @@ package com.diligrp.tax.adopt.service.impl; | ||
| 2 | 2 | ||
| 3 | import com.diligrp.tax.adopt.model.ReceiveMessageCO; | 3 | import com.diligrp.tax.adopt.model.ReceiveMessageCO; |
| 4 | import com.diligrp.tax.adopt.service.AdoptMessageService; | 4 | import com.diligrp.tax.adopt.service.AdoptMessageService; |
| 5 | +import com.diligrp.tax.adopt.util.ExcelUtils; | ||
| 5 | import com.diligrp.tax.central.exception.TaxAgentServiceException; | 6 | import com.diligrp.tax.central.exception.TaxAgentServiceException; |
| 6 | import com.diligrp.tax.central.model.PipelineBusinessKeyword; | 7 | import com.diligrp.tax.central.model.PipelineBusinessKeyword; |
| 7 | import com.diligrp.tax.central.model.TenantPipeline; | 8 | import com.diligrp.tax.central.model.TenantPipeline; |
| 8 | import com.diligrp.tax.central.service.ITaxPipelineBusinessKeywordService; | 9 | import com.diligrp.tax.central.service.ITaxPipelineBusinessKeywordService; |
| 9 | import com.diligrp.tax.central.service.ITaxTenantService; | 10 | import com.diligrp.tax.central.service.ITaxTenantService; |
| 11 | +import com.diligrp.tax.central.type.TaxSystemType; | ||
| 10 | import com.diligrp.tax.central.utils.AdoptUtils; | 12 | import com.diligrp.tax.central.utils.AdoptUtils; |
| 11 | import com.diligrp.tax.central.utils.JsonUtils; | 13 | import com.diligrp.tax.central.utils.JsonUtils; |
| 12 | import lombok.AllArgsConstructor; | 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 | import org.springframework.amqp.rabbit.core.RabbitTemplate; | 18 | import org.springframework.amqp.rabbit.core.RabbitTemplate; |
| 14 | import org.springframework.stereotype.Service; | 19 | import org.springframework.stereotype.Service; |
| 15 | import org.springframework.util.CollectionUtils; | 20 | import org.springframework.util.CollectionUtils; |
| 16 | import org.springframework.web.multipart.MultipartFile; | 21 | import org.springframework.web.multipart.MultipartFile; |
| 17 | 22 | ||
| 23 | +import java.io.IOException; | ||
| 18 | import java.util.List; | 24 | import java.util.List; |
| 19 | import java.util.Map; | 25 | import java.util.Map; |
| 20 | import java.util.Optional; | 26 | import java.util.Optional; |
| @@ -46,14 +52,38 @@ public class AdoptMessageServiceImpl implements AdoptMessageService { | @@ -46,14 +52,38 @@ public class AdoptMessageServiceImpl implements AdoptMessageService { | ||
| 46 | Map<String, Object> map = AdoptUtils.handleAdopt(pipelineBusinessKeywords, json); | 52 | Map<String, Object> map = AdoptUtils.handleAdopt(pipelineBusinessKeywords, json); |
| 47 | receiveMessageCO.setMsgBody(map); | 53 | receiveMessageCO.setMsgBody(map); |
| 48 | Optional<TenantPipeline> byTenantAndPipelineCode = taxTenantService.findByTenantAndPipelineCode(receiveMessageCO.getGroup(), receiveMessageCO.getEntity(), receiveMessageCO.getPipelineCode()); | 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 | // 发送mq | 56 | // 发送mq |
| 51 | String messageJson = JsonUtils.toJsonString(receiveMessageCO); | 57 | String messageJson = JsonUtils.toJsonString(receiveMessageCO); |
| 52 | rabbitTemplate.convertAndSend(NORMAL_EXCHANGE, NORMAL_ROUTING, messageJson); | 58 | rabbitTemplate.convertAndSend(NORMAL_EXCHANGE, NORMAL_ROUTING, messageJson); |
| 53 | } | 59 | } |
| 54 | 60 | ||
| 55 | @Override | 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 | +} |