清除多租户功能
This commit is contained in:
@@ -13,8 +13,6 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1_002_000_000, "登录失败,账号密码不正确");
|
||||
ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1_002_000_001, "登录失败,账号被禁用");
|
||||
ErrorCode AUTH_LOGIN_CAPTCHA_CODE_ERROR = new ErrorCode(1_002_000_004, "验证码不正确,原因:{}");
|
||||
ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1_002_000_005, "未绑定账号,需要进行绑定");
|
||||
ErrorCode AUTH_MOBILE_NOT_EXISTS = new ErrorCode(1_002_000_007, "手机号不存在");
|
||||
ErrorCode AUTH_REGISTER_CAPTCHA_CODE_ERROR = new ErrorCode(1_002_000_008, "验证码不正确,原因:{}");
|
||||
|
||||
// ========== 菜单模块 1-002-001-000 ==========
|
||||
@@ -44,7 +42,6 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode USER_IS_DISABLE = new ErrorCode(1_002_003_006, "名字为【{}】的用户已被禁用");
|
||||
ErrorCode USER_COUNT_MAX = new ErrorCode(1_002_003_008, "创建用户失败,原因:超过租户最大租户配额({})!");
|
||||
ErrorCode USER_IMPORT_INIT_PASSWORD = new ErrorCode(1_002_003_009, "初始密码不能为空");
|
||||
ErrorCode USER_MOBILE_NOT_EXISTS = new ErrorCode(1_002_003_010, "该手机号尚未注册");
|
||||
ErrorCode USER_REGISTER_DISABLED = new ErrorCode(1_002_003_011, "注册功能已关闭");
|
||||
|
||||
// ========== 部门模块 1-002-004-000 ==========
|
||||
@@ -77,57 +74,6 @@ public interface ErrorCodeConstants {
|
||||
// ========== 通知公告 1-002-008-000 ==========
|
||||
ErrorCode NOTICE_NOT_FOUND = new ErrorCode(1_002_008_001, "当前通知公告不存在");
|
||||
|
||||
// ========== 短信渠道 1-002-011-000 ==========
|
||||
ErrorCode SMS_CHANNEL_NOT_EXISTS = new ErrorCode(1_002_011_000, "短信渠道不存在");
|
||||
ErrorCode SMS_CHANNEL_DISABLE = new ErrorCode(1_002_011_001, "短信渠道不处于开启状态,不允许选择");
|
||||
ErrorCode SMS_CHANNEL_HAS_CHILDREN = new ErrorCode(1_002_011_002, "无法删除,该短信渠道还有短信模板");
|
||||
|
||||
// ========== 短信模板 1-002-012-000 ==========
|
||||
ErrorCode SMS_TEMPLATE_NOT_EXISTS = new ErrorCode(1_002_012_000, "短信模板不存在");
|
||||
ErrorCode SMS_TEMPLATE_CODE_DUPLICATE = new ErrorCode(1_002_012_001, "已经存在编码为【{}】的短信模板");
|
||||
ErrorCode SMS_TEMPLATE_API_ERROR = new ErrorCode(1_002_012_002, "短信 API 模板调用失败,原因是:{}");
|
||||
ErrorCode SMS_TEMPLATE_API_AUDIT_CHECKING = new ErrorCode(1_002_012_003, "短信 API 模版无法使用,原因:审批中");
|
||||
ErrorCode SMS_TEMPLATE_API_AUDIT_FAIL = new ErrorCode(1_002_012_004, "短信 API 模版无法使用,原因:审批不通过,{}");
|
||||
ErrorCode SMS_TEMPLATE_API_NOT_FOUND = new ErrorCode(1_002_012_005, "短信 API 模版无法使用,原因:模版不存在");
|
||||
|
||||
// ========== 短信发送 1-002-013-000 ==========
|
||||
ErrorCode SMS_SEND_MOBILE_NOT_EXISTS = new ErrorCode(1_002_013_000, "手机号不存在");
|
||||
ErrorCode SMS_SEND_MOBILE_TEMPLATE_PARAM_MISS = new ErrorCode(1_002_013_001, "模板参数({})缺失");
|
||||
ErrorCode SMS_SEND_TEMPLATE_NOT_EXISTS = new ErrorCode(1_002_013_002, "短信模板不存在");
|
||||
|
||||
// ========== 短信验证码 1-002-014-000 ==========
|
||||
ErrorCode SMS_CODE_NOT_FOUND = new ErrorCode(1_002_014_000, "验证码不存在");
|
||||
ErrorCode SMS_CODE_EXPIRED = new ErrorCode(1_002_014_001, "验证码已过期");
|
||||
ErrorCode SMS_CODE_USED = new ErrorCode(1_002_014_002, "验证码已使用");
|
||||
ErrorCode SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY = new ErrorCode(1_002_014_004, "超过每日短信发送数量");
|
||||
ErrorCode SMS_CODE_SEND_TOO_FAST = new ErrorCode(1_002_014_005, "短信发送过于频繁");
|
||||
|
||||
// ========== 租户信息 1-002-015-000 ==========
|
||||
ErrorCode TENANT_NOT_EXISTS = new ErrorCode(1_002_015_000, "租户不存在");
|
||||
ErrorCode TENANT_DISABLE = new ErrorCode(1_002_015_001, "名字为【{}】的租户已被禁用");
|
||||
ErrorCode TENANT_EXPIRE = new ErrorCode(1_002_015_002, "名字为【{}】的租户已过期");
|
||||
ErrorCode TENANT_CAN_NOT_UPDATE_SYSTEM = new ErrorCode(1_002_015_003, "系统租户不能进行修改、删除等操作!");
|
||||
ErrorCode TENANT_NAME_DUPLICATE = new ErrorCode(1_002_015_004, "名字为【{}】的租户已存在");
|
||||
ErrorCode TENANT_WEBSITE_DUPLICATE = new ErrorCode(1_002_015_005, "域名为【{}】的租户已存在");
|
||||
|
||||
// ========== 租户套餐 1-002-016-000 ==========
|
||||
ErrorCode TENANT_PACKAGE_NOT_EXISTS = new ErrorCode(1_002_016_000, "租户套餐不存在");
|
||||
ErrorCode TENANT_PACKAGE_USED = new ErrorCode(1_002_016_001, "租户正在使用该套餐,请给租户重新设置套餐后再尝试删除");
|
||||
ErrorCode TENANT_PACKAGE_DISABLE = new ErrorCode(1_002_016_002, "名字为【{}】的租户套餐已被禁用");
|
||||
ErrorCode TENANT_PACKAGE_NAME_DUPLICATE = new ErrorCode(1_002_016_003, "已经存在该名字的租户套餐");
|
||||
|
||||
// ========== 社交用户 1-002-018-000 ==========
|
||||
ErrorCode SOCIAL_USER_AUTH_FAILURE = new ErrorCode(1_002_018_000, "社交授权失败,原因是:{}");
|
||||
ErrorCode SOCIAL_USER_NOT_FOUND = new ErrorCode(1_002_018_001, "社交授权失败,找不到对应的用户");
|
||||
|
||||
ErrorCode SOCIAL_CLIENT_WEIXIN_MINI_APP_PHONE_CODE_ERROR = new ErrorCode(1_002_018_200, "获得手机号失败");
|
||||
ErrorCode SOCIAL_CLIENT_WEIXIN_MINI_APP_QRCODE_ERROR = new ErrorCode(1_002_018_201, "获得小程序码失败");
|
||||
ErrorCode SOCIAL_CLIENT_WEIXIN_MINI_APP_SUBSCRIBE_TEMPLATE_ERROR = new ErrorCode(1_002_018_202, "获得小程序订阅消息模版失败");
|
||||
ErrorCode SOCIAL_CLIENT_WEIXIN_MINI_APP_SUBSCRIBE_MESSAGE_ERROR = new ErrorCode(1_002_018_203, "发送小程序订阅消息失败");
|
||||
ErrorCode SOCIAL_CLIENT_WEIXIN_MINI_APP_ORDER_UPLOAD_SHIPPING_INFO_ERROR = new ErrorCode(1_002_018_204, "上传微信小程序发货信息失败");
|
||||
ErrorCode SOCIAL_CLIENT_WEIXIN_MINI_APP_ORDER_NOTIFY_CONFIRM_RECEIVE_ERROR = new ErrorCode(1_002_018_205, "上传微信小程序订单收货信息失败");
|
||||
ErrorCode SOCIAL_CLIENT_NOT_EXISTS = new ErrorCode(1_002_018_210, "社交客户端不存在");
|
||||
ErrorCode SOCIAL_CLIENT_UNIQUE = new ErrorCode(1_002_018_211, "社交客户端已存在配置");
|
||||
|
||||
// ========== OAuth2 客户端 1-002-020-000 =========
|
||||
ErrorCode OAUTH2_CLIENT_NOT_EXISTS = new ErrorCode(1_002_020_000, "OAuth2 客户端不存在");
|
||||
@@ -147,18 +93,6 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode OAUTH2_CODE_NOT_EXISTS = new ErrorCode(1_002_022_000, "code 不存在");
|
||||
ErrorCode OAUTH2_CODE_EXPIRE = new ErrorCode(1_002_022_001, "code 已过期");
|
||||
|
||||
// ========== 邮箱账号 1-002-023-000 ==========
|
||||
ErrorCode MAIL_ACCOUNT_NOT_EXISTS = new ErrorCode(1_002_023_000, "邮箱账号不存在");
|
||||
ErrorCode MAIL_ACCOUNT_RELATE_TEMPLATE_EXISTS = new ErrorCode(1_002_023_001, "无法删除,该邮箱账号还有邮件模板");
|
||||
|
||||
// ========== 邮件模版 1-002-024-000 ==========
|
||||
ErrorCode MAIL_TEMPLATE_NOT_EXISTS = new ErrorCode(1_002_024_000, "邮件模版不存在");
|
||||
ErrorCode MAIL_TEMPLATE_CODE_EXISTS = new ErrorCode(1_002_024_001, "邮件模版 code({}) 已存在");
|
||||
|
||||
// ========== 邮件发送 1-002-025-000 ==========
|
||||
ErrorCode MAIL_SEND_TEMPLATE_PARAM_MISS = new ErrorCode(1_002_025_000, "模板参数({})缺失");
|
||||
ErrorCode MAIL_SEND_MAIL_NOT_EXISTS = new ErrorCode(1_002_025_001, "邮箱不存在");
|
||||
|
||||
// ========== 站内信模版 1-002-026-000 ==========
|
||||
ErrorCode NOTIFY_TEMPLATE_NOT_EXISTS = new ErrorCode(1_002_026_000, "站内信模版不存在");
|
||||
ErrorCode NOTIFY_TEMPLATE_CODE_DUPLICATE = new ErrorCode(1_002_026_001, "已经存在编码为【{}】的站内信模板");
|
||||
|
||||
@@ -11,9 +11,7 @@ import lombok.Getter;
|
||||
@AllArgsConstructor
|
||||
public enum RoleCodeEnum {
|
||||
|
||||
SUPER_ADMIN("super_admin", "超级管理员"),
|
||||
TENANT_ADMIN("tenant_admin", "租户管理员"),
|
||||
CRM_ADMIN("crm_admin", "CRM 管理员"); // CRM 系统专用
|
||||
SUPER_ADMIN("super_admin", "超级管理员"); // CRM 系统专用
|
||||
;
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,10 +37,6 @@
|
||||
</dependency>
|
||||
|
||||
<!-- 业务组件 -->
|
||||
<dependency>
|
||||
<groupId>com.njcn</groupId>
|
||||
<artifactId>msgpush-spring-boot-starter-biz-tenant</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.njcn</groupId>
|
||||
<artifactId>msgpush-spring-boot-starter-biz-ip</artifactId>
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.njcn.msgpush.module.system.api.oauth2;
|
||||
import com.njcn.msgpush.framework.common.biz.system.oauth2.OAuth2TokenCommonApi;
|
||||
import com.njcn.msgpush.framework.common.pojo.CommonResult;
|
||||
import com.njcn.msgpush.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.msgpush.framework.tenant.core.aop.TenantIgnore;
|
||||
import com.njcn.msgpush.framework.common.biz.system.oauth2.dto.OAuth2AccessTokenCheckRespDTO;
|
||||
import com.njcn.msgpush.framework.common.biz.system.oauth2.dto.OAuth2AccessTokenCreateReqDTO;
|
||||
import com.njcn.msgpush.framework.common.biz.system.oauth2.dto.OAuth2AccessTokenRespDTO;
|
||||
@@ -30,7 +29,6 @@ public class OAuth2TokenApiImpl implements OAuth2TokenCommonApi {
|
||||
}
|
||||
|
||||
@Override
|
||||
@TenantIgnore // 访问令牌校验时,无需传递租户编号;主要解决上传文件的场景,前端不会传递 tenant-id
|
||||
public CommonResult<OAuth2AccessTokenCheckRespDTO> checkAccessToken(String accessToken) {
|
||||
OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.checkAccessToken(accessToken);
|
||||
return success(BeanUtils.toBean(accessTokenDO, OAuth2AccessTokenCheckRespDTO.class));
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.api.tenant;
|
||||
|
||||
import com.njcn.msgpush.framework.common.biz.system.tenant.TenantCommonApi;
|
||||
import com.njcn.msgpush.framework.common.pojo.CommonResult;
|
||||
import com.njcn.msgpush.framework.tenant.core.aop.TenantIgnore;
|
||||
import com.njcn.msgpush.module.system.service.tenant.TenantService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
import static com.njcn.msgpush.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@RestController // 提供 RESTful API 接口,给 Feign 调用
|
||||
@Validated
|
||||
public class TenantApiImpl implements TenantCommonApi {
|
||||
|
||||
@Resource
|
||||
private TenantService tenantService;
|
||||
|
||||
@Override
|
||||
@TenantIgnore // 防止递归。避免调用 /rpc-api/system/tenant/valid 接口时,又去触发 /rpc-api/system/tenant/valid 去校验
|
||||
public CommonResult<List<Long>> getTenantIdList() {
|
||||
return success(tenantService.getTenantIdList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@TenantIgnore // 获得租户列表的时候,无需传递租户编号
|
||||
public CommonResult<Boolean> validTenant(Long id) {
|
||||
tenantService.validTenant(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
### 请求 /login 接口 => 成功
|
||||
POST {{baseUrl}}/system/auth/login
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
tag: Yunai.local
|
||||
|
||||
{
|
||||
@@ -14,7 +14,7 @@ tag: Yunai.local
|
||||
### 请求 /login 接口【加密 AES】 => 成功
|
||||
POST {{baseUrl}}/system/auth/login
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
tag: Yunai.local
|
||||
X-API-ENCRYPT: true
|
||||
|
||||
@@ -23,7 +23,7 @@ WvSX9MOrenyGfBhEM0g1/hHgq8ocktMZ9OwAJ6MOG5FUrzYF/rG5JF1eMptQM1wT73VgDS05l/37WeRt
|
||||
### 请求 /login 接口【加密 RSA】 => 成功
|
||||
POST {{baseUrl}}/system/auth/login
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
tag: Yunai.local
|
||||
X-API-ENCRYPT: true
|
||||
|
||||
@@ -32,7 +32,7 @@ e7QZTork9ZV5CmgZvSd+cHZk3xdUxKtowLM02kOha+gxHK2H/daU8nVBYS3+bwuDRy5abf+Pz1QJJGVA
|
||||
### 请求 /login 接口 => 成功(无验证码)
|
||||
POST {{baseUrl}}/system/auth/login
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
{
|
||||
"username": "admin",
|
||||
@@ -42,10 +42,10 @@ tenant-id: {{adminTenantId}}
|
||||
### 请求 /get-permission-info 接口 => 成功
|
||||
GET {{baseUrl}}/system/auth/get-permission-info
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
### 请求 /list-menus 接口 => 成功
|
||||
GET {{baseUrl}}/system/list-menus
|
||||
Authorization: Bearer {{token}}
|
||||
#Authorization: Bearer a6aa7714a2e44c95aaa8a2c5adc2a67a
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.njcn.msgpush.module.system.controller.admin.captcha;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.njcn.msgpush.framework.common.util.servlet.ServletUtils;
|
||||
import com.njcn.msgpush.framework.tenant.core.aop.TenantIgnore;
|
||||
|
||||
import com.anji.captcha.model.common.ResponseModel;
|
||||
import com.anji.captcha.model.vo.CaptchaVO;
|
||||
import com.anji.captcha.service.CaptchaService;
|
||||
@@ -27,7 +27,6 @@ public class CaptchaController {
|
||||
@PostMapping({"/get"})
|
||||
@Operation(summary = "获得验证码")
|
||||
@PermitAll
|
||||
@TenantIgnore
|
||||
public ResponseModel get(@RequestBody CaptchaVO data, HttpServletRequest request) {
|
||||
assert request.getRemoteHost() != null;
|
||||
data.setBrowserInfo(getRemoteId(request));
|
||||
@@ -37,7 +36,6 @@ public class CaptchaController {
|
||||
@PostMapping("/check")
|
||||
@Operation(summary = "校验验证码")
|
||||
@PermitAll
|
||||
@TenantIgnore
|
||||
public ResponseModel check(@RequestBody CaptchaVO data, HttpServletRequest request) {
|
||||
data.setBrowserInfo(getRemoteId(request));
|
||||
return captchaService.check(data);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
### 请求 /menu/list 接口 => 成功
|
||||
GET {{baseUrl}}/system/dict-data/list-all-simple
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
### 获得地区树
|
||||
GET {{baseUrl}}/system/area/tree
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
### 请求 /system/operate-log/page 接口 => 成功
|
||||
GET {{baseUrl}}/system/operate-log/page
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
POST {{baseUrl}}/system/oauth2-client/create
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
{
|
||||
"id": "1",
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
### 请求 /system/oauth2/authorize 接口 => 成功
|
||||
GET {{baseUrl}}/system/oauth2/authorize?clientId=default
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
### 请求 /system/oauth2/authorize + token 接口 => 成功
|
||||
POST {{baseUrl}}/system/oauth2/authorize
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
response_type=token&client_id=default&scope={"user.read": true}&redirect_uri=https://www.iocoder.cn&auto_approve=true
|
||||
|
||||
@@ -15,7 +15,7 @@ response_type=token&client_id=default&scope={"user.read": true}&redirect_uri=htt
|
||||
POST {{baseUrl}}/system/oauth2/authorize
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
response_type=code&client_id=default&scope={"user.read": true}&redirect_uri=https://www.iocoder.cn&auto_approve=false
|
||||
|
||||
@@ -23,7 +23,7 @@ response_type=code&client_id=default&scope={"user.read": true}&redirect_uri=http
|
||||
POST {{baseUrl}}/system/oauth2/token
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw==
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
grant_type=authorization_code&redirect_uri=https://www.iocoder.cn&code=189956c07a174588a97157eabef2f93a
|
||||
|
||||
@@ -31,7 +31,7 @@ grant_type=authorization_code&redirect_uri=https://www.iocoder.cn&code=189956c07
|
||||
POST {{baseUrl}}/system/oauth2/token
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw==
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
grant_type=password&username=admin&password=admin123&scope=user.read
|
||||
|
||||
@@ -39,7 +39,7 @@ grant_type=password&username=admin&password=admin123&scope=user.read
|
||||
POST {{baseUrl}}/system/oauth2/token
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw==
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
grant_type=client_credentials&scope=user.read
|
||||
|
||||
@@ -47,16 +47,16 @@ grant_type=client_credentials&scope=user.read
|
||||
POST {{baseUrl}}/system/oauth2/token
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw==
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
grant_type=refresh_token&refresh_token=00895465d6994f72a9d926ceeed0f588
|
||||
|
||||
### 请求 /system/oauth2/token + DELETE 接口 => 成功
|
||||
DELETE {{baseUrl}}/system/oauth2/token?token=ca8a188f464441d6949c51493a2b7596
|
||||
Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw==
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
### 请求 /system/oauth2/check-token 接口 => 成功
|
||||
POST {{baseUrl}}/system/oauth2/check-token?token=620d307c5b4148df8a98dd6c6c547106
|
||||
Authorization: Basic ZGVmYXVsdDphZG1pbjEyMw==
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
### 请求 /system/oauth2/user/get 接口 => 成功
|
||||
GET {{baseUrl}}/system/oauth2/user/get
|
||||
Authorization: Bearer 47f9c74ec11041f193b777ebb95c3b0d
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
### 请求 /system/oauth2/user/update 接口 => 成功
|
||||
PUT {{baseUrl}}/system/oauth2/user/update
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer 47f9c74ec11041f193b777ebb95c3b0d
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
{
|
||||
"nickname": "灿能源码"
|
||||
|
||||
@@ -20,9 +20,6 @@ public class OAuth2OpenCheckTokenRespVO {
|
||||
@Schema(description = "用户类型,参见 UserTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@JsonProperty("user_type")
|
||||
private Integer userType;
|
||||
@Schema(description = "租户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@JsonProperty("tenant_id")
|
||||
private Long tenantId;
|
||||
|
||||
@Schema(description = "客户端编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "car")
|
||||
@JsonProperty("client_id")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
### 请求 /menu/list 接口 => 成功
|
||||
GET {{baseUrl}}/system/menu/list
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
@@ -75,17 +75,6 @@ public class MenuController {
|
||||
return success(BeanUtils.toBean(list, MenuRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping({"/list-all-simple", "simple-list"})
|
||||
@Operation(summary = "获取菜单精简信息列表",
|
||||
description = "只包含被开启的菜单,用于【角色分配菜单】功能的选项。在多租户的场景下,会只返回租户所在套餐有的菜单")
|
||||
public CommonResult<List<MenuSimpleRespVO>> getSimpleMenuList() {
|
||||
List<MenuDO> list = menuService.getMenuListByTenant(
|
||||
new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
list = menuService.filterDisableMenus(list);
|
||||
list.sort(Comparator.comparing(MenuDO::getSort));
|
||||
return success(BeanUtils.toBean(list, MenuSimpleRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获取菜单信息")
|
||||
@PreAuthorize("@ss.hasPermission('system:menu:query')")
|
||||
|
||||
@@ -6,7 +6,6 @@ import com.njcn.msgpush.module.system.controller.admin.permission.vo.permission.
|
||||
import com.njcn.msgpush.module.system.controller.admin.permission.vo.permission.PermissionAssignRoleMenuReqVO;
|
||||
import com.njcn.msgpush.module.system.controller.admin.permission.vo.permission.PermissionAssignUserRoleReqVO;
|
||||
import com.njcn.msgpush.module.system.service.permission.PermissionService;
|
||||
import com.njcn.msgpush.module.system.service.tenant.TenantService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -32,8 +31,6 @@ public class PermissionController {
|
||||
|
||||
@Resource
|
||||
private PermissionService permissionService;
|
||||
@Resource
|
||||
private TenantService tenantService;
|
||||
|
||||
@Operation(summary = "获得角色拥有的菜单编号")
|
||||
@Parameter(name = "roleId", description = "角色编号", required = true)
|
||||
@@ -47,9 +44,6 @@ public class PermissionController {
|
||||
@Operation(summary = "赋予角色菜单")
|
||||
@PreAuthorize("@ss.hasPermission('system:permission:assign-role-menu')")
|
||||
public CommonResult<Boolean> assignRoleMenu(@Validated @RequestBody PermissionAssignRoleMenuReqVO reqVO) {
|
||||
// 开启多租户的情况下,需要过滤掉未开通的菜单
|
||||
tenantService.handleTenantMenu(menuIds -> reqVO.getMenuIds().removeIf(menuId -> !CollUtil.contains(menuIds, menuId)));
|
||||
|
||||
// 执行菜单的分配
|
||||
permissionService.assignRoleMenu(reqVO.getRoleId(), reqVO.getMenuIds());
|
||||
return success(true);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
POST {{baseUrl}}/system/role/create
|
||||
Authorization: Bearer {{token}}
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
{
|
||||
"name": "测试角色",
|
||||
@@ -14,7 +14,7 @@ tenant-id: {{adminTenantId}}
|
||||
POST {{baseUrl}}/system/role/update
|
||||
Authorization: Bearer {{token}}
|
||||
Content-Type: application/json
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
{
|
||||
"id": 100,
|
||||
@@ -26,7 +26,7 @@ tenant-id: {{adminTenantId}}
|
||||
POST {{baseUrl}}/system/role/delete
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
roleId=14
|
||||
|
||||
@@ -34,9 +34,9 @@ roleId=14
|
||||
GET {{baseUrl}}/system/role/get?id=100
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
### /role/page 成功
|
||||
GET {{baseUrl}}/system/role/page?pageNo=1&pageSize=10
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
### 获取租户编号 /admin-api/system/get-id-by-name
|
||||
GET {{baseUrl}}/system/tenant/get-id-by-name?name=灿能源码
|
||||
|
||||
### 创建租户 /admin-api/system/tenant/create
|
||||
POST {{baseUrl}}/system/tenant/create
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
{
|
||||
"name": "灿能",
|
||||
"contactName": "芋艿",
|
||||
"contactMobile": "15601691300",
|
||||
"status": 0,
|
||||
"domain": "https://www.iocoder.cn",
|
||||
"packageId": 110,
|
||||
"expireTime": 1699545600000,
|
||||
"accountCount": 20,
|
||||
"username": "admin",
|
||||
"password": "123321"
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.controller.admin.tenant;
|
||||
|
||||
import com.njcn.msgpush.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.common.pojo.CommonResult;
|
||||
import com.njcn.msgpush.framework.common.pojo.PageParam;
|
||||
import com.njcn.msgpush.framework.common.pojo.PageResult;
|
||||
import com.njcn.msgpush.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.msgpush.framework.excel.core.util.ExcelUtils;
|
||||
import com.njcn.msgpush.framework.tenant.core.aop.TenantIgnore;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.tenant.TenantRespVO;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.tenant.TenantSaveReqVO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.tenant.TenantDO;
|
||||
import com.njcn.msgpush.module.system.service.tenant.TenantService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.annotation.security.PermitAll;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static com.njcn.msgpush.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static com.njcn.msgpush.framework.common.pojo.CommonResult.success;
|
||||
import static com.njcn.msgpush.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
@Tag(name = "管理后台 - 租户")
|
||||
@RestController
|
||||
@RequestMapping("/system/tenant")
|
||||
public class TenantController {
|
||||
|
||||
@Resource
|
||||
private TenantService tenantService;
|
||||
|
||||
@GetMapping("/get-id-by-name")
|
||||
@PermitAll
|
||||
@TenantIgnore
|
||||
@Operation(summary = "使用租户名,获得租户编号", description = "登录界面,根据用户的租户名,获得租户编号")
|
||||
@Parameter(name = "name", description = "租户名", required = true, example = "1024")
|
||||
public CommonResult<Long> getTenantIdByName(@RequestParam("name") String name) {
|
||||
TenantDO tenant = tenantService.getTenantByName(name);
|
||||
return success(tenant != null ? tenant.getId() : null);
|
||||
}
|
||||
|
||||
@GetMapping({ "simple-list" })
|
||||
@PermitAll
|
||||
@TenantIgnore
|
||||
@Operation(summary = "获取租户精简信息列表", description = "只包含被开启的租户,用于【首页】功能的选择租户选项")
|
||||
public CommonResult<List<TenantRespVO>> getTenantSimpleList() {
|
||||
List<TenantDO> list = tenantService.getTenantListByStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
return success(convertList(list, tenantDO ->
|
||||
new TenantRespVO().setId(tenantDO.getId()).setName(tenantDO.getName())));
|
||||
}
|
||||
|
||||
@GetMapping("/get-by-website")
|
||||
@PermitAll
|
||||
@TenantIgnore
|
||||
@Operation(summary = "使用域名,获得租户信息", description = "登录界面,根据用户的域名,获得租户信息")
|
||||
@Parameter(name = "website", description = "域名", required = true, example = "www.iocoder.cn")
|
||||
public CommonResult<TenantRespVO> getTenantByWebsite(@RequestParam("website") String website) {
|
||||
TenantDO tenant = tenantService.getTenantByWebsite(website);
|
||||
if (tenant == null || CommonStatusEnum.isDisable(tenant.getStatus())) {
|
||||
return success(null);
|
||||
}
|
||||
return success(new TenantRespVO().setId(tenant.getId()).setName(tenant.getName()));
|
||||
}
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建租户")
|
||||
@PreAuthorize("@ss.hasPermission('system:tenant:create')")
|
||||
public CommonResult<Long> createTenant(@Valid @RequestBody TenantSaveReqVO createReqVO) {
|
||||
return success(tenantService.createTenant(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新租户")
|
||||
@PreAuthorize("@ss.hasPermission('system:tenant:update')")
|
||||
public CommonResult<Boolean> updateTenant(@Valid @RequestBody TenantSaveReqVO updateReqVO) {
|
||||
tenantService.updateTenant(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除租户")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:tenant:delete')")
|
||||
public CommonResult<Boolean> deleteTenant(@RequestParam("id") Long id) {
|
||||
tenantService.deleteTenant(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete-list")
|
||||
@Parameter(name = "ids", description = "编号列表", required = true)
|
||||
@Operation(summary = "批量删除租户")
|
||||
@PreAuthorize("@ss.hasPermission('system:tenant:delete')")
|
||||
public CommonResult<Boolean> deleteTenantList(@RequestParam("ids") List<Long> ids) {
|
||||
tenantService.deleteTenantList(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得租户")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:tenant:query')")
|
||||
public CommonResult<TenantRespVO> getTenant(@RequestParam("id") Long id) {
|
||||
TenantDO tenant = tenantService.getTenant(id);
|
||||
return success(BeanUtils.toBean(tenant, TenantRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得租户分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:tenant:query')")
|
||||
public CommonResult<PageResult<TenantRespVO>> getTenantPage(@Valid TenantPageReqVO pageVO) {
|
||||
PageResult<TenantDO> pageResult = tenantService.getTenantPage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, TenantRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出租户 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('system:tenant:export')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportTenantExcel(@Valid TenantPageReqVO exportReqVO, HttpServletResponse response) throws IOException {
|
||||
exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<TenantDO> list = tenantService.getTenantPage(exportReqVO).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "租户.xls", "数据", TenantRespVO.class,
|
||||
BeanUtils.toBean(list, TenantRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.controller.admin.tenant;
|
||||
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.common.pojo.CommonResult;
|
||||
import com.njcn.msgpush.framework.common.pojo.PageResult;
|
||||
import com.njcn.msgpush.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.packages.TenantPackagePageReqVO;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.packages.TenantPackageRespVO;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.packages.TenantPackageSaveReqVO;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.packages.TenantPackageSimpleRespVO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.tenant.TenantPackageDO;
|
||||
import com.njcn.msgpush.module.system.service.tenant.TenantPackageService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.njcn.msgpush.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 租户套餐")
|
||||
@RestController
|
||||
@RequestMapping("/system/tenant-package")
|
||||
@Validated
|
||||
public class TenantPackageController {
|
||||
|
||||
@Resource
|
||||
private TenantPackageService tenantPackageService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建租户套餐")
|
||||
@PreAuthorize("@ss.hasPermission('system:tenant-package:create')")
|
||||
public CommonResult<Long> createTenantPackage(@Valid @RequestBody TenantPackageSaveReqVO createReqVO) {
|
||||
return success(tenantPackageService.createTenantPackage(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新租户套餐")
|
||||
@PreAuthorize("@ss.hasPermission('system:tenant-package:update')")
|
||||
public CommonResult<Boolean> updateTenantPackage(@Valid @RequestBody TenantPackageSaveReqVO updateReqVO) {
|
||||
tenantPackageService.updateTenantPackage(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除租户套餐")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('system:tenant-package:delete')")
|
||||
public CommonResult<Boolean> deleteTenantPackage(@RequestParam("id") Long id) {
|
||||
tenantPackageService.deleteTenantPackage(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete-list")
|
||||
@Parameter(name = "ids", description = "编号列表", required = true)
|
||||
@Operation(summary = "批量删除租户套餐")
|
||||
@PreAuthorize("@ss.hasPermission('system:tenant-package:delete')")
|
||||
public CommonResult<Boolean> deleteTenantPackageList(@RequestParam("ids") List<Long> ids) {
|
||||
tenantPackageService.deleteTenantPackageList(ids);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得租户套餐")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:tenant-package:query')")
|
||||
public CommonResult<TenantPackageRespVO> getTenantPackage(@RequestParam("id") Long id) {
|
||||
TenantPackageDO tenantPackage = tenantPackageService.getTenantPackage(id);
|
||||
return success(BeanUtils.toBean(tenantPackage, TenantPackageRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得租户套餐分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:tenant-package:query')")
|
||||
public CommonResult<PageResult<TenantPackageRespVO>> getTenantPackagePage(@Valid TenantPackagePageReqVO pageVO) {
|
||||
PageResult<TenantPackageDO> pageResult = tenantPackageService.getTenantPackagePage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, TenantPackageRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping({"/get-simple-list", "simple-list"})
|
||||
@Operation(summary = "获取租户套餐精简信息列表", description = "只包含被开启的租户套餐,主要用于前端的下拉选项")
|
||||
public CommonResult<List<TenantPackageSimpleRespVO>> getTenantPackageList() {
|
||||
List<TenantPackageDO> list = tenantPackageService.getTenantPackageListByStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
return success(BeanUtils.toBean(list, TenantPackageSimpleRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.controller.admin.tenant.vo.packages;
|
||||
|
||||
import com.njcn.msgpush.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.njcn.msgpush.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 租户套餐分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class TenantPackagePageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "套餐名", example = "VIP")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "备注", example = "好")
|
||||
private String remark;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime[] createTime;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.controller.admin.tenant.vo.packages;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Set;
|
||||
|
||||
@Schema(description = "管理后台 - 租户套餐 Response VO")
|
||||
@Data
|
||||
public class TenantPackageRespVO {
|
||||
|
||||
@Schema(description = "套餐编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "套餐名", requiredMode = Schema.RequiredMode.REQUIRED, example = "VIP")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "状态,参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "备注", example = "好")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "关联的菜单编号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Set<Long> menuIds;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.controller.admin.tenant.vo.packages;
|
||||
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.Set;
|
||||
|
||||
@Schema(description = "管理后台 - 租户套餐创建/修改 Request VO")
|
||||
@Data
|
||||
public class TenantPackageSaveReqVO {
|
||||
|
||||
@Schema(description = "套餐编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "套餐名", requiredMode = Schema.RequiredMode.REQUIRED, example = "VIP")
|
||||
@NotEmpty(message = "套餐名不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "状态,参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "状态不能为空")
|
||||
@InEnum(value = CommonStatusEnum.class, message = "状态必须是 {value}")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "备注", example = "好")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "关联的菜单编号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "关联的菜单编号不能为空")
|
||||
private Set<Long> menuIds;
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.controller.admin.tenant.vo.packages;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 租户套餐精简 Response VO")
|
||||
@Data
|
||||
public class TenantPackageSimpleRespVO {
|
||||
|
||||
@Schema(description = "套餐编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "套餐编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "套餐名", requiredMode = Schema.RequiredMode.REQUIRED, example = "VIP")
|
||||
@NotNull(message = "套餐名不能为空")
|
||||
private String name;
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.controller.admin.tenant.vo.tenant;
|
||||
|
||||
import com.njcn.msgpush.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.njcn.msgpush.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 租户分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class TenantPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "租户名", example = "灿能")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "联系人", example = "芋艿")
|
||||
private String contactName;
|
||||
|
||||
@Schema(description = "联系手机", example = "15601691300")
|
||||
private String contactMobile;
|
||||
|
||||
@Schema(description = "租户状态(0正常 1停用)", example = "1")
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.controller.admin.tenant.vo.tenant;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import com.njcn.msgpush.framework.excel.core.annotations.DictFormat;
|
||||
import com.njcn.msgpush.framework.excel.core.convert.DictConvert;
|
||||
import com.njcn.msgpush.module.system.enums.DictTypeConstants;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 租户 Response VO")
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class TenantRespVO {
|
||||
|
||||
@Schema(description = "租户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@ExcelProperty("租户编号")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "租户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "灿能")
|
||||
@ExcelProperty("租户名")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "联系人", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
|
||||
@ExcelProperty("联系人")
|
||||
private String contactName;
|
||||
|
||||
@Schema(description = "联系手机", example = "15601691300")
|
||||
@ExcelProperty("联系手机")
|
||||
private String contactMobile;
|
||||
|
||||
@Schema(description = "租户状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@ExcelProperty(value = "状态", converter = DictConvert.class)
|
||||
@DictFormat(DictTypeConstants.COMMON_STATUS)
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "绑定域名数组", example = "https://www.iocoder.cn")
|
||||
private List<String> websites;
|
||||
|
||||
@Schema(description = "租户套餐编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long packageId;
|
||||
|
||||
@Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime expireTime;
|
||||
|
||||
@Schema(description = "账号数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Integer accountCount;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.controller.admin.tenant.vo.tenant;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.AssertTrue;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 租户创建/修改 Request VO")
|
||||
@Data
|
||||
public class TenantSaveReqVO {
|
||||
|
||||
@Schema(description = "租户编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "租户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "灿能")
|
||||
@NotNull(message = "租户名不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "联系人", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
|
||||
@NotNull(message = "联系人不能为空")
|
||||
private String contactName;
|
||||
|
||||
@Schema(description = "联系手机", example = "15601691300")
|
||||
private String contactMobile;
|
||||
|
||||
@Schema(description = "租户状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "租户状态")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "绑定域名数组", example = "https://www.iocoder.cn")
|
||||
private List<String> websites;
|
||||
|
||||
@Schema(description = "租户套餐编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "租户套餐编号不能为空")
|
||||
private Long packageId;
|
||||
|
||||
@Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "过期时间不能为空")
|
||||
private LocalDateTime expireTime;
|
||||
|
||||
@Schema(description = "账号数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "账号数量不能为空")
|
||||
private Integer accountCount;
|
||||
|
||||
// ========== 仅【创建】时,需要传递的字段 ==========
|
||||
|
||||
@Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "msgpush")
|
||||
@Pattern(regexp = "^[a-zA-Z0-9]{4,30}$", message = "用户账号由 数字、字母 组成")
|
||||
@Size(min = 4, max = 30, message = "用户账号长度为 4-30 个字符")
|
||||
private String username;
|
||||
|
||||
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
||||
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
|
||||
private String password;
|
||||
|
||||
@AssertTrue(message = "用户账号、密码不能为空")
|
||||
@JsonIgnore
|
||||
public boolean isUsernameValid() {
|
||||
return id != null // 修改时,不需要传递
|
||||
|| (ObjectUtil.isAllNotEmpty(username, password)); // 新增时,必须都传递 username、password
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,10 +2,9 @@
|
||||
GET {{baseUrl}}/system/user/page?pageNo=1&pageSize=10
|
||||
Authorization: Bearer {{token}}
|
||||
#Authorization: Bearer test100
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
### 请求 /system/user/page 接口(测试访问别的租户)
|
||||
GET {{baseUrl}}/system/user/page?pageNo=1&pageSize=10
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenantId}}
|
||||
visit-tenant-id: 122
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
### 请求 /system/user/profile/get 接口 => 没有权限
|
||||
GET {{baseUrl}}/system/user/profile/get
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenantId}}
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.controller.app.tenant;
|
||||
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.common.pojo.CommonResult;
|
||||
import com.njcn.msgpush.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.msgpush.framework.tenant.core.aop.TenantIgnore;
|
||||
import com.njcn.msgpush.module.system.controller.app.tenant.vo.AppTenantRespVO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.tenant.TenantDO;
|
||||
import com.njcn.msgpush.module.system.service.tenant.TenantService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.annotation.security.PermitAll;
|
||||
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 static com.njcn.msgpush.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "用户 App - 租户")
|
||||
@RestController
|
||||
@RequestMapping("/system/tenant")
|
||||
public class AppTenantController {
|
||||
|
||||
@Resource
|
||||
private TenantService tenantService;
|
||||
|
||||
@GetMapping("/get-by-website")
|
||||
@PermitAll
|
||||
@TenantIgnore
|
||||
@Operation(summary = "使用域名,获得租户信息", description = "根据用户的域名,获得租户信息")
|
||||
@Parameter(name = "website", description = "域名", required = true, example = "www.iocoder.cn")
|
||||
public CommonResult<AppTenantRespVO> getTenantByWebsite(@RequestParam("website") String website) {
|
||||
TenantDO tenant = tenantService.getTenantByWebsite(website);
|
||||
if (tenant == null || CommonStatusEnum.isDisable(tenant.getStatus())) {
|
||||
return success(null);
|
||||
}
|
||||
return success(BeanUtils.toBean(tenant, AppTenantRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.controller.app.tenant.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "用户 App - 租户 Response VO")
|
||||
@Data
|
||||
public class AppTenantRespVO {
|
||||
|
||||
@Schema(description = "租户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "租户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "灿能")
|
||||
private String name;
|
||||
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.convert.tenant;
|
||||
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.tenant.TenantSaveReqVO;
|
||||
import com.njcn.msgpush.module.system.controller.admin.user.vo.user.UserSaveReqVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* 租户 Convert
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@Mapper
|
||||
public interface TenantConvert {
|
||||
|
||||
TenantConvert INSTANCE = Mappers.getMapper(TenantConvert.class);
|
||||
|
||||
default UserSaveReqVO convert02(TenantSaveReqVO bean) {
|
||||
UserSaveReqVO reqVO = new UserSaveReqVO();
|
||||
reqVO.setUsername(bean.getUsername());
|
||||
reqVO.setPassword(bean.getPassword());
|
||||
reqVO.setNickname(bean.getContactName()).setMobile(bean.getContactMobile());
|
||||
return reqVO;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.njcn.msgpush.module.system.dal.dataobject.dept;
|
||||
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.njcn.msgpush.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -19,7 +19,7 @@ import lombok.EqualsAndHashCode;
|
||||
@KeySequence("system_dept_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class DeptDO extends TenantBaseDO {
|
||||
public class DeptDO extends BaseDO {
|
||||
|
||||
public static final Long PARENT_ID_ROOT = 0L;
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.njcn.msgpush.module.system.dal.dataobject.dict;
|
||||
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.msgpush.framework.tenant.core.aop.TenantIgnore;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -16,7 +15,6 @@ import lombok.EqualsAndHashCode;
|
||||
@KeySequence("system_dict_data_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TenantIgnore
|
||||
public class DictDataDO extends BaseDO {
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.njcn.msgpush.module.system.dal.dataobject.dict;
|
||||
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.msgpush.framework.tenant.core.aop.TenantIgnore;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
@@ -23,7 +22,6 @@ import java.time.LocalDateTime;
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@TenantIgnore
|
||||
public class DictTypeDO extends BaseDO {
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.njcn.msgpush.module.system.dal.dataobject.mail;
|
||||
|
||||
import com.njcn.msgpush.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.msgpush.framework.tenant.core.aop.TenantIgnore;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
@@ -20,7 +20,6 @@ import lombok.EqualsAndHashCode;
|
||||
@KeySequence("system_mail_account_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TenantIgnore
|
||||
public class MailAccountDO extends BaseDO {
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.njcn.msgpush.module.system.dal.dataobject.mail;
|
||||
import com.njcn.msgpush.framework.common.enums.UserTypeEnum;
|
||||
import com.njcn.msgpush.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.msgpush.framework.mybatis.core.type.StringListTypeHandler;
|
||||
import com.njcn.msgpush.framework.tenant.core.aop.TenantIgnore;
|
||||
|
||||
import com.njcn.msgpush.module.system.enums.mail.MailSendStatusEnum;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
@@ -31,7 +31,6 @@ import java.util.Map;
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@TenantIgnore
|
||||
public class MailLogDO extends BaseDO implements Serializable {
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.njcn.msgpush.module.system.dal.dataobject.mail;
|
||||
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.msgpush.framework.tenant.core.aop.TenantIgnore;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
@@ -22,7 +22,6 @@ import java.util.List;
|
||||
@KeySequence("system_mail_template_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TenantIgnore
|
||||
public class MailTemplateDO extends BaseDO {
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.njcn.msgpush.module.system.dal.dataobject.notify;
|
||||
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.msgpush.framework.tenant.core.aop.TenantIgnore;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -25,7 +25,6 @@ import java.util.List;
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@TenantIgnore
|
||||
public class NotifyTemplateDO extends BaseDO {
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.njcn.msgpush.module.system.dal.dataobject.oauth2;
|
||||
|
||||
import com.njcn.msgpush.framework.common.enums.UserTypeEnum;
|
||||
import com.njcn.msgpush.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import com.njcn.msgpush.framework.mybatis.core.dataobject.BaseDO;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.util.Map;
|
||||
@KeySequence("system_oauth2_access_token_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class OAuth2AccessTokenDO extends TenantBaseDO {
|
||||
public class OAuth2AccessTokenDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号,数据库递增
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.njcn.msgpush.module.system.dal.dataobject.oauth2;
|
||||
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.msgpush.framework.tenant.core.aop.TenantIgnore;
|
||||
|
||||
import com.njcn.msgpush.module.system.enums.oauth2.OAuth2GrantTypeEnum;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
@@ -23,7 +23,6 @@ import java.util.List;
|
||||
@KeySequence("system_oauth2_client_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TenantIgnore
|
||||
public class OAuth2ClientDO extends BaseDO {
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.njcn.msgpush.module.system.dal.dataobject.oauth2;
|
||||
|
||||
import com.njcn.msgpush.framework.common.enums.UserTypeEnum;
|
||||
import com.njcn.msgpush.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import com.njcn.msgpush.framework.mybatis.core.dataobject.BaseDO;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@@ -20,7 +20,7 @@ import java.util.List;
|
||||
// 由于 Oracle 的 SEQ 的名字长度有限制,所以就先用 system_oauth2_access_token_seq 吧,反正也没啥问题
|
||||
@KeySequence("system_oauth2_access_token_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
public class OAuth2RefreshTokenDO extends TenantBaseDO {
|
||||
public class OAuth2RefreshTokenDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号,数据库字典
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.njcn.msgpush.module.system.dal.dataobject.permission;
|
||||
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.msgpush.framework.tenant.core.aop.TenantIgnore;
|
||||
|
||||
import com.njcn.msgpush.module.system.enums.permission.MenuTypeEnum;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -19,7 +19,6 @@ import lombok.EqualsAndHashCode;
|
||||
@KeySequence("system_menu_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TenantIgnore
|
||||
public class MenuDO extends BaseDO {
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.njcn.msgpush.module.system.dal.dataobject.permission;
|
||||
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.njcn.msgpush.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.msgpush.module.system.enums.permission.DataScopeEnum;
|
||||
import com.njcn.msgpush.module.system.enums.permission.RoleTypeEnum;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
@@ -23,7 +23,7 @@ import java.util.Set;
|
||||
@KeySequence("system_role_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class RoleDO extends TenantBaseDO {
|
||||
public class RoleDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 角色ID
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.njcn.msgpush.module.system.dal.dataobject.permission;
|
||||
|
||||
import com.njcn.msgpush.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.njcn.msgpush.framework.mybatis.core.dataobject.BaseDO;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@@ -16,7 +16,7 @@ import lombok.EqualsAndHashCode;
|
||||
@KeySequence("system_role_menu_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class RoleMenuDO extends TenantBaseDO {
|
||||
public class RoleMenuDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 自增主键
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.dal.dataobject.tenant;
|
||||
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.msgpush.framework.mybatis.core.type.StringListTypeHandler;
|
||||
import com.njcn.msgpush.framework.tenant.core.aop.TenantIgnore;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 租户 DO
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@TableName(value = "system_tenant", autoResultMap = true)
|
||||
@KeySequence("system_tenant_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@TenantIgnore
|
||||
public class TenantDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 套餐编号 - 系统
|
||||
*/
|
||||
public static final Long PACKAGE_ID_SYSTEM = 0L;
|
||||
|
||||
/**
|
||||
* 租户编号,自增
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 租户名,唯一
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 联系人的用户编号
|
||||
*
|
||||
* 关联 {@link AdminUserDO#getId()}
|
||||
*/
|
||||
private Long contactUserId;
|
||||
/**
|
||||
* 联系人
|
||||
*/
|
||||
private String contactName;
|
||||
/**
|
||||
* 联系手机
|
||||
*/
|
||||
private String contactMobile;
|
||||
/**
|
||||
* 租户状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 绑定域名列表
|
||||
*
|
||||
* 1. 考虑到对微信小程序的兼容,也允许传递 appid
|
||||
* 2. 为什么是数组,考虑到管理后台、会员前台都有独立的域名,又或者多个管理后台
|
||||
*/
|
||||
@TableField(typeHandler = StringListTypeHandler.class)
|
||||
private List<String> websites;
|
||||
/**
|
||||
* 租户套餐编号
|
||||
*
|
||||
* 关联 {@link TenantPackageDO#getId()}
|
||||
* 特殊逻辑:系统内置租户,不使用套餐,暂时使用 {@link #PACKAGE_ID_SYSTEM} 标识
|
||||
*/
|
||||
private Long packageId;
|
||||
/**
|
||||
* 过期时间
|
||||
*/
|
||||
private LocalDateTime expireTime;
|
||||
/**
|
||||
* 账号数量
|
||||
*/
|
||||
private Integer accountCount;
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.dal.dataobject.tenant;
|
||||
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.msgpush.framework.tenant.core.aop.TenantIgnore;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 租户套餐 DO
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@TableName(value = "system_tenant_package", autoResultMap = true)
|
||||
@KeySequence("system_tenant_package_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@TenantIgnore
|
||||
public class TenantPackageDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 套餐编号,自增
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 套餐名,唯一
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 租户套餐状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 关联的菜单编号
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private Set<Long> menuIds;
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.njcn.msgpush.module.system.dal.dataobject.user;
|
||||
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.njcn.msgpush.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.njcn.msgpush.module.system.enums.common.SexEnum;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
@@ -26,7 +26,7 @@ import java.util.Set;
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class AdminUserDO extends TenantBaseDO {
|
||||
public class AdminUserDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.njcn.msgpush.module.system.dal.mysql.oauth2;
|
||||
import com.njcn.msgpush.framework.common.pojo.PageResult;
|
||||
import com.njcn.msgpush.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.njcn.msgpush.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.njcn.msgpush.framework.tenant.core.aop.TenantIgnore;
|
||||
|
||||
import com.njcn.msgpush.module.system.controller.admin.oauth2.vo.token.OAuth2AccessTokenPageReqVO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
@@ -14,7 +14,6 @@ import java.util.List;
|
||||
@Mapper
|
||||
public interface OAuth2AccessTokenMapper extends BaseMapperX<OAuth2AccessTokenDO> {
|
||||
|
||||
@TenantIgnore // 获取 token 的时候,需要忽略租户编号。原因是:一些场景下,可能不会传递 tenant-id 请求头,例如说文件上传、积木报表等等
|
||||
default OAuth2AccessTokenDO selectByAccessToken(String accessToken) {
|
||||
return selectOne(OAuth2AccessTokenDO::getAccessToken, accessToken);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.njcn.msgpush.module.system.dal.mysql.oauth2;
|
||||
|
||||
import com.njcn.msgpush.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.njcn.msgpush.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.njcn.msgpush.framework.tenant.core.aop.TenantIgnore;
|
||||
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.oauth2.OAuth2RefreshTokenDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@@ -14,7 +14,6 @@ public interface OAuth2RefreshTokenMapper extends BaseMapperX<OAuth2RefreshToken
|
||||
.eq(OAuth2RefreshTokenDO::getRefreshToken, refreshToken));
|
||||
}
|
||||
|
||||
@TenantIgnore // 获取 token 的时候,需要忽略租户编号。原因是:一些场景下,可能不会传递 tenant-id 请求头,例如说文件上传、积木报表等等
|
||||
default OAuth2RefreshTokenDO selectByRefreshToken(String refreshToken) {
|
||||
return selectOne(OAuth2RefreshTokenDO::getRefreshToken, refreshToken);
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.dal.mysql.tenant;
|
||||
|
||||
import com.njcn.msgpush.framework.common.pojo.PageResult;
|
||||
import com.njcn.msgpush.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.njcn.msgpush.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.njcn.msgpush.framework.mybatis.core.util.MyBatisUtils;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.tenant.TenantDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface TenantMapper extends BaseMapperX<TenantDO> {
|
||||
|
||||
default PageResult<TenantDO> selectPage(TenantPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<TenantDO>()
|
||||
.likeIfPresent(TenantDO::getName, reqVO.getName())
|
||||
.likeIfPresent(TenantDO::getContactName, reqVO.getContactName())
|
||||
.likeIfPresent(TenantDO::getContactMobile, reqVO.getContactMobile())
|
||||
.eqIfPresent(TenantDO::getStatus, reqVO.getStatus())
|
||||
.betweenIfPresent(TenantDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(TenantDO::getId));
|
||||
}
|
||||
|
||||
default TenantDO selectByName(String name) {
|
||||
return selectOne(TenantDO::getName, name);
|
||||
}
|
||||
|
||||
default List<TenantDO> selectListByWebsite(String website) {
|
||||
return selectList(new LambdaQueryWrapperX<TenantDO>()
|
||||
.apply(MyBatisUtils.findInSet("websites", website)));
|
||||
}
|
||||
|
||||
default Long selectCountByPackageId(Long packageId) {
|
||||
return selectCount(TenantDO::getPackageId, packageId);
|
||||
}
|
||||
|
||||
default List<TenantDO> selectListByPackageId(Long packageId) {
|
||||
return selectList(TenantDO::getPackageId, packageId);
|
||||
}
|
||||
|
||||
default List<TenantDO> selectListByStatus(Integer status) {
|
||||
return selectList(TenantDO::getStatus, status);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.dal.mysql.tenant;
|
||||
|
||||
import com.njcn.msgpush.framework.common.pojo.PageResult;
|
||||
import com.njcn.msgpush.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.njcn.msgpush.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.packages.TenantPackagePageReqVO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.tenant.TenantPackageDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface TenantPackageMapper extends BaseMapperX<TenantPackageDO> {
|
||||
|
||||
default PageResult<TenantPackageDO> selectPage(TenantPackagePageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<TenantPackageDO>()
|
||||
.likeIfPresent(TenantPackageDO::getName, reqVO.getName())
|
||||
.eqIfPresent(TenantPackageDO::getStatus, reqVO.getStatus())
|
||||
.likeIfPresent(TenantPackageDO::getRemark, reqVO.getRemark())
|
||||
.betweenIfPresent(TenantPackageDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(TenantPackageDO::getId));
|
||||
}
|
||||
|
||||
default List<TenantPackageDO> selectListByStatus(Integer status) {
|
||||
return selectList(TenantPackageDO::getStatus, status);
|
||||
}
|
||||
|
||||
default TenantPackageDO selectByName(String name) {
|
||||
return selectOne(TenantPackageDO::getName, name);
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,6 @@ import com.njcn.msgpush.framework.common.pojo.PageResult;
|
||||
import com.njcn.msgpush.framework.common.util.date.DateUtils;
|
||||
import com.njcn.msgpush.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.msgpush.framework.security.core.LoginUser;
|
||||
import com.njcn.msgpush.framework.tenant.core.context.TenantContextHolder;
|
||||
import com.njcn.msgpush.framework.tenant.core.util.TenantUtils;
|
||||
import com.njcn.msgpush.module.system.controller.admin.oauth2.vo.token.OAuth2AccessTokenPageReqVO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
|
||||
@@ -180,13 +178,6 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService {
|
||||
.setClientId(clientDO.getClientId()).setScopes(refreshTokenDO.getScopes())
|
||||
.setRefreshToken(refreshTokenDO.getRefreshToken())
|
||||
.setExpiresTime(LocalDateTime.now().plusSeconds(clientDO.getAccessTokenValiditySeconds()));
|
||||
// 优先从 refreshToken 获取租户编号,避免 ThreadLocal 被污染时导致 tenantId 为 null
|
||||
// 可能关联的 issue:https://t.zsxq.com/JIi5G
|
||||
Long tenantId = refreshTokenDO.getTenantId();
|
||||
if (tenantId == null) {
|
||||
tenantId = TenantContextHolder.getTenantId();
|
||||
}
|
||||
accessTokenDO.setTenantId(tenantId);
|
||||
oauth2AccessTokenMapper.insert(accessTokenDO);
|
||||
// 记录到 Redis 中
|
||||
oauth2AccessTokenRedisDAO.set(accessTokenDO);
|
||||
@@ -205,8 +196,7 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService {
|
||||
private OAuth2AccessTokenDO convertToAccessToken(OAuth2RefreshTokenDO refreshTokenDO) {
|
||||
OAuth2AccessTokenDO accessTokenDO = BeanUtils.toBean(refreshTokenDO, OAuth2AccessTokenDO.class)
|
||||
.setAccessToken(refreshTokenDO.getRefreshToken());
|
||||
TenantUtils.execute(refreshTokenDO.getTenantId(),
|
||||
() -> accessTokenDO.setUserInfo(buildUserInfo(refreshTokenDO.getUserId(), refreshTokenDO.getUserType())));
|
||||
accessTokenDO.setUserInfo(buildUserInfo(refreshTokenDO.getUserId(), refreshTokenDO.getUserType()));
|
||||
return accessTokenDO;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,14 +50,6 @@ public interface MenuService {
|
||||
*/
|
||||
List<MenuDO> getMenuList();
|
||||
|
||||
/**
|
||||
* 基于租户,筛选菜单列表
|
||||
* 注意,如果是系统租户,返回的还是全菜单
|
||||
*
|
||||
* @param reqVO 筛选条件请求 VO
|
||||
* @return 菜单列表
|
||||
*/
|
||||
List<MenuDO> getMenuListByTenant(MenuListReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 过滤掉关闭的菜单及其子菜单
|
||||
|
||||
@@ -11,7 +11,6 @@ import com.njcn.msgpush.module.system.dal.dataobject.permission.MenuDO;
|
||||
import com.njcn.msgpush.module.system.dal.mysql.permission.MenuMapper;
|
||||
import com.njcn.msgpush.module.system.dal.redis.RedisKeyConstants;
|
||||
import com.njcn.msgpush.module.system.enums.permission.MenuTypeEnum;
|
||||
import com.njcn.msgpush.module.system.service.tenant.TenantService;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.Lists;
|
||||
import jakarta.annotation.Resource;
|
||||
@@ -43,9 +42,6 @@ public class MenuServiceImpl implements MenuService {
|
||||
private MenuMapper menuMapper;
|
||||
@Resource
|
||||
private PermissionService permissionService;
|
||||
@Resource
|
||||
@Lazy // 延迟,避免循环依赖报错
|
||||
private TenantService tenantService;
|
||||
|
||||
@Override
|
||||
@CacheEvict(value = RedisKeyConstants.PERMISSION_MENU_ID_LIST, key = "#createReqVO.permission",
|
||||
@@ -127,15 +123,6 @@ public class MenuServiceImpl implements MenuService {
|
||||
return menuMapper.selectList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MenuDO> getMenuListByTenant(MenuListReqVO reqVO) {
|
||||
// 查询所有菜单,并过滤掉关闭的节点
|
||||
List<MenuDO> menus = getMenuList(reqVO);
|
||||
// 开启多租户的情况下,需要过滤掉未开通的菜单
|
||||
tenantService.handleTenantMenu(menuIds -> menus.removeIf(menu -> !CollUtil.contains(menuIds, menu.getId())));
|
||||
return menus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MenuDO> filterDisableMenus(List<MenuDO> menuList) {
|
||||
if (CollUtil.isEmpty(menuList)){
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.service.tenant;
|
||||
|
||||
import com.njcn.msgpush.framework.common.pojo.PageResult;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.packages.TenantPackagePageReqVO;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.packages.TenantPackageSaveReqVO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.tenant.TenantPackageDO;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 租户套餐 Service 接口
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
public interface TenantPackageService {
|
||||
|
||||
/**
|
||||
* 创建租户套餐
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createTenantPackage(@Valid TenantPackageSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新租户套餐
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateTenantPackage(@Valid TenantPackageSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除租户套餐
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteTenantPackage(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除租户套餐
|
||||
*
|
||||
* @param ids 编号数组
|
||||
*/
|
||||
void deleteTenantPackageList(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得租户套餐
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 租户套餐
|
||||
*/
|
||||
TenantPackageDO getTenantPackage(Long id);
|
||||
|
||||
/**
|
||||
* 获得租户套餐分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 租户套餐分页
|
||||
*/
|
||||
PageResult<TenantPackageDO> getTenantPackagePage(TenantPackagePageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 校验租户套餐
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 租户套餐
|
||||
*/
|
||||
TenantPackageDO validTenantPackage(Long id);
|
||||
|
||||
/**
|
||||
* 获得指定状态的租户套餐列表
|
||||
*
|
||||
* @param status 状态
|
||||
* @return 租户套餐
|
||||
*/
|
||||
List<TenantPackageDO> getTenantPackageListByStatus(Integer status);
|
||||
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.service.tenant;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.common.pojo.PageResult;
|
||||
import com.njcn.msgpush.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.packages.TenantPackagePageReqVO;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.packages.TenantPackageSaveReqVO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.tenant.TenantDO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.tenant.TenantPackageDO;
|
||||
import com.njcn.msgpush.module.system.dal.mysql.tenant.TenantPackageMapper;
|
||||
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.njcn.msgpush.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.njcn.msgpush.module.system.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* 租户套餐 Service 实现类
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class TenantPackageServiceImpl implements TenantPackageService {
|
||||
|
||||
@Resource
|
||||
private TenantPackageMapper tenantPackageMapper;
|
||||
|
||||
@Resource
|
||||
@Lazy // 避免循环依赖的报错
|
||||
private TenantService tenantService;
|
||||
|
||||
@Override
|
||||
public Long createTenantPackage(TenantPackageSaveReqVO createReqVO) {
|
||||
// 校验套餐名是否重复
|
||||
validateTenantPackageNameUnique(null, createReqVO.getName());
|
||||
// 插入
|
||||
TenantPackageDO tenantPackage = BeanUtils.toBean(createReqVO, TenantPackageDO.class);
|
||||
tenantPackageMapper.insert(tenantPackage);
|
||||
// 返回
|
||||
return tenantPackage.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@DSTransactional // 多数据源,使用 @DSTransactional 保证本地事务,以及数据源的切换
|
||||
public void updateTenantPackage(TenantPackageSaveReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
TenantPackageDO tenantPackage = validateTenantPackageExists(updateReqVO.getId());
|
||||
// 校验套餐名是否重复
|
||||
validateTenantPackageNameUnique(updateReqVO.getId(), updateReqVO.getName());
|
||||
// 更新
|
||||
TenantPackageDO updateObj = BeanUtils.toBean(updateReqVO, TenantPackageDO.class);
|
||||
tenantPackageMapper.updateById(updateObj);
|
||||
// 如果菜单发生变化,则修改每个租户的菜单
|
||||
if (!CollUtil.isEqualList(tenantPackage.getMenuIds(), updateReqVO.getMenuIds())) {
|
||||
List<TenantDO> tenants = tenantService.getTenantListByPackageId(tenantPackage.getId());
|
||||
tenants.forEach(tenant -> tenantService.updateTenantRoleMenu(tenant.getId(), updateReqVO.getMenuIds()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteTenantPackage(Long id) {
|
||||
// 校验存在
|
||||
validateTenantPackageExists(id);
|
||||
// 校验正在使用
|
||||
validateTenantUsed(id);
|
||||
// 删除
|
||||
tenantPackageMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteTenantPackageList(List<Long> ids) {
|
||||
// 1. 校验是否有租户正在使用该套餐
|
||||
for (Long id : ids) {
|
||||
if (tenantService.getTenantCountByPackageId(id) > 0) {
|
||||
throw exception(TENANT_PACKAGE_USED);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 批量删除
|
||||
tenantPackageMapper.deleteByIds(ids);
|
||||
}
|
||||
|
||||
private TenantPackageDO validateTenantPackageExists(Long id) {
|
||||
TenantPackageDO tenantPackage = tenantPackageMapper.selectById(id);
|
||||
if (tenantPackage == null) {
|
||||
throw exception(TENANT_PACKAGE_NOT_EXISTS);
|
||||
}
|
||||
return tenantPackage;
|
||||
}
|
||||
|
||||
private void validateTenantUsed(Long id) {
|
||||
if (tenantService.getTenantCountByPackageId(id) > 0) {
|
||||
throw exception(TENANT_PACKAGE_USED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TenantPackageDO getTenantPackage(Long id) {
|
||||
return tenantPackageMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<TenantPackageDO> getTenantPackagePage(TenantPackagePageReqVO pageReqVO) {
|
||||
return tenantPackageMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TenantPackageDO validTenantPackage(Long id) {
|
||||
TenantPackageDO tenantPackage = tenantPackageMapper.selectById(id);
|
||||
if (tenantPackage == null) {
|
||||
throw exception(TENANT_PACKAGE_NOT_EXISTS);
|
||||
}
|
||||
if (tenantPackage.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) {
|
||||
throw exception(TENANT_PACKAGE_DISABLE, tenantPackage.getName());
|
||||
}
|
||||
return tenantPackage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TenantPackageDO> getTenantPackageListByStatus(Integer status) {
|
||||
return tenantPackageMapper.selectListByStatus(status);
|
||||
}
|
||||
|
||||
|
||||
@VisibleForTesting
|
||||
void validateTenantPackageNameUnique(Long id, String name) {
|
||||
if (StrUtil.isBlank(name)) {
|
||||
return;
|
||||
}
|
||||
TenantPackageDO tenantPackage = tenantPackageMapper.selectByName(name);
|
||||
if (tenantPackage == null) {
|
||||
return;
|
||||
}
|
||||
// 如果 id 为空,说明不用比较是否为相同 id 的用户
|
||||
if (id == null) {
|
||||
throw exception(TENANT_PACKAGE_NAME_DUPLICATE);
|
||||
}
|
||||
if (!tenantPackage.getId().equals(id)) {
|
||||
throw exception(TENANT_PACKAGE_NAME_DUPLICATE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.service.tenant;
|
||||
|
||||
import com.njcn.msgpush.framework.common.pojo.PageResult;
|
||||
import com.njcn.msgpush.framework.tenant.core.context.TenantContextHolder;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.tenant.TenantSaveReqVO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.tenant.TenantDO;
|
||||
import com.njcn.msgpush.module.system.service.tenant.handler.TenantInfoHandler;
|
||||
import com.njcn.msgpush.module.system.service.tenant.handler.TenantMenuHandler;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 租户 Service 接口
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
public interface TenantService {
|
||||
|
||||
/**
|
||||
* 创建租户
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createTenant(@Valid TenantSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新租户
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateTenant(@Valid TenantSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 更新租户的角色菜单
|
||||
*
|
||||
* @param tenantId 租户编号
|
||||
* @param menuIds 菜单编号数组
|
||||
*/
|
||||
void updateTenantRoleMenu(Long tenantId, Set<Long> menuIds);
|
||||
|
||||
/**
|
||||
* 删除租户
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteTenant(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除租户
|
||||
*
|
||||
* @param ids 编号数组
|
||||
*/
|
||||
void deleteTenantList(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得租户
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 租户
|
||||
*/
|
||||
TenantDO getTenant(Long id);
|
||||
|
||||
/**
|
||||
* 获得租户分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 租户分页
|
||||
*/
|
||||
PageResult<TenantDO> getTenantPage(TenantPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 获得名字对应的租户
|
||||
*
|
||||
* @param name 租户名
|
||||
* @return 租户
|
||||
*/
|
||||
TenantDO getTenantByName(String name);
|
||||
|
||||
/**
|
||||
* 获得域名对应的租户
|
||||
*
|
||||
* @param website 域名
|
||||
* @return 租户
|
||||
*/
|
||||
TenantDO getTenantByWebsite(String website);
|
||||
|
||||
/**
|
||||
* 获得使用指定套餐的租户数量
|
||||
*
|
||||
* @param packageId 租户套餐编号
|
||||
* @return 租户数量
|
||||
*/
|
||||
Long getTenantCountByPackageId(Long packageId);
|
||||
|
||||
/**
|
||||
* 获得使用指定套餐的租户数组
|
||||
*
|
||||
* @param packageId 租户套餐编号
|
||||
* @return 租户数组
|
||||
*/
|
||||
List<TenantDO> getTenantListByPackageId(Long packageId);
|
||||
|
||||
/**
|
||||
* 获得指定状态的租户列表
|
||||
*
|
||||
* @param status 状态
|
||||
* @return 租户列表
|
||||
*/
|
||||
List<TenantDO> getTenantListByStatus(Integer status);
|
||||
|
||||
/**
|
||||
* 进行租户的信息处理逻辑
|
||||
* 其中,租户编号从 {@link TenantContextHolder} 上下文中获取
|
||||
*
|
||||
* @param handler 处理器
|
||||
*/
|
||||
void handleTenantInfo(TenantInfoHandler handler);
|
||||
|
||||
/**
|
||||
* 进行租户的菜单处理逻辑
|
||||
* 其中,租户编号从 {@link TenantContextHolder} 上下文中获取
|
||||
*
|
||||
* @param handler 处理器
|
||||
*/
|
||||
void handleTenantMenu(TenantMenuHandler handler);
|
||||
|
||||
/**
|
||||
* 获得所有租户
|
||||
*
|
||||
* @return 租户编号数组
|
||||
*/
|
||||
List<Long> getTenantIdList();
|
||||
|
||||
/**
|
||||
* 校验租户是否合法
|
||||
*
|
||||
* @param id 租户编号
|
||||
*/
|
||||
void validTenant(Long id);
|
||||
|
||||
}
|
||||
@@ -1,318 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.service.tenant;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.common.pojo.PageResult;
|
||||
import com.njcn.msgpush.framework.common.util.collection.CollectionUtils;
|
||||
import com.njcn.msgpush.framework.common.util.date.DateUtils;
|
||||
import com.njcn.msgpush.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.msgpush.framework.tenant.config.TenantProperties;
|
||||
import com.njcn.msgpush.framework.tenant.core.context.TenantContextHolder;
|
||||
import com.njcn.msgpush.framework.tenant.core.util.TenantUtils;
|
||||
import com.njcn.msgpush.module.system.controller.admin.permission.vo.role.RoleSaveReqVO;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.tenant.TenantSaveReqVO;
|
||||
import com.njcn.msgpush.module.system.convert.tenant.TenantConvert;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.permission.MenuDO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.permission.RoleDO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.tenant.TenantDO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.tenant.TenantPackageDO;
|
||||
import com.njcn.msgpush.module.system.dal.mysql.tenant.TenantMapper;
|
||||
import com.njcn.msgpush.module.system.enums.permission.RoleCodeEnum;
|
||||
import com.njcn.msgpush.module.system.enums.permission.RoleTypeEnum;
|
||||
import com.njcn.msgpush.module.system.service.permission.MenuService;
|
||||
import com.njcn.msgpush.module.system.service.permission.PermissionService;
|
||||
import com.njcn.msgpush.module.system.service.permission.RoleService;
|
||||
import com.njcn.msgpush.module.system.service.tenant.handler.TenantInfoHandler;
|
||||
import com.njcn.msgpush.module.system.service.tenant.handler.TenantMenuHandler;
|
||||
import com.njcn.msgpush.module.system.service.user.AdminUserService;
|
||||
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.njcn.msgpush.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.njcn.msgpush.module.system.enums.ErrorCodeConstants.*;
|
||||
import static java.util.Collections.singleton;
|
||||
|
||||
/**
|
||||
* 租户 Service 实现类
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class TenantServiceImpl implements TenantService {
|
||||
|
||||
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
|
||||
@Autowired(required = false) // 由于 msgpush.tenant.enable 配置项,可以关闭多租户的功能,所以这里只能不强制注入
|
||||
private TenantProperties tenantProperties;
|
||||
|
||||
@Resource
|
||||
private TenantMapper tenantMapper;
|
||||
|
||||
@Resource
|
||||
private TenantPackageService tenantPackageService;
|
||||
@Resource
|
||||
@Lazy // 延迟,避免循环依赖报错
|
||||
private AdminUserService userService;
|
||||
@Resource
|
||||
private RoleService roleService;
|
||||
@Resource
|
||||
private MenuService menuService;
|
||||
@Resource
|
||||
private PermissionService permissionService;
|
||||
|
||||
@Override
|
||||
public List<Long> getTenantIdList() {
|
||||
List<TenantDO> tenants = tenantMapper.selectList();
|
||||
return CollectionUtils.convertList(tenants, TenantDO::getId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validTenant(Long id) {
|
||||
TenantDO tenant = getTenant(id);
|
||||
if (tenant == null) {
|
||||
throw exception(TENANT_NOT_EXISTS);
|
||||
}
|
||||
if (tenant.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) {
|
||||
throw exception(TENANT_DISABLE, tenant.getName());
|
||||
}
|
||||
if (DateUtils.isExpired(tenant.getExpireTime())) {
|
||||
throw exception(TENANT_EXPIRE, tenant.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@DSTransactional // 多数据源,使用 @DSTransactional 保证本地事务,以及数据源的切换
|
||||
public Long createTenant(TenantSaveReqVO createReqVO) {
|
||||
// 校验租户名称是否重复
|
||||
validTenantNameDuplicate(createReqVO.getName(), null);
|
||||
// 校验租户域名是否重复
|
||||
validTenantWebsiteDuplicate(createReqVO.getWebsites(), null);
|
||||
// 校验套餐被禁用
|
||||
TenantPackageDO tenantPackage = tenantPackageService.validTenantPackage(createReqVO.getPackageId());
|
||||
|
||||
// 创建租户
|
||||
TenantDO tenant = BeanUtils.toBean(createReqVO, TenantDO.class);
|
||||
tenantMapper.insert(tenant);
|
||||
// 创建租户的管理员
|
||||
TenantUtils.execute(tenant.getId(), () -> {
|
||||
// 创建角色
|
||||
Long roleId = createRole(tenantPackage);
|
||||
// 创建用户,并分配角色
|
||||
Long userId = createUser(roleId, createReqVO);
|
||||
// 修改租户的管理员
|
||||
tenantMapper.updateById(new TenantDO().setId(tenant.getId()).setContactUserId(userId));
|
||||
});
|
||||
return tenant.getId();
|
||||
}
|
||||
|
||||
private Long createUser(Long roleId, TenantSaveReqVO createReqVO) {
|
||||
// 创建用户
|
||||
Long userId = userService.createUser(TenantConvert.INSTANCE.convert02(createReqVO));
|
||||
// 分配角色
|
||||
permissionService.assignUserRole(userId, singleton(roleId));
|
||||
return userId;
|
||||
}
|
||||
|
||||
private Long createRole(TenantPackageDO tenantPackage) {
|
||||
// 创建角色
|
||||
RoleSaveReqVO reqVO = new RoleSaveReqVO();
|
||||
reqVO.setName(RoleCodeEnum.TENANT_ADMIN.getName()).setCode(RoleCodeEnum.TENANT_ADMIN.getCode())
|
||||
.setSort(0).setRemark("系统自动生成");
|
||||
Long roleId = roleService.createRole(reqVO, RoleTypeEnum.SYSTEM.getType());
|
||||
// 分配权限
|
||||
permissionService.assignRoleMenu(roleId, tenantPackage.getMenuIds());
|
||||
return roleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DSTransactional // 多数据源,使用 @DSTransactional 保证本地事务,以及数据源的切换
|
||||
public void updateTenant(TenantSaveReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
TenantDO tenant = validateUpdateTenant(updateReqVO.getId());
|
||||
// 校验租户名称是否重复
|
||||
validTenantNameDuplicate(updateReqVO.getName(), updateReqVO.getId());
|
||||
// 校验租户域名是否重复
|
||||
validTenantWebsiteDuplicate(updateReqVO.getWebsites(), updateReqVO.getId());
|
||||
// 校验套餐被禁用
|
||||
TenantPackageDO tenantPackage = tenantPackageService.validTenantPackage(updateReqVO.getPackageId());
|
||||
|
||||
// 更新租户
|
||||
TenantDO updateObj = BeanUtils.toBean(updateReqVO, TenantDO.class);
|
||||
tenantMapper.updateById(updateObj);
|
||||
// 如果套餐发生变化,则修改其角色的权限
|
||||
if (ObjectUtil.notEqual(tenant.getPackageId(), updateReqVO.getPackageId())) {
|
||||
updateTenantRoleMenu(tenant.getId(), tenantPackage.getMenuIds());
|
||||
}
|
||||
}
|
||||
|
||||
private void validTenantNameDuplicate(String name, Long id) {
|
||||
TenantDO tenant = tenantMapper.selectByName(name);
|
||||
if (tenant == null) {
|
||||
return;
|
||||
}
|
||||
// 如果 id 为空,说明不用比较是否为相同名字的租户
|
||||
if (id == null) {
|
||||
throw exception(TENANT_NAME_DUPLICATE, name);
|
||||
}
|
||||
if (!tenant.getId().equals(id)) {
|
||||
throw exception(TENANT_NAME_DUPLICATE, name);
|
||||
}
|
||||
}
|
||||
|
||||
private void validTenantWebsiteDuplicate(List<String> websites, Long excludeId) {
|
||||
if (CollUtil.isEmpty(websites)) {
|
||||
return;
|
||||
}
|
||||
websites.forEach(website -> {
|
||||
List<TenantDO> tenants = tenantMapper.selectListByWebsite(website);
|
||||
if (excludeId != null) {
|
||||
tenants.removeIf(tenant -> tenant.getId().equals(excludeId));
|
||||
}
|
||||
if (CollUtil.isNotEmpty(tenants)) {
|
||||
throw exception(TENANT_WEBSITE_DUPLICATE, website);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@DSTransactional
|
||||
public void updateTenantRoleMenu(Long tenantId, Set<Long> menuIds) {
|
||||
TenantUtils.execute(tenantId, () -> {
|
||||
// 获得所有角色
|
||||
List<RoleDO> roles = roleService.getRoleList();
|
||||
roles.forEach(role -> Assert.isTrue(tenantId.equals(role.getTenantId()), "角色({}/{}) 租户不匹配",
|
||||
role.getId(), role.getTenantId(), tenantId)); // 兜底校验
|
||||
// 重新分配每个角色的权限
|
||||
roles.forEach(role -> {
|
||||
// 如果是租户管理员,重新分配其权限为租户套餐的权限
|
||||
if (Objects.equals(role.getCode(), RoleCodeEnum.TENANT_ADMIN.getCode())) {
|
||||
permissionService.assignRoleMenu(role.getId(), menuIds);
|
||||
log.info("[updateTenantRoleMenu][租户管理员({}/{}) 的权限修改为({})]", role.getId(), role.getTenantId(), menuIds);
|
||||
return;
|
||||
}
|
||||
// 如果是其他角色,则去掉超过套餐的权限
|
||||
Set<Long> roleMenuIds = permissionService.getRoleMenuListByRoleId(role.getId());
|
||||
roleMenuIds = CollUtil.intersectionDistinct(roleMenuIds, menuIds);
|
||||
permissionService.assignRoleMenu(role.getId(), roleMenuIds);
|
||||
log.info("[updateTenantRoleMenu][角色({}/{}) 的权限修改为({})]", role.getId(), role.getTenantId(), roleMenuIds);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteTenant(Long id) {
|
||||
// 校验存在
|
||||
validateUpdateTenant(id);
|
||||
// 删除
|
||||
tenantMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteTenantList(List<Long> ids) {
|
||||
// 1. 校验存在
|
||||
ids.forEach(this::validateUpdateTenant);
|
||||
|
||||
// 2. 批量删除
|
||||
tenantMapper.deleteByIds(ids);
|
||||
}
|
||||
|
||||
private TenantDO validateUpdateTenant(Long id) {
|
||||
TenantDO tenant = tenantMapper.selectById(id);
|
||||
if (tenant == null) {
|
||||
throw exception(TENANT_NOT_EXISTS);
|
||||
}
|
||||
// 内置租户,不允许删除
|
||||
if (isSystemTenant(tenant)) {
|
||||
throw exception(TENANT_CAN_NOT_UPDATE_SYSTEM);
|
||||
}
|
||||
return tenant;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TenantDO getTenant(Long id) {
|
||||
return tenantMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<TenantDO> getTenantPage(TenantPageReqVO pageReqVO) {
|
||||
return tenantMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TenantDO getTenantByName(String name) {
|
||||
return tenantMapper.selectByName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TenantDO getTenantByWebsite(String website) {
|
||||
List<TenantDO> tenants = tenantMapper.selectListByWebsite(website);
|
||||
return CollUtil.getFirst(tenants);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getTenantCountByPackageId(Long packageId) {
|
||||
return tenantMapper.selectCountByPackageId(packageId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TenantDO> getTenantListByPackageId(Long packageId) {
|
||||
return tenantMapper.selectListByPackageId(packageId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TenantDO> getTenantListByStatus(Integer status) {
|
||||
return tenantMapper.selectListByStatus(status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTenantInfo(TenantInfoHandler handler) {
|
||||
// 如果禁用,则不执行逻辑
|
||||
if (isTenantDisable()) {
|
||||
return;
|
||||
}
|
||||
// 获得租户
|
||||
TenantDO tenant = getTenant(TenantContextHolder.getRequiredTenantId());
|
||||
// 执行处理器
|
||||
handler.handle(tenant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTenantMenu(TenantMenuHandler handler) {
|
||||
// 如果禁用,则不执行逻辑
|
||||
if (isTenantDisable()) {
|
||||
return;
|
||||
}
|
||||
// 获得租户,然后获得菜单
|
||||
TenantDO tenant = getTenant(TenantContextHolder.getRequiredTenantId());
|
||||
Set<Long> menuIds;
|
||||
if (isSystemTenant(tenant)) { // 系统租户,菜单是全量的
|
||||
menuIds = CollectionUtils.convertSet(menuService.getMenuList(), MenuDO::getId);
|
||||
} else {
|
||||
menuIds = tenantPackageService.getTenantPackage(tenant.getPackageId()).getMenuIds();
|
||||
}
|
||||
// 执行处理器
|
||||
handler.handle(menuIds);
|
||||
}
|
||||
|
||||
private static boolean isSystemTenant(TenantDO tenant) {
|
||||
return Objects.equals(tenant.getPackageId(), TenantDO.PACKAGE_ID_SYSTEM);
|
||||
}
|
||||
|
||||
private boolean isTenantDisable() {
|
||||
return tenantProperties == null || Boolean.FALSE.equals(tenantProperties.getEnable());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.service.tenant.handler;
|
||||
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.tenant.TenantDO;
|
||||
|
||||
/**
|
||||
* 租户信息处理
|
||||
* 目的:尽量减少租户逻辑耦合到系统中
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
public interface TenantInfoHandler {
|
||||
|
||||
/**
|
||||
* 基于传入的租户信息,进行相关逻辑的执行
|
||||
* 例如说,创建用户时,超过最大账户配额
|
||||
*
|
||||
* @param tenant 租户信息
|
||||
*/
|
||||
void handle(TenantDO tenant);
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.service.tenant.handler;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 租户菜单处理
|
||||
* 目的:尽量减少租户逻辑耦合到系统中
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
public interface TenantMenuHandler {
|
||||
|
||||
/**
|
||||
* 基于传入的租户菜单【全】列表,进行相关逻辑的执行
|
||||
* 例如说,返回可分配菜单的时候,可以移除多余的
|
||||
*
|
||||
* @param menuIds 菜单列表
|
||||
*/
|
||||
void handle(Set<Long> menuIds);
|
||||
|
||||
}
|
||||
@@ -28,7 +28,6 @@ import com.njcn.msgpush.module.system.service.dept.DeptService;
|
||||
import com.njcn.msgpush.module.system.service.dept.PostService;
|
||||
import com.njcn.msgpush.module.system.service.oauth2.OAuth2TokenService;
|
||||
import com.njcn.msgpush.module.system.service.permission.PermissionService;
|
||||
import com.njcn.msgpush.module.system.service.tenant.TenantService;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.mzt.logapi.context.LogRecordContext;
|
||||
import com.mzt.logapi.service.impl.DiffParseFunction;
|
||||
@@ -74,9 +73,6 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||
@Resource
|
||||
private PasswordEncoder passwordEncoder;
|
||||
@Resource
|
||||
@Lazy // 延迟,避免循环依赖报错
|
||||
private TenantService tenantService;
|
||||
@Resource
|
||||
@Lazy // 懒加载,避免循环依赖
|
||||
private OAuth2TokenService oauth2TokenService;
|
||||
|
||||
@@ -91,14 +87,7 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||
@LogRecord(type = SYSTEM_USER_TYPE, subType = SYSTEM_USER_CREATE_SUB_TYPE, bizNo = "{{#user.id}}",
|
||||
success = SYSTEM_USER_CREATE_SUCCESS)
|
||||
public Long createUser(UserSaveReqVO createReqVO) {
|
||||
// 1.1 校验账户配合
|
||||
tenantService.handleTenantInfo(tenant -> {
|
||||
long count = userMapper.selectCount();
|
||||
if (count >= tenant.getAccountCount()) {
|
||||
throw exception(USER_COUNT_MAX, tenant.getAccountCount());
|
||||
}
|
||||
});
|
||||
// 1.2 校验正确性
|
||||
// 1.1 校验正确性
|
||||
validateUserForCreateOrUpdate(null, createReqVO.getUsername(),
|
||||
createReqVO.getMobile(), createReqVO.getEmail(), createReqVO.getDeptId(), createReqVO.getPostIds());
|
||||
// 2.1 插入用户
|
||||
@@ -123,14 +112,7 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||
if (ObjUtil.notEqual(configApi.getConfigValueByKey(USER_REGISTER_ENABLED_KEY).getCheckedData(), "true")) {
|
||||
throw exception(USER_REGISTER_DISABLED);
|
||||
}
|
||||
// 1.2 校验账户配合
|
||||
tenantService.handleTenantInfo(tenant -> {
|
||||
long count = userMapper.selectCount();
|
||||
if (count >= tenant.getAccountCount()) {
|
||||
throw exception(USER_COUNT_MAX, tenant.getAccountCount());
|
||||
}
|
||||
});
|
||||
// 1.3 校验正确性
|
||||
// 1.2 校验正确性
|
||||
validateUserForCreateOrUpdate(null, registerReqVO.getUsername(), null, null, null, null);
|
||||
|
||||
// 2. 插入用户
|
||||
|
||||
@@ -126,20 +126,6 @@ msgpush:
|
||||
title: 管理后台
|
||||
description: 提供管理员管理的所有功能
|
||||
version: ${msgpush.info.version}
|
||||
tenant:
|
||||
enable: true
|
||||
ignore-urls:
|
||||
ignore-visit-urls:
|
||||
- /admin-api/system/user/profile/**
|
||||
- /admin-api/system/auth/**
|
||||
ignore-tables:
|
||||
ignore-caches:
|
||||
- user_role_ids
|
||||
- permission_menu_ids
|
||||
- oauth_client
|
||||
- notify_template
|
||||
- mail_account
|
||||
- mail_template
|
||||
- sms_template
|
||||
|
||||
|
||||
debug: false
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.njcn.msgpush.framework.common.enums.UserTypeEnum;
|
||||
import com.njcn.msgpush.framework.common.exception.ErrorCode;
|
||||
import com.njcn.msgpush.framework.common.pojo.PageResult;
|
||||
import com.njcn.msgpush.framework.common.util.date.DateUtils;
|
||||
import com.njcn.msgpush.framework.tenant.core.context.TenantContextHolder;
|
||||
import com.njcn.msgpush.framework.test.core.ut.BaseDbAndRedisUnitTest;
|
||||
import com.njcn.msgpush.module.system.controller.admin.oauth2.vo.token.OAuth2AccessTokenPageReqVO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||
@@ -59,7 +58,6 @@ public class OAuth2TokenServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
@Test
|
||||
public void testCreateAccessToken() {
|
||||
TenantContextHolder.setTenantId(0L);
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = UserTypeEnum.ADMIN.getValue();
|
||||
@@ -149,7 +147,6 @@ public class OAuth2TokenServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshAccessToken_success() {
|
||||
TenantContextHolder.setTenantId(0L);
|
||||
// 准备参数
|
||||
String refreshToken = randomString();
|
||||
String clientId = randomString();
|
||||
@@ -161,8 +158,7 @@ public class OAuth2TokenServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class, o ->
|
||||
o.setRefreshToken(refreshToken).setClientId(clientId)
|
||||
.setExpiresTime(LocalDateTime.now().plusDays(1))
|
||||
.setUserType(UserTypeEnum.ADMIN.getValue())
|
||||
.setTenantId(TenantContextHolder.getTenantId()));
|
||||
.setUserType(UserTypeEnum.ADMIN.getValue()));
|
||||
oauth2RefreshTokenMapper.insert(refreshTokenDO);
|
||||
// mock 数据(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class).setRefreshToken(refreshToken)
|
||||
|
||||
@@ -7,7 +7,6 @@ import com.njcn.msgpush.module.system.controller.admin.permission.vo.menu.MenuSa
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.permission.MenuDO;
|
||||
import com.njcn.msgpush.module.system.dal.mysql.permission.MenuMapper;
|
||||
import com.njcn.msgpush.module.system.enums.permission.MenuTypeEnum;
|
||||
import com.njcn.msgpush.module.system.service.tenant.TenantService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
@@ -42,8 +41,6 @@ public class MenuServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@MockitoBean
|
||||
private PermissionService permissionService;
|
||||
@MockitoBean
|
||||
private TenantService tenantService;
|
||||
|
||||
@Test
|
||||
public void testCreateMenu_success() {
|
||||
@@ -162,30 +159,6 @@ public class MenuServiceImplTest extends BaseDbUnitTest {
|
||||
assertPojoEquals(menuDO, result.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMenuListByTenant() {
|
||||
// mock 数据
|
||||
MenuDO menu100 = randomPojo(MenuDO.class, o -> o.setId(100L).setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
menuMapper.insert(menu100);
|
||||
MenuDO menu101 = randomPojo(MenuDO.class, o -> o.setId(101L).setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
||||
menuMapper.insert(menu101);
|
||||
MenuDO menu102 = randomPojo(MenuDO.class, o -> o.setId(102L).setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
menuMapper.insert(menu102);
|
||||
// mock 过滤菜单
|
||||
Set<Long> menuIds = asSet(100L, 101L);
|
||||
doNothing().when(tenantService).handleTenantMenu(argThat(handler -> {
|
||||
handler.handle(menuIds);
|
||||
return true;
|
||||
}));
|
||||
// 准备参数
|
||||
MenuListReqVO reqVO = new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
|
||||
// 调用
|
||||
List<MenuDO> result = menuService.getMenuListByTenant(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, result.size());
|
||||
assertPojoEquals(menu100, result.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMenuIdListByPermissionFromCache() {
|
||||
|
||||
@@ -320,23 +320,6 @@ public class RoleServiceImplTest extends BaseDbUnitTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasAnySuperAdmin_false() {
|
||||
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
|
||||
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(RoleServiceImpl.class)))
|
||||
.thenReturn(roleService);
|
||||
|
||||
// mock 数据
|
||||
RoleDO dbRole = randomPojo(RoleDO.class).setCode("tenant_admin");
|
||||
roleMapper.insert(dbRole);
|
||||
// 准备参数
|
||||
Long id = dbRole.getId();
|
||||
|
||||
// 调用,并调用
|
||||
assertFalse(roleService.hasAnySuperAdmin(singletonList(id)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateRoleList_success() {
|
||||
// mock 数据
|
||||
|
||||
@@ -1,237 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.service.tenant;
|
||||
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.common.pojo.PageResult;
|
||||
import com.njcn.msgpush.framework.test.core.ut.BaseDbUnitTest;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.packages.TenantPackagePageReqVO;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.packages.TenantPackageSaveReqVO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.tenant.TenantDO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.tenant.TenantPackageDO;
|
||||
import com.njcn.msgpush.module.system.dal.mysql.tenant.TenantPackageMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.njcn.msgpush.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static com.njcn.msgpush.framework.common.util.date.LocalDateTimeUtils.buildTime;
|
||||
import static com.njcn.msgpush.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static com.njcn.msgpush.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static com.njcn.msgpush.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static com.njcn.msgpush.framework.test.core.util.RandomUtils.*;
|
||||
import static com.njcn.msgpush.module.system.enums.ErrorCodeConstants.*;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link TenantPackageServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@Import(TenantPackageServiceImpl.class)
|
||||
public class TenantPackageServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private TenantPackageServiceImpl tenantPackageService;
|
||||
|
||||
@Resource
|
||||
private TenantPackageMapper tenantPackageMapper;
|
||||
|
||||
@MockitoBean
|
||||
private TenantService tenantService;
|
||||
|
||||
@Test
|
||||
public void testCreateTenantPackage_success() {
|
||||
// 准备参数
|
||||
TenantPackageSaveReqVO reqVO = randomPojo(TenantPackageSaveReqVO.class,
|
||||
o -> o.setStatus(randomCommonStatus()))
|
||||
.setId(null); // 防止 id 被赋值
|
||||
|
||||
// 调用
|
||||
Long tenantPackageId = tenantPackageService.createTenantPackage(reqVO);
|
||||
// 断言
|
||||
assertNotNull(tenantPackageId);
|
||||
// 校验记录的属性是否正确
|
||||
TenantPackageDO tenantPackage = tenantPackageMapper.selectById(tenantPackageId);
|
||||
assertPojoEquals(reqVO, tenantPackage, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateTenantPackage_success() {
|
||||
// mock 数据
|
||||
TenantPackageDO dbTenantPackage = randomPojo(TenantPackageDO.class,
|
||||
o -> o.setStatus(randomCommonStatus()));
|
||||
tenantPackageMapper.insert(dbTenantPackage);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
TenantPackageSaveReqVO reqVO = randomPojo(TenantPackageSaveReqVO.class, o -> {
|
||||
o.setId(dbTenantPackage.getId()); // 设置更新的 ID
|
||||
o.setStatus(randomCommonStatus());
|
||||
});
|
||||
// mock 方法
|
||||
Long tenantId01 = randomLongId();
|
||||
Long tenantId02 = randomLongId();
|
||||
when(tenantService.getTenantListByPackageId(eq(reqVO.getId()))).thenReturn(
|
||||
asList(randomPojo(TenantDO.class, o -> o.setId(tenantId01)),
|
||||
randomPojo(TenantDO.class, o -> o.setId(tenantId02))));
|
||||
|
||||
// 调用
|
||||
tenantPackageService.updateTenantPackage(reqVO);
|
||||
// 校验是否更新正确
|
||||
TenantPackageDO tenantPackage = tenantPackageMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, tenantPackage);
|
||||
// 校验调用租户的菜单
|
||||
verify(tenantService).updateTenantRoleMenu(eq(tenantId01), eq(reqVO.getMenuIds()));
|
||||
verify(tenantService).updateTenantRoleMenu(eq(tenantId02), eq(reqVO.getMenuIds()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateTenantPackage_notExists() {
|
||||
// 准备参数
|
||||
TenantPackageSaveReqVO reqVO = randomPojo(TenantPackageSaveReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> tenantPackageService.updateTenantPackage(reqVO), TENANT_PACKAGE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteTenantPackage_success() {
|
||||
// mock 数据
|
||||
TenantPackageDO dbTenantPackage = randomPojo(TenantPackageDO.class);
|
||||
tenantPackageMapper.insert(dbTenantPackage);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbTenantPackage.getId();
|
||||
// mock 租户未使用该套餐
|
||||
when(tenantService.getTenantCountByPackageId(eq(id))).thenReturn(0L);
|
||||
|
||||
// 调用
|
||||
tenantPackageService.deleteTenantPackage(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(tenantPackageMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteTenantPackage_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> tenantPackageService.deleteTenantPackage(id), TENANT_PACKAGE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteTenantPackage_used() {
|
||||
// mock 数据
|
||||
TenantPackageDO dbTenantPackage = randomPojo(TenantPackageDO.class);
|
||||
tenantPackageMapper.insert(dbTenantPackage);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbTenantPackage.getId();
|
||||
// mock 租户在使用该套餐
|
||||
when(tenantService.getTenantCountByPackageId(eq(id))).thenReturn(1L);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> tenantPackageService.deleteTenantPackage(id), TENANT_PACKAGE_USED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantPackagePage() {
|
||||
// mock 数据
|
||||
TenantPackageDO dbTenantPackage = randomPojo(TenantPackageDO.class, o -> { // 等会查询到
|
||||
o.setName("灿能源码");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setRemark("源码解析");
|
||||
o.setCreateTime(buildTime(2022, 10, 10));
|
||||
});
|
||||
tenantPackageMapper.insert(dbTenantPackage);
|
||||
// 测试 name 不匹配
|
||||
tenantPackageMapper.insert(cloneIgnoreId(dbTenantPackage, o -> o.setName("源码")));
|
||||
// 测试 status 不匹配
|
||||
tenantPackageMapper.insert(cloneIgnoreId(dbTenantPackage, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 测试 remark 不匹配
|
||||
tenantPackageMapper.insert(cloneIgnoreId(dbTenantPackage, o -> o.setRemark("解析")));
|
||||
// 测试 createTime 不匹配
|
||||
tenantPackageMapper.insert(cloneIgnoreId(dbTenantPackage, o -> o.setCreateTime(buildTime(2022, 11, 11))));
|
||||
// 准备参数
|
||||
TenantPackagePageReqVO reqVO = new TenantPackagePageReqVO();
|
||||
reqVO.setName("灿能");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setRemark("源码");
|
||||
reqVO.setCreateTime(buildBetweenTime(2022, 10, 9, 2022, 10, 11));
|
||||
|
||||
// 调用
|
||||
PageResult<TenantPackageDO> pageResult = tenantPackageService.getTenantPackagePage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbTenantPackage, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidTenantPackage_success() {
|
||||
// mock 数据
|
||||
TenantPackageDO dbTenantPackage = randomPojo(TenantPackageDO.class,
|
||||
o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
tenantPackageMapper.insert(dbTenantPackage);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用
|
||||
TenantPackageDO result = tenantPackageService.validTenantPackage(dbTenantPackage.getId());
|
||||
// 断言
|
||||
assertPojoEquals(dbTenantPackage, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidTenantPackage_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> tenantPackageService.validTenantPackage(id), TENANT_PACKAGE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidTenantPackage_disable() {
|
||||
// mock 数据
|
||||
TenantPackageDO dbTenantPackage = randomPojo(TenantPackageDO.class,
|
||||
o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
||||
tenantPackageMapper.insert(dbTenantPackage);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> tenantPackageService.validTenantPackage(dbTenantPackage.getId()),
|
||||
TENANT_PACKAGE_DISABLE, dbTenantPackage.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantPackage() {
|
||||
// mock 数据
|
||||
TenantPackageDO dbTenantPackage = randomPojo(TenantPackageDO.class);
|
||||
tenantPackageMapper.insert(dbTenantPackage);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用
|
||||
TenantPackageDO result = tenantPackageService.getTenantPackage(dbTenantPackage.getId());
|
||||
// 断言
|
||||
assertPojoEquals(result, dbTenantPackage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantPackageListByStatus() {
|
||||
// mock 数据
|
||||
TenantPackageDO dbTenantPackage = randomPojo(TenantPackageDO.class,
|
||||
o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
tenantPackageMapper.insert(dbTenantPackage);
|
||||
// 测试 status 不匹配
|
||||
tenantPackageMapper.insert(cloneIgnoreId(dbTenantPackage,
|
||||
o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
|
||||
// 调用
|
||||
List<TenantPackageDO> list = tenantPackageService.getTenantPackageListByStatus(
|
||||
CommonStatusEnum.ENABLE.getStatus());
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbTenantPackage, list.get(0));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,461 +0,0 @@
|
||||
package com.njcn.msgpush.module.system.service.tenant;
|
||||
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.common.pojo.PageResult;
|
||||
import com.njcn.msgpush.framework.tenant.config.TenantProperties;
|
||||
import com.njcn.msgpush.framework.tenant.core.context.TenantContextHolder;
|
||||
import com.njcn.msgpush.framework.test.core.ut.BaseDbUnitTest;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
|
||||
import com.njcn.msgpush.module.system.controller.admin.tenant.vo.tenant.TenantSaveReqVO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.permission.MenuDO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.permission.RoleDO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.tenant.TenantDO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.tenant.TenantPackageDO;
|
||||
import com.njcn.msgpush.module.system.dal.mysql.tenant.TenantMapper;
|
||||
import com.njcn.msgpush.module.system.enums.permission.RoleCodeEnum;
|
||||
import com.njcn.msgpush.module.system.enums.permission.RoleTypeEnum;
|
||||
import com.njcn.msgpush.module.system.service.permission.MenuService;
|
||||
import com.njcn.msgpush.module.system.service.permission.PermissionService;
|
||||
import com.njcn.msgpush.module.system.service.permission.RoleService;
|
||||
import com.njcn.msgpush.module.system.service.tenant.handler.TenantInfoHandler;
|
||||
import com.njcn.msgpush.module.system.service.tenant.handler.TenantMenuHandler;
|
||||
import com.njcn.msgpush.module.system.service.user.AdminUserService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.njcn.msgpush.framework.common.util.collection.SetUtils.asSet;
|
||||
import static com.njcn.msgpush.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static com.njcn.msgpush.framework.common.util.date.LocalDateTimeUtils.buildTime;
|
||||
import static com.njcn.msgpush.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static com.njcn.msgpush.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static com.njcn.msgpush.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static com.njcn.msgpush.framework.test.core.util.RandomUtils.*;
|
||||
import static com.njcn.msgpush.module.system.dal.dataobject.tenant.TenantDO.PACKAGE_ID_SYSTEM;
|
||||
import static com.njcn.msgpush.module.system.enums.ErrorCodeConstants.*;
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singleton;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* {@link TenantServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author hongawen
|
||||
*/
|
||||
@Import(TenantServiceImpl.class)
|
||||
public class TenantServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private TenantServiceImpl tenantService;
|
||||
|
||||
@Resource
|
||||
private TenantMapper tenantMapper;
|
||||
|
||||
@MockitoBean
|
||||
private TenantProperties tenantProperties;
|
||||
@MockitoBean
|
||||
private TenantPackageService tenantPackageService;
|
||||
@MockitoBean
|
||||
private AdminUserService userService;
|
||||
@MockitoBean
|
||||
private RoleService roleService;
|
||||
@MockitoBean
|
||||
private MenuService menuService;
|
||||
@MockitoBean
|
||||
private PermissionService permissionService;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
// 清理租户上下文
|
||||
TenantContextHolder.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantIdList() {
|
||||
// mock 数据
|
||||
TenantDO tenant = randomPojo(TenantDO.class, o -> o.setId(1L));
|
||||
tenantMapper.insert(tenant);
|
||||
|
||||
// 调用,并断言业务异常
|
||||
List<Long> result = tenantService.getTenantIdList();
|
||||
assertEquals(Collections.singletonList(1L), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidTenant_notExists() {
|
||||
assertServiceException(() -> tenantService.validTenant(randomLongId()), TENANT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidTenant_disable() {
|
||||
// mock 数据
|
||||
TenantDO tenant = randomPojo(TenantDO.class, o -> o.setId(1L).setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
||||
tenantMapper.insert(tenant);
|
||||
|
||||
// 调用,并断言业务异常
|
||||
assertServiceException(() -> tenantService.validTenant(1L), TENANT_DISABLE, tenant.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidTenant_expired() {
|
||||
// mock 数据
|
||||
TenantDO tenant = randomPojo(TenantDO.class, o -> o.setId(1L).setStatus(CommonStatusEnum.ENABLE.getStatus())
|
||||
.setExpireTime(buildTime(2020, 2, 2)));
|
||||
tenantMapper.insert(tenant);
|
||||
|
||||
// 调用,并断言业务异常
|
||||
assertServiceException(() -> tenantService.validTenant(1L), TENANT_EXPIRE, tenant.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidTenant_success() {
|
||||
// mock 数据
|
||||
TenantDO tenant = randomPojo(TenantDO.class, o -> o.setId(1L).setStatus(CommonStatusEnum.ENABLE.getStatus())
|
||||
.setExpireTime(LocalDateTime.now().plusDays(1)));
|
||||
tenantMapper.insert(tenant);
|
||||
|
||||
// 调用,并断言业务异常
|
||||
tenantService.validTenant(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateTenant() {
|
||||
// mock 套餐 100L
|
||||
TenantPackageDO tenantPackage = randomPojo(TenantPackageDO.class, o -> o.setId(100L));
|
||||
when(tenantPackageService.validTenantPackage(eq(100L))).thenReturn(tenantPackage);
|
||||
// mock 角色 200L
|
||||
when(roleService.createRole(argThat(role -> {
|
||||
assertEquals(RoleCodeEnum.TENANT_ADMIN.getName(), role.getName());
|
||||
assertEquals(RoleCodeEnum.TENANT_ADMIN.getCode(), role.getCode());
|
||||
assertEquals(0, role.getSort());
|
||||
assertEquals("系统自动生成", role.getRemark());
|
||||
return true;
|
||||
}), eq(RoleTypeEnum.SYSTEM.getType()))).thenReturn(200L);
|
||||
// mock 用户 300L
|
||||
when(userService.createUser(argThat(user -> {
|
||||
assertEquals("yunai", user.getUsername());
|
||||
assertEquals("yuanma", user.getPassword());
|
||||
assertEquals("灿能", user.getNickname());
|
||||
assertEquals("15601691300", user.getMobile());
|
||||
return true;
|
||||
}))).thenReturn(300L);
|
||||
|
||||
// 准备参数
|
||||
TenantSaveReqVO reqVO = randomPojo(TenantSaveReqVO.class, o -> {
|
||||
o.setContactName("灿能");
|
||||
o.setContactMobile("15601691300");
|
||||
o.setPackageId(100L);
|
||||
o.setStatus(randomCommonStatus());
|
||||
o.setWebsites(singletonList("https://www.iocoder.cn"));
|
||||
o.setUsername("yunai");
|
||||
o.setPassword("yuanma");
|
||||
}).setId(null); // 设置为 null,方便后面校验
|
||||
|
||||
// 调用
|
||||
Long tenantId = tenantService.createTenant(reqVO);
|
||||
// 断言
|
||||
assertNotNull(tenantId);
|
||||
// 校验记录的属性是否正确
|
||||
TenantDO tenant = tenantMapper.selectById(tenantId);
|
||||
assertPojoEquals(reqVO, tenant, "id");
|
||||
assertEquals(300L, tenant.getContactUserId());
|
||||
// verify 分配权限
|
||||
verify(permissionService).assignRoleMenu(eq(200L), same(tenantPackage.getMenuIds()));
|
||||
// verify 分配角色
|
||||
verify(permissionService).assignUserRole(eq(300L), eq(singleton(200L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateTenant_success() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setStatus(randomCommonStatus()));
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
TenantSaveReqVO reqVO = randomPojo(TenantSaveReqVO.class, o -> {
|
||||
o.setId(dbTenant.getId()); // 设置更新的 ID
|
||||
o.setStatus(randomCommonStatus());
|
||||
o.setWebsites(singletonList(randomString()));
|
||||
});
|
||||
|
||||
// mock 套餐
|
||||
TenantPackageDO tenantPackage = randomPojo(TenantPackageDO.class,
|
||||
o -> o.setMenuIds(asSet(200L, 201L)));
|
||||
when(tenantPackageService.validTenantPackage(eq(reqVO.getPackageId()))).thenReturn(tenantPackage);
|
||||
// mock 所有角色
|
||||
RoleDO role100 = randomPojo(RoleDO.class, o -> o.setId(100L).setCode(RoleCodeEnum.TENANT_ADMIN.getCode()));
|
||||
role100.setTenantId(dbTenant.getId());
|
||||
RoleDO role101 = randomPojo(RoleDO.class, o -> o.setId(101L));
|
||||
role101.setTenantId(dbTenant.getId());
|
||||
when(roleService.getRoleList()).thenReturn(asList(role100, role101));
|
||||
// mock 每个角色的权限
|
||||
when(permissionService.getRoleMenuListByRoleId(eq(101L))).thenReturn(asSet(201L, 202L));
|
||||
|
||||
// 调用
|
||||
tenantService.updateTenant(reqVO);
|
||||
// 校验是否更新正确
|
||||
TenantDO tenant = tenantMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, tenant);
|
||||
// verify 设置角色权限
|
||||
verify(permissionService).assignRoleMenu(eq(100L), eq(asSet(200L, 201L)));
|
||||
verify(permissionService).assignRoleMenu(eq(101L), eq(asSet(201L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateTenant_notExists() {
|
||||
// 准备参数
|
||||
TenantSaveReqVO reqVO = randomPojo(TenantSaveReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> tenantService.updateTenant(reqVO), TENANT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateTenant_system() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(PACKAGE_ID_SYSTEM));
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
TenantSaveReqVO reqVO = randomPojo(TenantSaveReqVO.class, o -> {
|
||||
o.setId(dbTenant.getId()); // 设置更新的 ID
|
||||
});
|
||||
|
||||
// 调用,校验业务异常
|
||||
assertServiceException(() -> tenantService.updateTenant(reqVO), TENANT_CAN_NOT_UPDATE_SYSTEM);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteTenant_success() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant = randomPojo(TenantDO.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 testDeleteTenant_system() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(PACKAGE_ID_SYSTEM));
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbTenant.getId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> tenantService.deleteTenant(id), TENANT_CAN_NOT_UPDATE_SYSTEM);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenant() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant = randomPojo(TenantDO.class);
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbTenant.getId();
|
||||
|
||||
// 调用
|
||||
TenantDO result = tenantService.getTenant(id);
|
||||
// 校验存在
|
||||
assertPojoEquals(result, dbTenant);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantPage() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant = randomPojo(TenantDO.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))));
|
||||
// 准备参数
|
||||
TenantPageReqVO reqVO = new TenantPageReqVO();
|
||||
reqVO.setName("灿能");
|
||||
reqVO.setContactName("艿");
|
||||
reqVO.setContactMobile("1560");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setCreateTime(buildBetweenTime(2020, 12, 1, 2020, 12, 24));
|
||||
|
||||
// 调用
|
||||
PageResult<TenantDO> pageResult = tenantService.getTenantPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbTenant, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantByName() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setName("灿能"));
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用
|
||||
TenantDO result = tenantService.getTenantByName("灿能");
|
||||
// 校验存在
|
||||
assertPojoEquals(result, dbTenant);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled // H2 不支持 find_in_set 函数
|
||||
public void testGetTenantByWebsite() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setWebsites(singletonList("https://www.iocoder.cn")));
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用
|
||||
TenantDO result = tenantService.getTenantByWebsite("https://www.iocoder.cn");
|
||||
// 校验存在
|
||||
assertPojoEquals(result, dbTenant);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantListByPackageId() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant1 = randomPojo(TenantDO.class, o -> o.setPackageId(1L));
|
||||
tenantMapper.insert(dbTenant1);// @Sql: 先插入出一条存在的数据
|
||||
TenantDO dbTenant2 = randomPojo(TenantDO.class, o -> o.setPackageId(2L));
|
||||
tenantMapper.insert(dbTenant2);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用
|
||||
List<TenantDO> result = tenantService.getTenantListByPackageId(1L);
|
||||
assertEquals(1, result.size());
|
||||
assertPojoEquals(dbTenant1, result.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantCountByPackageId() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant1 = randomPojo(TenantDO.class, o -> o.setPackageId(1L));
|
||||
tenantMapper.insert(dbTenant1);// @Sql: 先插入出一条存在的数据
|
||||
TenantDO dbTenant2 = randomPojo(TenantDO.class, o -> o.setPackageId(2L));
|
||||
tenantMapper.insert(dbTenant2);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用
|
||||
Long count = tenantService.getTenantCountByPackageId(1L);
|
||||
assertEquals(1, count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleTenantInfo_disable() {
|
||||
// 准备参数
|
||||
TenantInfoHandler handler = mock(TenantInfoHandler.class);
|
||||
// mock 禁用
|
||||
when(tenantProperties.getEnable()).thenReturn(false);
|
||||
|
||||
// 调用
|
||||
tenantService.handleTenantInfo(handler);
|
||||
// 断言
|
||||
verify(handler, never()).handle(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleTenantInfo_success() {
|
||||
// 准备参数
|
||||
TenantInfoHandler handler = mock(TenantInfoHandler.class);
|
||||
// mock 未禁用
|
||||
when(tenantProperties.getEnable()).thenReturn(true);
|
||||
// mock 租户
|
||||
TenantDO dbTenant = randomPojo(TenantDO.class);
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
TenantContextHolder.setTenantId(dbTenant.getId());
|
||||
|
||||
// 调用
|
||||
tenantService.handleTenantInfo(handler);
|
||||
// 断言
|
||||
verify(handler).handle(argThat(argument -> {
|
||||
assertPojoEquals(dbTenant, argument);
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleTenantMenu_disable() {
|
||||
// 准备参数
|
||||
TenantMenuHandler handler = mock(TenantMenuHandler.class);
|
||||
// mock 禁用
|
||||
when(tenantProperties.getEnable()).thenReturn(false);
|
||||
|
||||
// 调用
|
||||
tenantService.handleTenantMenu(handler);
|
||||
// 断言
|
||||
verify(handler, never()).handle(any());
|
||||
}
|
||||
|
||||
@Test // 系统租户的情况
|
||||
public void testHandleTenantMenu_system() {
|
||||
// 准备参数
|
||||
TenantMenuHandler handler = mock(TenantMenuHandler.class);
|
||||
// mock 未禁用
|
||||
when(tenantProperties.getEnable()).thenReturn(true);
|
||||
// mock 租户
|
||||
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(PACKAGE_ID_SYSTEM));
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
TenantContextHolder.setTenantId(dbTenant.getId());
|
||||
// mock 菜单
|
||||
when(menuService.getMenuList()).thenReturn(Arrays.asList(randomPojo(MenuDO.class, o -> o.setId(100L)),
|
||||
randomPojo(MenuDO.class, o -> o.setId(101L))));
|
||||
|
||||
// 调用
|
||||
tenantService.handleTenantMenu(handler);
|
||||
// 断言
|
||||
verify(handler).handle(asSet(100L, 101L));
|
||||
}
|
||||
|
||||
@Test // 普通租户的情况
|
||||
public void testHandleTenantMenu_normal() {
|
||||
// 准备参数
|
||||
TenantMenuHandler handler = mock(TenantMenuHandler.class);
|
||||
// mock 未禁用
|
||||
when(tenantProperties.getEnable()).thenReturn(true);
|
||||
// mock 租户
|
||||
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(200L));
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
TenantContextHolder.setTenantId(dbTenant.getId());
|
||||
// mock 菜单
|
||||
when(tenantPackageService.getTenantPackage(eq(200L))).thenReturn(randomPojo(TenantPackageDO.class,
|
||||
o -> o.setMenuIds(asSet(100L, 101L))));
|
||||
|
||||
// 调用
|
||||
tenantService.handleTenantMenu(handler);
|
||||
// 断言
|
||||
verify(handler).handle(asSet(100L, 101L));
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package com.njcn.msgpush.module.system.service.user;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.njcn.msgpush.framework.common.enums.CommonStatusEnum;
|
||||
import com.njcn.msgpush.framework.common.exception.ServiceException;
|
||||
import com.njcn.msgpush.framework.common.pojo.CommonResult;
|
||||
import com.njcn.msgpush.framework.common.pojo.PageResult;
|
||||
import com.njcn.msgpush.framework.common.util.collection.ArrayUtils;
|
||||
import com.njcn.msgpush.framework.common.util.collection.CollectionUtils;
|
||||
@@ -19,7 +18,6 @@ import com.njcn.msgpush.module.system.controller.admin.user.vo.user.UserSaveReqV
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.dept.DeptDO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.dept.PostDO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.dept.UserPostDO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.tenant.TenantDO;
|
||||
import com.njcn.msgpush.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import com.njcn.msgpush.module.system.dal.mysql.dept.UserPostMapper;
|
||||
import com.njcn.msgpush.module.system.dal.mysql.user.AdminUserMapper;
|
||||
@@ -28,7 +26,6 @@ import com.njcn.msgpush.module.system.service.dept.DeptService;
|
||||
import com.njcn.msgpush.module.system.service.dept.PostService;
|
||||
import com.njcn.msgpush.module.system.service.oauth2.OAuth2TokenService;
|
||||
import com.njcn.msgpush.module.system.service.permission.PermissionService;
|
||||
import com.njcn.msgpush.module.system.service.tenant.TenantService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -80,8 +77,6 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
|
||||
@MockitoBean
|
||||
private PasswordEncoder passwordEncoder;
|
||||
@MockitoBean
|
||||
private TenantService tenantService;
|
||||
@MockitoBean
|
||||
private FileApi fileApi;
|
||||
@MockitoBean
|
||||
private ConfigApi configApi;
|
||||
@@ -102,12 +97,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
|
||||
o.setMobile(randomString());
|
||||
o.setPostIds(asSet(1L, 2L));
|
||||
}).setId(null); // 避免 id 被赋值
|
||||
// mock 账户额度充足
|
||||
TenantDO tenant = randomPojo(TenantDO.class, o -> o.setAccountCount(1));
|
||||
doNothing().when(tenantService).handleTenantInfo(argThat(handler -> {
|
||||
handler.handle(tenant);
|
||||
return true;
|
||||
}));
|
||||
|
||||
// mock deptService 的方法
|
||||
DeptDO dept = randomPojo(DeptDO.class, o -> {
|
||||
o.setId(reqVO.getDeptId());
|
||||
@@ -137,20 +127,6 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
|
||||
assertEquals(2L, userPosts.get(1).getPostId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreatUser_max() {
|
||||
// 准备参数
|
||||
UserSaveReqVO reqVO = randomPojo(UserSaveReqVO.class);
|
||||
// mock 账户额度不足
|
||||
TenantDO tenant = randomPojo(TenantDO.class, o -> o.setAccountCount(-1));
|
||||
doNothing().when(tenantService).handleTenantInfo(argThat(handler -> {
|
||||
handler.handle(tenant);
|
||||
return true;
|
||||
}));
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> userService.createUser(reqVO), USER_COUNT_MAX, -1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateUser_success() {
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
DELETE FROM "system_dept";
|
||||
DELETE FROM "system_dict_data";
|
||||
DELETE FROM "system_role";
|
||||
DELETE FROM "system_role_menu";
|
||||
DELETE FROM "system_menu";
|
||||
DELETE FROM "system_user_role";
|
||||
DELETE FROM "system_dict_type";
|
||||
DELETE FROM "system_user_session";
|
||||
DELETE FROM "system_post";
|
||||
DELETE FROM "system_user_post";
|
||||
DELETE FROM "system_notice";
|
||||
DELETE FROM "system_login_log";
|
||||
DELETE FROM "system_operate_log";
|
||||
DELETE FROM "system_users";
|
||||
DELETE FROM "system_sms_channel";
|
||||
DELETE FROM "system_sms_template";
|
||||
DELETE FROM "system_sms_log";
|
||||
DELETE FROM "system_sms_code";
|
||||
DELETE FROM "system_social_client";
|
||||
DELETE FROM "system_social_user";
|
||||
DELETE FROM "system_social_user_bind";
|
||||
DELETE FROM "system_tenant";
|
||||
DELETE FROM "system_tenant_package";
|
||||
DELETE FROM "system_oauth2_client";
|
||||
DELETE FROM "system_oauth2_approve";
|
||||
DELETE FROM "system_oauth2_access_token";
|
||||
DELETE FROM "system_oauth2_refresh_token";
|
||||
DELETE FROM "system_oauth2_code";
|
||||
DELETE FROM "system_mail_account";
|
||||
DELETE FROM "system_mail_template";
|
||||
DELETE FROM "system_mail_log";
|
||||
DELETE FROM "system_notify_template";
|
||||
DELETE FROM "system_notify_message";
|
||||
@@ -1,617 +0,0 @@
|
||||
CREATE TABLE IF NOT EXISTS "system_dept" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"name" varchar(30) NOT NULL DEFAULT '',
|
||||
"parent_id" bigint NOT NULL DEFAULT '0',
|
||||
"sort" int NOT NULL DEFAULT '0',
|
||||
"leader_user_id" bigint DEFAULT NULL,
|
||||
"phone" varchar(11) DEFAULT NULL,
|
||||
"email" varchar(50) DEFAULT NULL,
|
||||
"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,
|
||||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '部门表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_dict_data" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"sort" int NOT NULL DEFAULT '0',
|
||||
"label" varchar(100) NOT NULL DEFAULT '',
|
||||
"value" varchar(100) NOT NULL DEFAULT '',
|
||||
"dict_type" varchar(100) NOT NULL DEFAULT '',
|
||||
"status" tinyint NOT NULL DEFAULT '0',
|
||||
"color_type" varchar(100) NOT NULL DEFAULT '',
|
||||
"css_class" varchar(100) NOT NULL DEFAULT '',
|
||||
"remark" varchar(500) DEFAULT 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 '字典数据表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_role" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"name" varchar(30) NOT NULL,
|
||||
"code" varchar(100) NOT NULL,
|
||||
"sort" int NOT NULL,
|
||||
"data_scope" tinyint NOT NULL DEFAULT '1',
|
||||
"data_scope_dept_ids" varchar(500) NOT NULL DEFAULT '',
|
||||
"status" tinyint NOT NULL,
|
||||
"type" tinyint NOT NULL,
|
||||
"remark" varchar(500) DEFAULT 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,
|
||||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '角色信息表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_role_menu" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"role_id" bigint NOT NULL,
|
||||
"menu_id" bigint 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,
|
||||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '角色和菜单关联表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_menu" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"name" varchar(50) NOT NULL,
|
||||
"permission" varchar(100) NOT NULL DEFAULT '',
|
||||
"type" tinyint NOT NULL,
|
||||
"sort" int NOT NULL DEFAULT '0',
|
||||
"parent_id" bigint NOT NULL DEFAULT '0',
|
||||
"path" varchar(200) DEFAULT '',
|
||||
"icon" varchar(100) DEFAULT '#',
|
||||
"component" varchar(255) DEFAULT NULL,
|
||||
"component_name" varchar(255) DEFAULT NULL,
|
||||
"status" tinyint NOT NULL DEFAULT '0',
|
||||
"visible" bit NOT NULL DEFAULT TRUE,
|
||||
"keep_alive" bit NOT NULL DEFAULT TRUE,
|
||||
"always_show" bit NOT NULL DEFAULT TRUE,
|
||||
"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 '菜单权限表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_user_role" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"user_id" bigint NOT NULL,
|
||||
"role_id" bigint NOT NULL,
|
||||
"creator" varchar(64) DEFAULT '',
|
||||
"create_time" timestamp DEFAULT NULL,
|
||||
"updater" varchar(64) DEFAULT '',
|
||||
"update_time" timestamp DEFAULT NULL,
|
||||
"deleted" bit DEFAULT FALSE,
|
||||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '用户和角色关联表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_dict_type" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"name" varchar(100) NOT NULL DEFAULT '',
|
||||
"type" varchar(100) NOT NULL DEFAULT '',
|
||||
"status" tinyint NOT NULL DEFAULT '0',
|
||||
"remark" varchar(500) DEFAULT 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,
|
||||
"deleted_time" timestamp NOT NULL,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '字典类型表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `system_user_session` (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
`token` varchar(32) NOT NULL,
|
||||
`user_id` bigint DEFAULT NULL,
|
||||
"user_type" tinyint NOT NULL,
|
||||
`username` varchar(50) NOT NULL DEFAULT '',
|
||||
`user_ip` varchar(50) DEFAULT NULL,
|
||||
`user_agent` varchar(512) DEFAULT NULL,
|
||||
`session_timeout` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"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,
|
||||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY (`id`)
|
||||
) COMMENT '用户在线 Session';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_post" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"code" varchar(64) NOT NULL,
|
||||
"name" varchar(50) NOT NULL,
|
||||
"sort" integer NOT NULL,
|
||||
"status" tinyint NOT NULL,
|
||||
"remark" varchar(500) DEFAULT 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,
|
||||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '岗位信息表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `system_user_post`(
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"user_id" bigint DEFAULT NULL,
|
||||
"post_id" bigint DEFAULT 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,
|
||||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY (`id`)
|
||||
) COMMENT ='用户岗位表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_notice" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"title" varchar(50) NOT NULL COMMENT '公告标题',
|
||||
"content" text NOT NULL COMMENT '公告内容',
|
||||
"type" tinyint NOT NULL COMMENT '公告类型(1通知 2公告)',
|
||||
"status" tinyint NOT NULL DEFAULT '0' COMMENT '公告状态(0正常 1关闭)',
|
||||
"creator" varchar(64) DEFAULT '' COMMENT '创建者',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
"updater" varchar(64) DEFAULT '' COMMENT '更新者',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
"deleted" bit NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY("id")
|
||||
) COMMENT '通知公告表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `system_login_log` (
|
||||
`id` bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
`log_type` bigint(4) NOT NULL,
|
||||
"user_id" bigint not null default '0',
|
||||
"user_type" tinyint NOT NULL,
|
||||
`trace_id` varchar(64) NOT NULL DEFAULT '',
|
||||
`username` varchar(50) NOT NULL DEFAULT '',
|
||||
`result` tinyint(4) NOT NULL,
|
||||
`user_ip` varchar(50) NOT NULL,
|
||||
`user_agent` varchar(512) NOT NULL,
|
||||
`creator` varchar(64) DEFAULT '',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updater` varchar(64) DEFAULT '',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`deleted` bit(1) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`)
|
||||
) COMMENT ='系统访问记录';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `system_operate_log` (
|
||||
`id` bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
`trace_id` varchar(64) NOT NULL DEFAULT '',
|
||||
`user_id` bigint(20) NOT NULL,
|
||||
"user_type" tinyint not null default '0',
|
||||
`type` varchar(50) NOT NULL,
|
||||
`sub_type` varchar(50) NOT NULL,
|
||||
`biz_id` bigint(20) NOT NULL,
|
||||
`action` varchar(2000) NOT NULL DEFAULT '',
|
||||
`extra` varchar(512) NOT NULL DEFAULT '',
|
||||
`request_method` varchar(16) DEFAULT '',
|
||||
`request_url` varchar(255) DEFAULT '',
|
||||
`user_ip` varchar(50) DEFAULT NULL,
|
||||
`user_agent` varchar(200) DEFAULT NULL,
|
||||
`creator` varchar(64) DEFAULT '',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updater` varchar(64) DEFAULT '',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`deleted` bit(1) NOT NULL DEFAULT '0',
|
||||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY (`id`)
|
||||
) COMMENT ='操作日志记录';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_users" (
|
||||
"id" bigint not null GENERATED BY DEFAULT AS IDENTITY,
|
||||
"username" varchar(30) not null,
|
||||
"password" varchar(100) not null default '',
|
||||
"nickname" varchar(30) not null,
|
||||
"remark" varchar(500) default null,
|
||||
"dept_id" bigint default null,
|
||||
"post_ids" varchar(255) default null,
|
||||
"email" varchar(50) default '',
|
||||
"mobile" varchar(11) default '',
|
||||
"sex" tinyint default '0',
|
||||
"avatar" varchar(100) default '',
|
||||
"status" tinyint not null default '0',
|
||||
"login_ip" varchar(50) default '',
|
||||
"login_date" timestamp default 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,
|
||||
"tenant_id" bigint not null default '0',
|
||||
primary key ("id")
|
||||
) comment '用户信息表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_sms_channel" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"signature" varchar(10) NOT NULL,
|
||||
"code" varchar(63) NOT NULL,
|
||||
"status" tinyint NOT NULL,
|
||||
"remark" varchar(255) DEFAULT NULL,
|
||||
"api_key" varchar(63) NOT NULL,
|
||||
"api_secret" varchar(63) DEFAULT NULL,
|
||||
"callback_url" varchar(255) DEFAULT 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 '短信渠道';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_sms_template" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"type" tinyint NOT NULL,
|
||||
"status" tinyint NOT NULL,
|
||||
"code" varchar(63) NOT NULL,
|
||||
"name" varchar(63) NOT NULL,
|
||||
"content" varchar(255) NOT NULL,
|
||||
"params" varchar(255) NOT NULL,
|
||||
"remark" varchar(255) DEFAULT NULL,
|
||||
"api_template_id" varchar(63) NOT NULL,
|
||||
"channel_id" bigint NOT NULL,
|
||||
"channel_code" varchar(63) 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 '短信模板';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_sms_log" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"channel_id" bigint NOT NULL,
|
||||
"channel_code" varchar(63) NOT NULL,
|
||||
"template_id" bigint NOT NULL,
|
||||
"template_code" varchar(63) NOT NULL,
|
||||
"template_type" tinyint NOT NULL,
|
||||
"template_content" varchar(255) NOT NULL,
|
||||
"template_params" varchar(255) NOT NULL,
|
||||
"api_template_id" varchar(63) NOT NULL,
|
||||
"mobile" varchar(11) NOT NULL,
|
||||
"user_id" bigint DEFAULT '0',
|
||||
"user_type" tinyint DEFAULT '0',
|
||||
"send_status" tinyint NOT NULL DEFAULT '0',
|
||||
"send_time" timestamp DEFAULT NULL,
|
||||
"send_code" int DEFAULT NULL,
|
||||
"send_msg" varchar(255) DEFAULT NULL,
|
||||
"api_send_code" varchar(63) DEFAULT NULL,
|
||||
"api_send_msg" varchar(255) DEFAULT NULL,
|
||||
"api_request_id" varchar(255) DEFAULT NULL,
|
||||
"api_serial_no" varchar(255) DEFAULT NULL,
|
||||
"receive_status" tinyint NOT NULL DEFAULT '0',
|
||||
"receive_time" timestamp DEFAULT NULL,
|
||||
"api_receive_code" varchar(63) DEFAULT NULL,
|
||||
"api_receive_msg" varchar(255) DEFAULT 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 '短信日志';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_sms_code" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"mobile" varchar(11) NOT NULL,
|
||||
"code" varchar(11) NOT NULL,
|
||||
"scene" bigint NOT NULL,
|
||||
"create_ip" varchar NOT NULL,
|
||||
"today_index" int NOT NULL,
|
||||
"used" bit NOT NULL DEFAULT FALSE,
|
||||
"used_time" timestamp DEFAULT NULL,
|
||||
"used_ip" varchar 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 '短信日志';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_social_client" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"name" varchar(255) NOT NULL,
|
||||
"social_type" int NOT NULL,
|
||||
"user_type" int NOT NULL,
|
||||
"client_id" varchar(255) NOT NULL,
|
||||
"client_secret" varchar(255) NOT NULL,
|
||||
"public_key" varchar(2048) NOT NULL,
|
||||
"agent_id" varchar(255) NOT NULL,
|
||||
"status" int NOT NULL,
|
||||
"creator" varchar(64) DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar(64) DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '社交客户端表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_social_user" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"type" tinyint NOT NULL,
|
||||
"openid" varchar(64) NOT NULL,
|
||||
"token" varchar(256) DEFAULT NULL,
|
||||
"raw_token_info" varchar(1024) NOT NULL,
|
||||
"nickname" varchar(32) NOT NULL,
|
||||
"avatar" varchar(255) DEFAULT NULL,
|
||||
"raw_user_info" varchar(1024) NOT NULL,
|
||||
"code" varchar(64) NOT NULL,
|
||||
"state" varchar(64),
|
||||
"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 '社交用户';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_social_user_bind" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"user_id" bigint NOT NULL,
|
||||
"user_type" tinyint NOT NULL,
|
||||
"social_type" tinyint NOT NULL,
|
||||
"social_user_id" number 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 '社交用户的绑定';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_tenant" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"name" varchar(63) NOT NULL,
|
||||
"contact_user_id" bigint NOT NULL DEFAULT '0',
|
||||
"contact_name" varchar(255) NOT NULL,
|
||||
"contact_mobile" varchar(255),
|
||||
"status" tinyint NOT NULL,
|
||||
"websites" varchar(1024) DEFAULT '',
|
||||
"package_id" bigint NOT NULL,
|
||||
"expire_time" timestamp NOT NULL,
|
||||
"account_count" int 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 '租户';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_tenant_package" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"name" varchar(30) NOT NULL,
|
||||
"status" tinyint NOT NULL,
|
||||
"remark" varchar(256),
|
||||
"menu_ids" varchar(2048) NOT NULL,
|
||||
"creator" varchar(64) DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar(64) DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '租户套餐表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_oauth2_client" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"client_id" varchar NOT NULL,
|
||||
"secret" varchar NOT NULL,
|
||||
"name" varchar NOT NULL,
|
||||
"logo" varchar NOT NULL,
|
||||
"description" varchar,
|
||||
"status" int NOT NULL,
|
||||
"access_token_validity_seconds" int NOT NULL,
|
||||
"refresh_token_validity_seconds" int NOT NULL,
|
||||
"redirect_uris" varchar NOT NULL,
|
||||
"authorized_grant_types" varchar NOT NULL,
|
||||
"scopes" varchar NOT NULL DEFAULT '',
|
||||
"auto_approve_scopes" varchar NOT NULL DEFAULT '',
|
||||
"authorities" varchar NOT NULL DEFAULT '',
|
||||
"resource_ids" varchar NOT NULL DEFAULT '',
|
||||
"additional_information" varchar NOT NULL DEFAULT '',
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT 'OAuth2 客户端表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_oauth2_approve" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"user_id" bigint NOT NULL,
|
||||
"user_type" tinyint NOT NULL,
|
||||
"client_id" varchar NOT NULL,
|
||||
"scope" varchar NOT NULL,
|
||||
"approved" bit NOT NULL DEFAULT FALSE,
|
||||
"expires_time" datetime NOT NULL,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT 'OAuth2 批准表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_oauth2_access_token" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"user_id" bigint NOT NULL,
|
||||
"user_type" tinyint NOT NULL,
|
||||
"user_info" varchar NOT NULL,
|
||||
"access_token" varchar NOT NULL,
|
||||
"refresh_token" varchar NOT NULL,
|
||||
"client_id" varchar NOT NULL,
|
||||
"scopes" varchar NOT NULL,
|
||||
"approved" bit NOT NULL DEFAULT FALSE,
|
||||
"expires_time" datetime NOT NULL,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
"tenant_id" bigint not null,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT 'OAuth2 访问令牌';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_oauth2_refresh_token" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"user_id" bigint NOT NULL,
|
||||
"user_type" tinyint NOT NULL,
|
||||
"refresh_token" varchar NOT NULL,
|
||||
"client_id" varchar NOT NULL,
|
||||
"scopes" varchar NOT NULL,
|
||||
"approved" bit NOT NULL DEFAULT FALSE,
|
||||
"expires_time" datetime NOT NULL,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT 'OAuth2 刷新令牌';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_oauth2_code" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"user_id" bigint NOT NULL,
|
||||
"user_type" tinyint NOT NULL,
|
||||
"code" varchar NOT NULL,
|
||||
"client_id" varchar NOT NULL,
|
||||
"scopes" varchar NOT NULL,
|
||||
"expires_time" datetime NOT NULL,
|
||||
"redirect_uri" varchar NOT NULL,
|
||||
"state" varchar NOT NULL,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT 'OAuth2 刷新令牌';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_mail_account" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"mail" varchar NOT NULL,
|
||||
"username" varchar NOT NULL,
|
||||
"password" varchar NOT NULL,
|
||||
"host" varchar NOT NULL,
|
||||
"port" int NOT NULL,
|
||||
"ssl_enable" bit NOT NULL,
|
||||
"starttls_enable" bit NOT NULL,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '邮箱账号表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_mail_template" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"name" varchar NOT NULL,
|
||||
"code" varchar NOT NULL,
|
||||
"account_id" bigint NOT NULL,
|
||||
"nickname" varchar,
|
||||
"title" varchar NOT NULL,
|
||||
"content" varchar NOT NULL,
|
||||
"params" varchar NOT NULL,
|
||||
"status" varchar NOT NULL,
|
||||
"remark" varchar,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '邮件模版表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_mail_log" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"user_id" bigint,
|
||||
"user_type" varchar,
|
||||
"to_mails" varchar NOT NULL,
|
||||
"cc_mails" varchar,
|
||||
"bcc_mails" varchar,
|
||||
"account_id" bigint NOT NULL,
|
||||
"from_mail" varchar NOT NULL,
|
||||
"template_id" bigint NOT NULL,
|
||||
"template_code" varchar NOT NULL,
|
||||
"template_nickname" varchar,
|
||||
"template_title" varchar NOT NULL,
|
||||
"template_content" varchar NOT NULL,
|
||||
"template_params" varchar NOT NULL,
|
||||
"send_status" varchar NOT NULL,
|
||||
"send_time" datetime,
|
||||
"send_message_id" varchar,
|
||||
"send_exception" varchar,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '邮件日志表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_notify_template" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"name" varchar NOT NULL,
|
||||
"code" varchar NOT NULL,
|
||||
"nickname" varchar NOT NULL,
|
||||
"content" varchar NOT NULL,
|
||||
"type" varchar NOT NULL,
|
||||
"params" varchar,
|
||||
"status" varchar NOT NULL,
|
||||
"remark" varchar,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '站内信模板表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "system_notify_message" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"user_id" bigint NOT NULL,
|
||||
"user_type" varchar NOT NULL,
|
||||
"template_id" bigint NOT NULL,
|
||||
"template_code" varchar NOT NULL,
|
||||
"template_nickname" varchar NOT NULL,
|
||||
"template_content" varchar NOT NULL,
|
||||
"template_type" int NOT NULL,
|
||||
"template_params" varchar NOT NULL,
|
||||
"read_status" bit NOT NULL,
|
||||
"read_time" varchar,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '站内信消息表';
|
||||
Reference in New Issue
Block a user