From 65797fa2bf9effa91f313162da0cb3d6dbd942ea Mon Sep 17 00:00:00 2001 From: chenwenjian Date: Fri, 22 Dec 2023 18:58:22 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat(REQ-1980):=20=E6=94=AF=E6=8C=81excel?= =?UTF-8?q?=E5=AF=BC=E5=85=A5=E9=BB=91=E7=99=BD=E5=90=8D=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nanopart/api/BlackAndWhiteListApi.java | 20 +++ .../BlackAndWhiteListExcelImportReq.java | 47 +++++++ .../BlackAndWhiteListExcelImportResp.java | 31 +++++ .../api/BlackAndWhiteListApiTest.java | 12 ++ .../BlackAndWhiteListController.java | 23 ++++ .../service/BlackAndWhiteListService.java | 6 + .../impl/BlackAndWhiteListServiceImpl.java | 128 ++++++++++++++++++ black-list/pom.xml | 24 +++- pom.xml | 7 + 9 files changed, 291 insertions(+), 7 deletions(-) create mode 100644 black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/request/BlackAndWhiteListExcelImportReq.java create mode 100644 black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/response/BlackAndWhiteListExcelImportResp.java create mode 100644 black-list/black-list-api/src/test/java/cn/axzo/nanopart/api/BlackAndWhiteListApiTest.java diff --git a/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/BlackAndWhiteListApi.java b/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/BlackAndWhiteListApi.java index 0083c319..06a55d0f 100644 --- a/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/BlackAndWhiteListApi.java +++ b/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/BlackAndWhiteListApi.java @@ -1,13 +1,22 @@ package cn.axzo.nanopart.api; import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.nanopart.api.constant.enums.ListTypeEnum; +import cn.axzo.nanopart.api.request.BlackAndWhiteListExcelImportReq; import cn.axzo.nanopart.api.request.BlackAndWhiteListReq; +import cn.axzo.nanopart.api.response.BlackAndWhiteListExcelImportResp; import cn.axzo.nanopart.api.response.BlackAndWhiteListResp; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.multipart.MultipartFile; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.IOException; import java.util.List; /** @@ -52,4 +61,15 @@ public interface BlackAndWhiteListApi { @PostMapping("api/black-white-list/is-in") ApiResult isInBlackOrWhiteList(@RequestBody @Validated BlackAndWhiteListReq req); + /** + * 通过excel导入黑白名单 + * + * @param req excel文件 {@link BlackAndWhiteListExcelImportReq} + * @return 导入结果 + */ + @PostMapping("api/black-white-list/import") + ApiResult importBlackAndWhiteListExcel(@RequestParam(value = "type") @NotNull(message = "名单类型不能为空")ListTypeEnum type, + @RequestParam(value = "module") @NotBlank(message = "模块不能为空")String module, + @RequestParam(value = "url", required = false) String url, + @RequestPart(value = "file")MultipartFile file); } diff --git a/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/request/BlackAndWhiteListExcelImportReq.java b/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/request/BlackAndWhiteListExcelImportReq.java new file mode 100644 index 00000000..e32045ff --- /dev/null +++ b/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/request/BlackAndWhiteListExcelImportReq.java @@ -0,0 +1,47 @@ +package cn.axzo.nanopart.api.request; + +import cn.axzo.nanopart.api.constant.enums.ListTypeEnum; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.web.multipart.MultipartFile; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 黑白名单excel导入入参 + * + * @author chenwenjian + * @version 1.0 + * @date 2023/12/22 15:37 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class BlackAndWhiteListExcelImportReq { + + /** + * excel文件地址,url和file二选一,若有url则忽略file + */ + private String url; + + /** + * excel文件,url和file二选一,若有url则忽略file + */ + private MultipartFile file; + + /** + * 业务模块名,如:“cms-register”,”attendance-pass“ + */ + @NotBlank(message = "module名不能为空") + private String module; + + /** + * 黑白名单类型,0-黑名单,1-白名单 + */ + @NotNull(message = "名单类型不能为空") + private ListTypeEnum type; +} diff --git a/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/response/BlackAndWhiteListExcelImportResp.java b/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/response/BlackAndWhiteListExcelImportResp.java new file mode 100644 index 00000000..f3427aff --- /dev/null +++ b/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/response/BlackAndWhiteListExcelImportResp.java @@ -0,0 +1,31 @@ +package cn.axzo.nanopart.api.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Map; + +/** + * 黑白名单导入返回结果 + * + * @author chenwenjian + * @version 1.0 + * @date 2023/12/21 18:48 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class BlackAndWhiteListExcelImportResp { + /** + * 导入结果,0表示全部导入成功,1表示部分导入成功,2表示全部导入失败 + */ + private Integer result; + + /** + * 只有result导入失败的行号和错误信息,key为行号,value为错误信息 + */ + private Map errorMap; +} diff --git a/black-list/black-list-api/src/test/java/cn/axzo/nanopart/api/BlackAndWhiteListApiTest.java b/black-list/black-list-api/src/test/java/cn/axzo/nanopart/api/BlackAndWhiteListApiTest.java new file mode 100644 index 00000000..a521cb15 --- /dev/null +++ b/black-list/black-list-api/src/test/java/cn/axzo/nanopart/api/BlackAndWhiteListApiTest.java @@ -0,0 +1,12 @@ +package cn.axzo.nanopart.api; + +/** + * @author chenwenjian + * @version 1.0 + * @date 2023/12/22 15:17 + */ +public class BlackAndWhiteListApiTest { + + + +} diff --git a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/controller/BlackAndWhiteListController.java b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/controller/BlackAndWhiteListController.java index ac9efcdf..b9e62e36 100644 --- a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/controller/BlackAndWhiteListController.java +++ b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/controller/BlackAndWhiteListController.java @@ -3,13 +3,28 @@ package cn.axzo.nanopart.server.controller; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.nanopart.api.BlackAndWhiteListApi; +import cn.axzo.nanopart.api.constant.enums.ListTypeEnum; +import cn.axzo.nanopart.api.request.BlackAndWhiteListExcelImportReq; import cn.axzo.nanopart.api.request.BlackAndWhiteListReq; +import cn.axzo.nanopart.api.response.BlackAndWhiteListExcelImportResp; import cn.axzo.nanopart.api.response.BlackAndWhiteListResp; +import cn.axzo.nanopart.server.dao.entity.SaasBlackWhiteList; import cn.axzo.nanopart.server.service.BlackAndWhiteListService; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; import lombok.RequiredArgsConstructor; +import org.json.JSONObject; +import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @author: chenwenjian @@ -23,6 +38,7 @@ import java.util.List; public class BlackAndWhiteListController implements BlackAndWhiteListApi { private final BlackAndWhiteListService blackAndWhiteListService; + @Override public ApiResult create(BlackAndWhiteListReq req) { return blackAndWhiteListService.create(req); @@ -42,4 +58,11 @@ public class BlackAndWhiteListController implements BlackAndWhiteListApi { public ApiResult isInBlackOrWhiteList(BlackAndWhiteListReq req) { return blackAndWhiteListService.isInBlackOrWhiteList(req); } + + @Override + public ApiResult importBlackAndWhiteListExcel(ListTypeEnum type, String module, String url, MultipartFile file) { + return blackAndWhiteListService.importBlackAndWhiteListExcel(type, module, url, file); + } + + } diff --git a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/BlackAndWhiteListService.java b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/BlackAndWhiteListService.java index 8987ad75..ff0fd933 100644 --- a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/BlackAndWhiteListService.java +++ b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/BlackAndWhiteListService.java @@ -1,8 +1,12 @@ package cn.axzo.nanopart.server.service; import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.nanopart.api.constant.enums.ListTypeEnum; +import cn.axzo.nanopart.api.request.BlackAndWhiteListExcelImportReq; import cn.axzo.nanopart.api.request.BlackAndWhiteListReq; +import cn.axzo.nanopart.api.response.BlackAndWhiteListExcelImportResp; import cn.axzo.nanopart.api.response.BlackAndWhiteListResp; +import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -24,4 +28,6 @@ public interface BlackAndWhiteListService { ApiResult isInBlackOrWhiteList(BlackAndWhiteListReq req); + ApiResult importBlackAndWhiteListExcel(ListTypeEnum type, String module, String url, MultipartFile file); + } diff --git a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/impl/BlackAndWhiteListServiceImpl.java b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/impl/BlackAndWhiteListServiceImpl.java index 2b2cb9a6..2ec81b69 100644 --- a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/impl/BlackAndWhiteListServiceImpl.java +++ b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/impl/BlackAndWhiteListServiceImpl.java @@ -4,17 +4,31 @@ import cn.axzo.basics.common.BeanMapper; import cn.axzo.basics.common.exception.ServiceException; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.nanopart.api.constant.enums.ListTypeEnum; +import cn.axzo.nanopart.api.request.BlackAndWhiteListExcelImportReq; import cn.axzo.nanopart.api.request.BlackAndWhiteListReq; +import cn.axzo.nanopart.api.response.BlackAndWhiteListExcelImportResp; import cn.axzo.nanopart.api.response.BlackAndWhiteListResp; import cn.axzo.nanopart.server.dao.entity.SaasBlackWhiteList; import cn.axzo.nanopart.server.dao.repository.BlackAndWhiteListRepository; import cn.axzo.nanopart.server.service.BlackAndWhiteListService; import cn.hutool.core.collection.CollectionUtil; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * @author: chenwenjian @@ -82,4 +96,118 @@ public class BlackAndWhiteListServiceImpl implements BlackAndWhiteListService { List blackWhiteLists = blackAndWhiteListRepository.detail(req); return ApiResult.ok(CollectionUtil.isNotEmpty(blackWhiteLists)); } + + @Override + public ApiResult importBlackAndWhiteListExcel(ListTypeEnum type, String module, String url, MultipartFile file) { + InputStream inputStream = null; + BlackAndWhiteListExcelImportResp importResp = new BlackAndWhiteListExcelImportResp(); + // 获取文件 + try { + inputStream = file.getInputStream(); + if (StringUtils.hasText(url)) { + inputStream = new URL(url).openStream(); + } + } catch (IOException e) { + throw new ServiceException("文件读取异常"); + } + // 使用EasyExcel解析文件 + List> excelData = readExcel(inputStream, importResp); + // 将数据写入数据库 + writeDataToDatabase(excelData, module, type.getValue()); + return null; + } + + /** + * 使用EasyExcel读取Excel数据 + * + * @param inputStream + * @param importResp + * @return + */ + public List> readExcel(InputStream inputStream, BlackAndWhiteListExcelImportResp importResp) { + // 存储读取的每一行数据 + List> dataList = new ArrayList<>(); + + // 使用EasyExcel读取数据 + EasyExcel.read(inputStream, new AnalysisEventListener>() { + private boolean firstRow = true; + + // 所有列名 + private List headerList = new ArrayList<>(); + + /** + * 读取每一行数据 + * @param rowData 每一行数据 + * @param context 上下文 + */ + @Override + public void invoke(Map rowData, AnalysisContext context) { + if (firstRow) { + headerList.addAll(rowData.values()); + firstRow = false; + } else { + Map dataMap = new HashMap<>(); + for (Map.Entry entry : rowData.entrySet()) { + int columnIndex = entry.getKey(); + String columnName = headerList.get(columnIndex); + dataMap.put(columnName, entry.getValue()); + } + dataList.add(dataMap); + } + } + + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + // 解析完成后的操作 + try { + inputStream.close(); + } catch (IOException e) { + throw new ServiceException("资源关闭失败"); + } + } + }).autoTrim(true).ignoreEmptyRow(true).sheet().doRead(); + + return dataList; + } + + + /** + * 将数据转换为JSON对象 + * + * @param dataList + * @return + */ + private List convertExcelDataToJson(List> dataList) { + List jsonList = new ArrayList<>(); + // 遍历数据列表 + for (Map dataMap : dataList) { + com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject(); + // 构造JSON对象 + for (Map.Entry entry : dataMap.entrySet()) { + String columnName = entry.getKey(); + Object columnValue = entry.getValue(); + jsonObject.put(columnName, columnValue); + } + jsonList.add(jsonObject); + } + return jsonList; + } + + /** + * 将数据写入数据库 + * + * @param dataList param参数 + * @param module 模块 + * @return 写入结果 + */ + private Boolean writeDataToDatabase(List> dataList, String module, Integer type) { + List list = dataList.stream().map(map -> { + SaasBlackWhiteList blackWhiteList = new SaasBlackWhiteList(); + blackWhiteList.setType(type); + blackWhiteList.setModule(module); + blackWhiteList.setParam(map); + return blackWhiteList; + }).collect(Collectors.toList()); + return blackAndWhiteListRepository.saveBatch(list); + } } \ No newline at end of file diff --git a/black-list/pom.xml b/black-list/pom.xml index c9135890..50a52c62 100644 --- a/black-list/pom.xml +++ b/black-list/pom.xml @@ -19,11 +19,21 @@ black-list-service - - - - - - - + + + + org.apache.poi + poi-ooxml + ${poi.version} + + + + + com.alibaba + easyexcel + ${easyexcel.version} + + + + diff --git a/pom.xml b/pom.xml index c57ee360..38182ced 100644 --- a/pom.xml +++ b/pom.xml @@ -22,6 +22,8 @@ 2.0.0-SNAPSHOT 1.18.22 1.4.2.Final + 5.2.2 + 3.3.3 @@ -57,6 +59,11 @@ lombok + + cn.hutool + hutool-all + + From e85bacd3508936907eb3d803fb9e47f81b6b42c1 Mon Sep 17 00:00:00 2001 From: chenwenjian Date: Tue, 26 Dec 2023 11:40:57 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat(REQ-1980):=20excel=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E8=A1=A8=E5=A4=B4=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nanopart/api/BlackAndWhiteListApi.java | 2 +- .../BlackAndWhiteListExcelImportResp.java | 4 +- .../BlackAndWhiteListController.java | 6 ++- .../service/BlackAndWhiteListService.java | 3 +- .../impl/BlackAndWhiteListServiceImpl.java | 51 ++++++++++++------- 5 files changed, 43 insertions(+), 23 deletions(-) diff --git a/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/BlackAndWhiteListApi.java b/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/BlackAndWhiteListApi.java index 06a55d0f..91ee7005 100644 --- a/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/BlackAndWhiteListApi.java +++ b/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/BlackAndWhiteListApi.java @@ -64,7 +64,7 @@ public interface BlackAndWhiteListApi { /** * 通过excel导入黑白名单 * - * @param req excel文件 {@link BlackAndWhiteListExcelImportReq} + * * @return 导入结果 */ @PostMapping("api/black-white-list/import") diff --git a/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/response/BlackAndWhiteListExcelImportResp.java b/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/response/BlackAndWhiteListExcelImportResp.java index f3427aff..1d971573 100644 --- a/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/response/BlackAndWhiteListExcelImportResp.java +++ b/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/response/BlackAndWhiteListExcelImportResp.java @@ -20,9 +20,9 @@ import java.util.Map; @AllArgsConstructor public class BlackAndWhiteListExcelImportResp { /** - * 导入结果,0表示全部导入成功,1表示部分导入成功,2表示全部导入失败 + * 导入结果,true表示导入成功,false表示导入失败 */ - private Integer result; + private Boolean result; /** * 只有result导入失败的行号和错误信息,key为行号,value为错误信息 diff --git a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/controller/BlackAndWhiteListController.java b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/controller/BlackAndWhiteListController.java index b9e62e36..80c46d44 100644 --- a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/controller/BlackAndWhiteListController.java +++ b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/controller/BlackAndWhiteListController.java @@ -14,6 +14,8 @@ import com.alibaba.excel.EasyExcel; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.annotations.Select; import org.json.JSONObject; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RestController; @@ -33,6 +35,7 @@ import java.util.Map; * @modifiedBy: * @version: 1.0` */ +@Slf4j @RestController @RequiredArgsConstructor public class BlackAndWhiteListController implements BlackAndWhiteListApi { @@ -61,7 +64,8 @@ public class BlackAndWhiteListController implements BlackAndWhiteListApi { @Override public ApiResult importBlackAndWhiteListExcel(ListTypeEnum type, String module, String url, MultipartFile file) { - return blackAndWhiteListService.importBlackAndWhiteListExcel(type, module, url, file); + log.info("导入Excel数据参数:type={}, module={}, url={}, file={}", type, module, url, file); + return ApiResult.ok(blackAndWhiteListService.importBlackAndWhiteListExcel(type, module, url, file)); } diff --git a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/BlackAndWhiteListService.java b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/BlackAndWhiteListService.java index ff0fd933..60d66ca1 100644 --- a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/BlackAndWhiteListService.java +++ b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/BlackAndWhiteListService.java @@ -2,7 +2,6 @@ package cn.axzo.nanopart.server.service; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.nanopart.api.constant.enums.ListTypeEnum; -import cn.axzo.nanopart.api.request.BlackAndWhiteListExcelImportReq; import cn.axzo.nanopart.api.request.BlackAndWhiteListReq; import cn.axzo.nanopart.api.response.BlackAndWhiteListExcelImportResp; import cn.axzo.nanopart.api.response.BlackAndWhiteListResp; @@ -28,6 +27,6 @@ public interface BlackAndWhiteListService { ApiResult isInBlackOrWhiteList(BlackAndWhiteListReq req); - ApiResult importBlackAndWhiteListExcel(ListTypeEnum type, String module, String url, MultipartFile file); + BlackAndWhiteListExcelImportResp importBlackAndWhiteListExcel(ListTypeEnum type, String module, String url, MultipartFile file); } diff --git a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/impl/BlackAndWhiteListServiceImpl.java b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/impl/BlackAndWhiteListServiceImpl.java index 2ec81b69..f635298b 100644 --- a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/impl/BlackAndWhiteListServiceImpl.java +++ b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/impl/BlackAndWhiteListServiceImpl.java @@ -4,7 +4,6 @@ import cn.axzo.basics.common.BeanMapper; import cn.axzo.basics.common.exception.ServiceException; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.nanopart.api.constant.enums.ListTypeEnum; -import cn.axzo.nanopart.api.request.BlackAndWhiteListExcelImportReq; import cn.axzo.nanopart.api.request.BlackAndWhiteListReq; import cn.axzo.nanopart.api.response.BlackAndWhiteListExcelImportResp; import cn.axzo.nanopart.api.response.BlackAndWhiteListResp; @@ -46,6 +45,7 @@ public class BlackAndWhiteListServiceImpl implements BlackAndWhiteListService { /** * 新增一条黑白名单记录 + * * @param req 包含type,module和param三个字段 * @return 记录id */ @@ -53,12 +53,12 @@ public class BlackAndWhiteListServiceImpl implements BlackAndWhiteListService { public ApiResult create(BlackAndWhiteListReq req) { // 黑白名单创建互斥,若存在于黑名单中则不允许存在于白名单中,反之亦然 BlackAndWhiteListReq reverseReq = BeanMapper.copyBean(req, BlackAndWhiteListReq.class, (req1, req2) -> req2.setType((req1.getType().equals(ListTypeEnum.BLACK_LIST)) ? ListTypeEnum.WHITE_LIST : ListTypeEnum.BLACK_LIST)); - if (isInBlackOrWhiteList(reverseReq).getData()){ - throw new ServiceException("该记录已存在于"+reverseReq.getType().getDescription()+"中,不能创建对应"+req.getType().getDescription()); + if (isInBlackOrWhiteList(reverseReq).getData()) { + throw new ServiceException("该记录已存在于" + reverseReq.getType().getDescription() + "中,不能创建对应" + req.getType().getDescription()); } // 同类型名单内唯一性校验 - if (isInBlackOrWhiteList(req).getData()){ - throw new ServiceException("该记录已存在于"+req.getType().getDescription()+"中"); + if (isInBlackOrWhiteList(req).getData()) { + throw new ServiceException("该记录已存在于" + req.getType().getDescription() + "中"); } return ApiResult.ok(blackAndWhiteListRepository.create(req)); } @@ -76,6 +76,7 @@ public class BlackAndWhiteListServiceImpl implements BlackAndWhiteListService { /** * 查询指定条件的所有黑白名单记录 + * * @param req 包含type,module和param三个字段 * @return 记录列表 */ @@ -88,6 +89,7 @@ public class BlackAndWhiteListServiceImpl implements BlackAndWhiteListService { /** * 判断是否存在指定条件的黑白名单记录 + * * @param req 包含type,module和param三个字段 * @return 记录存在返回true,否则返回false */ @@ -97,13 +99,21 @@ public class BlackAndWhiteListServiceImpl implements BlackAndWhiteListService { return ApiResult.ok(CollectionUtil.isNotEmpty(blackWhiteLists)); } + /** + * 导入黑白名单Excel文件 + * + * @param type 名单类型 + * @param module 模块 + * @param url 文件url,如果为空则从文件流中读取 + * @param file 文件流 + */ @Override - public ApiResult importBlackAndWhiteListExcel(ListTypeEnum type, String module, String url, MultipartFile file) { + public BlackAndWhiteListExcelImportResp importBlackAndWhiteListExcel(ListTypeEnum type, String module, String url, MultipartFile file) { InputStream inputStream = null; BlackAndWhiteListExcelImportResp importResp = new BlackAndWhiteListExcelImportResp(); // 获取文件 try { - inputStream = file.getInputStream(); + inputStream = file.getInputStream(); if (StringUtils.hasText(url)) { inputStream = new URL(url).openStream(); } @@ -113,8 +123,8 @@ public class BlackAndWhiteListServiceImpl implements BlackAndWhiteListService { // 使用EasyExcel解析文件 List> excelData = readExcel(inputStream, importResp); // 将数据写入数据库 - writeDataToDatabase(excelData, module, type.getValue()); - return null; + importResp.setResult(writeDataToDatabase(excelData, module, type.getValue())); + return importResp; } /** @@ -130,10 +140,15 @@ public class BlackAndWhiteListServiceImpl implements BlackAndWhiteListService { // 使用EasyExcel读取数据 EasyExcel.read(inputStream, new AnalysisEventListener>() { - private boolean firstRow = true; - // 所有列名 - private List headerList = new ArrayList<>(); + // 表头 + private Map header; + + @Override + public void invokeHeadMap(Map headMap, AnalysisContext context) { + log.info("表头信息:{}", headMap); + header = headMap; + } /** * 读取每一行数据 @@ -142,17 +157,19 @@ public class BlackAndWhiteListServiceImpl implements BlackAndWhiteListService { */ @Override public void invoke(Map rowData, AnalysisContext context) { - if (firstRow) { - headerList.addAll(rowData.values()); - firstRow = false; - } else { + try { + log.info("第{}行数据:{}", context.readRowHolder().getRowIndex(), rowData); Map dataMap = new HashMap<>(); for (Map.Entry entry : rowData.entrySet()) { int columnIndex = entry.getKey(); - String columnName = headerList.get(columnIndex); + String columnName = header.get(columnIndex); dataMap.put(columnName, entry.getValue()); } dataList.add(dataMap); + } catch (Exception e) { + HashMap errorMap = new HashMap<>(); + errorMap.put(Long.valueOf(context.readRowHolder().getRowIndex()), e.getMessage()); + importResp.setErrorMap(errorMap); } } From c0bae49ed3c4212662783df74f765a8d78021655 Mon Sep 17 00:00:00 2001 From: chenwenjian Date: Tue, 26 Dec 2023 15:47:18 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat(REQ-1980):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E9=80=9A=E8=BF=87id=E6=89=B9=E9=87=8F=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E5=90=8D=E5=8D=95=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nanopart/api/BlackAndWhiteListApi.java | 22 ++++- .../BlackAndWhiteListController.java | 6 +- .../BlackAndWhiteListRepository.java | 8 ++ .../service/BlackAndWhiteListService.java | 1 + .../impl/BlackAndWhiteListServiceImpl.java | 17 ++++ .../nanopart/NanopartApplicationTests.java | 97 +++++++++++++++++++ 6 files changed, 145 insertions(+), 6 deletions(-) diff --git a/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/BlackAndWhiteListApi.java b/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/BlackAndWhiteListApi.java index 91ee7005..1a1bba5a 100644 --- a/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/BlackAndWhiteListApi.java +++ b/black-list/black-list-api/src/main/java/cn/axzo/nanopart/api/BlackAndWhiteListApi.java @@ -8,6 +8,7 @@ import cn.axzo.nanopart.api.response.BlackAndWhiteListExcelImportResp; import cn.axzo.nanopart.api.response.BlackAndWhiteListResp; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; @@ -15,6 +16,7 @@ import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.multipart.MultipartFile; import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.io.IOException; import java.util.List; @@ -31,6 +33,7 @@ public interface BlackAndWhiteListApi { /** * 创建黑名单或白名单 + * * @param req 包含type,module,params三个字段 * @return 记录id */ @@ -39,14 +42,25 @@ public interface BlackAndWhiteListApi { /** * 删除黑名单或白名单 + * * @param req 包含type,module,params三个字段 * @return void */ @PostMapping("api/black-white-list/delete") ApiResult delete(@RequestBody @Validated BlackAndWhiteListReq req); + /** + * 批量删除黑名单或白名单 + * + * @param ids 黑白名单id列表 + * @return true-删除成功,false-删除失败 + */ + @GetMapping("/api/black-white-list/delete-by-id") + ApiResult deleteByIds(@RequestParam(value = "ids") @NotEmpty(message = "id不能为空") List ids); + /** * 查询黑名单或白名单 + * * @param req 包含type,module,params三个字段 * @return 黑白名单记录列表 */ @@ -55,6 +69,7 @@ public interface BlackAndWhiteListApi { /** * 判断指定模块、指定参数记录是否在黑名单或白名单中 + * * @param req 包含type,module,params三个字段 * @return 若记录存在则返回true,否则返回false */ @@ -64,12 +79,9 @@ public interface BlackAndWhiteListApi { /** * 通过excel导入黑白名单 * - * * @return 导入结果 */ @PostMapping("api/black-white-list/import") - ApiResult importBlackAndWhiteListExcel(@RequestParam(value = "type") @NotNull(message = "名单类型不能为空")ListTypeEnum type, - @RequestParam(value = "module") @NotBlank(message = "模块不能为空")String module, - @RequestParam(value = "url", required = false) String url, - @RequestPart(value = "file")MultipartFile file); + ApiResult importBlackAndWhiteListExcel(@RequestParam(value = "type") @NotNull(message = "名单类型不能为空") ListTypeEnum type, + @RequestParam(value = "module") @NotBlank(message = "模块不能为空") String module, @RequestParam(value = "url", required = false) String url, @RequestPart(value = "file") MultipartFile file); } diff --git a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/controller/BlackAndWhiteListController.java b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/controller/BlackAndWhiteListController.java index 80c46d44..fee9a255 100644 --- a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/controller/BlackAndWhiteListController.java +++ b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/controller/BlackAndWhiteListController.java @@ -52,6 +52,11 @@ public class BlackAndWhiteListController implements BlackAndWhiteListApi { return blackAndWhiteListService.delete(req); } + @Override + public ApiResult deleteByIds(List ids) { + return ApiResult.ok(blackAndWhiteListService.deleteByIds(ids)); + } + @Override public ApiResult> detail(BlackAndWhiteListReq req) { return blackAndWhiteListService.detail(req); @@ -68,5 +73,4 @@ public class BlackAndWhiteListController implements BlackAndWhiteListApi { return ApiResult.ok(blackAndWhiteListService.importBlackAndWhiteListExcel(type, module, url, file)); } - } diff --git a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/dao/repository/BlackAndWhiteListRepository.java b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/dao/repository/BlackAndWhiteListRepository.java index 1bfbeddf..4c69e6de 100644 --- a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/dao/repository/BlackAndWhiteListRepository.java +++ b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/dao/repository/BlackAndWhiteListRepository.java @@ -17,6 +17,7 @@ import org.springframework.stereotype.Repository; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Set; /** * @author: chenwenjian @@ -75,4 +76,11 @@ public class BlackAndWhiteListRepository extends ServiceImpl idSet) { + return lambdaUpdate() + .in(SaasBlackWhiteList::getId, idSet) + .set(SaasBlackWhiteList::getIsDelete, 1) + .update(); + } } \ No newline at end of file diff --git a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/BlackAndWhiteListService.java b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/BlackAndWhiteListService.java index 60d66ca1..4ceeed1f 100644 --- a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/BlackAndWhiteListService.java +++ b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/BlackAndWhiteListService.java @@ -29,4 +29,5 @@ public interface BlackAndWhiteListService { BlackAndWhiteListExcelImportResp importBlackAndWhiteListExcel(ListTypeEnum type, String module, String url, MultipartFile file); + Boolean deleteByIds(List ids); } diff --git a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/impl/BlackAndWhiteListServiceImpl.java b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/impl/BlackAndWhiteListServiceImpl.java index f635298b..6452b9e8 100644 --- a/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/impl/BlackAndWhiteListServiceImpl.java +++ b/black-list/black-list-service/src/main/java/cn/axzo/nanopart/server/service/impl/BlackAndWhiteListServiceImpl.java @@ -25,8 +25,10 @@ import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; /** @@ -127,6 +129,21 @@ public class BlackAndWhiteListServiceImpl implements BlackAndWhiteListService { return importResp; } + /** + * 批量删除黑白名单记录 + * + * @param ids 记录id列表 + * @return true-删除成功,false-删除失败 + */ + @Override + public Boolean deleteByIds(List ids) { + if (CollectionUtil.isNotEmpty(ids)) { + Set idSet = new HashSet<>(ids); + return blackAndWhiteListRepository.deleteByIds(idSet); + } + return true; + } + /** * 使用EasyExcel读取Excel数据 * diff --git a/nanopart-server/src/test/java/cn/axzo/nanopart/NanopartApplicationTests.java b/nanopart-server/src/test/java/cn/axzo/nanopart/NanopartApplicationTests.java index 9de4dd20..dbcf7842 100644 --- a/nanopart-server/src/test/java/cn/axzo/nanopart/NanopartApplicationTests.java +++ b/nanopart-server/src/test/java/cn/axzo/nanopart/NanopartApplicationTests.java @@ -1,15 +1,34 @@ package cn.axzo.nanopart; +import cn.axzo.basics.common.exception.ServiceException; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.nanopart.api.BlackAndWhiteListApi; +import cn.axzo.nanopart.api.constant.enums.ListTypeEnum; import cn.axzo.nanopart.api.request.BlackAndWhiteListReq; import cn.axzo.nanopart.api.response.BlackAndWhiteListResp; +import cn.axzo.nanopart.server.dao.entity.SaasBlackWhiteList; +import cn.hutool.extra.spring.SpringUtil; +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONUtil; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import lombok.extern.slf4j.Slf4j; +import okhttp3.RequestBody; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import javax.annotation.Resource; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Function; /** * @author: chenwenjian @@ -18,12 +37,17 @@ import java.util.List; * @modifiedBy: * @version: 1.0 */ +@Slf4j @SpringBootTest public class NanopartApplicationTests { + private final String[] envs ={"dev", "test", "pre", "prod"}; + @Resource private BlackAndWhiteListApi blackAndWhiteListApi; + private + @Test void contextLoad(){ BlackAndWhiteListReq blackAndWhiteListReq = new BlackAndWhiteListReq(); @@ -35,4 +59,77 @@ public class NanopartApplicationTests { ApiResult> detail = blackAndWhiteListApi.detail(blackAndWhiteListReq); System.out.println(detail.getData().toString()); } + + @Test + void batchAdd(){ + // 指定环境和文件路径 + String env = "test"; + String type = "BLACK_LIST"; + // String filePath = "C:\\Users\\admin\\Desktop\\企业黑名单.xlsx"; + // String module = "gxjg-blackcompany"; + String filePath = "C:\\Users\\admin\\Desktop\\产业工人黑名单.xlsx"; + String module = "gxjg-blackuser-worker"; + + HashMap envMap = new HashMap<>(); + envMap.put("dev", "https://dev-app.axzo.cn/"); + envMap.put("test", "https://test-api.axzo.cn/"); + envMap.put("pre", "https://pre-api.axzo.cn/"); + envMap.put("prod", "https://api.axzo.cn/"); + + // 存储读取的每一行数据 + List> dataList = new ArrayList<>(); + + // 使用EasyExcel读取数据 + EasyExcel.read(filePath, new AnalysisEventListener>() { + + // 表头 + private Map header; + + @Override + public void invokeHeadMap(Map headMap, AnalysisContext context) { + log.info("表头信息:{}", headMap); + header = headMap; + } + + /** + * 读取每一行数据 + * @param rowData 每一行数据 + * @param context 上下文 + */ + @Override + public void invoke(Map rowData, AnalysisContext context) { + log.info("第{}行数据:{}", context.readRowHolder().getRowIndex(), rowData); + Map dataMap = new HashMap<>(); + for (Map.Entry entry : rowData.entrySet()) { + int columnIndex = entry.getKey(); + String columnName = header.get(columnIndex); + dataMap.put(columnName, entry.getValue()); + } + dataList.add(dataMap); + } + + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + // 解析完成后的操作 + } + }).autoTrim(true).ignoreEmptyRow(true).sheet().doRead(); + + // 发送请求 + dataList.stream().map(map -> { + HashMap body = new HashMap<>(); + body.put("module", module); + body.put("type", type); + body.put("param", map); + return JSONUtil.toJsonStr(body); + }).forEach(body -> { + // 构建参数 + String result = HttpRequest.post(envMap.get(env) + SpringUtil.getApplicationName() + "/api/black-white-list/create") + .body(body, "application/json") + .execute().body(); + log.info("请求结果:{}", result); + }); + + + + } }