Browse Source

1. 管理后台,增加租户管理
2. 修复大量因为租户报错的单元测试

YunaiV 3 years ago
parent
commit
098c5b4723
45 changed files with 1239 additions and 177 deletions
  1. 86 9
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/tenant/SysTenantController.java
  2. 30 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/tenant/vo/SysTenantBaseVO.java
  3. 14 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/tenant/vo/SysTenantCreateReqVO.java
  4. 39 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/tenant/vo/SysTenantExcelVO.java
  5. 36 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/tenant/vo/SysTenantExportReqVO.java
  6. 41 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/tenant/vo/SysTenantPageReqVO.java
  7. 19 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/tenant/vo/SysTenantRespVO.java
  8. 18 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/tenant/vo/SysTenantUpdateReqVO.java
  9. 36 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/convert/tenant/SysTenantConvert.java
  10. 44 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/tenant/SysTenantMapper.java
  11. 3 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/SysErrorCodeConstants.java
  12. 83 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/tenant/SysTenantService.java
  13. 91 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/tenant/impl/SysTenantServiceImpl.java
  14. 4 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/tool/service/codegen/impl/ToolCodegenEngine.java
  15. 5 5
      yudao-admin-server/src/main/resources/codegen/java/test/serviceTest.vm
  16. 1 1
      yudao-admin-server/src/main/resources/mybatis-config/mybatis-config.xml
  17. 8 8
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/infra/service/config/InfConfigServiceTest.java
  18. 3 3
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/infra/service/file/InfFileServiceTest.java
  19. 11 11
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/infra/service/job/InfJobLogServiceTest.java
  20. 7 7
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/infra/service/job/InfJobServiceTest.java
  21. 14 14
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/infra/service/logger/InfApiAccessLogServiceImplTest.java
  22. 17 18
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/infra/service/logger/InfApiErrorLogServiceImplTest.java
  23. 2 2
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysUserSessionServiceImplTest.java
  24. 2 2
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/dept/SysDeptServiceTest.java
  25. 4 4
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/dept/SysPostServiceTest.java
  26. 6 9
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/dict/SysDictDataServiceTest.java
  27. 8 8
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/dict/SysDictTypeServiceTest.java
  28. 5 5
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/errorcode/SysErrorCodeServiceTest.java
  29. 8 8
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/SysLoginLogServiceImplTest.java
  30. 10 10
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/SysOperateLogServiceImplTest.java
  31. 2 2
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/notice/SysNoticeServiceImplTest.java
  32. 3 3
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/sms/SysSmsChannelServiceTest.java
  33. 14 14
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/sms/SysSmsLogServiceTest.java
  34. 14 14
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/sms/SysSmsTemplateServiceTest.java
  35. 181 0
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/tenant/SysTenantServiceTest.java
  36. 5 6
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserServiceImplTest.java
  37. 1 0
      yudao-admin-server/src/test/resources/sql/clean.sql
  38. 25 3
      yudao-admin-server/src/test/resources/sql/create_tables.sql
  39. 48 6
      yudao-admin-ui/src/api/system/tenant.js
  40. 259 0
      yudao-admin-ui/src/views/system/tenant/index.vue
  41. 3 0
      yudao-core-service/src/test-integration/resources/application-integration-test.yaml
  42. 4 1
      yudao-core-service/src/test/java/cn/iocoder/yudao/coreservice/modules/system/service/auth/SysUserSessionCoreServiceTest.java
  43. 6 0
      yudao-core-service/src/test/resources/sql/create_tables.sql
  44. 16 1
      yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/ObjectUtils.java
  45. 3 2
      更新日志.md

+ 86 - 9
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/tenant/SysTenantController.java

@@ -1,29 +1,106 @@
 package cn.iocoder.yudao.adminserver.modules.system.controller.tenant;
 package cn.iocoder.yudao.adminserver.modules.system.controller.tenant;
 
 
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.*;
+import cn.iocoder.yudao.adminserver.modules.system.convert.tenant.SysTenantConvert;
+import cn.iocoder.yudao.adminserver.modules.system.service.tenant.SysTenantService;
+import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.tenant.SysTenantDO;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiOperation;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
 
 
-import java.util.Objects;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
 
 
 @Api(tags = "租户")
 @Api(tags = "租户")
 @RestController
 @RestController
 @RequestMapping("/system/tenant")
 @RequestMapping("/system/tenant")
 public class SysTenantController {
 public class SysTenantController {
 
 
+    @Resource
+    private SysTenantService tenantService;
+
     @GetMapping("/get-id-by-name")
     @GetMapping("/get-id-by-name")
     @ApiOperation(value = "使用租户名,获得租户编号", notes = "登录界面,根据用户的租户名,获得租户编号")
     @ApiOperation(value = "使用租户名,获得租户编号", notes = "登录界面,根据用户的租户名,获得租户编号")
     @ApiImplicitParam(name = "name", value = "租户名", required = true, example = "芋道源码", dataTypeClass = Long.class)
     @ApiImplicitParam(name = "name", value = "租户名", required = true, example = "芋道源码", dataTypeClass = Long.class)
     public CommonResult<Long> getTenantIdByName(@RequestParam("name") String name) {
     public CommonResult<Long> getTenantIdByName(@RequestParam("name") String name) {
-        if (Objects.equals("芋道源码", name)) {
-            return CommonResult.success(1L);
-        }
-        return CommonResult.success(null);
+        SysTenantDO tenantDO = tenantService.getTenantByName(name);
+        return success(tenantDO != null ? tenantDO.getId() : null);
     }
     }
 
 
+    @PostMapping("/create")
+    @ApiOperation("创建租户")
+    @PreAuthorize("@ss.hasPermission('system:tenant:create')")
+    public CommonResult<Long> createTenant(@Valid @RequestBody SysTenantCreateReqVO createReqVO) {
+        return success(tenantService.createTenant(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @ApiOperation("更新租户")
+    @PreAuthorize("@ss.hasPermission('system:tenant:update')")
+    public CommonResult<Boolean> updateTenant(@Valid @RequestBody SysTenantUpdateReqVO updateReqVO) {
+        tenantService.updateTenant(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @ApiOperation("删除租户")
+    @ApiImplicitParam(name = "id", value = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('system:tenant:delete')")
+    public CommonResult<Boolean> deleteTenant(@RequestParam("id") Long id) {
+        tenantService.deleteTenant(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @ApiOperation("获得租户")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
+    @PreAuthorize("@ss.hasPermission('system:tenant:query')")
+    public CommonResult<SysTenantRespVO> getTenant(@RequestParam("id") Long id) {
+        SysTenantDO tenant = tenantService.getTenant(id);
+        return success(SysTenantConvert.INSTANCE.convert(tenant));
+    }
+
+    @GetMapping("/list")
+    @ApiOperation("获得租户列表")
+    @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
+    @PreAuthorize("@ss.hasPermission('system:tenant:query')")
+    public CommonResult<List<SysTenantRespVO>> getTenantList(@RequestParam("ids") Collection<Long> ids) {
+        List<SysTenantDO> list = tenantService.getTenantList(ids);
+        return success(SysTenantConvert.INSTANCE.convertList(list));
+    }
+
+    @GetMapping("/page")
+    @ApiOperation("获得租户分页")
+    @PreAuthorize("@ss.hasPermission('system:tenant:query')")
+    public CommonResult<PageResult<SysTenantRespVO>> getTenantPage(@Valid SysTenantPageReqVO pageVO) {
+        PageResult<SysTenantDO> pageResult = tenantService.getTenantPage(pageVO);
+        return success(SysTenantConvert.INSTANCE.convertPage(pageResult));
+    }
+
+    @GetMapping("/export-excel")
+    @ApiOperation("导出租户 Excel")
+    @PreAuthorize("@ss.hasPermission('system:tenant:export')")
+    @OperateLog(type = EXPORT)
+    public void exportTenantExcel(@Valid SysTenantExportReqVO exportReqVO,
+                                  HttpServletResponse response) throws IOException {
+        List<SysTenantDO> list = tenantService.getTenantList(exportReqVO);
+        // 导出 Excel
+        List<SysTenantExcelVO> datas = SysTenantConvert.INSTANCE.convertList02(list);
+        ExcelUtils.write(response, "租户.xls", "数据", SysTenantExcelVO.class, datas);
+    }
+
+
 }
 }

+ 30 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/tenant/vo/SysTenantBaseVO.java

@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+
+/**
+* 租户 Base VO,提供给添加、修改、详细的子 VO 使用
+* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
+*/
+@Data
+public class SysTenantBaseVO {
+
+    @ApiModelProperty(value = "租户名", required = true, example = "芋道")
+    @NotNull(message = "租户名不能为空")
+    private String name;
+
+    @ApiModelProperty(value = "联系人", required = true, example = "芋艿")
+    @NotNull(message = "联系人不能为空")
+    private String contactName;
+
+    @ApiModelProperty(value = "联系手机", example = "15601691300")
+    private String contactMobile;
+
+    @ApiModelProperty(value = "租户状态(0正常 1停用)", required = true, example = "1")
+    @NotNull(message = "租户状态(0正常 1停用)不能为空")
+    private Integer status;
+
+}

+ 14 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/tenant/vo/SysTenantCreateReqVO.java

@@ -0,0 +1,14 @@
+package cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+
+@ApiModel("租户创建 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SysTenantCreateReqVO extends SysTenantBaseVO {
+
+}

+ 39 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/tenant/vo/SysTenantExcelVO.java

@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
+import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
+
+
+/**
+ * 租户 Excel VO
+ *
+ * @author 芋道源码
+ */
+@Data
+public class SysTenantExcelVO {
+
+    @ExcelProperty("租户编号")
+    private Long id;
+
+    @ExcelProperty("租户名")
+    private String name;
+
+    @ExcelProperty("联系人")
+    private String contactName;
+
+    @ExcelProperty("联系手机")
+    private String contactMobile;
+
+    @ExcelProperty(value = "租户状态(0正常 1停用)", converter = DictConvert.class)
+    @DictFormat("sys_common_status") // TODO 代码优化:建议设置到对应的 XXXDictTypeConstants 枚举类中
+    private Integer status;
+
+    @ExcelProperty("创建时间")
+    private Date createTime;
+
+}

+ 36 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/tenant/vo/SysTenantExportReqVO.java

@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@ApiModel(value = "租户 Excel 导出 Request VO", description = "参数和 SysTenantPageReqVO 是一致的")
+@Data
+public class SysTenantExportReqVO {
+
+    @ApiModelProperty(value = "租户名", example = "芋道")
+    private String name;
+
+    @ApiModelProperty(value = "联系人", example = "芋艿")
+    private String contactName;
+
+    @ApiModelProperty(value = "联系手机", example = "15601691300")
+    private String contactMobile;
+
+    @ApiModelProperty(value = "租户状态(0正常 1停用)", example = "1")
+    private Integer status;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "开始创建时间")
+    private Date beginCreateTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "结束创建时间")
+    private Date endCreateTime;
+
+}

+ 41 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/tenant/vo/SysTenantPageReqVO.java

@@ -0,0 +1,41 @@
+package cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@ApiModel("租户分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SysTenantPageReqVO extends PageParam {
+
+    @ApiModelProperty(value = "租户名", example = "芋道")
+    private String name;
+
+    @ApiModelProperty(value = "联系人", example = "芋艿")
+    private String contactName;
+
+    @ApiModelProperty(value = "联系手机", example = "15601691300")
+    private String contactMobile;
+
+    @ApiModelProperty(value = "租户状态(0正常 1停用)", example = "1")
+    private Integer status;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "开始创建时间")
+    private Date beginCreateTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "结束创建时间")
+    private Date endCreateTime;
+
+}

+ 19 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/tenant/vo/SysTenantRespVO.java

@@ -0,0 +1,19 @@
+package cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+
+@ApiModel("租户 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SysTenantRespVO extends SysTenantBaseVO {
+
+    @ApiModelProperty(value = "租户编号", required = true, example = "1024")
+    private Long id;
+
+    @ApiModelProperty(value = "创建时间", required = true)
+    private Date createTime;
+
+}

+ 18 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/tenant/vo/SysTenantUpdateReqVO.java

@@ -0,0 +1,18 @@
+package cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+
+@ApiModel("租户更新 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SysTenantUpdateReqVO extends SysTenantBaseVO {
+
+    @ApiModelProperty(value = "租户编号", required = true, example = "1024")
+    @NotNull(message = "租户编号不能为空")
+    private Long id;
+
+}

+ 36 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/convert/tenant/SysTenantConvert.java

@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.adminserver.modules.system.convert.tenant;
+
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.SysTenantCreateReqVO;
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.SysTenantExcelVO;
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.SysTenantRespVO;
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.SysTenantUpdateReqVO;
+import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.tenant.SysTenantDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+ * 租户 Convert
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface SysTenantConvert {
+
+    SysTenantConvert INSTANCE = Mappers.getMapper(SysTenantConvert.class);
+
+    SysTenantDO convert(SysTenantCreateReqVO bean);
+
+    SysTenantDO convert(SysTenantUpdateReqVO bean);
+
+    SysTenantRespVO convert(SysTenantDO bean);
+
+    List<SysTenantRespVO> convertList(List<SysTenantDO> list);
+
+    PageResult<SysTenantRespVO> convertPage(PageResult<SysTenantDO> page);
+
+    List<SysTenantExcelVO> convertList02(List<SysTenantDO> list);
+
+}

+ 44 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/tenant/SysTenantMapper.java

@@ -0,0 +1,44 @@
+package cn.iocoder.yudao.adminserver.modules.system.dal.mysql.tenant;
+
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.SysTenantExportReqVO;
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.SysTenantPageReqVO;
+import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.tenant.SysTenantDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 租户 Mapper
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface SysTenantMapper extends BaseMapperX<SysTenantDO> {
+
+    default PageResult<SysTenantDO> selectPage(SysTenantPageReqVO reqVO) {
+        return selectPage(reqVO, new QueryWrapperX<SysTenantDO>()
+                .likeIfPresent("name", reqVO.getName())
+                .likeIfPresent("contact_name", reqVO.getContactName())
+                .likeIfPresent("contact_mobile", reqVO.getContactMobile())
+                .eqIfPresent("status", reqVO.getStatus())
+                .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
+                .orderByDesc("id"));
+    }
+
+    default List<SysTenantDO> selectList(SysTenantExportReqVO reqVO) {
+        return selectList(new QueryWrapperX<SysTenantDO>()
+                .likeIfPresent("name", reqVO.getName())
+                .likeIfPresent("contact_name", reqVO.getContactName())
+                .likeIfPresent("contact_mobile", reqVO.getContactMobile())
+                .eqIfPresent("status", reqVO.getStatus())
+                .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
+                .orderByDesc("id"));
+    }
+
+    default SysTenantDO selectByName(String name) {
+        return selectOne("name", name);
+    }
+}

+ 3 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/SysErrorCodeConstants.java

@@ -85,10 +85,12 @@ public interface SysErrorCodeConstants {
     ErrorCode SMS_TEMPLATE_NOT_EXISTS = new ErrorCode(1002011000, "短信模板不存在");
     ErrorCode SMS_TEMPLATE_NOT_EXISTS = new ErrorCode(1002011000, "短信模板不存在");
     ErrorCode SMS_TEMPLATE_CODE_DUPLICATE = new ErrorCode(1002011001, "已经存在编码为【{}】的短信模板");
     ErrorCode SMS_TEMPLATE_CODE_DUPLICATE = new ErrorCode(1002011001, "已经存在编码为【{}】的短信模板");
 
 
+    // ========== 租户模块 1002012000 ==========
+    ErrorCode TENANT_NOT_EXISTS = new ErrorCode(1002012000, "租户不存在");
+
     // ========== 错误码模块 1002013000 ==========
     // ========== 错误码模块 1002013000 ==========
     ErrorCode ERROR_CODE_NOT_EXISTS = new ErrorCode(1002013000, "错误码不存在");
     ErrorCode ERROR_CODE_NOT_EXISTS = new ErrorCode(1002013000, "错误码不存在");
     ErrorCode ERROR_CODE_DUPLICATE = new ErrorCode(1002013001, "已经存在编码为【{}】的错误码");
     ErrorCode ERROR_CODE_DUPLICATE = new ErrorCode(1002013001, "已经存在编码为【{}】的错误码");
 
 
 
 
-
 }
 }

+ 83 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/tenant/SysTenantService.java

@@ -0,0 +1,83 @@
+package cn.iocoder.yudao.adminserver.modules.system.service.tenant;
+
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.SysTenantCreateReqVO;
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.SysTenantExportReqVO;
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.SysTenantPageReqVO;
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.SysTenantUpdateReqVO;
+import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.tenant.SysTenantDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import javax.validation.Valid;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 租户 Service 接口
+ *
+ * @author 芋道源码
+ */
+public interface SysTenantService {
+
+    /**
+     * 创建租户
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createTenant(@Valid SysTenantCreateReqVO createReqVO);
+
+    /**
+     * 更新租户
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateTenant(@Valid SysTenantUpdateReqVO updateReqVO);
+
+    /**
+     * 删除租户
+     *
+     * @param id 编号
+     */
+    void deleteTenant(Long id);
+
+    /**
+     * 获得租户
+     *
+     * @param id 编号
+     * @return 租户
+     */
+    SysTenantDO getTenant(Long id);
+
+    /**
+     * 获得租户列表
+     *
+     * @param ids 编号
+     * @return 租户列表
+     */
+    List<SysTenantDO> getTenantList(Collection<Long> ids);
+
+    /**
+     * 获得租户分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 租户分页
+     */
+    PageResult<SysTenantDO> getTenantPage(SysTenantPageReqVO pageReqVO);
+
+    /**
+     * 获得租户列表, 用于 Excel 导出
+     *
+     * @param exportReqVO 查询条件
+     * @return 租户列表
+     */
+    List<SysTenantDO> getTenantList(SysTenantExportReqVO exportReqVO);
+
+    /**
+     * 获得名字对应的租户
+     *
+     * @param name 组户名
+     * @return 租户
+     */
+    SysTenantDO getTenantByName(String name);
+
+}

+ 91 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/tenant/impl/SysTenantServiceImpl.java

@@ -0,0 +1,91 @@
+package cn.iocoder.yudao.adminserver.modules.system.service.tenant.impl;
+
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.SysTenantCreateReqVO;
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.SysTenantExportReqVO;
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.SysTenantPageReqVO;
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.SysTenantUpdateReqVO;
+import cn.iocoder.yudao.adminserver.modules.system.convert.tenant.SysTenantConvert;
+import cn.iocoder.yudao.adminserver.modules.system.dal.mysql.tenant.SysTenantMapper;
+import cn.iocoder.yudao.adminserver.modules.system.service.tenant.SysTenantService;
+import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.tenant.SysTenantDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+import java.util.Collection;
+import java.util.List;
+
+import static cn.iocoder.yudao.adminserver.modules.system.enums.SysErrorCodeConstants.TENANT_NOT_EXISTS;
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+
+/**
+ * 租户 Service 实现类
+ *
+ * @author 芋道源码
+ */
+@Service
+@Validated
+public class SysTenantServiceImpl implements SysTenantService {
+
+    @Resource
+    private SysTenantMapper tenantMapper;
+
+    @Override
+    public Long createTenant(SysTenantCreateReqVO createReqVO) {
+        // 插入
+        SysTenantDO tenant = SysTenantConvert.INSTANCE.convert(createReqVO);
+        tenantMapper.insert(tenant);
+        // 返回
+        return tenant.getId();
+    }
+
+    @Override
+    public void updateTenant(SysTenantUpdateReqVO updateReqVO) {
+        // 校验存在
+        this.validateTenantExists(updateReqVO.getId());
+        // 更新
+        SysTenantDO updateObj = SysTenantConvert.INSTANCE.convert(updateReqVO);
+        tenantMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteTenant(Long id) {
+        // 校验存在
+        this.validateTenantExists(id);
+        // 删除
+        tenantMapper.deleteById(id);
+    }
+
+    private void validateTenantExists(Long id) {
+        if (tenantMapper.selectById(id) == null) {
+            throw exception(TENANT_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public SysTenantDO getTenant(Long id) {
+        return tenantMapper.selectById(id);
+    }
+
+    @Override
+    public List<SysTenantDO> getTenantList(Collection<Long> ids) {
+        return tenantMapper.selectBatchIds(ids);
+    }
+
+    @Override
+    public PageResult<SysTenantDO> getTenantPage(SysTenantPageReqVO pageReqVO) {
+        return tenantMapper.selectPage(pageReqVO);
+    }
+
+    @Override
+    public List<SysTenantDO> getTenantList(SysTenantExportReqVO exportReqVO) {
+        return tenantMapper.selectList(exportReqVO);
+    }
+
+    @Override
+    public SysTenantDO getTenantByName(String name) {
+        return tenantMapper.selectByName(name);
+    }
+
+}

+ 4 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/tool/service/codegen/impl/ToolCodegenEngine.java

@@ -10,6 +10,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.adminserver.modules.system.framework.codegen.config.CodegenProperties;
 import cn.iocoder.yudao.adminserver.modules.system.framework.codegen.config.CodegenProperties;
+import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
 import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
 import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
@@ -119,6 +120,8 @@ public class ToolCodegenEngine {
     private void initGlobalBindingMap() {
     private void initGlobalBindingMap() {
         // 全局配置
         // 全局配置
         globalBindingMap.put("basePackage", codegenProperties.getBasePackage());
         globalBindingMap.put("basePackage", codegenProperties.getBasePackage());
+        globalBindingMap.put("baseFrameworkPackage", StrUtil.subBefore(codegenProperties.getBasePackage(),
+                '.', true) + '.' + "framework");
         // 全局 Java Bean
         // 全局 Java Bean
         globalBindingMap.put("CommonResultClassName", CommonResult.class.getName());
         globalBindingMap.put("CommonResultClassName", CommonResult.class.getName());
         globalBindingMap.put("PageResultClassName", PageResult.class.getName());
         globalBindingMap.put("PageResultClassName", PageResult.class.getName());
@@ -134,6 +137,7 @@ public class ToolCodegenEngine {
         globalBindingMap.put("ServiceExceptionUtilClassName", ServiceExceptionUtil.class.getName());
         globalBindingMap.put("ServiceExceptionUtilClassName", ServiceExceptionUtil.class.getName());
         globalBindingMap.put("DateUtilsClassName", DateUtils.class.getName());
         globalBindingMap.put("DateUtilsClassName", DateUtils.class.getName());
         globalBindingMap.put("ExcelUtilsClassName", ExcelUtils.class.getName());
         globalBindingMap.put("ExcelUtilsClassName", ExcelUtils.class.getName());
+        globalBindingMap.put("ObjectUtilsClassName", ObjectUtils.class.getName());
         globalBindingMap.put("DictConvertClassName", DictConvert.class.getName());
         globalBindingMap.put("DictConvertClassName", DictConvert.class.getName());
         globalBindingMap.put("OperateLogClassName", OperateLog.class.getName());
         globalBindingMap.put("OperateLogClassName", OperateLog.class.getName());
         globalBindingMap.put("OperateTypeEnumClassName", OperateTypeEnum.class.getName());
         globalBindingMap.put("OperateTypeEnumClassName", OperateTypeEnum.class.getName());

+ 5 - 5
yudao-admin-server/src/main/resources/codegen/java/test/serviceTest.vm

@@ -10,7 +10,6 @@ import ${basePackage}.modules.${table.moduleName}.service.${table.businessName}.
 import ${basePackage}.modules.${table.moduleName}.controller.${table.businessName}.vo.*;
 import ${basePackage}.modules.${table.moduleName}.controller.${table.businessName}.vo.*;
 import ${basePackage}.modules.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
 import ${basePackage}.modules.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
 import ${basePackage}.modules.${table.moduleName}.dal.mysql.${table.businessName}.${table.className}Mapper;
 import ${basePackage}.modules.${table.moduleName}.dal.mysql.${table.businessName}.${table.className}Mapper;
-import ${basePackage}.util.object.ObjectUtils;
 import ${PageResultClassName};
 import ${PageResultClassName};
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
@@ -19,9 +18,10 @@ import java.util.*;
 
 
 import static cn.hutool.core.util.RandomUtil.*;
 import static cn.hutool.core.util.RandomUtil.*;
 import static ${basePackage}.modules.${table.moduleName}.enums.${simpleModuleName_upperFirst}ErrorCodeConstants.*;
 import static ${basePackage}.modules.${table.moduleName}.enums.${simpleModuleName_upperFirst}ErrorCodeConstants.*;
-import static ${basePackage}.util.AssertUtils.*;
-import static ${basePackage}.util.RandomUtils.*;
-import static ${basePackage}.util.date.DateUtils.*;
+import static ${baseFrameworkPackage}.test.core.util.AssertUtils.*;
+import static ${baseFrameworkPackage}.test.core.util.RandomUtils.*;
+import static ${ObjectUtilsClassName}.*;
+import static ${DateUtilsClassName}.*;
 import static org.junit.jupiter.api.Assertions.*;
 import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.Mockito.*;
 import static org.mockito.Mockito.*;
 
 
@@ -41,7 +41,7 @@ import static org.mockito.Mockito.*;
        #if (${column.listOperation})
        #if (${column.listOperation})
        #set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写
        #set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写
        // 测试 ${column.javaField} 不匹配
        // 测试 ${column.javaField} 不匹配
-       ${classNameVar}Mapper.insert(ObjectUtils.clone(db${simpleClassName}, o -> o.set$JavaField(null)));
+       ${classNameVar}Mapper.insert(cloneIgnoreId(db${simpleClassName}, o -> o.set$JavaField(null)));
        #end
        #end
        #end
        #end
        // 准备参数
        // 准备参数

+ 1 - 1
yudao-admin-server/src/main/resources/mybatis-config/mybatis-config.xml

@@ -6,7 +6,7 @@
     <settings>
     <settings>
         <setting name="lazyLoadingEnabled" value="false" />
         <setting name="lazyLoadingEnabled" value="false" />
         <setting name="mapUnderscoreToCamelCase" value="true"/>
         <setting name="mapUnderscoreToCamelCase" value="true"/>
-        <setting name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/>
+        <setting name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/> <!-- 如果不想打 SQL 日志,可以注释掉 -->
     </settings>
     </settings>
     <typeAliases>
     <typeAliases>
         <typeAlias type="org.activiti.engine.impl.persistence.ByteArrayRefTypeHandler" alias="ByteArrayRefTypeHandler"/>
         <typeAlias type="org.activiti.engine.impl.persistence.ByteArrayRefTypeHandler" alias="ByteArrayRefTypeHandler"/>

+ 8 - 8
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/infra/service/config/InfConfigServiceTest.java

@@ -172,13 +172,13 @@ public class InfConfigServiceTest extends BaseDbUnitTest {
         });
         });
         configMapper.insert(dbConfig);
         configMapper.insert(dbConfig);
         // 测试 name 不匹配
         // 测试 name 不匹配
-        configMapper.insert(ObjectUtils.clone(dbConfig, o -> o.setName("土豆")));
+        configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setName("土豆")));
         // 测试 key 不匹配
         // 测试 key 不匹配
-        configMapper.insert(ObjectUtils.clone(dbConfig, o -> o.setKey("tudou")));
+        configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setKey("tudou")));
         // 测试 type 不匹配
         // 测试 type 不匹配
-        configMapper.insert(ObjectUtils.clone(dbConfig, o -> o.setType(InfConfigTypeEnum.CUSTOM.getType())));
+        configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setType(InfConfigTypeEnum.CUSTOM.getType())));
         // 测试 createTime 不匹配
         // 测试 createTime 不匹配
-        configMapper.insert(ObjectUtils.clone(dbConfig, o -> o.setCreateTime(buildTime(2021, 1, 1))));
+        configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setCreateTime(buildTime(2021, 1, 1))));
         // 准备参数
         // 准备参数
         InfConfigPageReqVO reqVO = new InfConfigPageReqVO();
         InfConfigPageReqVO reqVO = new InfConfigPageReqVO();
         reqVO.setName("艿");
         reqVO.setName("艿");
@@ -206,13 +206,13 @@ public class InfConfigServiceTest extends BaseDbUnitTest {
         });
         });
         configMapper.insert(dbConfig);
         configMapper.insert(dbConfig);
         // 测试 name 不匹配
         // 测试 name 不匹配
-        configMapper.insert(ObjectUtils.clone(dbConfig, o -> o.setName("土豆")));
+        configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setName("土豆")));
         // 测试 key 不匹配
         // 测试 key 不匹配
-        configMapper.insert(ObjectUtils.clone(dbConfig, o -> o.setKey("tudou")));
+        configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setKey("tudou")));
         // 测试 type 不匹配
         // 测试 type 不匹配
-        configMapper.insert(ObjectUtils.clone(dbConfig, o -> o.setType(InfConfigTypeEnum.CUSTOM.getType())));
+        configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setType(InfConfigTypeEnum.CUSTOM.getType())));
         // 测试 createTime 不匹配
         // 测试 createTime 不匹配
-        configMapper.insert(ObjectUtils.clone(dbConfig, o -> o.setCreateTime(buildTime(2021, 1, 1))));
+        configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setCreateTime(buildTime(2021, 1, 1))));
         // 准备参数
         // 准备参数
         InfConfigExportReqVO reqVO = new InfConfigExportReqVO();
         InfConfigExportReqVO reqVO = new InfConfigExportReqVO();
         reqVO.setName("艿");
         reqVO.setName("艿");

+ 3 - 3
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/infra/service/file/InfFileServiceTest.java

@@ -41,14 +41,14 @@ public class InfFileServiceTest extends BaseDbUnitTest {
         });
         });
         fileMapper.insert(dbFile);
         fileMapper.insert(dbFile);
         // 测试 id 不匹配
         // 测试 id 不匹配
-        fileMapper.insert(ObjectUtils.clone(dbFile, o -> o.setId("tudou")));
+        fileMapper.insert(ObjectUtils.cloneIgnoreId(dbFile, o -> o.setId("tudou")));
         // 测试 type 不匹配
         // 测试 type 不匹配
-        fileMapper.insert(ObjectUtils.clone(dbFile, o -> {
+        fileMapper.insert(ObjectUtils.cloneIgnoreId(dbFile, o -> {
             o.setId("yudao02");
             o.setId("yudao02");
             o.setType("png");
             o.setType("png");
         }));
         }));
         // 测试 createTime 不匹配
         // 测试 createTime 不匹配
-        fileMapper.insert(ObjectUtils.clone(dbFile, o -> {
+        fileMapper.insert(ObjectUtils.cloneIgnoreId(dbFile, o -> {
             o.setId("yudao03");
             o.setId("yudao03");
             o.setCreateTime(buildTime(2020, 1, 15));
             o.setCreateTime(buildTime(2020, 1, 15));
         }));
         }));

+ 11 - 11
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/infra/service/job/InfJobLogServiceTest.java

@@ -84,7 +84,7 @@ public class InfJobLogServiceTest extends BaseDbUnitTest {
             o.setExecuteIndex(1);
             o.setExecuteIndex(1);
             o.setStatus(randomEle(InfJobLogStatusEnum.values()).getStatus()); // 保证 status 的范围
             o.setStatus(randomEle(InfJobLogStatusEnum.values()).getStatus()); // 保证 status 的范围
         });
         });
-        InfJobLogDO cloneJobLog = ObjectUtils.clone(dbJobLog, o -> o.setHandlerName(randomString()));
+        InfJobLogDO cloneJobLog = ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setHandlerName(randomString()));
         jobLogMapper.insert(dbJobLog);
         jobLogMapper.insert(dbJobLog);
         // 测试 handlerName 不匹配
         // 测试 handlerName 不匹配
         jobLogMapper.insert(cloneJobLog);
         jobLogMapper.insert(cloneJobLog);
@@ -111,15 +111,15 @@ public class InfJobLogServiceTest extends BaseDbUnitTest {
         });
         });
         jobLogMapper.insert(dbJobLog);
         jobLogMapper.insert(dbJobLog);
         // 测试 jobId 不匹配
         // 测试 jobId 不匹配
-        jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setJobId(randomLongId())));
+        jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setJobId(randomLongId())));
         // 测试 handlerName 不匹配
         // 测试 handlerName 不匹配
-        jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setHandlerName(randomString())));
+        jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setHandlerName(randomString())));
         // 测试 beginTime 不匹配
         // 测试 beginTime 不匹配
-        jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setBeginTime(buildTime(2021, 1, 7))));
+        jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setBeginTime(buildTime(2021, 1, 7))));
         // 测试 endTime 不匹配
         // 测试 endTime 不匹配
-        jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setEndTime(buildTime(2021, 1, 9))));
+        jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setEndTime(buildTime(2021, 1, 9))));
         // 测试 status 不匹配
         // 测试 status 不匹配
-        jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setStatus(InfJobLogStatusEnum.FAILURE.getStatus())));
+        jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setStatus(InfJobLogStatusEnum.FAILURE.getStatus())));
         // 准备参数
         // 准备参数
         InfJobLogPageReqVO reqVo = new InfJobLogPageReqVO();
         InfJobLogPageReqVO reqVo = new InfJobLogPageReqVO();
         reqVo.setJobId(dbJobLog.getJobId());
         reqVo.setJobId(dbJobLog.getJobId());
@@ -147,15 +147,15 @@ public class InfJobLogServiceTest extends BaseDbUnitTest {
         });
         });
         jobLogMapper.insert(dbJobLog);
         jobLogMapper.insert(dbJobLog);
         // 测试 jobId 不匹配
         // 测试 jobId 不匹配
-        jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setJobId(randomLongId())));
+        jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setJobId(randomLongId())));
         // 测试 handlerName 不匹配
         // 测试 handlerName 不匹配
-        jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setHandlerName(randomString())));
+        jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setHandlerName(randomString())));
         // 测试 beginTime 不匹配
         // 测试 beginTime 不匹配
-        jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setBeginTime(buildTime(2021, 1, 7))));
+        jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setBeginTime(buildTime(2021, 1, 7))));
         // 测试 endTime 不匹配
         // 测试 endTime 不匹配
-        jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setEndTime(buildTime(2021, 1, 9))));
+        jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setEndTime(buildTime(2021, 1, 9))));
         // 测试 status 不匹配
         // 测试 status 不匹配
-        jobLogMapper.insert(ObjectUtils.clone(dbJobLog, o -> o.setStatus(InfJobLogStatusEnum.FAILURE.getStatus())));
+        jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setStatus(InfJobLogStatusEnum.FAILURE.getStatus())));
         // 准备参数
         // 准备参数
         InfJobLogExportReqVO reqVo = new InfJobLogExportReqVO();
         InfJobLogExportReqVO reqVo = new InfJobLogExportReqVO();
         reqVo.setJobId(dbJobLog.getJobId());
         reqVo.setJobId(dbJobLog.getJobId());

+ 7 - 7
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/infra/service/job/InfJobServiceTest.java

@@ -230,7 +230,7 @@ public class InfJobServiceTest extends BaseDbUnitTest {
         InfJobDO dbJob = randomPojo(InfJobDO.class, o -> {
         InfJobDO dbJob = randomPojo(InfJobDO.class, o -> {
             o.setStatus(randomEle(InfJobStatusEnum.values()).getStatus()); // 保证 status 的范围
             o.setStatus(randomEle(InfJobStatusEnum.values()).getStatus()); // 保证 status 的范围
         });
         });
-        InfJobDO cloneJob = ObjectUtils.clone(dbJob, o -> o.setHandlerName(randomString()));
+        InfJobDO cloneJob = ObjectUtils.cloneIgnoreId(dbJob, o -> o.setHandlerName(randomString()));
         jobMapper.insert(dbJob);
         jobMapper.insert(dbJob);
         // 测试 handlerName 不匹配
         // 测试 handlerName 不匹配
         jobMapper.insert(cloneJob);
         jobMapper.insert(cloneJob);
@@ -255,11 +255,11 @@ public class InfJobServiceTest extends BaseDbUnitTest {
         });
         });
         jobMapper.insert(dbJob);
         jobMapper.insert(dbJob);
         // 测试 name 不匹配
         // 测试 name 不匹配
-        jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setName("土豆")));
+        jobMapper.insert(ObjectUtils.cloneIgnoreId(dbJob, o -> o.setName("土豆")));
         // 测试 status 不匹配
         // 测试 status 不匹配
-        jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setStatus(InfJobStatusEnum.NORMAL.getStatus())));
+        jobMapper.insert(ObjectUtils.cloneIgnoreId(dbJob, o -> o.setStatus(InfJobStatusEnum.NORMAL.getStatus())));
         // 测试 handlerName 不匹配
         // 测试 handlerName 不匹配
-        jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setHandlerName(randomString())));
+        jobMapper.insert(ObjectUtils.cloneIgnoreId(dbJob, o -> o.setHandlerName(randomString())));
         // 准备参数
         // 准备参数
         InfJobPageReqVO reqVo = new InfJobPageReqVO();
         InfJobPageReqVO reqVo = new InfJobPageReqVO();
         reqVo.setName("定时");
         reqVo.setName("定时");
@@ -283,11 +283,11 @@ public class InfJobServiceTest extends BaseDbUnitTest {
         });
         });
         jobMapper.insert(dbJob);
         jobMapper.insert(dbJob);
         // 测试 name 不匹配
         // 测试 name 不匹配
-        jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setName("土豆")));
+        jobMapper.insert(ObjectUtils.cloneIgnoreId(dbJob, o -> o.setName("土豆")));
         // 测试 status 不匹配
         // 测试 status 不匹配
-        jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setStatus(InfJobStatusEnum.NORMAL.getStatus())));
+        jobMapper.insert(ObjectUtils.cloneIgnoreId(dbJob, o -> o.setStatus(InfJobStatusEnum.NORMAL.getStatus())));
         // 测试 handlerName 不匹配
         // 测试 handlerName 不匹配
-        jobMapper.insert(ObjectUtils.clone(dbJob, o -> o.setHandlerName(randomString())));
+        jobMapper.insert(ObjectUtils.cloneIgnoreId(dbJob, o -> o.setHandlerName(randomString())));
         // 准备参数
         // 准备参数
         InfJobExportReqVO reqVo = new InfJobExportReqVO();
         InfJobExportReqVO reqVo = new InfJobExportReqVO();
         reqVo.setName("定时");
         reqVo.setName("定时");

+ 14 - 14
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/infra/service/logger/InfApiAccessLogServiceImplTest.java

@@ -59,19 +59,19 @@ public class InfApiAccessLogServiceImplTest extends BaseDbUnitTest {
 
 
         // 下面几个都是不匹配的数据
         // 下面几个都是不匹配的数据
         // userId 不同的
         // userId 不同的
-        infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setUserId(3344L)));
+        infApiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setUserId(3344L)));
         // userType
         // userType
-        infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue())));
+        infApiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue())));
         // applicationName 不同的
         // applicationName 不同的
-        infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setApplicationName("test")));
+        infApiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setApplicationName("test")));
         // requestUrl 不同的
         // requestUrl 不同的
-        infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setRequestUrl("bar")));
+        infApiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setRequestUrl("bar")));
         // 构造一个早期时间 2021-02-06 00:00:00
         // 构造一个早期时间 2021-02-06 00:00:00
-        infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setBeginTime(buildTime(2021, 2, 6))));
+        infApiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setBeginTime(buildTime(2021, 2, 6))));
         // duration 不同的
         // duration 不同的
-        infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setDuration(100)));
+        infApiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setDuration(100)));
         // resultCode 不同的
         // resultCode 不同的
-        infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setResultCode(2)));
+        infApiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setResultCode(2)));
 
 
         // 构造调用参数
         // 构造调用参数
         InfApiAccessLogPageReqVO reqVO = new InfApiAccessLogPageReqVO();
         InfApiAccessLogPageReqVO reqVO = new InfApiAccessLogPageReqVO();
@@ -117,19 +117,19 @@ public class InfApiAccessLogServiceImplTest extends BaseDbUnitTest {
 
 
         // 下面几个都是不匹配的数据
         // 下面几个都是不匹配的数据
         // userId 不同的
         // userId 不同的
-        infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setUserId(3344L)));
+        infApiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setUserId(3344L)));
         // userType
         // userType
-        infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue())));
+        infApiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue())));
         // applicationName 不同的
         // applicationName 不同的
-        infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setApplicationName("test")));
+        infApiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setApplicationName("test")));
         // requestUrl 不同的
         // requestUrl 不同的
-        infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setRequestUrl("bar")));
+        infApiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setRequestUrl("bar")));
         // 构造一个早期时间 2021-02-06 00:00:00
         // 构造一个早期时间 2021-02-06 00:00:00
-        infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setBeginTime(buildTime(2021, 2, 6))));
+        infApiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setBeginTime(buildTime(2021, 2, 6))));
         // duration 不同的
         // duration 不同的
-        infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setDuration(100)));
+        infApiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setDuration(100)));
         // resultCode 不同的
         // resultCode 不同的
-        infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setResultCode(2)));
+        infApiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setResultCode(2)));
 
 
         // 构造调用参数
         // 构造调用参数
         InfApiAccessLogExportReqVO reqVO = new InfApiAccessLogExportReqVO();
         InfApiAccessLogExportReqVO reqVO = new InfApiAccessLogExportReqVO();

+ 17 - 18
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/infra/service/logger/InfApiErrorLogServiceImplTest.java

@@ -1,16 +1,16 @@
 package cn.iocoder.yudao.adminserver.modules.infra.service.logger;
 package cn.iocoder.yudao.adminserver.modules.infra.service.logger;
 
 
 import cn.iocoder.yudao.adminserver.BaseDbUnitTest;
 import cn.iocoder.yudao.adminserver.BaseDbUnitTest;
-import cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.logger.InfApiErrorLogDO;
-import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.adminserver.modules.infra.controller.logger.vo.apierrorlog.InfApiErrorLogExportReqVO;
 import cn.iocoder.yudao.adminserver.modules.infra.controller.logger.vo.apierrorlog.InfApiErrorLogExportReqVO;
 import cn.iocoder.yudao.adminserver.modules.infra.controller.logger.vo.apierrorlog.InfApiErrorLogPageReqVO;
 import cn.iocoder.yudao.adminserver.modules.infra.controller.logger.vo.apierrorlog.InfApiErrorLogPageReqVO;
 import cn.iocoder.yudao.adminserver.modules.infra.dal.mysql.logger.InfApiErrorLogMapper;
 import cn.iocoder.yudao.adminserver.modules.infra.dal.mysql.logger.InfApiErrorLogMapper;
 import cn.iocoder.yudao.adminserver.modules.infra.enums.logger.InfApiErrorLogProcessStatusEnum;
 import cn.iocoder.yudao.adminserver.modules.infra.enums.logger.InfApiErrorLogProcessStatusEnum;
 import cn.iocoder.yudao.adminserver.modules.infra.service.logger.impl.InfApiErrorLogServiceImpl;
 import cn.iocoder.yudao.adminserver.modules.infra.service.logger.impl.InfApiErrorLogServiceImpl;
-import cn.iocoder.yudao.framework.test.core.util.RandomUtils;
+import cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.logger.InfApiErrorLogDO;
+import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
+import cn.iocoder.yudao.framework.test.core.util.RandomUtils;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Test;
 import org.springframework.context.annotation.Import;
 import org.springframework.context.annotation.Import;
 
 
@@ -20,11 +20,10 @@ import java.util.List;
 
 
 import static cn.iocoder.yudao.adminserver.modules.infra.enums.InfErrorCodeConstants.API_ERROR_LOG_NOT_FOUND;
 import static cn.iocoder.yudao.adminserver.modules.infra.enums.InfErrorCodeConstants.API_ERROR_LOG_NOT_FOUND;
 import static cn.iocoder.yudao.adminserver.modules.infra.enums.InfErrorCodeConstants.API_ERROR_LOG_PROCESSED;
 import static cn.iocoder.yudao.adminserver.modules.infra.enums.InfErrorCodeConstants.API_ERROR_LOG_PROCESSED;
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 
 /**
 /**
  * {@link InfApiErrorLogServiceImpl} 单元测试
  * {@link InfApiErrorLogServiceImpl} 单元测试
@@ -60,17 +59,17 @@ public class InfApiErrorLogServiceImplTest extends BaseDbUnitTest {
 
 
         // 下面几个都是不匹配的数据
         // 下面几个都是不匹配的数据
         // userId 不同的
         // userId 不同的
-        infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setUserId(3344L)));
+        infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setUserId(3344L)));
         // userType
         // userType
-        infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue())));
+        infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue())));
         // applicationName 不同的
         // applicationName 不同的
-        infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setApplicationName("test")));
+        infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setApplicationName("test")));
         // requestUrl 不同的
         // requestUrl 不同的
-        infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setRequestUrl("bar")));
+        infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setRequestUrl("bar")));
         // 构造一个早期时间 2021-02-06 00:00:00
         // 构造一个早期时间 2021-02-06 00:00:00
-        infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setExceptionTime(buildTime(2021, 2, 6))));
+        infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setExceptionTime(buildTime(2021, 2, 6))));
         // progressStatus 不同的
         // progressStatus 不同的
-        infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setProcessStatus(InfApiErrorLogProcessStatusEnum.DONE.getStatus())));
+        infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setProcessStatus(InfApiErrorLogProcessStatusEnum.DONE.getStatus())));
 
 
         // 构造调用参数
         // 构造调用参数
         InfApiErrorLogPageReqVO reqVO = new InfApiErrorLogPageReqVO();
         InfApiErrorLogPageReqVO reqVO = new InfApiErrorLogPageReqVO();
@@ -113,17 +112,17 @@ public class InfApiErrorLogServiceImplTest extends BaseDbUnitTest {
 
 
         // 下面几个都是不匹配的数据
         // 下面几个都是不匹配的数据
         // userId 不同的
         // userId 不同的
-        infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setUserId(3344L)));
+        infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setUserId(3344L)));
         // userType
         // userType
-        infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue())));
+        infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue())));
         // applicationName 不同的
         // applicationName 不同的
-        infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setApplicationName("test")));
+        infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setApplicationName("test")));
         // requestUrl 不同的
         // requestUrl 不同的
-        infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setRequestUrl("bar")));
+        infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setRequestUrl("bar")));
         // 构造一个早期时间 2021-02-06 00:00:00
         // 构造一个早期时间 2021-02-06 00:00:00
-        infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setExceptionTime(buildTime(2021, 2, 6))));
+        infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setExceptionTime(buildTime(2021, 2, 6))));
         // progressStatus 不同的
         // progressStatus 不同的
-        infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setProcessStatus(InfApiErrorLogProcessStatusEnum.DONE.getStatus())));
+        infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setProcessStatus(InfApiErrorLogProcessStatusEnum.DONE.getStatus())));
 
 
         // 构造调用参数
         // 构造调用参数
         InfApiErrorLogExportReqVO reqVO = new InfApiErrorLogExportReqVO();
         InfApiErrorLogExportReqVO reqVO = new InfApiErrorLogExportReqVO();

+ 2 - 2
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysUserSessionServiceImplTest.java

@@ -73,12 +73,12 @@ public class SysUserSessionServiceImplTest extends BaseDbAndRedisUnitTest {
         });
         });
         userSessionMapper.insert(dbSession);
         userSessionMapper.insert(dbSession);
         // 测试 username 不匹配
         // 测试 username 不匹配
-        userSessionMapper.insert(ObjectUtils.clone(dbSession, o -> {
+        userSessionMapper.insert(ObjectUtils.cloneIgnoreId(dbSession, o -> {
             o.setId(randomString());
             o.setId(randomString());
             o.setUserId(123456L);
             o.setUserId(123456L);
         }));
         }));
         // 测试 userIp 不匹配
         // 测试 userIp 不匹配
-        userSessionMapper.insert(ObjectUtils.clone(dbSession, o -> {
+        userSessionMapper.insert(ObjectUtils.cloneIgnoreId(dbSession, o -> {
             o.setId(randomString());
             o.setId(randomString());
             o.setUserIp("testUserIp");
             o.setUserIp("testUserIp");
         }));
         }));

+ 2 - 2
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/dept/SysDeptServiceTest.java

@@ -83,9 +83,9 @@ class SysDeptServiceTest extends BaseDbUnitTest {
         });
         });
         deptMapper.insert(dept);
         deptMapper.insert(dept);
         // 测试 name 不匹配
         // 测试 name 不匹配
-        deptMapper.insert(ObjectUtils.clone(dept, o -> o.setName("发")));
+        deptMapper.insert(ObjectUtils.cloneIgnoreId(dept, o -> o.setName("发")));
         // 测试 status 不匹配
         // 测试 status 不匹配
-        deptMapper.insert(ObjectUtils.clone(dept, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
+        deptMapper.insert(ObjectUtils.cloneIgnoreId(dept, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
         // 准备参数
         // 准备参数
         SysDeptListReqVO reqVO = new SysDeptListReqVO();
         SysDeptListReqVO reqVO = new SysDeptListReqVO();
         reqVO.setName("开");
         reqVO.setName("开");

+ 4 - 4
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/dept/SysPostServiceTest.java

@@ -49,9 +49,9 @@ class SysPostServiceTest extends BaseDbUnitTest {
         });
         });
         postMapper.insert(postDO);
         postMapper.insert(postDO);
         // 测试 name 不匹配
         // 测试 name 不匹配
-        postMapper.insert(ObjectUtils.clone(postDO, o -> o.setName("程序员")));
+        postMapper.insert(ObjectUtils.cloneIgnoreId(postDO, o -> o.setName("程序员")));
         // 测试 status 不匹配
         // 测试 status 不匹配
-        postMapper.insert(ObjectUtils.clone(postDO, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
+        postMapper.insert(ObjectUtils.cloneIgnoreId(postDO, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
 
 
         // 准备参数
         // 准备参数
         SysPostPageReqVO reqVO = new SysPostPageReqVO();
         SysPostPageReqVO reqVO = new SysPostPageReqVO();
@@ -76,9 +76,9 @@ class SysPostServiceTest extends BaseDbUnitTest {
         });
         });
         postMapper.insert(postDO);
         postMapper.insert(postDO);
         // 测试 name 不匹配
         // 测试 name 不匹配
-        postMapper.insert(ObjectUtils.clone(postDO, o -> o.setName("程序员")));
+        postMapper.insert(ObjectUtils.cloneIgnoreId(postDO, o -> o.setName("程序员")));
         // 测试 status 不匹配
         // 测试 status 不匹配
-        postMapper.insert(ObjectUtils.clone(postDO, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
+        postMapper.insert(ObjectUtils.cloneIgnoreId(postDO, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
         // 准备参数
         // 准备参数
         SysPostExportReqVO reqVO = new SysPostExportReqVO();
         SysPostExportReqVO reqVO = new SysPostExportReqVO();
         reqVO.setName("码");
         reqVO.setName("码");

+ 6 - 9
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/dict/SysDictDataServiceTest.java

@@ -14,17 +14,14 @@ import cn.iocoder.yudao.adminserver.modules.system.mq.producer.dict.SysDictDataP
 import cn.iocoder.yudao.adminserver.modules.system.service.dict.impl.SysDictDataServiceImpl;
 import cn.iocoder.yudao.adminserver.modules.system.service.dict.impl.SysDictDataServiceImpl;
 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
-import com.google.common.collect.ImmutableTable;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.context.annotation.Import;
 import org.springframework.context.annotation.Import;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
-import java.util.Date;
 import java.util.List;
 import java.util.List;
 import java.util.function.Consumer;
 import java.util.function.Consumer;
 
 
-import static cn.hutool.core.bean.BeanUtil.getFieldValue;
 import static cn.iocoder.yudao.adminserver.modules.system.enums.SysErrorCodeConstants.*;
 import static cn.iocoder.yudao.adminserver.modules.system.enums.SysErrorCodeConstants.*;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
@@ -61,11 +58,11 @@ public class SysDictDataServiceTest extends BaseDbUnitTest {
         });
         });
         dictDataMapper.insert(dbDictData);
         dictDataMapper.insert(dbDictData);
         // 测试 label 不匹配
         // 测试 label 不匹配
-        dictDataMapper.insert(ObjectUtils.clone(dbDictData, o -> o.setLabel("艿")));
+        dictDataMapper.insert(ObjectUtils.cloneIgnoreId(dbDictData, o -> o.setLabel("艿")));
         // 测试 dictType 不匹配
         // 测试 dictType 不匹配
-        dictDataMapper.insert(ObjectUtils.clone(dbDictData, o -> o.setDictType("nai")));
+        dictDataMapper.insert(ObjectUtils.cloneIgnoreId(dbDictData, o -> o.setDictType("nai")));
         // 测试 status 不匹配
         // 测试 status 不匹配
-        dictDataMapper.insert(ObjectUtils.clone(dbDictData, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
+        dictDataMapper.insert(ObjectUtils.cloneIgnoreId(dbDictData, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
         // 准备参数
         // 准备参数
         SysDictDataPageReqVO reqVO = new SysDictDataPageReqVO();
         SysDictDataPageReqVO reqVO = new SysDictDataPageReqVO();
         reqVO.setLabel("芋");
         reqVO.setLabel("芋");
@@ -90,11 +87,11 @@ public class SysDictDataServiceTest extends BaseDbUnitTest {
         });
         });
         dictDataMapper.insert(dbDictData);
         dictDataMapper.insert(dbDictData);
         // 测试 label 不匹配
         // 测试 label 不匹配
-        dictDataMapper.insert(ObjectUtils.clone(dbDictData, o -> o.setLabel("艿")));
+        dictDataMapper.insert(ObjectUtils.cloneIgnoreId(dbDictData, o -> o.setLabel("艿")));
         // 测试 dictType 不匹配
         // 测试 dictType 不匹配
-        dictDataMapper.insert(ObjectUtils.clone(dbDictData, o -> o.setDictType("nai")));
+        dictDataMapper.insert(ObjectUtils.cloneIgnoreId(dbDictData, o -> o.setDictType("nai")));
         // 测试 status 不匹配
         // 测试 status 不匹配
-        dictDataMapper.insert(ObjectUtils.clone(dbDictData, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
+        dictDataMapper.insert(ObjectUtils.cloneIgnoreId(dbDictData, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
         // 准备参数
         // 准备参数
         SysDictDataExportReqVO reqVO = new SysDictDataExportReqVO();
         SysDictDataExportReqVO reqVO = new SysDictDataExportReqVO();
         reqVO.setLabel("芋");
         reqVO.setLabel("芋");

+ 8 - 8
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/dict/SysDictTypeServiceTest.java

@@ -57,13 +57,13 @@ public class SysDictTypeServiceTest extends BaseDbUnitTest {
        });
        });
        dictTypeMapper.insert(dbDictType);
        dictTypeMapper.insert(dbDictType);
        // 测试 name 不匹配
        // 测试 name 不匹配
-       dictTypeMapper.insert(ObjectUtils.clone(dbDictType, o -> o.setName("tudou")));
+       dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setName("tudou")));
        // 测试 type 不匹配
        // 测试 type 不匹配
-       dictTypeMapper.insert(ObjectUtils.clone(dbDictType, o -> o.setType("土豆")));
+       dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setType("土豆")));
        // 测试 status 不匹配
        // 测试 status 不匹配
-       dictTypeMapper.insert(ObjectUtils.clone(dbDictType, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
+       dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
        // 测试 createTime 不匹配
        // 测试 createTime 不匹配
-       dictTypeMapper.insert(ObjectUtils.clone(dbDictType, o -> o.setCreateTime(buildTime(2021, 1, 1))));
+       dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setCreateTime(buildTime(2021, 1, 1))));
        // 准备参数
        // 准备参数
        SysDictTypePageReqVO reqVO = new SysDictTypePageReqVO();
        SysDictTypePageReqVO reqVO = new SysDictTypePageReqVO();
        reqVO.setName("nai");
        reqVO.setName("nai");
@@ -91,13 +91,13 @@ public class SysDictTypeServiceTest extends BaseDbUnitTest {
         });
         });
         dictTypeMapper.insert(dbDictType);
         dictTypeMapper.insert(dbDictType);
         // 测试 name 不匹配
         // 测试 name 不匹配
-        dictTypeMapper.insert(ObjectUtils.clone(dbDictType, o -> o.setName("tudou")));
+        dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setName("tudou")));
         // 测试 type 不匹配
         // 测试 type 不匹配
-        dictTypeMapper.insert(ObjectUtils.clone(dbDictType, o -> o.setType("土豆")));
+        dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setType("土豆")));
         // 测试 status 不匹配
         // 测试 status 不匹配
-        dictTypeMapper.insert(ObjectUtils.clone(dbDictType, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
+        dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
         // 测试 createTime 不匹配
         // 测试 createTime 不匹配
-        dictTypeMapper.insert(ObjectUtils.clone(dbDictType, o -> o.setCreateTime(buildTime(2021, 1, 1))));
+        dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setCreateTime(buildTime(2021, 1, 1))));
         // 准备参数
         // 准备参数
         SysDictTypeExportReqVO reqVO = new SysDictTypeExportReqVO();
         SysDictTypeExportReqVO reqVO = new SysDictTypeExportReqVO();
         reqVO.setName("nai");
         reqVO.setName("nai");

+ 5 - 5
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/errorcode/SysErrorCodeServiceTest.java

@@ -131,15 +131,15 @@ public class SysErrorCodeServiceTest extends BaseDbUnitTest {
         });
         });
         errorCodeMapper.insert(dbErrorCode);
         errorCodeMapper.insert(dbErrorCode);
         // 测试 type 不匹配
         // 测试 type 不匹配
-        errorCodeMapper.insert(ObjectUtils.clone(dbErrorCode, o -> o.setType(SysErrorCodeTypeEnum.MANUAL_OPERATION.getType())));
+        errorCodeMapper.insert(ObjectUtils.cloneIgnoreId(dbErrorCode, o -> o.setType(SysErrorCodeTypeEnum.MANUAL_OPERATION.getType())));
         // 测试 applicationName 不匹配
         // 测试 applicationName 不匹配
-        errorCodeMapper.insert(ObjectUtils.clone(dbErrorCode, o -> o.setApplicationName("yunai")));
+        errorCodeMapper.insert(ObjectUtils.cloneIgnoreId(dbErrorCode, o -> o.setApplicationName("yunai")));
         // 测试 code 不匹配
         // 测试 code 不匹配
-        errorCodeMapper.insert(ObjectUtils.clone(dbErrorCode, o -> o.setCode(2)));
+        errorCodeMapper.insert(ObjectUtils.cloneIgnoreId(dbErrorCode, o -> o.setCode(2)));
         // 测试 message 不匹配
         // 测试 message 不匹配
-        errorCodeMapper.insert(ObjectUtils.clone(dbErrorCode, o -> o.setMessage("nai")));
+        errorCodeMapper.insert(ObjectUtils.cloneIgnoreId(dbErrorCode, o -> o.setMessage("nai")));
         // 测试 createTime 不匹配
         // 测试 createTime 不匹配
-        errorCodeMapper.insert(ObjectUtils.clone(dbErrorCode, o -> o.setCreateTime(buildTime(2020, 12, 12))));
+        errorCodeMapper.insert(ObjectUtils.cloneIgnoreId(dbErrorCode, o -> o.setCreateTime(buildTime(2020, 12, 12))));
         return dbErrorCode;
         return dbErrorCode;
     }
     }
 
 

+ 8 - 8
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/SysLoginLogServiceImplTest.java

@@ -51,13 +51,13 @@ public class SysLoginLogServiceImplTest extends BaseDbUnitTest {
 
 
         // 下面几个都是不匹配的数据
         // 下面几个都是不匹配的数据
         // 登录失败的
         // 登录失败的
-        loginLogMapper.insert(ObjectUtils.clone(loginLogDO, logDO -> logDO.setResult(SysLoginResultEnum.CAPTCHA_CODE_ERROR.getResult())));
+        loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setResult(SysLoginResultEnum.CAPTCHA_CODE_ERROR.getResult())));
         // 不同ip段的
         // 不同ip段的
-        loginLogMapper.insert(ObjectUtils.clone(loginLogDO, logDO -> logDO.setUserIp("192.168.128.18")));
+        loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setUserIp("192.168.128.18")));
         // 不同username
         // 不同username
-        loginLogMapper.insert(ObjectUtils.clone(loginLogDO, logDO -> logDO.setUsername("yunai")));
+        loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setUsername("yunai")));
         // 构造一个早期时间 2021-02-06 00:00:00
         // 构造一个早期时间 2021-02-06 00:00:00
-        loginLogMapper.insert(ObjectUtils.clone(loginLogDO, logDO -> logDO.setCreateTime(buildTime(2021, 2, 6))));
+        loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setCreateTime(buildTime(2021, 2, 6))));
 
 
 
 
         // 构造调用参数
         // 构造调用参数
@@ -96,13 +96,13 @@ public class SysLoginLogServiceImplTest extends BaseDbUnitTest {
 
 
         // 下面几个都是不匹配的数据
         // 下面几个都是不匹配的数据
         // 登录失败的
         // 登录失败的
-        loginLogMapper.insert(ObjectUtils.clone(loginLogDO, logDO -> logDO.setResult(SysLoginResultEnum.CAPTCHA_CODE_ERROR.getResult())));
+        loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setResult(SysLoginResultEnum.CAPTCHA_CODE_ERROR.getResult())));
         // 不同ip段的
         // 不同ip段的
-        loginLogMapper.insert(ObjectUtils.clone(loginLogDO, logDO -> logDO.setUserIp("192.168.128.18")));
+        loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setUserIp("192.168.128.18")));
         // 不同username
         // 不同username
-        loginLogMapper.insert(ObjectUtils.clone(loginLogDO, logDO -> logDO.setUsername("yunai")));
+        loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setUsername("yunai")));
         // 构造一个早期时间 2021-02-06 00:00:00
         // 构造一个早期时间 2021-02-06 00:00:00
-        loginLogMapper.insert(ObjectUtils.clone(loginLogDO, logDO -> logDO.setCreateTime(buildTime(2021, 2, 6))));
+        loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setCreateTime(buildTime(2021, 2, 6))));
 
 
 
 
         // 构造调用参数
         // 构造调用参数

+ 10 - 10
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/SysOperateLogServiceImplTest.java

@@ -87,15 +87,15 @@ public class SysOperateLogServiceImplTest extends BaseDbUnitTest {
 
 
         // 下面几个是不匹配的数据
         // 下面几个是不匹配的数据
         // 随机 userId
         // 随机 userId
-        operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setUserId(userId + 1)));
+        operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setUserId(userId + 1)));
         // module 不同
         // module 不同
-        operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setModule("user")));
+        operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setModule("user")));
         // type 不同
         // type 不同
-        operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setType(OperateTypeEnum.IMPORT.getType())));
+        operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setType(OperateTypeEnum.IMPORT.getType())));
         // createTime 不同
         // createTime 不同
-        operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setStartTime(buildTime(2021, 2, 6))));
+        operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setStartTime(buildTime(2021, 2, 6))));
         // resultCode 不同
         // resultCode 不同
-        operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setResultCode(GlobalErrorCodeConstants.BAD_REQUEST.getCode())));
+        operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setResultCode(GlobalErrorCodeConstants.BAD_REQUEST.getCode())));
 
 
         // 构造调用参数
         // 构造调用参数
         SysOperateLogPageReqVO reqVO = new SysOperateLogPageReqVO();
         SysOperateLogPageReqVO reqVO = new SysOperateLogPageReqVO();
@@ -138,15 +138,15 @@ public class SysOperateLogServiceImplTest extends BaseDbUnitTest {
 
 
         // 下面几个是不匹配的数据
         // 下面几个是不匹配的数据
         // 随机 userId
         // 随机 userId
-        operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setUserId(userId + 1)));
+        operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setUserId(userId + 1)));
         // module 不同
         // module 不同
-        operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setModule("user")));
+        operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setModule("user")));
         // type 不同
         // type 不同
-        operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setType(OperateTypeEnum.IMPORT.getType())));
+        operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setType(OperateTypeEnum.IMPORT.getType())));
         // createTime 不同
         // createTime 不同
-        operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setStartTime(buildTime(2021, 2, 6))));
+        operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setStartTime(buildTime(2021, 2, 6))));
         // resultCode 不同
         // resultCode 不同
-        operateLogMapper.insert(ObjectUtils.clone(sysOperateLogDO, logDO -> logDO.setResultCode(GlobalErrorCodeConstants.BAD_REQUEST.getCode())));
+        operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setResultCode(GlobalErrorCodeConstants.BAD_REQUEST.getCode())));
 
 
         // 构造调用参数
         // 构造调用参数
         SysOperateLogExportReqVO reqVO = new SysOperateLogExportReqVO();
         SysOperateLogExportReqVO reqVO = new SysOperateLogExportReqVO();

+ 2 - 2
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/notice/SysNoticeServiceImplTest.java

@@ -46,9 +46,9 @@ class SysNoticeServiceImplTest extends BaseDbUnitTest {
         sysNoticeMapper.insert(dbNotice);
         sysNoticeMapper.insert(dbNotice);
 
 
         // 测试 title 不匹配
         // 测试 title 不匹配
-        sysNoticeMapper.insert(ObjectUtils.clone(dbNotice, o -> o.setTitle("尼古拉斯凯奇也来啦!")));
+        sysNoticeMapper.insert(ObjectUtils.cloneIgnoreId(dbNotice, o -> o.setTitle("尼古拉斯凯奇也来啦!")));
         // 测试 status 不匹配
         // 测试 status 不匹配
-        sysNoticeMapper.insert(ObjectUtils.clone(dbNotice, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
+        sysNoticeMapper.insert(ObjectUtils.cloneIgnoreId(dbNotice, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
 
 
 
 
         // 查询
         // 查询

+ 3 - 3
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/sms/SysSmsChannelServiceTest.java

@@ -169,11 +169,11 @@ public class SysSmsChannelServiceTest extends BaseDbUnitTest {
        });
        });
        smsChannelMapper.insert(dbSmsChannel);
        smsChannelMapper.insert(dbSmsChannel);
        // 测试 signature 不匹配
        // 测试 signature 不匹配
-       smsChannelMapper.insert(ObjectUtils.clone(dbSmsChannel, o -> o.setSignature("源码")));
+       smsChannelMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsChannel, o -> o.setSignature("源码")));
        // 测试 status 不匹配
        // 测试 status 不匹配
-       smsChannelMapper.insert(ObjectUtils.clone(dbSmsChannel, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
+       smsChannelMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsChannel, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
        // 测试 createTime 不匹配
        // 测试 createTime 不匹配
-       smsChannelMapper.insert(ObjectUtils.clone(dbSmsChannel, o -> o.setCreateTime(buildTime(2020, 11, 11))));
+       smsChannelMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsChannel, o -> o.setCreateTime(buildTime(2020, 11, 11))));
        // 准备参数
        // 准备参数
        SysSmsChannelPageReqVO reqVO = new SysSmsChannelPageReqVO();
        SysSmsChannelPageReqVO reqVO = new SysSmsChannelPageReqVO();
        reqVO.setSignature("芋道");
        reqVO.setSignature("芋道");

+ 14 - 14
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/sms/SysSmsLogServiceTest.java

@@ -57,19 +57,19 @@ public class SysSmsLogServiceTest extends BaseDbUnitTest {
        });
        });
        smsLogMapper.insert(dbSmsLog);
        smsLogMapper.insert(dbSmsLog);
        // 测试 channelId 不匹配
        // 测试 channelId 不匹配
-       smsLogMapper.insert(ObjectUtils.clone(dbSmsLog, o -> o.setChannelId(2L)));
+       smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setChannelId(2L)));
        // 测试 templateId 不匹配
        // 测试 templateId 不匹配
-       smsLogMapper.insert(ObjectUtils.clone(dbSmsLog, o -> o.setTemplateId(20L)));
+       smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setTemplateId(20L)));
        // 测试 mobile 不匹配
        // 测试 mobile 不匹配
-       smsLogMapper.insert(ObjectUtils.clone(dbSmsLog, o -> o.setMobile("18818260999")));
+       smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setMobile("18818260999")));
        // 测试 sendStatus 不匹配
        // 测试 sendStatus 不匹配
-       smsLogMapper.insert(ObjectUtils.clone(dbSmsLog, o -> o.setSendStatus(SysSmsSendStatusEnum.IGNORE.getStatus())));
+       smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setSendStatus(SysSmsSendStatusEnum.IGNORE.getStatus())));
        // 测试 sendTime 不匹配
        // 测试 sendTime 不匹配
-       smsLogMapper.insert(ObjectUtils.clone(dbSmsLog, o -> o.setSendTime(buildTime(2020, 12, 12))));
+       smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setSendTime(buildTime(2020, 12, 12))));
        // 测试 receiveStatus 不匹配
        // 测试 receiveStatus 不匹配
-       smsLogMapper.insert(ObjectUtils.clone(dbSmsLog, o -> o.setReceiveStatus(SysSmsReceiveStatusEnum.SUCCESS.getStatus())));
+       smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setReceiveStatus(SysSmsReceiveStatusEnum.SUCCESS.getStatus())));
        // 测试 receiveTime 不匹配
        // 测试 receiveTime 不匹配
-       smsLogMapper.insert(ObjectUtils.clone(dbSmsLog, o -> o.setReceiveTime(buildTime(2021, 12, 12))));
+       smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setReceiveTime(buildTime(2021, 12, 12))));
        // 准备参数
        // 准备参数
        SysSmsLogPageReqVO reqVO = new SysSmsLogPageReqVO();
        SysSmsLogPageReqVO reqVO = new SysSmsLogPageReqVO();
        reqVO.setChannelId(1L);
        reqVO.setChannelId(1L);
@@ -104,19 +104,19 @@ public class SysSmsLogServiceTest extends BaseDbUnitTest {
         });
         });
         smsLogMapper.insert(dbSmsLog);
         smsLogMapper.insert(dbSmsLog);
         // 测试 channelId 不匹配
         // 测试 channelId 不匹配
-        smsLogMapper.insert(ObjectUtils.clone(dbSmsLog, o -> o.setChannelId(2L)));
+        smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setChannelId(2L)));
         // 测试 templateId 不匹配
         // 测试 templateId 不匹配
-        smsLogMapper.insert(ObjectUtils.clone(dbSmsLog, o -> o.setTemplateId(20L)));
+        smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setTemplateId(20L)));
         // 测试 mobile 不匹配
         // 测试 mobile 不匹配
-        smsLogMapper.insert(ObjectUtils.clone(dbSmsLog, o -> o.setMobile("18818260999")));
+        smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setMobile("18818260999")));
         // 测试 sendStatus 不匹配
         // 测试 sendStatus 不匹配
-        smsLogMapper.insert(ObjectUtils.clone(dbSmsLog, o -> o.setSendStatus(SysSmsSendStatusEnum.IGNORE.getStatus())));
+        smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setSendStatus(SysSmsSendStatusEnum.IGNORE.getStatus())));
         // 测试 sendTime 不匹配
         // 测试 sendTime 不匹配
-        smsLogMapper.insert(ObjectUtils.clone(dbSmsLog, o -> o.setSendTime(buildTime(2020, 12, 12))));
+        smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setSendTime(buildTime(2020, 12, 12))));
         // 测试 receiveStatus 不匹配
         // 测试 receiveStatus 不匹配
-        smsLogMapper.insert(ObjectUtils.clone(dbSmsLog, o -> o.setReceiveStatus(SysSmsReceiveStatusEnum.SUCCESS.getStatus())));
+        smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setReceiveStatus(SysSmsReceiveStatusEnum.SUCCESS.getStatus())));
         // 测试 receiveTime 不匹配
         // 测试 receiveTime 不匹配
-        smsLogMapper.insert(ObjectUtils.clone(dbSmsLog, o -> o.setReceiveTime(buildTime(2021, 12, 12))));
+        smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setReceiveTime(buildTime(2021, 12, 12))));
         // 准备参数
         // 准备参数
         SysSmsLogExportReqVO reqVO = new SysSmsLogExportReqVO();
         SysSmsLogExportReqVO reqVO = new SysSmsLogExportReqVO();
         reqVO.setChannelId(1L);
         reqVO.setChannelId(1L);

+ 14 - 14
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/sms/SysSmsTemplateServiceTest.java

@@ -190,19 +190,19 @@ public class SysSmsTemplateServiceTest extends BaseDbUnitTest {
        });
        });
        smsTemplateMapper.insert(dbSmsTemplate);
        smsTemplateMapper.insert(dbSmsTemplate);
        // 测试 type 不匹配
        // 测试 type 不匹配
-       smsTemplateMapper.insert(ObjectUtils.clone(dbSmsTemplate, o -> o.setType(SysSmsTemplateTypeEnum.VERIFICATION_CODE.getType())));
+       smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setType(SysSmsTemplateTypeEnum.VERIFICATION_CODE.getType())));
        // 测试 status 不匹配
        // 测试 status 不匹配
-       smsTemplateMapper.insert(ObjectUtils.clone(dbSmsTemplate, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
+       smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
        // 测试 code 不匹配
        // 测试 code 不匹配
-       smsTemplateMapper.insert(ObjectUtils.clone(dbSmsTemplate, o -> o.setCode("yuanma")));
+       smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setCode("yuanma")));
        // 测试 content 不匹配
        // 测试 content 不匹配
-       smsTemplateMapper.insert(ObjectUtils.clone(dbSmsTemplate, o -> o.setContent("源码")));
+       smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setContent("源码")));
        // 测试 apiTemplateId 不匹配
        // 测试 apiTemplateId 不匹配
-       smsTemplateMapper.insert(ObjectUtils.clone(dbSmsTemplate, o -> o.setApiTemplateId("nai")));
+       smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setApiTemplateId("nai")));
        // 测试 channelId 不匹配
        // 测试 channelId 不匹配
-       smsTemplateMapper.insert(ObjectUtils.clone(dbSmsTemplate, o -> o.setChannelId(2L)));
+       smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setChannelId(2L)));
        // 测试 createTime 不匹配
        // 测试 createTime 不匹配
-       smsTemplateMapper.insert(ObjectUtils.clone(dbSmsTemplate, o -> o.setCreateTime(buildTime(2021, 12, 12))));
+       smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setCreateTime(buildTime(2021, 12, 12))));
        // 准备参数
        // 准备参数
        SysSmsTemplatePageReqVO reqVO = new SysSmsTemplatePageReqVO();
        SysSmsTemplatePageReqVO reqVO = new SysSmsTemplatePageReqVO();
        reqVO.setType(SysSmsTemplateTypeEnum.PROMOTION.getType());
        reqVO.setType(SysSmsTemplateTypeEnum.PROMOTION.getType());
@@ -236,19 +236,19 @@ public class SysSmsTemplateServiceTest extends BaseDbUnitTest {
         });
         });
         smsTemplateMapper.insert(dbSmsTemplate);
         smsTemplateMapper.insert(dbSmsTemplate);
         // 测试 type 不匹配
         // 测试 type 不匹配
-        smsTemplateMapper.insert(ObjectUtils.clone(dbSmsTemplate, o -> o.setType(SysSmsTemplateTypeEnum.VERIFICATION_CODE.getType())));
+        smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setType(SysSmsTemplateTypeEnum.VERIFICATION_CODE.getType())));
         // 测试 status 不匹配
         // 测试 status 不匹配
-        smsTemplateMapper.insert(ObjectUtils.clone(dbSmsTemplate, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
+        smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
         // 测试 code 不匹配
         // 测试 code 不匹配
-        smsTemplateMapper.insert(ObjectUtils.clone(dbSmsTemplate, o -> o.setCode("yuanma")));
+        smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setCode("yuanma")));
         // 测试 content 不匹配
         // 测试 content 不匹配
-        smsTemplateMapper.insert(ObjectUtils.clone(dbSmsTemplate, o -> o.setContent("源码")));
+        smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setContent("源码")));
         // 测试 apiTemplateId 不匹配
         // 测试 apiTemplateId 不匹配
-        smsTemplateMapper.insert(ObjectUtils.clone(dbSmsTemplate, o -> o.setApiTemplateId("nai")));
+        smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setApiTemplateId("nai")));
         // 测试 channelId 不匹配
         // 测试 channelId 不匹配
-        smsTemplateMapper.insert(ObjectUtils.clone(dbSmsTemplate, o -> o.setChannelId(2L)));
+        smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setChannelId(2L)));
         // 测试 createTime 不匹配
         // 测试 createTime 不匹配
-        smsTemplateMapper.insert(ObjectUtils.clone(dbSmsTemplate, o -> o.setCreateTime(buildTime(2021, 12, 12))));
+        smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setCreateTime(buildTime(2021, 12, 12))));
         // 准备参数
         // 准备参数
         SysSmsTemplateExportReqVO reqVO = new SysSmsTemplateExportReqVO();
         SysSmsTemplateExportReqVO reqVO = new SysSmsTemplateExportReqVO();
         reqVO.setType(SysSmsTemplateTypeEnum.PROMOTION.getType());
         reqVO.setType(SysSmsTemplateTypeEnum.PROMOTION.getType());

+ 181 - 0
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/tenant/SysTenantServiceTest.java

@@ -0,0 +1,181 @@
+package cn.iocoder.yudao.adminserver.modules.system.service.tenant;
+
+import cn.iocoder.yudao.adminserver.BaseDbUnitTest;
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.SysTenantCreateReqVO;
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.SysTenantExportReqVO;
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.SysTenantPageReqVO;
+import cn.iocoder.yudao.adminserver.modules.system.controller.tenant.vo.SysTenantUpdateReqVO;
+import cn.iocoder.yudao.adminserver.modules.system.dal.mysql.tenant.SysTenantMapper;
+import cn.iocoder.yudao.adminserver.modules.system.service.tenant.impl.SysTenantServiceImpl;
+import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.tenant.SysTenantDO;
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.annotation.Import;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+import static cn.iocoder.yudao.adminserver.modules.system.enums.SysErrorCodeConstants.TENANT_NOT_EXISTS;
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
+import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
+import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
+import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
+import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * {@link SysTenantServiceImpl} 的单元测试类
+ *
+ * @author 芋道源码
+ */
+@Import(SysTenantServiceImpl.class)
+public class SysTenantServiceTest extends BaseDbUnitTest {
+
+    @Resource
+    private SysTenantServiceImpl tenantService;
+
+    @Resource
+    private SysTenantMapper tenantMapper;
+
+    @Test
+    public void testCreateTenant_success() {
+        // 准备参数
+        SysTenantCreateReqVO reqVO = randomPojo(SysTenantCreateReqVO.class, o -> o.setStatus(randomCommonStatus()));
+
+        // 调用
+        Long tenantId = tenantService.createTenant(reqVO);
+        // 断言
+        assertNotNull(tenantId);
+        // 校验记录的属性是否正确
+        SysTenantDO tenant = tenantMapper.selectById(tenantId);
+        assertPojoEquals(reqVO, tenant);
+    }
+
+    @Test
+    public void testUpdateTenant_success() {
+        // mock 数据
+        SysTenantDO dbTenant = randomPojo(SysTenantDO.class, o -> o.setStatus(randomCommonStatus()));
+        tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        SysTenantUpdateReqVO reqVO = randomPojo(SysTenantUpdateReqVO.class, o -> {
+            o.setId(dbTenant.getId()); // 设置更新的 ID
+            o.setStatus(randomCommonStatus());
+        });
+
+        // 调用
+        tenantService.updateTenant(reqVO);
+        // 校验是否更新正确
+        SysTenantDO tenant = tenantMapper.selectById(reqVO.getId()); // 获取最新的
+        assertPojoEquals(reqVO, tenant);
+    }
+
+    @Test
+    public void testUpdateTenant_notExists() {
+        // 准备参数
+        SysTenantUpdateReqVO reqVO = randomPojo(SysTenantUpdateReqVO.class);
+
+        // 调用, 并断言异常
+        assertServiceException(() -> tenantService.updateTenant(reqVO), TENANT_NOT_EXISTS);
+    }
+
+    @Test
+    public void testDeleteTenant_success() {
+        // mock 数据
+        SysTenantDO dbTenant = randomPojo(SysTenantDO.class,
+                o -> o.setStatus(randomCommonStatus()));
+        tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        Long id = dbTenant.getId();
+
+        // 调用
+        tenantService.deleteTenant(id);
+        // 校验数据不存在了
+        assertNull(tenantMapper.selectById(id));
+    }
+
+    @Test
+    public void testDeleteTenant_notExists() {
+        // 准备参数
+        Long id = randomLongId();
+
+        // 调用, 并断言异常
+        assertServiceException(() -> tenantService.deleteTenant(id), TENANT_NOT_EXISTS);
+    }
+
+    @Test
+    public void testGetTenantPage() {
+        // mock 数据
+        SysTenantDO dbTenant = randomPojo(SysTenantDO.class, o -> { // 等会查询到
+            o.setName("芋道源码");
+            o.setContactName("芋艿");
+            o.setContactMobile("15601691300");
+            o.setStatus(CommonStatusEnum.ENABLE.getStatus());
+            o.setCreateTime(buildTime(2020, 12, 12));
+        });
+        tenantMapper.insert(dbTenant);
+        // 测试 name 不匹配
+        tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setName(randomString())));
+        // 测试 contactName 不匹配
+        tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setContactName(randomString())));
+        // 测试 contactMobile 不匹配
+        tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setContactMobile(randomString())));
+        // 测试 status 不匹配
+        tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
+        // 测试 createTime 不匹配
+        tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setCreateTime(buildTime(2021, 12, 12))));
+        // 准备参数
+        SysTenantPageReqVO reqVO = new SysTenantPageReqVO();
+        reqVO.setName("芋道");
+        reqVO.setContactName("艿");
+        reqVO.setContactMobile("1560");
+        reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
+        reqVO.setBeginCreateTime(buildTime(2020, 12, 1));
+        reqVO.setEndCreateTime(buildTime(2020, 12, 24));
+
+        // 调用
+        PageResult<SysTenantDO> pageResult = tenantService.getTenantPage(reqVO);
+        // 断言
+        assertEquals(1, pageResult.getTotal());
+        assertEquals(1, pageResult.getList().size());
+        assertPojoEquals(dbTenant, pageResult.getList().get(0));
+    }
+
+    @Test
+    public void testGetTenantList() {
+        // mock 数据
+        SysTenantDO dbTenant = randomPojo(SysTenantDO.class, o -> { // 等会查询到
+            o.setName("芋道源码");
+            o.setContactName("芋艿");
+            o.setContactMobile("15601691300");
+            o.setStatus(CommonStatusEnum.ENABLE.getStatus());
+            o.setCreateTime(buildTime(2020, 12, 12));
+        });
+        tenantMapper.insert(dbTenant);
+        // 测试 name 不匹配
+        tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setName(randomString())));
+        // 测试 contactName 不匹配
+        tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setContactName(randomString())));
+        // 测试 contactMobile 不匹配
+        tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setContactMobile(randomString())));
+        // 测试 status 不匹配
+        tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
+        // 测试 createTime 不匹配
+        tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setCreateTime(buildTime(2021, 12, 12))));
+        // 准备参数
+        SysTenantExportReqVO reqVO = new SysTenantExportReqVO();
+        reqVO.setName("芋道");
+        reqVO.setContactName("艿");
+        reqVO.setContactMobile("1560");
+        reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
+        reqVO.setBeginCreateTime(buildTime(2020, 12, 1));
+        reqVO.setEndCreateTime(buildTime(2020, 12, 24));
+
+        // 调用
+        List<SysTenantDO> list = tenantService.getTenantList(reqVO);
+        // 断言
+        assertEquals(1, list.size());
+        assertPojoEquals(dbTenant, list.get(0));
+    }
+
+}

+ 5 - 6
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserServiceImplTest.java

@@ -21,7 +21,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
-import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Test;
 import org.mockito.stubbing.Answer;
 import org.mockito.stubbing.Answer;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.boot.test.mock.mockito.MockBean;
@@ -310,15 +309,15 @@ public class SysUserServiceImplTest extends BaseDbUnitTest {
         });
         });
         userMapper.insert(dbUser);
         userMapper.insert(dbUser);
         // 测试 username 不匹配
         // 测试 username 不匹配
-        userMapper.insert(ObjectUtils.clone(dbUser, o -> o.setUsername("yuanma")));
+        userMapper.insert(ObjectUtils.cloneIgnoreId(dbUser, o -> o.setUsername("yuanma")));
         // 测试 mobile 不匹配
         // 测试 mobile 不匹配
-        userMapper.insert(ObjectUtils.clone(dbUser, o -> o.setMobile("18818260888")));
+        userMapper.insert(ObjectUtils.cloneIgnoreId(dbUser, o -> o.setMobile("18818260888")));
         // 测试 status 不匹配
         // 测试 status 不匹配
-        userMapper.insert(ObjectUtils.clone(dbUser, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
+        userMapper.insert(ObjectUtils.cloneIgnoreId(dbUser, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
         // 测试 createTime 不匹配
         // 测试 createTime 不匹配
-        userMapper.insert(ObjectUtils.clone(dbUser, o -> o.setCreateTime(buildTime(2020, 11, 11))));
+        userMapper.insert(ObjectUtils.cloneIgnoreId(dbUser, o -> o.setCreateTime(buildTime(2020, 11, 11))));
         // 测试 dept 不匹配
         // 测试 dept 不匹配
-        userMapper.insert(ObjectUtils.clone(dbUser, o -> o.setDeptId(0L)));
+        userMapper.insert(ObjectUtils.cloneIgnoreId(dbUser, o -> o.setDeptId(0L)));
         return dbUser;
         return dbUser;
     }
     }
 
 

+ 1 - 0
yudao-admin-server/src/test/resources/sql/clean.sql

@@ -24,3 +24,4 @@ DELETE FROM "sys_sms_template";
 DELETE FROM "sys_sms_log";
 DELETE FROM "sys_sms_log";
 DELETE FROM "sys_error_code";
 DELETE FROM "sys_error_code";
 DELETE FROM "sys_social_user";
 DELETE FROM "sys_social_user";
+DELETE FROM "sys_tenant";

+ 25 - 3
yudao-admin-server/src/test/resources/sql/create_tables.sql

@@ -1,7 +1,7 @@
 -- inf 开头的 DB
 -- inf 开头的 DB
 
 
 CREATE TABLE IF NOT EXISTS "inf_config" (
 CREATE TABLE IF NOT EXISTS "inf_config" (
-    "id" int NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY,
     "group" varchar(50) NOT NULL,
     "group" varchar(50) NOT NULL,
     "type" tinyint NOT NULL,
     "type" tinyint NOT NULL,
     "name" varchar(100) NOT NULL DEFAULT '',
     "name" varchar(100) NOT NULL DEFAULT '',
@@ -26,6 +26,7 @@ CREATE TABLE IF NOT EXISTS "inf_file" (
     "updater" varchar(64) DEFAULT '',
     "updater" varchar(64) DEFAULT '',
     "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
     "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
     "deleted" bit NOT NULL DEFAULT FALSE,
     "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint not null default  '0',
     PRIMARY KEY ("id")
     PRIMARY KEY ("id")
 ) COMMENT '文件表';
 ) COMMENT '文件表';
 
 
@@ -82,6 +83,7 @@ CREATE TABLE IF NOT EXISTS "sys_dept" (
     "updater" varchar(64) DEFAULT '',
     "updater" varchar(64) DEFAULT '',
     "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
     "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
     "deleted" bit NOT NULL DEFAULT FALSE,
     "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint not null default  '0',
     PRIMARY KEY ("id")
     PRIMARY KEY ("id")
 ) COMMENT '部门表';
 ) COMMENT '部门表';
 
 
@@ -189,6 +191,7 @@ CREATE TABLE IF NOT EXISTS `sys_user_session` (
     `updater` varchar(64) DEFAULT '' ,
     `updater` varchar(64) DEFAULT '' ,
     "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
     "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
     "deleted" bit NOT NULL DEFAULT FALSE,
     "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint not null default  '0',
     PRIMARY KEY (`id`)
     PRIMARY KEY (`id`)
 ) COMMENT '用户在线 Session';
 ) COMMENT '用户在线 Session';
 
 
@@ -204,6 +207,7 @@ CREATE TABLE IF NOT EXISTS "sys_post" (
     "updater"     varchar(64)          DEFAULT '',
     "updater"     varchar(64)          DEFAULT '',
     "update_time" timestamp   NOT NULL DEFAULT CURRENT_TIMESTAMP,
     "update_time" timestamp   NOT NULL DEFAULT CURRENT_TIMESTAMP,
     "deleted"     bit         NOT NULL DEFAULT FALSE,
     "deleted"     bit         NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint not null default  '0',
     PRIMARY KEY ("id")
     PRIMARY KEY ("id")
 ) COMMENT '岗位信息表';
 ) COMMENT '岗位信息表';
 
 
@@ -218,7 +222,8 @@ CREATE TABLE IF NOT EXISTS "sys_notice" (
 	"updater" varchar(64) DEFAULT '' COMMENT '更新者',
 	"updater" varchar(64) DEFAULT '' COMMENT '更新者',
 	"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
 	"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
 	"deleted" bit NOT NULL DEFAULT 0 COMMENT '是否删除',
 	"deleted" bit NOT NULL DEFAULT 0 COMMENT '是否删除',
-	PRIMARY KEY("id")
+    "tenant_id" bigint not null default  '0',
+    PRIMARY KEY("id")
 ) COMMENT '通知公告表';
 ) COMMENT '通知公告表';
 
 
 CREATE TABLE IF NOT EXISTS `sys_login_log` (
 CREATE TABLE IF NOT EXISTS `sys_login_log` (
@@ -264,6 +269,7 @@ CREATE TABLE IF NOT EXISTS `sys_operate_log` (
     `updater`        varchar(64)            DEFAULT '',
     `updater`        varchar(64)            DEFAULT '',
     `update_time`      datetime      NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
     `update_time`      datetime      NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
     `deleted`          bit(1)        NOT NULL DEFAULT '0',
     `deleted`          bit(1)        NOT NULL DEFAULT '0',
+    "tenant_id"         bigint not null default  '0',
     PRIMARY KEY (`id`)
     PRIMARY KEY (`id`)
 ) COMMENT ='操作日志记录';
 ) COMMENT ='操作日志记录';
 
 
@@ -312,11 +318,12 @@ CREATE TABLE IF NOT EXISTS "inf_api_access_log" (
   "updater" varchar(64) default '',
   "updater" varchar(64) default '',
   "update_time" timestamp not null default current_timestamp,
   "update_time" timestamp not null default current_timestamp,
   "deleted" bit not null default false,
   "deleted" bit not null default false,
+  "tenant_id" bigint not null default  '0',
   primary key ("id")
   primary key ("id")
 ) COMMENT 'API 访问日志表';
 ) COMMENT 'API 访问日志表';
 
 
 CREATE TABLE IF NOT EXISTS "inf_api_error_log" (
 CREATE TABLE IF NOT EXISTS "inf_api_error_log" (
- "id" integer not null GENERATED BY DEFAULT AS IDENTITY,
+ "id" bigint not null GENERATED BY DEFAULT AS IDENTITY,
  "trace_id" varchar(64) not null,
  "trace_id" varchar(64) not null,
  "user_id" bigint not null default '0',
  "user_id" bigint not null default '0',
  "user_type" tinyint not null default '0',
  "user_type" tinyint not null default '0',
@@ -343,6 +350,7 @@ CREATE TABLE IF NOT EXISTS "inf_api_error_log" (
  "updater" varchar(64) default '',
  "updater" varchar(64) default '',
  "update_time" timestamp not null default current_timestamp,
  "update_time" timestamp not null default current_timestamp,
  "deleted" bit not null default false,
  "deleted" bit not null default false,
+ "tenant_id" bigint not null default  '0',
  primary key ("id")
  primary key ("id")
 ) COMMENT '系统异常日志';
 ) COMMENT '系统异常日志';
 
 
@@ -450,3 +458,17 @@ CREATE TABLE IF NOT EXISTS "sys_social_user" (
    "deleted" bit NOT NULL DEFAULT FALSE,
    "deleted" bit NOT NULL DEFAULT FALSE,
    PRIMARY KEY ("id")
    PRIMARY KEY ("id")
 ) COMMENT '社交用户';
 ) COMMENT '社交用户';
+
+CREATE TABLE IF NOT EXISTS "sys_tenant" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "name" varchar(63) NOT NULL,
+    "contact_name" varchar(255) NOT NULL,
+    "contact_mobile" varchar(255),
+    "status" tinyint NOT NULL,
+    "creator" varchar(64) DEFAULT '',
+    "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar(64) DEFAULT '',
+    "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    PRIMARY KEY ("id")
+) COMMENT '租户';

+ 48 - 6
yudao-admin-ui/src/api/system/tenant.js

@@ -1,12 +1,54 @@
 import request from '@/utils/request'
 import request from '@/utils/request'
 
 
-// 使用租户名,获得租户编号
-export function getTenantIdByName(name) {
+// 创建租户
+export function createTenant(data) {
   return request({
   return request({
-    url: '/system/tenant/get-id-by-name',
+    url: '/system/tenant/create',
+    method: 'post',
+    data: data
+  })
+}
+
+// 更新租户
+export function updateTenant(data) {
+  return request({
+    url: '/system/tenant/update',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除租户
+export function deleteTenant(id) {
+  return request({
+    url: '/system/tenant/delete?id=' + id,
+    method: 'delete'
+  })
+}
+
+// 获得租户
+export function getTenant(id) {
+  return request({
+    url: '/system/tenant/get?id=' + id,
+    method: 'get'
+  })
+}
+
+// 获得租户分页
+export function getTenantPage(query) {
+  return request({
+    url: '/system/tenant/page',
+    method: 'get',
+    params: query
+  })
+}
+
+// 导出租户 Excel
+export function exportTenantExcel(query) {
+  return request({
+    url: '/system/tenant/export-excel',
     method: 'get',
     method: 'get',
-    params: {
-      name
-    }
+    params: query,
+    responseType: 'blob'
   })
   })
 }
 }

+ 259 - 0
yudao-admin-ui/src/views/system/tenant/index.vue

@@ -0,0 +1,259 @@
+<template>
+  <div class="app-container">
+
+    <!-- 搜索工作栏 -->
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="租户名" prop="name">
+        <el-input v-model="queryParams.name" placeholder="请输入租户名" clearable size="small" @keyup.enter.native="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="联系人" prop="contactName">
+        <el-input v-model="queryParams.contactName" placeholder="请输入联系人" clearable size="small" @keyup.enter.native="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="联系手机" prop="contactMobile">
+        <el-input v-model="queryParams.contactMobile" placeholder="请输入联系手机" clearable size="small" @keyup.enter.native="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="租户状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择租户状态" clearable size="small">
+          <el-option v-for="dict in this.getDictDatas(DICT_TYPE.SYS_COMMON_STATUS)"
+                       :key="dict.value" :label="dict.label" :value="dict.value"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="创建时间">
+        <el-date-picker v-model="dateRangeCreateTime" size="small" style="width: 240px" value-format="yyyy-MM-dd"
+                        type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <!-- 操作工具栏 -->
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
+                   v-hasPermi="['system:tenant:create']">新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
+                   v-hasPermi="['system:tenant:export']">导出</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <!-- 列表 -->
+    <el-table v-loading="loading" :data="list">
+      <el-table-column label="租户编号" align="center" prop="id" />
+      <el-table-column label="租户名" align="center" prop="name" />
+      <el-table-column label="联系人" align="center" prop="contactName" />
+      <el-table-column label="联系手机" align="center" prop="contactMobile" />
+      <el-table-column label="租户状态" align="center" prop="status">
+        <template slot-scope="scope">
+          <span>{{ getDictDataLabel(DICT_TYPE.SYS_COMMON_STATUS, scope.row.status) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createTime) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
+                     v-hasPermi="['system:tenant:update']">修改</el-button>
+          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
+                     v-hasPermi="['system:tenant:delete']">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页组件 -->
+    <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
+                @pagination="getList"/>
+
+    <!-- 对话框(添加 / 修改) -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="租户名" prop="name">
+          <el-input v-model="form.name" placeholder="请输入租户名" />
+        </el-form-item>
+        <el-form-item label="联系人" prop="contactName">
+          <el-input v-model="form.contactName" placeholder="请输入联系人" />
+        </el-form-item>
+        <el-form-item label="联系手机" prop="contactMobile">
+          <el-input v-model="form.contactMobile" placeholder="请输入联系手机" />
+        </el-form-item>
+        <el-form-item label="租户状态" prop="status">
+          <el-radio-group v-model="form.status">
+            <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.SYS_COMMON_STATUS)"
+                      :key="dict.value" :label="parseInt(dict.value)">{{dict.label}}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { createTenant, updateTenant, deleteTenant, getTenant, getTenantPage, exportTenantExcel } from "@/api/system/tenant";
+import { SysCommonStatusEnum } from '@/utils/constants'
+
+export default {
+  name: "Tenant",
+  components: {
+  },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 租户列表
+      list: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      dateRangeCreateTime: [],
+      // 查询参数
+      queryParams: {
+        pageNo: 1,
+        pageSize: 10,
+        name: null,
+        contactName: null,
+        contactMobile: null,
+        status: undefined,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        name: [{ required: true, message: "租户名不能为空", trigger: "blur" }],
+        contactName: [{ required: true, message: "联系人不能为空", trigger: "blur" }],
+        status: [{ required: true, message: "租户状态(0正常 1停用)不能为空", trigger: "blur" }],
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询列表 */
+    getList() {
+      this.loading = true;
+      // 处理查询参数
+      let params = {...this.queryParams};
+      this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime');
+      // 执行查询
+      getTenantPage(params).then(response => {
+        this.list = response.data.list;
+        this.total = response.data.total;
+        this.loading = false;
+      });
+    },
+    /** 取消按钮 */
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    /** 表单重置 */
+    reset() {
+      this.form = {
+        id: undefined,
+        name: undefined,
+        contactName: undefined,
+        contactMobile: undefined,
+        status: SysCommonStatusEnum.ENABLE,
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNo = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.dateRangeCreateTime = [];
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加租户";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id;
+      getTenant(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改租户";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (!valid) {
+          return;
+        }
+        // 修改的提交
+        if (this.form.id != null) {
+          updateTenant(this.form).then(response => {
+            this.msgSuccess("修改成功");
+            this.open = false;
+            this.getList();
+          });
+          return;
+        }
+        // 添加的提交
+        createTenant(this.form).then(response => {
+          this.msgSuccess("新增成功");
+          this.open = false;
+          this.getList();
+        });
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const id = row.id;
+      this.$confirm('是否确认删除租户编号为"' + id + '"的数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return deleteTenant(id);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        })
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      // 处理查询参数
+      let params = {...this.queryParams};
+      params.pageNo = undefined;
+      params.pageSize = undefined;
+      this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime');
+      // 执行导出
+      this.$confirm('是否确认导出所有租户数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return exportTenantExcel(params);
+        }).then(response => {
+          this.downloadExcel(response, '租户.xls');
+        })
+    }
+  }
+};
+</script>

+ 3 - 0
yudao-core-service/src/test-integration/resources/application-integration-test.yaml

@@ -90,3 +90,6 @@ yudao:
     base-package: cn.iocoder.yudao.adminserver
     base-package: cn.iocoder.yudao.adminserver
   core-service:
   core-service:
     base-package: cn.iocoder.yudao.coreservice
     base-package: cn.iocoder.yudao.coreservice
+  pay:
+    pay-notify-url: http://niubi.natapp1.cc/api/pay/order/notify
+    refund-notify-url: http://niubi.natapp1.cc/api/pay/refund/notify

+ 4 - 1
yudao-core-service/src/test/java/cn/iocoder/yudao/coreservice/modules/system/service/auth/SysUserSessionCoreServiceTest.java

@@ -42,7 +42,10 @@ public class SysUserSessionCoreServiceTest extends BaseDbAndRedisUnitTest {
         // 准备参数
         // 准备参数
         String userIp = randomString();
         String userIp = randomString();
         String userAgent = randomString();
         String userAgent = randomString();
-        LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setUserType(randomEle(UserTypeEnum.values()).getValue()));
+        LoginUser loginUser = randomPojo(LoginUser.class, o -> {
+            o.setUserType(randomEle(UserTypeEnum.values()).getValue());
+            o.setTenantId(0L); // 租户设置为 0,因为暂未启用多租户组件
+        });
         // mock 方法
         // mock 方法
         when(securityProperties.getSessionTimeout()).thenReturn(Duration.ofDays(1));
         when(securityProperties.getSessionTimeout()).thenReturn(Duration.ofDays(1));
 
 

+ 6 - 0
yudao-core-service/src/test/resources/sql/create_tables.sql

@@ -9,6 +9,7 @@ CREATE TABLE IF NOT EXISTS "inf_file" (
     "updater" varchar(64) DEFAULT '',
     "updater" varchar(64) DEFAULT '',
     "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
     "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
     "deleted" bit NOT NULL DEFAULT FALSE,
     "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint not null default  '0',
     PRIMARY KEY ("id")
     PRIMARY KEY ("id")
 ) COMMENT '文件表';
 ) COMMENT '文件表';
 
 
@@ -27,6 +28,7 @@ CREATE TABLE IF NOT EXISTS `sys_user_session` (
     `updater` varchar(64) DEFAULT '' ,
     `updater` varchar(64) DEFAULT '' ,
     "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
     "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
     "deleted" bit NOT NULL DEFAULT FALSE,
     "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint not null default  '0',
     PRIMARY KEY (`id`)
     PRIMARY KEY (`id`)
 ) COMMENT '用户在线 Session';
 ) COMMENT '用户在线 Session';
 
 
@@ -67,6 +69,7 @@ CREATE TABLE IF NOT EXISTS "inf_api_access_log" (
     "updater" varchar(64) default '',
     "updater" varchar(64) default '',
     "update_time" timestamp not null default current_timestamp,
     "update_time" timestamp not null default current_timestamp,
     "deleted" bit not null default false,
     "deleted" bit not null default false,
+    "tenant_id" bigint not null default  '0',
     primary key ("id")
     primary key ("id")
 ) COMMENT 'API 访问日志表';
 ) COMMENT 'API 访问日志表';
 
 
@@ -98,6 +101,7 @@ CREATE TABLE IF NOT EXISTS "inf_api_error_log" (
     "updater" varchar(64) default '',
     "updater" varchar(64) default '',
     "update_time" timestamp not null default current_timestamp,
     "update_time" timestamp not null default current_timestamp,
     "deleted" bit not null default false,
     "deleted" bit not null default false,
+    "tenant_id" bigint not null default  '0',
     primary key ("id")
     primary key ("id")
 ) COMMENT '系统异常日志';
 ) COMMENT '系统异常日志';
 
 
@@ -151,6 +155,7 @@ CREATE TABLE IF NOT EXISTS "sys_sms_log" (
     "updater" varchar(64) DEFAULT '',
     "updater" varchar(64) DEFAULT '',
     "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
     "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
     "deleted" bit NOT NULL DEFAULT FALSE,
     "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint not null default  '0',
     PRIMARY KEY ("id")
     PRIMARY KEY ("id")
 ) COMMENT '短信日志';
 ) COMMENT '短信日志';
 
 
@@ -169,5 +174,6 @@ CREATE TABLE IF NOT EXISTS `sys_login_log` (
     `updater`   varchar(64)           DEFAULT '',
     `updater`   varchar(64)           DEFAULT '',
     `update_time` datetime     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
     `update_time` datetime     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
     `deleted`     bit(1)       NOT NULL DEFAULT '0',
     `deleted`     bit(1)       NOT NULL DEFAULT '0',
+    "tenant_id" bigint not null default  '0',
     PRIMARY KEY (`id`)
     PRIMARY KEY (`id`)
 ) COMMENT ='系统访问记录';
 ) COMMENT ='系统访问记录';

+ 16 - 1
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/ObjectUtils.java

@@ -1,7 +1,9 @@
 package cn.iocoder.yudao.framework.common.util.object;
 package cn.iocoder.yudao.framework.common.util.object;
 
 
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.ReflectUtil;
 
 
+import java.lang.reflect.Field;
 import java.util.function.Consumer;
 import java.util.function.Consumer;
 
 
 /**
 /**
@@ -11,8 +13,21 @@ import java.util.function.Consumer;
  */
  */
 public class ObjectUtils {
 public class ObjectUtils {
 
 
-    public static <T> T clone(T object, Consumer<T> consumer) {
+    /**
+     * 复制对象,并忽略 Id 编号
+     *
+     * @param object 被复制对象
+     * @param consumer 消费者,可以二次编辑被复制对象
+     * @return 复制后的对象
+     */
+    public static <T> T cloneIgnoreId(T object, Consumer<T> consumer) {
         T result = ObjectUtil.clone(object);
         T result = ObjectUtil.clone(object);
+        // 忽略 id 编号
+        Field field = ReflectUtil.getField(object.getClass(), "id");
+        if (field != null) {
+            ReflectUtil.setFieldValue(result, field, null);
+        }
+        // 二次编辑
         if (result != null) {
         if (result != null) {
             consumer.accept(result);
             consumer.accept(result);
         }
         }

+ 3 - 2
更新日志.md

@@ -33,8 +33,9 @@
 
 
 ### 🐞 Bug Fixes
 ### 🐞 Bug Fixes
 
 
-* 【修复】通知和字典查询权限
-* 【修复】代码生成器的 Java 类路径缺少 modules 目录的 Bug
+* 【修复】通知和字典查询接口的 @PreAuthorize 权限标识错误 
+* 【修复】代码生成的 Java 类路径缺少 modules 目录
+* 【修复】代码生成的 Test 单元测试类的引入 Util 工具类的包路径不正确
 
 
 ### 🔨 Dependency Upgrades
 ### 🔨 Dependency Upgrades