From aa4c6b5c8667fd03d6449800036db346c1a41327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LI-CCONG=5C=E6=9D=8E=E8=81=AA=E8=81=AA?= <1441652193@qq.com> Date: Fri, 18 Aug 2023 16:44:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AD=97=E6=AE=B5=E5=8A=A0=E5=AF=86=E8=A7=A3?= =?UTF-8?q?=E5=AF=86=E5=8A=9F=E8=83=BD=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mybatis/core/type/EncryptTypeHandler.java | 1 + .../controller/admin/DemoTestController.java | 43 ++++++++++++++++--- .../material/vo/MaterialExportTestVO.java | 3 ++ .../convert/material/MaterialXConvert.java | 24 +++++++++++ .../dal/dataobject/material/MaterialXDO.java | 17 +++++++- .../dal/mysql/material/MaterialXMapper.java | 15 +++++++ .../db/DataSourceConfigServiceImplTest.java | 15 +++---- .../test/resources/application-unit-test.yaml | 2 + .../src/main/resources/application.yaml | 1 + 9 files changed, 106 insertions(+), 15 deletions(-) create mode 100644 yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/convert/material/MaterialXConvert.java create mode 100644 yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/dal/mysql/material/MaterialXMapper.java diff --git a/yunxi-framework/yunxi-spring-boot-starter-mybatis/src/main/java/com/yunxi/scm/framework/mybatis/core/type/EncryptTypeHandler.java b/yunxi-framework/yunxi-spring-boot-starter-mybatis/src/main/java/com/yunxi/scm/framework/mybatis/core/type/EncryptTypeHandler.java index ea029a9..985358f 100644 --- a/yunxi-framework/yunxi-spring-boot-starter-mybatis/src/main/java/com/yunxi/scm/framework/mybatis/core/type/EncryptTypeHandler.java +++ b/yunxi-framework/yunxi-spring-boot-starter-mybatis/src/main/java/com/yunxi/scm/framework/mybatis/core/type/EncryptTypeHandler.java @@ -67,6 +67,7 @@ public class EncryptTypeHandler extends BaseTypeHandler { } // 构建 AES String password = SpringUtil.getProperty(ENCRYPTOR_PROPERTY_NAME); +// String password = Optional.ofNullable(SpringUtil.getProperty(ENCRYPTOR_PROPERTY_NAME)).orElse("X+aZvWkl9jtRP9b2"); Assert.notEmpty(password, "配置项({}) 不能为空", ENCRYPTOR_PROPERTY_NAME); aes = SecureUtil.aes(password.getBytes()); return aes; diff --git a/yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/controller/admin/DemoTestController.java b/yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/controller/admin/DemoTestController.java index f35bba5..e0ea321 100644 --- a/yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/controller/admin/DemoTestController.java +++ b/yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/controller/admin/DemoTestController.java @@ -2,11 +2,13 @@ package com.yunxi.scm.module.demo.controller.admin; import com.yunxi.scm.framework.common.pojo.CommonResult; import com.yunxi.scm.framework.excel.core.util.ExcelUtils; +import com.yunxi.scm.framework.mybatis.core.query.LambdaQueryWrapperX; import com.yunxi.scm.framework.operatelog.core.annotations.OperateLog; import com.yunxi.scm.module.demo.controller.admin.material.vo.MaterialExportTestVO; import com.yunxi.scm.module.demo.controller.admin.material.vo.MaterialImportTestVO; -import com.yunxi.scm.module.demo.convert.material.MaterialConvert; +import com.yunxi.scm.module.demo.convert.material.MaterialXConvert; import com.yunxi.scm.module.demo.dal.dataobject.material.MaterialXDO; +import com.yunxi.scm.module.demo.dal.mysql.material.MaterialXMapper; import com.yunxi.scm.module.demo.enums.material.CategoryEnum; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -16,6 +18,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import javax.annotation.Resource; import javax.annotation.security.PermitAll; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -23,6 +26,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; +import java.util.stream.Stream; import static com.yunxi.scm.framework.common.pojo.CommonResult.success; import static com.yunxi.scm.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; @@ -47,12 +51,12 @@ public class DemoTestController { @PermitAll @OperateLog(type = EXPORT) public void testExport(HttpServletResponse response) throws IOException { - MaterialXDO xdo1 = new MaterialXDO(Arrays.asList("1","2")); - MaterialXDO xdo2 = new MaterialXDO(Arrays.asList("1","3")); + MaterialXDO xdo1 = new MaterialXDO(1L,"80inu5yxl3",Arrays.asList("1","2")); + MaterialXDO xdo2 = new MaterialXDO(2L,"Q2ZY1I9cCBf0YKvDUlzCbw==",Arrays.asList("1","3")); List xdos = new ArrayList<>(); xdos.add(xdo1); xdos.add(xdo2); - List datas = MaterialConvert.INSTANCE.convertList03(xdos); + List datas = MaterialXConvert.INSTANCE.convertList03(xdos); ExcelUtils.write(response, "测试导出.xls", "数据", MaterialExportTestVO.class, datas); } @@ -76,8 +80,8 @@ public class DemoTestController { @PermitAll @Operation(summary = "获得导入模板") public void importTemplate(HttpServletResponse response) throws IOException { - List values = Arrays.asList(CategoryEnum.COMMON.getCode(),CategoryEnum.KANJIA.getCode()) - .stream().map(v-> String.valueOf(v)).collect(Collectors.toList()); + List values = Stream.of(CategoryEnum.COMMON.getCode(),CategoryEnum.KANJIA.getCode()) + .map(String::valueOf).collect(Collectors.toList()); // 手动创建导出 demo List list = Arrays.asList( MaterialImportTestVO.builder().category(values).build() @@ -85,4 +89,31 @@ public class DemoTestController { // 输出 ExcelUtils.write(response, "导入模板.xls", "物料标准模版", MaterialImportTestVO.class, list); } + + @Resource + MaterialXMapper materialXMapper; + + @GetMapping("/test_encrypt") + @Operation(summary = "测试字段加密") + @PermitAll + public CommonResult testEncrypt() { + MaterialXDO xdo1 = new MaterialXDO(1L,"80inu5yxl3",Arrays.asList("1","2")); + MaterialXDO xdo2 = new MaterialXDO(2L,"80inu5yxl3",Arrays.asList("1","3")); + List xdos = new ArrayList<>(); + xdos.add(xdo1); + xdos.add(xdo2); + materialXMapper.insertBatch(xdos); + return success("ok"); + } + + @GetMapping("/test_decrypt") + @Operation(summary = "测试字段解密") + @PermitAll + public CommonResult testDecrypt() { + LambdaQueryWrapperX wrapperX = new LambdaQueryWrapperX<>(); + wrapperX.eq(MaterialXDO::getId, 1); + MaterialXDO xdo = materialXMapper.selectOne(wrapperX); + return success(MaterialXConvert.INSTANCE.convert(xdo)); + } + } diff --git a/yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/controller/admin/material/vo/MaterialExportTestVO.java b/yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/controller/admin/material/vo/MaterialExportTestVO.java index 2a63529..55330c8 100644 --- a/yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/controller/admin/material/vo/MaterialExportTestVO.java +++ b/yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/controller/admin/material/vo/MaterialExportTestVO.java @@ -12,6 +12,9 @@ import java.util.List; @Data public class MaterialExportTestVO { + @ExcelProperty(value = "密码") + private String password; + @ExcelProperty(value = "分类测试", converter = MutilDictConvert.class) @DictFormat(DictTypeConstants.TRADE_ORDER_TYPE) private List category; diff --git a/yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/convert/material/MaterialXConvert.java b/yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/convert/material/MaterialXConvert.java new file mode 100644 index 0000000..b59f25f --- /dev/null +++ b/yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/convert/material/MaterialXConvert.java @@ -0,0 +1,24 @@ +package com.yunxi.scm.module.demo.convert.material; + +import com.yunxi.scm.module.demo.controller.admin.material.vo.MaterialExportTestVO; +import com.yunxi.scm.module.demo.dal.dataobject.material.MaterialXDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * 物料管理 Convert + * + * @author ccongli + */ +@Mapper +public interface MaterialXConvert { + + MaterialXConvert INSTANCE = Mappers.getMapper(MaterialXConvert.class); + + MaterialExportTestVO convert(MaterialXDO xdo); + + List convertList03(List list); + +} diff --git a/yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/dal/dataobject/material/MaterialXDO.java b/yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/dal/dataobject/material/MaterialXDO.java index 686cae9..f0c246e 100644 --- a/yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/dal/dataobject/material/MaterialXDO.java +++ b/yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/dal/dataobject/material/MaterialXDO.java @@ -1,15 +1,30 @@ package com.yunxi.scm.module.demo.dal.dataobject.material; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.yunxi.scm.framework.mybatis.core.type.EncryptTypeHandler; +import com.yunxi.scm.framework.mybatis.core.type.StringListTypeHandler; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import java.io.Serializable; import java.util.List; @Data @NoArgsConstructor @AllArgsConstructor -public class MaterialXDO { +@TableName(value = "demo_xxx", autoResultMap = true) +public class MaterialXDO implements Serializable { + @TableId + private Long id; + + // 字段加密注解 + @TableField(typeHandler = EncryptTypeHandler.class) + private String password; + + @TableField(typeHandler = StringListTypeHandler.class) private List category; } diff --git a/yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/dal/mysql/material/MaterialXMapper.java b/yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/dal/mysql/material/MaterialXMapper.java new file mode 100644 index 0000000..ea31e5b --- /dev/null +++ b/yunxi-module-demo/yunxi-module-demo-biz/src/main/java/com/yunxi/scm/module/demo/dal/mysql/material/MaterialXMapper.java @@ -0,0 +1,15 @@ +package com.yunxi.scm.module.demo.dal.mysql.material; + +import com.yunxi.scm.framework.mybatis.core.mapper.BaseMapperX; +import com.yunxi.scm.module.demo.dal.dataobject.material.MaterialXDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 测试专用 Mapper + * + * @author ccongli + */ +@Mapper +public interface MaterialXMapper extends BaseMapperX { + +} diff --git a/yunxi-module-infra/yunxi-module-infra-biz/src/test/java/com/yunxi/scm/module/infra/service/db/DataSourceConfigServiceImplTest.java b/yunxi-module-infra/yunxi-module-infra-biz/src/test/java/com/yunxi/scm/module/infra/service/db/DataSourceConfigServiceImplTest.java index 89d01d4..46f6f54 100644 --- a/yunxi-module-infra/yunxi-module-infra-biz/src/test/java/com/yunxi/scm/module/infra/service/db/DataSourceConfigServiceImplTest.java +++ b/yunxi-module-infra/yunxi-module-infra-biz/src/test/java/com/yunxi/scm/module/infra/service/db/DataSourceConfigServiceImplTest.java @@ -1,8 +1,9 @@ package com.yunxi.scm.module.infra.service.db; import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.ReflectUtil; import cn.hutool.crypto.symmetric.AES; +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty; +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties; import com.yunxi.scm.framework.mybatis.core.type.EncryptTypeHandler; import com.yunxi.scm.framework.mybatis.core.util.JdbcUtils; import com.yunxi.scm.framework.test.core.ut.BaseDbUnitTest; @@ -10,12 +11,9 @@ import com.yunxi.scm.module.infra.controller.admin.db.vo.DataSourceConfigCreateR import com.yunxi.scm.module.infra.controller.admin.db.vo.DataSourceConfigUpdateReqVO; import com.yunxi.scm.module.infra.dal.dataobject.db.DataSourceConfigDO; import com.yunxi.scm.module.infra.dal.mysql.db.DataSourceConfigMapper; -import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty; -import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; -import org.mockito.stubbing.Answer; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; @@ -28,7 +26,6 @@ import static com.yunxi.scm.framework.test.core.util.RandomUtils.randomLongId; import static com.yunxi.scm.framework.test.core.util.RandomUtils.randomPojo; import static com.yunxi.scm.module.infra.enums.ErrorCodeConstants.DATA_SOURCE_CONFIG_NOT_EXISTS; import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.when; @@ -56,9 +53,9 @@ public class DataSourceConfigServiceImplTest extends BaseDbUnitTest { @BeforeEach public void setUp() { // mock 一个空实现的 StringEncryptor,避免 EncryptTypeHandler 报错 - ReflectUtil.setFieldValue(EncryptTypeHandler.class, "aes", aes); - when(aes.encryptBase64(anyString())).then((Answer) invocation -> invocation.getArgument(0)); - when(aes.decryptStr(anyString())).then((Answer) invocation -> invocation.getArgument(0)); +// ReflectUtil.setFieldValue(EncryptTypeHandler.class, "aes", aes); +// when(aes.encryptBase64(anyString())).then((Answer) invocation -> invocation.getArgument(0)); +// when(aes.decryptStr(anyString())).then((Answer) invocation -> invocation.getArgument(0)); // mock DynamicDataSourceProperties when(dynamicDataSourceProperties.getPrimary()).thenReturn("primary"); @@ -145,6 +142,8 @@ public class DataSourceConfigServiceImplTest extends BaseDbUnitTest { DataSourceConfigDO dbDataSourceConfig = randomPojo(DataSourceConfigDO.class); dataSourceConfigMapper.insert(dbDataSourceConfig);// @Sql: 先插入出一条存在的数据 + System.out.println(dbDataSourceConfig.getPassword()); + System.out.println(EncryptTypeHandler.encrypt(dbDataSourceConfig.getPassword())); // 调用 DataSourceConfigDO result = dataSourceConfigMapper.selectOne(DataSourceConfigDO::getPassword, EncryptTypeHandler.encrypt(dbDataSourceConfig.getPassword())); diff --git a/yunxi-module-infra/yunxi-module-infra-biz/src/test/resources/application-unit-test.yaml b/yunxi-module-infra/yunxi-module-infra-biz/src/test/resources/application-unit-test.yaml index b994814..2684a2d 100644 --- a/yunxi-module-infra/yunxi-module-infra-biz/src/test/resources/application-unit-test.yaml +++ b/yunxi-module-infra/yunxi-module-infra-biz/src/test/resources/application-unit-test.yaml @@ -29,6 +29,8 @@ spring: mybatis-plus: lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 type-aliases-package: ${yunxi.info.base-package}.module.*.dal.dataobject + encryptor: + password: X+aZvWkl9jtRP9b2 --- #################### 定时任务相关配置 #################### diff --git a/yunxi-server/src/main/resources/application.yaml b/yunxi-server/src/main/resources/application.yaml index c4fdadf..b73a62d 100644 --- a/yunxi-server/src/main/resources/application.yaml +++ b/yunxi-server/src/main/resources/application.yaml @@ -194,6 +194,7 @@ yunxi: - rep_demo_jianpiao - tmp_report_data_1 - tmp_report_data_income + - demo_xxx sms-code: # 短信验证码相关的配置项 expire-times: 10m send-frequency: 1m