mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 23:31:52 +08:00
【新增】【优化】新建租户时,自动创建对应的管理员账号、角色等基础信息
This commit is contained in:
parent
6b6d676a6b
commit
2598c033a9
@ -147,4 +147,7 @@ public class CollectionUtils {
|
|||||||
coll.add(item);
|
coll.add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T> Collection<T> singleton(T deptId) {
|
||||||
|
return deptId == null ? Collections.emptyList() : Collections.singleton(deptId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,9 @@ package cn.iocoder.yudao.framework.tenant.config;
|
|||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
|
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter;
|
import cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService;
|
||||||
import cn.iocoder.yudao.framework.web.config.WebProperties;
|
import cn.iocoder.yudao.framework.web.config.WebProperties;
|
||||||
|
import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||||
@ -22,9 +24,12 @@ public class YudaoTenantSecurityAutoConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public FilterRegistrationBean<TenantSecurityWebFilter> tenantSecurityWebFilter(TenantProperties tenantProperties,
|
public FilterRegistrationBean<TenantSecurityWebFilter> tenantSecurityWebFilter(TenantProperties tenantProperties,
|
||||||
WebProperties webProperties) {
|
WebProperties webProperties,
|
||||||
|
GlobalExceptionHandler globalExceptionHandler,
|
||||||
|
TenantFrameworkService tenantFrameworkService) {
|
||||||
FilterRegistrationBean<TenantSecurityWebFilter> registrationBean = new FilterRegistrationBean<>();
|
FilterRegistrationBean<TenantSecurityWebFilter> registrationBean = new FilterRegistrationBean<>();
|
||||||
registrationBean.setFilter(new TenantSecurityWebFilter(tenantProperties, webProperties));
|
registrationBean.setFilter(new TenantSecurityWebFilter(tenantProperties, webProperties,
|
||||||
|
globalExceptionHandler, tenantFrameworkService));
|
||||||
registrationBean.setOrder(WebFilterOrderEnum.TENANT_SECURITY_FILTER);
|
registrationBean.setOrder(WebFilterOrderEnum.TENANT_SECURITY_FILTER);
|
||||||
return registrationBean;
|
return registrationBean;
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,6 @@ public class TenantContextHolder {
|
|||||||
|
|
||||||
private static final ThreadLocal<Long> TENANT_ID = new TransmittableThreadLocal<>();
|
private static final ThreadLocal<Long> TENANT_ID = new TransmittableThreadLocal<>();
|
||||||
|
|
||||||
/**
|
|
||||||
* 租户编号 - 空
|
|
||||||
*/
|
|
||||||
private static final Long TENANT_ID_NULL = 0L;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得租户编号。
|
* 获得租户编号。
|
||||||
*
|
*
|
||||||
@ -38,15 +33,6 @@ public class TenantContextHolder {
|
|||||||
return tenantId;
|
return tenantId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 在一些前端场景下,可能无法请求带上租户。例如说,<img /> 方式获取图片等
|
|
||||||
* 此时,暂时的解决方案,是在该接口的 Controller 方法上,调用该方法
|
|
||||||
* TODO 芋艿:思考有没更合适的方案,目标是去掉该方法
|
|
||||||
*/
|
|
||||||
public static void setNullTenantId() {
|
|
||||||
TENANT_ID.set(TENANT_ID_NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setTenantId(Long tenantId) {
|
public static void setTenantId(Long tenantId) {
|
||||||
TENANT_ID.set(tenantId);
|
TENANT_ID.set(tenantId);
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,10 @@ import cn.iocoder.yudao.framework.security.core.LoginUser;
|
|||||||
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
||||||
import cn.iocoder.yudao.framework.tenant.config.TenantProperties;
|
import cn.iocoder.yudao.framework.tenant.config.TenantProperties;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService;
|
||||||
import cn.iocoder.yudao.framework.web.config.WebProperties;
|
import cn.iocoder.yudao.framework.web.config.WebProperties;
|
||||||
import cn.iocoder.yudao.framework.web.core.filter.ApiRequestFilter;
|
import cn.iocoder.yudao.framework.web.core.filter.ApiRequestFilter;
|
||||||
|
import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.util.AntPathMatcher;
|
import org.springframework.util.AntPathMatcher;
|
||||||
|
|
||||||
@ -24,6 +26,7 @@ import java.util.Objects;
|
|||||||
* 多租户 Security Web 过滤器
|
* 多租户 Security Web 过滤器
|
||||||
* 1. 如果是登陆的用户,校验是否有权限访问该租户,避免越权问题。
|
* 1. 如果是登陆的用户,校验是否有权限访问该租户,避免越权问题。
|
||||||
* 2. 如果请求未带租户的编号,检查是否是忽略的 URL,否则也不允许访问。
|
* 2. 如果请求未带租户的编号,检查是否是忽略的 URL,否则也不允许访问。
|
||||||
|
* 3. 校验租户是合法,例如说被禁用、到期
|
||||||
*
|
*
|
||||||
* 校验用户访问的租户,是否是其所在的租户,
|
* 校验用户访问的租户,是否是其所在的租户,
|
||||||
*
|
*
|
||||||
@ -33,13 +36,21 @@ import java.util.Objects;
|
|||||||
public class TenantSecurityWebFilter extends ApiRequestFilter {
|
public class TenantSecurityWebFilter extends ApiRequestFilter {
|
||||||
|
|
||||||
private final TenantProperties tenantProperties;
|
private final TenantProperties tenantProperties;
|
||||||
|
|
||||||
private final AntPathMatcher pathMatcher;
|
private final AntPathMatcher pathMatcher;
|
||||||
|
|
||||||
|
private final GlobalExceptionHandler globalExceptionHandler;
|
||||||
|
private final TenantFrameworkService tenantFrameworkService;
|
||||||
|
|
||||||
public TenantSecurityWebFilter(TenantProperties tenantProperties,
|
public TenantSecurityWebFilter(TenantProperties tenantProperties,
|
||||||
WebProperties webProperties) {
|
WebProperties webProperties,
|
||||||
|
GlobalExceptionHandler globalExceptionHandler,
|
||||||
|
TenantFrameworkService tenantFrameworkService) {
|
||||||
super(webProperties);
|
super(webProperties);
|
||||||
this.tenantProperties = tenantProperties;
|
this.tenantProperties = tenantProperties;
|
||||||
this.pathMatcher = new AntPathMatcher();
|
this.pathMatcher = new AntPathMatcher();
|
||||||
|
this.globalExceptionHandler = globalExceptionHandler;
|
||||||
|
this.tenantFrameworkService = tenantFrameworkService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -72,6 +83,17 @@ public class TenantSecurityWebFilter extends ApiRequestFilter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3. 校验租户是合法,例如说被禁用、到期
|
||||||
|
if (tenantId != null) {
|
||||||
|
try {
|
||||||
|
tenantFrameworkService.validTenant(tenantId);
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
CommonResult<?> result = globalExceptionHandler.allExceptionHandler(request, ex);
|
||||||
|
ServletUtils.writeJSON(response, result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 继续过滤
|
// 继续过滤
|
||||||
chain.doFilter(request, response);
|
chain.doFilter(request, response);
|
||||||
}
|
}
|
||||||
|
@ -16,4 +16,11 @@ public interface TenantFrameworkService {
|
|||||||
*/
|
*/
|
||||||
List<Long> getTenantIds();
|
List<Long> getTenantIds();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验租户是否合法
|
||||||
|
*
|
||||||
|
* @param id 租户编号
|
||||||
|
*/
|
||||||
|
void validTenant(Long id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
package cn.iocoder.yudao.framework.tenant.core.util;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多租户 Util
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public class TenantUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用指定租户,执行对应的逻辑
|
||||||
|
*
|
||||||
|
* @param tenantId 租户编号
|
||||||
|
* @param runnable 逻辑
|
||||||
|
*/
|
||||||
|
public static void execute(Long tenantId, Runnable runnable) {
|
||||||
|
Long oldTenantId = TenantContextHolder.getTenantId();
|
||||||
|
try {
|
||||||
|
TenantContextHolder.setTenantId(tenantId);
|
||||||
|
// 执行逻辑
|
||||||
|
runnable.run();
|
||||||
|
} finally {
|
||||||
|
TenantContextHolder.setTenantId(oldTenantId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -104,10 +104,13 @@ public interface ErrorCodeConstants {
|
|||||||
|
|
||||||
// ========== 租户信息 1002014000 ==========
|
// ========== 租户信息 1002014000 ==========
|
||||||
ErrorCode TENANT_NOT_EXISTS = new ErrorCode(1002014000, "租户不存在");
|
ErrorCode TENANT_NOT_EXISTS = new ErrorCode(1002014000, "租户不存在");
|
||||||
|
ErrorCode TENANT_DISABLE = new ErrorCode(1002014001, "名字为【{}】的租户已被禁用");
|
||||||
|
ErrorCode TENANT_EXPIRE = new ErrorCode(1002014002, "名字为【{}】的租户已过期");
|
||||||
|
|
||||||
// ========== 租户套餐 1002015000 ==========
|
// ========== 租户套餐 1002015000 ==========
|
||||||
ErrorCode TENANT_PACKAGE_NOT_EXISTS = new ErrorCode(1002015000, "租户套餐不存在");
|
ErrorCode TENANT_PACKAGE_NOT_EXISTS = new ErrorCode(1002015000, "租户套餐不存在");
|
||||||
ErrorCode TENANT_PACKAGE_USED = new ErrorCode(1002015001, "租户正在使用该套餐,请给租户重新设置套餐后再尝试删除");
|
ErrorCode TENANT_PACKAGE_USED = new ErrorCode(1002015001, "租户正在使用该套餐,请给租户重新设置套餐后再尝试删除");
|
||||||
|
ErrorCode TENANT_PACKAGE_DISABLE = new ErrorCode(1002015002, "名字为【{}】的租户套餐已被禁用");
|
||||||
|
|
||||||
// ========== 错误码模块 1002016000 ==========
|
// ========== 错误码模块 1002016000 ==========
|
||||||
ErrorCode ERROR_CODE_NOT_EXISTS = new ErrorCode(1002016000, "错误码不存在");
|
ErrorCode ERROR_CODE_NOT_EXISTS = new ErrorCode(1002016000, "错误码不存在");
|
||||||
|
@ -40,7 +40,7 @@ public class RoleController {
|
|||||||
@ApiOperation("创建角色")
|
@ApiOperation("创建角色")
|
||||||
@PreAuthorize("@ss.hasPermission('system:role:create')")
|
@PreAuthorize("@ss.hasPermission('system:role:create')")
|
||||||
public CommonResult<Long> createRole(@Valid @RequestBody RoleCreateReqVO reqVO) {
|
public CommonResult<Long> createRole(@Valid @RequestBody RoleCreateReqVO reqVO) {
|
||||||
return success(roleService.createRole(reqVO));
|
return success(roleService.createRole(reqVO, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/update")
|
@PutMapping("/update")
|
||||||
@ -88,7 +88,7 @@ public class RoleController {
|
|||||||
public CommonResult<List<RoleSimpleRespVO>> getSimpleRoles() {
|
public CommonResult<List<RoleSimpleRespVO>> getSimpleRoles() {
|
||||||
// 获得角色列表,只要开启状态的
|
// 获得角色列表,只要开启状态的
|
||||||
List<RoleDO> list = roleService.getRoles(Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
|
List<RoleDO> list = roleService.getRoles(Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||||
// 排序后,返回个诶前端
|
// 排序后,返回给前端
|
||||||
list.sort(Comparator.comparing(RoleDO::getSort));
|
list.sort(Comparator.comparing(RoleDO::getSort));
|
||||||
return success(RoleConvert.INSTANCE.convertList02(list));
|
return success(RoleConvert.INSTANCE.convertList02(list));
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,6 @@ public class RoleBaseVO {
|
|||||||
@NotNull(message = "显示顺序不能为空")
|
@NotNull(message = "显示顺序不能为空")
|
||||||
private Integer sort;
|
private Integer sort;
|
||||||
|
|
||||||
@ApiModelProperty(value = "角色类型", required = true, example = "1", notes = "见 RoleTypeEnum 枚举")
|
|
||||||
private Integer type;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "备注", example = "我是一个角色")
|
@ApiModelProperty(value = "备注", example = "我是一个角色")
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
### 创建租户 /admin-api/system/tenant/create
|
||||||
|
POST {{baseUrl}}/system/tenant/create
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer {{token}}
|
||||||
|
tenant-id: {{adminTenentId}}
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "芋道",
|
||||||
|
"contactName": "芋艿",
|
||||||
|
"contactMobile": "15601691300",
|
||||||
|
"status": 0,
|
||||||
|
"domain": "https://www.iocoder.cn",
|
||||||
|
"packageId": 110,
|
||||||
|
"expireTime": 1699545600000,
|
||||||
|
"accountCount": 20,
|
||||||
|
"username": "admin",
|
||||||
|
"password": "123321"
|
||||||
|
}
|
@ -1,11 +1,9 @@
|
|||||||
package cn.iocoder.yudao.module.system.controller.admin.tenant;
|
package cn.iocoder.yudao.module.system.controller.admin.tenant;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageCreateReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.*;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackagePageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageRespVO;
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageUpdateReqVO;
|
|
||||||
import cn.iocoder.yudao.module.system.convert.tenant.TenantPackageConvert;
|
import cn.iocoder.yudao.module.system.convert.tenant.TenantPackageConvert;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO;
|
||||||
import cn.iocoder.yudao.module.system.service.tenant.TenantPackageService;
|
import cn.iocoder.yudao.module.system.service.tenant.TenantPackageService;
|
||||||
@ -82,4 +80,12 @@ public class TenantPackageController {
|
|||||||
return success(TenantPackageConvert.INSTANCE.convertPage(pageResult));
|
return success(TenantPackageConvert.INSTANCE.convertPage(pageResult));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get-simple-list")
|
||||||
|
@ApiOperation(value = "获取租户套餐精简信息列表", notes = "只包含被开启的租户套餐,主要用于前端的下拉选项")
|
||||||
|
public CommonResult<List<TenantPackageSimpleRespVO>> getTenantPackageList() {
|
||||||
|
// 获得角色列表,只要开启状态的
|
||||||
|
List<TenantPackageDO> list = tenantPackageService.getTenantPackageListByStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
return success(TenantPackageConvert.INSTANCE.convertList02(list));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@ApiModel("管理后台 - 租户套餐精简 Response VO")
|
||||||
|
@Data
|
||||||
|
public class TenantPackageSimpleRespVO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "套餐编号", required = true, example = "1024")
|
||||||
|
@NotNull(message = "套餐编号不能为空")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "套餐名", required = true, example = "VIP")
|
||||||
|
@NotNull(message = "套餐名不能为空")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
}
|
@ -2,7 +2,10 @@ package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant;
|
|||||||
|
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import io.swagger.annotations.*;
|
import io.swagger.annotations.*;
|
||||||
|
import org.hibernate.validator.constraints.URL;
|
||||||
|
|
||||||
import javax.validation.constraints.*;
|
import javax.validation.constraints.*;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 租户 Base VO,提供给添加、修改、详细的子 VO 使用
|
* 租户 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||||
@ -22,8 +25,24 @@ public class TenantBaseVO {
|
|||||||
@ApiModelProperty(value = "联系手机", example = "15601691300")
|
@ApiModelProperty(value = "联系手机", example = "15601691300")
|
||||||
private String contactMobile;
|
private String contactMobile;
|
||||||
|
|
||||||
@ApiModelProperty(value = "租户状态(0正常 1停用)", required = true, example = "1")
|
@ApiModelProperty(value = "租户状态", required = true, example = "1")
|
||||||
@NotNull(message = "租户状态(0正常 1停用)不能为空")
|
@NotNull(message = "租户状态")
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "绑定域名", example = "https://www.iocoder.cn")
|
||||||
|
@URL(message = "绑定域名的地址非 URL 格式")
|
||||||
|
private String domain;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "租户套餐编号", required = true, example = "1024")
|
||||||
|
@NotNull(message = "租户套餐编号不能为空")
|
||||||
|
private Long packageId;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "过期时间", required = true)
|
||||||
|
@NotNull(message = "过期时间不能为空")
|
||||||
|
private Date expireTime;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "账号数量", required = true, example = "1024")
|
||||||
|
@NotNull(message = "账号数量不能为空")
|
||||||
|
private Integer accountCount;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,12 @@ package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant;
|
|||||||
|
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import io.swagger.annotations.*;
|
import io.swagger.annotations.*;
|
||||||
|
import org.hibernate.validator.constraints.Length;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.Pattern;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
|
||||||
@ApiModel("管理后台 - 租户创建 Request VO")
|
@ApiModel("管理后台 - 租户创建 Request VO")
|
||||||
@Data
|
@Data
|
||||||
@ -9,4 +15,15 @@ import io.swagger.annotations.*;
|
|||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
public class TenantCreateReqVO extends TenantBaseVO {
|
public class TenantCreateReqVO extends TenantBaseVO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "用户账号", required = true, example = "yudao")
|
||||||
|
@NotBlank(message = "用户账号不能为空")
|
||||||
|
@Pattern(regexp = "^[a-zA-Z0-9]{4,30}$", message = "用户账号由 数字、字母 组成")
|
||||||
|
@Size(min = 4, max = 30, message = "用户账号长度为 4-30 个字符")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "密码", required = true, example = "123456")
|
||||||
|
@NotEmpty(message = "密码不能为空")
|
||||||
|
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
|
||||||
|
private String password;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package cn.iocoder.yudao.module.system.controller.admin.user.vo.user;
|
package cn.iocoder.yudao.module.system.controller.admin.user.vo.user;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.validation.Mobile;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.hibernate.validator.constraints.Length;
|
|
||||||
|
|
||||||
import javax.validation.constraints.Email;
|
import javax.validation.constraints.Email;
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
@ -42,7 +42,7 @@ public class UserBaseVO {
|
|||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
@ApiModelProperty(value = "手机号码", example = "15601691300")
|
@ApiModelProperty(value = "手机号码", example = "15601691300")
|
||||||
@Length(min = 11, max = 11, message = "手机号长度必须 11 位")
|
@Mobile
|
||||||
private String mobile;
|
private String mobile;
|
||||||
|
|
||||||
@ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SexEnum 枚举类")
|
@ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SexEnum 枚举类")
|
||||||
|
@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.convert.permission;
|
|||||||
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.*;
|
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.*;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
|
||||||
|
import cn.iocoder.yudao.module.system.service.permission.bo.RoleCreateReqBO;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
@ -22,4 +23,6 @@ public interface RoleConvert {
|
|||||||
|
|
||||||
List<RoleExcelVO> convertList03(List<RoleDO> list);
|
List<RoleExcelVO> convertList03(List<RoleDO> list);
|
||||||
|
|
||||||
|
RoleDO convert(RoleCreateReqBO bean);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package cn.iocoder.yudao.module.system.convert.tenant;
|
package cn.iocoder.yudao.module.system.convert.tenant;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantCreateReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantExcelVO;
|
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantExcelVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantRespVO;
|
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantRespVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantUpdateReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantUpdateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
@ -33,4 +34,12 @@ public interface TenantConvert {
|
|||||||
|
|
||||||
List<TenantExcelVO> convertList02(List<TenantDO> list);
|
List<TenantExcelVO> convertList02(List<TenantDO> list);
|
||||||
|
|
||||||
|
default UserCreateReqVO convert02(TenantCreateReqVO bean) {
|
||||||
|
UserCreateReqVO reqVO = new UserCreateReqVO();
|
||||||
|
reqVO.setUsername(bean.getUsername());
|
||||||
|
reqVO.setPassword(bean.getPassword());
|
||||||
|
reqVO.setNickname(bean.getContactName()).setMobile(bean.getContactMobile());
|
||||||
|
return reqVO;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package cn.iocoder.yudao.module.system.convert.tenant;
|
package cn.iocoder.yudao.module.system.convert.tenant;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleSimpleRespVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageCreateReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageRespVO;
|
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageRespVO;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageSimpleRespVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageUpdateReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
@ -30,4 +32,6 @@ public interface TenantPackageConvert {
|
|||||||
|
|
||||||
PageResult<TenantPackageRespVO> convertPage(PageResult<TenantPackageDO> page);
|
PageResult<TenantPackageRespVO> convertPage(PageResult<TenantPackageDO> page);
|
||||||
|
|
||||||
|
List<TenantPackageSimpleRespVO> convertList02(List<TenantPackageDO> list);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
|||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
|
import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
|
||||||
import cn.iocoder.yudao.framework.security.core.enums.DataScopeEnum;
|
import cn.iocoder.yudao.framework.security.core.enums.DataScopeEnum;
|
||||||
|
import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
@ -50,7 +51,7 @@ public class RoleDO extends BaseDO {
|
|||||||
/**
|
/**
|
||||||
* 角色类型
|
* 角色类型
|
||||||
*
|
*
|
||||||
* 枚举
|
* 枚举 {@link RoleTypeEnum}
|
||||||
*/
|
*/
|
||||||
private Integer type;
|
private Integer type;
|
||||||
/**
|
/**
|
||||||
|
@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.Tenant
|
|||||||
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 租户套餐 Mapper
|
* 租户套餐 Mapper
|
||||||
*
|
*
|
||||||
@ -24,4 +26,7 @@ public interface TenantPackageMapper extends BaseMapperX<TenantPackageDO> {
|
|||||||
.orderByDesc(TenantPackageDO::getId));
|
.orderByDesc(TenantPackageDO::getId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default List<TenantPackageDO> selectListByStatus(Integer status) {
|
||||||
|
return selectList(TenantPackageDO::getStatus, status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,8 +224,6 @@ public class PermissionServiceImpl implements PermissionService {
|
|||||||
UserRoleDO::getRoleId);
|
UserRoleDO::getRoleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void assignUserRole(Long userId, Set<Long> roleIds) {
|
public void assignUserRole(Long userId, Set<Long> roleIds) {
|
||||||
// 获得角色拥有角色编号
|
// 获得角色拥有角色编号
|
||||||
|
@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleUp
|
|||||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -28,16 +29,17 @@ public interface RoleService {
|
|||||||
* 创建角色
|
* 创建角色
|
||||||
*
|
*
|
||||||
* @param reqVO 创建角色信息
|
* @param reqVO 创建角色信息
|
||||||
|
* @param type 角色类型
|
||||||
* @return 角色编号
|
* @return 角色编号
|
||||||
*/
|
*/
|
||||||
Long createRole(RoleCreateReqVO reqVO);
|
Long createRole(@Valid RoleCreateReqVO reqVO, Integer type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新角色
|
* 更新角色
|
||||||
*
|
*
|
||||||
* @param reqVO 更新角色信息
|
* @param reqVO 更新角色信息
|
||||||
*/
|
*/
|
||||||
void updateRole(RoleUpdateReqVO reqVO);
|
void updateRole(@Valid RoleUpdateReqVO reqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除角色
|
* 删除角色
|
||||||
|
@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.service.permission;
|
|||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
@ -120,12 +121,12 @@ public class RoleServiceImpl implements RoleService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long createRole(RoleCreateReqVO reqVO) {
|
public Long createRole(RoleCreateReqVO reqVO, Integer type) {
|
||||||
// 校验角色
|
// 校验角色
|
||||||
checkDuplicateRole(reqVO.getName(), reqVO.getCode(), null);
|
checkDuplicateRole(reqVO.getName(), reqVO.getCode(), null);
|
||||||
// 插入到数据库
|
// 插入到数据库
|
||||||
RoleDO role = RoleConvert.INSTANCE.convert(reqVO);
|
RoleDO role = RoleConvert.INSTANCE.convert(reqVO);
|
||||||
role.setType(RoleTypeEnum.CUSTOM.getType());
|
role.setType(ObjectUtil.defaultIfNull(type, RoleTypeEnum.CUSTOM.getType()));
|
||||||
role.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
role.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
role.setDataScope(DataScopeEnum.ALL.getScope()); // 默认可查看所有数据。原因是,可能一些项目不需要项目权限
|
role.setDataScope(DataScopeEnum.ALL.getScope()); // 默认可查看所有数据。原因是,可能一些项目不需要项目权限
|
||||||
roleMapper.insert(role);
|
roleMapper.insert(role);
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.service.permission.bo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色创建 Request BO
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class RoleCreateReqBO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 租户编号
|
||||||
|
*/
|
||||||
|
@NotNull(message = "租户编号不能为空")
|
||||||
|
private Long tenantId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色名称
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "角色名称不能为空")
|
||||||
|
@Size(max = 30, message = "角色名称长度不能超过30个字符")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色标志
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "角色标志不能为空")
|
||||||
|
@Size(max = 100, message = "角色标志长度不能超过100个字符")
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示顺序
|
||||||
|
*/
|
||||||
|
@NotNull(message = "显示顺序不能为空")
|
||||||
|
private Integer sort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色类型
|
||||||
|
*/
|
||||||
|
@NotNull(message = "角色类型不能为空")
|
||||||
|
private Integer type;
|
||||||
|
|
||||||
|
}
|
@ -63,4 +63,20 @@ public interface TenantPackageService {
|
|||||||
*/
|
*/
|
||||||
PageResult<TenantPackageDO> getTenantPackagePage(TenantPackagePageReqVO pageReqVO);
|
PageResult<TenantPackageDO> getTenantPackagePage(TenantPackagePageReqVO pageReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验租户套餐
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
* @return 租户套餐
|
||||||
|
*/
|
||||||
|
TenantPackageDO validTenantPackage(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得指定状态的租户套餐列表
|
||||||
|
*
|
||||||
|
* @param status 状态
|
||||||
|
* @return 租户套餐
|
||||||
|
*/
|
||||||
|
List<TenantPackageDO> getTenantPackageListByStatus(Integer status);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cn.iocoder.yudao.module.system.service.tenant;
|
package cn.iocoder.yudao.module.system.service.tenant;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageCreateReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackagePageReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackagePageReqVO;
|
||||||
@ -7,6 +8,7 @@ import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.Tenant
|
|||||||
import cn.iocoder.yudao.module.system.convert.tenant.TenantPackageConvert;
|
import cn.iocoder.yudao.module.system.convert.tenant.TenantPackageConvert;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantPackageMapper;
|
import cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantPackageMapper;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
@ -15,8 +17,7 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.TENANT_PACKAGE_NOT_EXISTS;
|
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.TENANT_PACKAGE_USED;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 租户套餐 Service 实现类
|
* 租户套餐 Service 实现类
|
||||||
@ -31,6 +32,7 @@ public class TenantPackageServiceImpl implements TenantPackageService {
|
|||||||
private TenantPackageMapper tenantPackageMapper;
|
private TenantPackageMapper tenantPackageMapper;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
|
@Lazy // 避免循环依赖的报错
|
||||||
private TenantService tenantService;
|
private TenantService tenantService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -88,4 +90,21 @@ public class TenantPackageServiceImpl implements TenantPackageService {
|
|||||||
return tenantPackageMapper.selectPage(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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
package cn.iocoder.yudao.module.system.service.tenant;
|
package cn.iocoder.yudao.module.system.service.tenant;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantCreateReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantExportReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantExportReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
|
||||||
@ -9,15 +13,22 @@ import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantUp
|
|||||||
import cn.iocoder.yudao.module.system.convert.tenant.TenantConvert;
|
import cn.iocoder.yudao.module.system.convert.tenant.TenantConvert;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantMapper;
|
import cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantMapper;
|
||||||
|
import cn.iocoder.yudao.module.system.enums.permission.RoleCodeEnum;
|
||||||
|
import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.system.service.permission.PermissionService;
|
||||||
|
import cn.iocoder.yudao.module.system.service.permission.RoleService;
|
||||||
|
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.TENANT_NOT_EXISTS;
|
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 租户 Service 实现类
|
* 租户 Service 实现类
|
||||||
@ -31,6 +42,15 @@ public class TenantServiceImpl implements TenantService {
|
|||||||
@Resource
|
@Resource
|
||||||
private TenantMapper tenantMapper;
|
private TenantMapper tenantMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TenantPackageService tenantPackageService;
|
||||||
|
@Resource
|
||||||
|
private AdminUserService userService;
|
||||||
|
@Resource
|
||||||
|
private RoleService roleService;
|
||||||
|
@Resource
|
||||||
|
private PermissionService permissionService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Long> getTenantIds() {
|
public List<Long> getTenantIds() {
|
||||||
List<TenantDO> tenants = tenantMapper.selectList();
|
List<TenantDO> tenants = tenantMapper.selectList();
|
||||||
@ -38,18 +58,62 @@ public class TenantServiceImpl implements TenantService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public void validTenant(Long id) {
|
||||||
|
TenantDO tenant = tenantMapper.selectById(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
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public Long createTenant(TenantCreateReqVO createReqVO) {
|
public Long createTenant(TenantCreateReqVO createReqVO) {
|
||||||
// 插入
|
// 校验套餐被禁用
|
||||||
|
tenantPackageService.validTenantPackage(createReqVO.getPackageId());
|
||||||
|
|
||||||
|
// 创建租户
|
||||||
TenantDO tenant = TenantConvert.INSTANCE.convert(createReqVO);
|
TenantDO tenant = TenantConvert.INSTANCE.convert(createReqVO);
|
||||||
tenantMapper.insert(tenant);
|
tenantMapper.insert(tenant);
|
||||||
|
|
||||||
|
TenantUtils.execute(tenant.getId(), () -> {
|
||||||
|
// 创建角色
|
||||||
|
Long roleId = createRole();
|
||||||
|
// 创建用户,并分配角色
|
||||||
|
Long userId = createUser(roleId, createReqVO);
|
||||||
|
// 修改租户的管理员
|
||||||
|
tenantMapper.updateById(new TenantDO().setId(tenant.getId()).setContactUserId(userId));
|
||||||
|
});
|
||||||
// 返回
|
// 返回
|
||||||
return tenant.getId();
|
return tenant.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Long createUser(Long roleId, TenantCreateReqVO createReqVO) {
|
||||||
|
// 创建用户
|
||||||
|
Long userId = userService.createUser(TenantConvert.INSTANCE.convert02(createReqVO));
|
||||||
|
// 分配角色
|
||||||
|
permissionService.assignUserRole(userId, Collections.singleton(roleId));
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long createRole() {
|
||||||
|
RoleCreateReqVO reqVO = new RoleCreateReqVO();
|
||||||
|
reqVO.setName(RoleCodeEnum.ADMIN.name()).setCode(RoleCodeEnum.ADMIN.getKey()).setSort(0);
|
||||||
|
return roleService.createRole(reqVO, RoleTypeEnum.SYSTEM.getType());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateTenant(TenantUpdateReqVO updateReqVO) {
|
public void updateTenant(TenantUpdateReqVO updateReqVO) {
|
||||||
// 校验存在
|
// 校验存在
|
||||||
this.validateTenantExists(updateReqVO.getId());
|
this.validateTenantExists(updateReqVO.getId());
|
||||||
|
// 校验套餐被禁用
|
||||||
|
tenantPackageService.validTenantPackage(updateReqVO.getPackageId());
|
||||||
|
|
||||||
// 更新
|
// 更新
|
||||||
TenantDO updateObj = TenantConvert.INSTANCE.convert(updateReqVO);
|
TenantDO updateObj = TenantConvert.INSTANCE.convert(updateReqVO);
|
||||||
tenantMapper.updateById(updateObj);
|
tenantMapper.updateById(updateObj);
|
||||||
|
@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.*;
|
|||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -24,14 +25,14 @@ public interface AdminUserService {
|
|||||||
* @param reqVO 用户信息
|
* @param reqVO 用户信息
|
||||||
* @return 用户编号
|
* @return 用户编号
|
||||||
*/
|
*/
|
||||||
Long createUser(UserCreateReqVO reqVO);
|
Long createUser(@Valid UserCreateReqVO reqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改用户
|
* 修改用户
|
||||||
*
|
*
|
||||||
* @param reqVO 用户信息
|
* @param reqVO 用户信息
|
||||||
*/
|
*/
|
||||||
void updateUser(UserUpdateReqVO reqVO);
|
void updateUser(@Valid UserUpdateReqVO reqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新用户的最后登陆信息
|
* 更新用户的最后登陆信息
|
||||||
@ -47,7 +48,7 @@ public interface AdminUserService {
|
|||||||
* @param id 用户编号
|
* @param id 用户编号
|
||||||
* @param reqVO 用户个人信息
|
* @param reqVO 用户个人信息
|
||||||
*/
|
*/
|
||||||
void updateUserProfile(Long id, UserProfileUpdateReqVO reqVO);
|
void updateUserProfile(Long id, @Valid UserProfileUpdateReqVO reqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改用户个人密码
|
* 修改用户个人密码
|
||||||
@ -55,7 +56,7 @@ public interface AdminUserService {
|
|||||||
* @param id 用户编号
|
* @param id 用户编号
|
||||||
* @param reqVO 更新用户个人密码
|
* @param reqVO 更新用户个人密码
|
||||||
*/
|
*/
|
||||||
void updateUserPassword(Long id, UserProfileUpdatePasswordReqVO reqVO);
|
void updateUserPassword(Long id, @Valid UserProfileUpdatePasswordReqVO reqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新用户头像
|
* 更新用户头像
|
||||||
|
@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.system.service.user;
|
|||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.io.IoUtil;
|
import cn.hutool.core.io.IoUtil;
|
||||||
import cn.hutool.core.util.IdUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||||
@ -258,7 +257,7 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||||||
// 校验邮箱唯一
|
// 校验邮箱唯一
|
||||||
this.checkEmailUnique(id, email);
|
this.checkEmailUnique(id, email);
|
||||||
// 校验部门处于开启状态
|
// 校验部门处于开启状态
|
||||||
deptService.validDepts(Collections.singleton(deptId));
|
deptService.validDepts(CollectionUtils.singleton(deptId));
|
||||||
// 校验岗位处于开启状态
|
// 校验岗位处于开启状态
|
||||||
postService.validPosts(postIds);
|
postService.validPosts(postIds);
|
||||||
}
|
}
|
||||||
|
@ -72,10 +72,9 @@ public class RoleServiceTest extends BaseDbUnitTest {
|
|||||||
o.setCode("role_code");
|
o.setCode("role_code");
|
||||||
o.setName("role_name");
|
o.setName("role_name");
|
||||||
o.setRemark("remark");
|
o.setRemark("remark");
|
||||||
o.setType(RoleTypeEnum.CUSTOM.getType());
|
|
||||||
o.setSort(1);
|
o.setSort(1);
|
||||||
});
|
});
|
||||||
Long roleId = sysRoleService.createRole(reqVO);
|
Long roleId = sysRoleService.createRole(reqVO, null);
|
||||||
|
|
||||||
//断言
|
//断言
|
||||||
assertNotNull(roleId);
|
assertNotNull(roleId);
|
||||||
@ -96,7 +95,6 @@ public class RoleServiceTest extends BaseDbUnitTest {
|
|||||||
o.setId(roleId);
|
o.setId(roleId);
|
||||||
o.setCode("role_code");
|
o.setCode("role_code");
|
||||||
o.setName("update_name");
|
o.setName("update_name");
|
||||||
o.setType(RoleTypeEnum.SYSTEM.getType());
|
|
||||||
o.setSort(999);
|
o.setSort(999);
|
||||||
});
|
});
|
||||||
sysRoleService.updateRole(reqVO);
|
sysRoleService.updateRole(reqVO);
|
||||||
|
@ -80,7 +80,7 @@ yudao:
|
|||||||
tenant: # 多租户相关配置项
|
tenant: # 多租户相关配置项
|
||||||
enable: true
|
enable: true
|
||||||
ignore-urls: /admin-api/system/captcha/get-image, /admin-api/infra/file/get/*
|
ignore-urls: /admin-api/system/captcha/get-image, /admin-api/infra/file/get/*
|
||||||
ignore-tables: infra_config, infra_file, infra_job, infra_job_log, infra_job_log, system_tenant, system_tenant_package, system_dict_data, system_dict_type, system_error_code, system_menu, system_role, system_role_menu, system_sms_channel, tool_codegen_column, tool_codegen_table, tool_test_demo, tables, columns
|
ignore-tables: infra_config, infra_file, infra_job, infra_job_log, infra_job_log, system_tenant, system_tenant_package, system_dict_data, system_dict_type, system_error_code, system_menu, system_sms_channel, tool_codegen_column, tool_codegen_table, tool_test_demo, tables, columns
|
||||||
sms-code: # 短信验证码相关的配置项
|
sms-code: # 短信验证码相关的配置项
|
||||||
expire-times: 10m
|
expire-times: 10m
|
||||||
send-frequency: 1m
|
send-frequency: 1m
|
||||||
|
@ -43,12 +43,10 @@ export function getTenantPackagePage(query) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 导出租户套餐 Excel
|
// 获取租户套餐精简信息列表
|
||||||
export function exportTenantPackageExcel(query) {
|
export function getTenantPackageList() {
|
||||||
return request({
|
return request({
|
||||||
url: '/system/tenant-package/export-excel',
|
url: '/system/tenant-package/get-simple-list',
|
||||||
method: 'get',
|
method: 'get'
|
||||||
params: query,
|
|
||||||
responseType: 'blob'
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,6 @@
|
|||||||
:key="dict.value" :label="dict.label" :value="dict.value"/>
|
:key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="创建时间">
|
|
||||||
<el-date-picker v-model="dateRangeCreateTime" size="small" style="width: 240px" value-format="yyyy-MM-dd"
|
|
||||||
type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
@ -45,8 +41,24 @@
|
|||||||
<el-table v-loading="loading" :data="list">
|
<el-table v-loading="loading" :data="list">
|
||||||
<el-table-column label="租户编号" align="center" prop="id" />
|
<el-table-column label="租户编号" align="center" prop="id" />
|
||||||
<el-table-column label="租户名" align="center" prop="name" />
|
<el-table-column label="租户名" align="center" prop="name" />
|
||||||
|
<el-table-column label="租户套餐" align="center" prop="packageId">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag> {{getPackageName(scope.row.packageId)}} </el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="联系人" align="center" prop="contactName" />
|
<el-table-column label="联系人" align="center" prop="contactName" />
|
||||||
<el-table-column label="联系手机" align="center" prop="contactMobile" />
|
<el-table-column label="联系手机" align="center" prop="contactMobile" />
|
||||||
|
<el-table-column label="账号额度" align="center" prop="accountCount">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag> {{scope.row.accountCount}} </el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="过期时间" align="center" prop="expireTime" width="180">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ parseTime(scope.row.expireTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="绑定域名" align="center" prop="domain" width="180" />
|
||||||
<el-table-column label="租户状态" align="center" prop="status">
|
<el-table-column label="租户状态" align="center" prop="status">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/>
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/>
|
||||||
@ -76,12 +88,33 @@
|
|||||||
<el-form-item label="租户名" prop="name">
|
<el-form-item label="租户名" prop="name">
|
||||||
<el-input v-model="form.name" placeholder="请输入租户名" />
|
<el-input v-model="form.name" placeholder="请输入租户名" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="租户套餐" prop="packageId">
|
||||||
|
<el-select v-model="form.packageId" placeholder="请选择租户套餐" clearable size="small">
|
||||||
|
<el-option v-for="item in packageList" :key="item.id" :label="item.name" :value="item.id"/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="联系人" prop="contactName">
|
<el-form-item label="联系人" prop="contactName">
|
||||||
<el-input v-model="form.contactName" placeholder="请输入联系人" />
|
<el-input v-model="form.contactName" placeholder="请输入联系人" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="联系手机" prop="contactMobile">
|
<el-form-item label="联系手机" prop="contactMobile">
|
||||||
<el-input v-model="form.contactMobile" placeholder="请输入联系手机" />
|
<el-input v-model="form.contactMobile" placeholder="请输入联系手机" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item v-if="form.id === undefined" label="用户名称" prop="username">
|
||||||
|
<el-input v-model="form.username" placeholder="请输入用户名称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="form.id === undefined" label="用户密码" prop="password">
|
||||||
|
<el-input v-model="form.password" placeholder="请输入用户密码" type="password" show-password />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="账号额度" prop="accountCount">
|
||||||
|
<el-input-number v-model="form.accountCount" placeholder="请输入账号额度" controls-position="right" :min="0" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="过期时间" prop="expireTime">
|
||||||
|
<el-date-picker clearable size="small" v-model="form.expireTime" type="date"
|
||||||
|
value-format="timestamp" placeholder="请选择过期时间" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="绑定域名" prop="domain">
|
||||||
|
<el-input v-model="form.domain" placeholder="请输入绑定域名" />
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="租户状态" prop="status">
|
<el-form-item label="租户状态" prop="status">
|
||||||
<el-radio-group v-model="form.status">
|
<el-radio-group v-model="form.status">
|
||||||
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)"
|
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)"
|
||||||
@ -100,6 +133,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { createTenant, updateTenant, deleteTenant, getTenant, getTenantPage, exportTenantExcel } from "@/api/system/tenant";
|
import { createTenant, updateTenant, deleteTenant, getTenant, getTenantPage, exportTenantExcel } from "@/api/system/tenant";
|
||||||
import { CommonStatusEnum } from '@/utils/constants'
|
import { CommonStatusEnum } from '@/utils/constants'
|
||||||
|
import {getTenantPackageList} from "@/api/system/tenantPackage";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Tenant",
|
name: "Tenant",
|
||||||
@ -117,6 +151,8 @@ export default {
|
|||||||
total: 0,
|
total: 0,
|
||||||
// 租户列表
|
// 租户列表
|
||||||
list: [],
|
list: [],
|
||||||
|
// 租户套餐列表
|
||||||
|
packageList: [],
|
||||||
// 弹出层标题
|
// 弹出层标题
|
||||||
title: "",
|
title: "",
|
||||||
// 是否显示弹出层
|
// 是否显示弹出层
|
||||||
@ -136,13 +172,23 @@ export default {
|
|||||||
// 表单校验
|
// 表单校验
|
||||||
rules: {
|
rules: {
|
||||||
name: [{ required: true, message: "租户名不能为空", trigger: "blur" }],
|
name: [{ required: true, message: "租户名不能为空", trigger: "blur" }],
|
||||||
|
packageId: [{ required: true, message: "租户套餐不能为空", trigger: "blur" }],
|
||||||
contactName: [{ required: true, message: "联系人不能为空", trigger: "blur" }],
|
contactName: [{ required: true, message: "联系人不能为空", trigger: "blur" }],
|
||||||
status: [{ required: true, message: "租户状态(0正常 1停用)不能为空", trigger: "blur" }],
|
status: [{ required: true, message: "租户状态不能为空", trigger: "blur" }],
|
||||||
|
accountCount: [{ required: true, message: "账号额度不能为空", trigger: "blur" }],
|
||||||
|
expireTime: [{ required: true, message: "过期时间不能为空", trigger: "blur" }],
|
||||||
|
domain: [{ required: true, message: "绑定域名不能为空", trigger: "blur" }],
|
||||||
|
username: [{ required: true, message: "用户名称不能为空", trigger: "blur" }],
|
||||||
|
password: [{ required: true, message: "用户密码不能为空", trigger: "blur" }],
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getList();
|
this.getList();
|
||||||
|
// 获得租户套餐列表
|
||||||
|
getTenantPackageList().then(response => {
|
||||||
|
this.packageList = response.data;
|
||||||
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/** 查询列表 */
|
/** 查询列表 */
|
||||||
@ -168,8 +214,12 @@ export default {
|
|||||||
this.form = {
|
this.form = {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
|
packageId: undefined,
|
||||||
contactName: undefined,
|
contactName: undefined,
|
||||||
contactMobile: undefined,
|
contactMobile: undefined,
|
||||||
|
accountCount: undefined,
|
||||||
|
expireTime: undefined,
|
||||||
|
domain: undefined,
|
||||||
status: CommonStatusEnum.ENABLE,
|
status: CommonStatusEnum.ENABLE,
|
||||||
};
|
};
|
||||||
this.resetForm("form");
|
this.resetForm("form");
|
||||||
@ -249,6 +299,15 @@ export default {
|
|||||||
this.$download.excel(response, '租户.xls');
|
this.$download.excel(response, '租户.xls');
|
||||||
this.exportLoading = false;
|
this.exportLoading = false;
|
||||||
}).catch(() => {});
|
}).catch(() => {});
|
||||||
|
},
|
||||||
|
/** 套餐名格式化 */
|
||||||
|
getPackageName(packageId) {
|
||||||
|
for (const item of this.packageList) {
|
||||||
|
if (item.id === packageId) {
|
||||||
|
return item.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '未知套餐';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
3
更新日志.md
3
更新日志.md
@ -29,7 +29,8 @@ TODO
|
|||||||
* 【新增】后端 `yudao.tenant.enable` 配置项,前端 `VUE_APP_TENANT_ENABLE` 配置项,用于开关租户功能。 [commit](https://gitee.com/zhijiantianya/ruoyi-vue-pro/commit/79311ecc71f0c6beabe0e5f84e1423ce745a5f09)
|
* 【新增】后端 `yudao.tenant.enable` 配置项,前端 `VUE_APP_TENANT_ENABLE` 配置项,用于开关租户功能。 [commit](https://gitee.com/zhijiantianya/ruoyi-vue-pro/commit/79311ecc71f0c6beabe0e5f84e1423ce745a5f09)
|
||||||
* 【优化】调整默认所有表开启多租户的特性,可通过 `yudao.tenant.ignore-tables` 配置项进行忽略,替代原本默认不开启的策略 [commit](https://gitee.com/zhijiantianya/ruoyi-vue-pro/commit/79311ecc71f0c6beabe0e5f84e1423ce745a5f09)
|
* 【优化】调整默认所有表开启多租户的特性,可通过 `yudao.tenant.ignore-tables` 配置项进行忽略,替代原本默认不开启的策略 [commit](https://gitee.com/zhijiantianya/ruoyi-vue-pro/commit/79311ecc71f0c6beabe0e5f84e1423ce745a5f09)
|
||||||
* 【新增】通过 `yudao.tenant.ignore-urls` 配置忽略多租户的请求,例如说 ,例如说短信回调、支付回调等 Open API [commit](https://gitee.com/zhijiantianya/ruoyi-vue-pro/commit/79311ecc71f0c6beabe0e5f84e1423ce745a5f09)
|
* 【新增】通过 `yudao.tenant.ignore-urls` 配置忽略多租户的请求,例如说 ,例如说短信回调、支付回调等 Open API [commit](https://gitee.com/zhijiantianya/ruoyi-vue-pro/commit/79311ecc71f0c6beabe0e5f84e1423ce745a5f09)
|
||||||
* 【新增】租户套餐的管理,可配置每个租户的可使用的功能
|
* 【新增】租户套餐的管理,可配置每个租户的可使用的功能权限 [commit](https://gitee.com/zhijiantianya/ruoyi-vue-pro/commit/6b6d676a6baa2dad16ae9bf03d5002209064c8cc)
|
||||||
|
* 【优化】新建租户时,自动创建对应的管理员账号、角色等基础信息 []()
|
||||||
|
|
||||||
### 🐞 Bug Fixes
|
### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user