mirror of
https://github.com/continew-org/continew-admin.git
synced 2025-09-08 12:57:13 +08:00
feat(plugin/tenant): 新增多租户插件模块 (#175)
This commit is contained in:
@@ -19,6 +19,7 @@ package top.continew.admin.auth;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
@@ -36,10 +37,13 @@ import top.continew.admin.system.service.DeptService;
|
||||
import top.continew.admin.system.service.OptionService;
|
||||
import top.continew.admin.system.service.RoleService;
|
||||
import top.continew.admin.system.service.UserService;
|
||||
import top.continew.starter.core.util.ServletUtils;
|
||||
import top.continew.starter.core.util.validation.CheckUtils;
|
||||
import top.continew.starter.core.util.validation.Validator;
|
||||
import top.continew.starter.core.util.ServletUtils;
|
||||
import top.continew.starter.extension.tenant.TenantHandler;
|
||||
import top.continew.starter.extension.tenant.context.TenantContextHolder;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@@ -90,10 +94,21 @@ public abstract class AbstractLoginHandler<T extends LoginReq> implements LoginH
|
||||
protected String authenticate(UserDO user, ClientResp client) {
|
||||
// 获取权限、角色、密码过期天数
|
||||
Long userId = user.getId();
|
||||
CompletableFuture<Set<String>> permissionFuture = CompletableFuture.supplyAsync(() -> roleService
|
||||
.listPermissionByUserId(userId), threadPoolTaskExecutor);
|
||||
CompletableFuture<Set<RoleContext>> roleFuture = CompletableFuture.supplyAsync(() -> roleService
|
||||
.listByUserId(userId), threadPoolTaskExecutor);
|
||||
Long tenantId = TenantContextHolder.getTenantId();
|
||||
CompletableFuture<Set<String>> permissionFuture = CompletableFuture.supplyAsync(() -> {
|
||||
Set<String> permissions = new HashSet<>();
|
||||
SpringUtil.getBean(TenantHandler.class).execute(tenantId, () -> {
|
||||
permissions.addAll(roleService.listPermissionByUserId(userId));
|
||||
});
|
||||
return permissions;
|
||||
}, threadPoolTaskExecutor);
|
||||
CompletableFuture<Set<RoleContext>> roleFuture = CompletableFuture.supplyAsync(() -> {
|
||||
Set<RoleContext> roles = new HashSet<>();
|
||||
SpringUtil.getBean(TenantHandler.class).execute(tenantId, () -> {
|
||||
roles.addAll(roleService.listByUserId(userId));
|
||||
});
|
||||
return roles;
|
||||
}, threadPoolTaskExecutor);
|
||||
CompletableFuture<Integer> passwordExpirationDaysFuture = CompletableFuture.supplyAsync(() -> optionService
|
||||
.getValueByCode2Int(PASSWORD_EXPIRATION_DAYS.name()));
|
||||
CompletableFuture.allOf(permissionFuture, roleFuture, passwordExpirationDaysFuture);
|
||||
@@ -108,6 +123,7 @@ public abstract class AbstractLoginHandler<T extends LoginReq> implements LoginH
|
||||
userContext.setClientType(client.getClientType());
|
||||
loginParameter.setExtra(CLIENT_ID, client.getClientId());
|
||||
userContext.setClientId(client.getClientId());
|
||||
userContext.setTenantId(tenantId);
|
||||
// 登录并缓存用户信息
|
||||
StpUtil.login(userContext.getId(), loginParameter.setExtraData(BeanUtil
|
||||
.beanToMap(new UserExtraContext(ServletUtils.getRequest()))));
|
||||
|
@@ -123,4 +123,5 @@ public class AuthServiceImpl implements AuthService {
|
||||
});
|
||||
return BeanUtil.copyToList(treeList, RouteResp.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -29,12 +29,14 @@ import org.springframework.stereotype.Service;
|
||||
import top.continew.admin.auth.model.query.OnlineUserQuery;
|
||||
import top.continew.admin.auth.model.resp.OnlineUserResp;
|
||||
import top.continew.admin.auth.service.OnlineUserService;
|
||||
import top.continew.admin.common.config.properties.TenantProperties;
|
||||
import top.continew.admin.common.context.UserContext;
|
||||
import top.continew.admin.common.context.UserContextHolder;
|
||||
import top.continew.admin.common.context.UserExtraContext;
|
||||
import top.continew.starter.core.constant.StringConstants;
|
||||
import top.continew.starter.extension.crud.model.query.PageQuery;
|
||||
import top.continew.starter.extension.crud.model.resp.PageResp;
|
||||
import top.continew.starter.extension.tenant.context.TenantContextHolder;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
@@ -50,6 +52,8 @@ import java.util.stream.Collectors;
|
||||
@RequiredArgsConstructor
|
||||
public class OnlineUserServiceImpl implements OnlineUserService {
|
||||
|
||||
private final TenantProperties tenantProperties;
|
||||
|
||||
@Override
|
||||
@AutoOperate(type = OnlineUserResp.class, on = "list")
|
||||
public PageResp<OnlineUserResp> page(OnlineUserQuery query, PageQuery pageQuery) {
|
||||
@@ -88,6 +92,12 @@ public class OnlineUserServiceImpl implements OnlineUserService {
|
||||
.isMatchClientId(query.getClientId(), userContext)) {
|
||||
continue;
|
||||
}
|
||||
//租户数据过滤
|
||||
if (tenantProperties.isEnabled()) {
|
||||
if (!TenantContextHolder.getTenantId().equals(userContext.getTenantId())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
List<LocalDateTime> loginTimeList = query.getLoginTime();
|
||||
entry.getValue().parallelStream().forEach(token -> {
|
||||
UserExtraContext extraContext = UserContextHolder.getExtraContext(token);
|
||||
|
@@ -16,6 +16,8 @@
|
||||
|
||||
package top.continew.admin.system.mapper;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import top.continew.admin.common.constant.SysConstants;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import top.continew.admin.system.model.entity.StorageDO;
|
||||
import top.continew.starter.data.mapper.BaseMapper;
|
||||
@@ -26,6 +28,7 @@ import top.continew.starter.data.mapper.BaseMapper;
|
||||
* @author Charles7c
|
||||
* @since 2023/12/26 22:09
|
||||
*/
|
||||
@DS(SysConstants.DEFAULT_DATASOURCE)
|
||||
@Mapper
|
||||
public interface StorageMapper extends BaseMapper<StorageDO> {
|
||||
}
|
@@ -108,4 +108,10 @@ public class UserDO extends BaseDO {
|
||||
* 部门 ID
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 租户 ID
|
||||
*/
|
||||
@TableField(select = false)
|
||||
private Long tenantId;
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ import top.continew.starter.data.enums.QueryType;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 菜单查询条件
|
||||
@@ -56,4 +57,12 @@ public class MenuQuery implements Serializable {
|
||||
public MenuQuery(DisEnableStatusEnum status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* 排除的菜单
|
||||
*/
|
||||
@Schema(description = "排除的菜单")
|
||||
@Query(columns = "id", type = QueryType.NOT_IN)
|
||||
private List<Long> excludeMenuIdList;
|
||||
|
||||
}
|
||||
|
@@ -56,4 +56,12 @@ public interface DeptService extends BaseService<DeptResp, DeptResp, DeptQuery,
|
||||
* @return 部门数量
|
||||
*/
|
||||
int countByNames(List<String> deptNames);
|
||||
|
||||
/**
|
||||
* 初始化租户部门
|
||||
*
|
||||
* @param deptName
|
||||
* @return 部门ID
|
||||
*/
|
||||
Long initTenantDept(String deptName);
|
||||
}
|
||||
|
@@ -34,6 +34,13 @@ import java.util.Set;
|
||||
*/
|
||||
public interface MenuService extends BaseService<MenuResp, MenuResp, MenuQuery, MenuReq>, IService<MenuDO> {
|
||||
|
||||
/**
|
||||
* 查询全部菜单
|
||||
*
|
||||
* @return 菜单列表
|
||||
*/
|
||||
List<MenuResp> listAll(Long tenantId);
|
||||
|
||||
/**
|
||||
* 根据用户 ID 查询
|
||||
*
|
||||
@@ -43,10 +50,35 @@ public interface MenuService extends BaseService<MenuResp, MenuResp, MenuQuery,
|
||||
Set<String> listPermissionByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 根据角色 ID 查询
|
||||
* 根据角色id查询
|
||||
*
|
||||
* @param roleId 角色 ID
|
||||
* @param roleId 角色id
|
||||
* @return 菜单列表
|
||||
*/
|
||||
List<MenuResp> listByRoleId(Long roleId);
|
||||
|
||||
/**
|
||||
* 递归初始化菜单
|
||||
*
|
||||
* @param menuList 需要初始化的菜单ID
|
||||
* @param oldParentId 原来的父级ID
|
||||
* @param newParentId 新的父级ID
|
||||
*/
|
||||
void menuInit(List<MenuDO> menuList, Long oldParentId, Long newParentId);
|
||||
|
||||
/**
|
||||
* 删除租户菜单
|
||||
*
|
||||
* @param menuList
|
||||
*/
|
||||
void deleteTenantMenus(List<MenuDO> menuList);
|
||||
|
||||
/**
|
||||
* 新增租户菜单
|
||||
*
|
||||
* @param menu 新增的菜单
|
||||
* @param pMenu 新增菜单的父级别
|
||||
*/
|
||||
void addTenantMenu(MenuDO menu, MenuDO pMenu);
|
||||
|
||||
}
|
||||
|
@@ -16,6 +16,9 @@
|
||||
|
||||
package top.continew.admin.system.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import top.continew.admin.system.model.entity.RoleMenuDO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -24,7 +27,7 @@ import java.util.List;
|
||||
* @author Charles7c
|
||||
* @since 2023/2/19 10:40
|
||||
*/
|
||||
public interface RoleMenuService {
|
||||
public interface RoleMenuService extends IService<RoleMenuDO> {
|
||||
|
||||
/**
|
||||
* 新增
|
||||
|
@@ -100,4 +100,12 @@ public interface RoleService extends BaseService<RoleResp, RoleDetailResp, RoleQ
|
||||
* @return 角色数量
|
||||
*/
|
||||
int countByNames(List<String> roleNames);
|
||||
|
||||
/**
|
||||
* 初始化租户角色
|
||||
*
|
||||
* @return 角色ID
|
||||
*/
|
||||
Long initTenantRole();
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.admin.system.service;
|
||||
|
||||
/**
|
||||
* @description: 多租户系统数据接口
|
||||
* @author: 小熊
|
||||
* @create: 2024-12-02 20:08
|
||||
*/
|
||||
public interface TenantSysDataService {
|
||||
|
||||
/**
|
||||
* 清除所有系统数据
|
||||
*/
|
||||
void clear();
|
||||
|
||||
}
|
@@ -155,4 +155,13 @@ public interface UserService extends BaseService<UserResp, UserDetailResp, UserQ
|
||||
* @return 用户数量
|
||||
*/
|
||||
Long countByDeptIds(List<Long> deptIds);
|
||||
|
||||
/**
|
||||
* 初始化租户管理员
|
||||
*
|
||||
* @param username
|
||||
* @param password
|
||||
* @return 管理员id
|
||||
*/
|
||||
Long initTenantUser(String username, String password, Long deptId);
|
||||
}
|
||||
|
@@ -214,4 +214,25 @@ public class DeptServiceImpl extends BaseServiceImpl<DeptMapper, DeptDO, DeptRes
|
||||
}
|
||||
baseMapper.updateById(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化租户部门
|
||||
*
|
||||
* @param deptName
|
||||
* @return 部门ID
|
||||
*/
|
||||
@Override
|
||||
public Long initTenantDept(String deptName) {
|
||||
//部门添加
|
||||
DeptDO deptDO = new DeptDO();
|
||||
deptDO.setName(deptName);
|
||||
deptDO.setParentId(0l);
|
||||
deptDO.setAncestors("0");
|
||||
deptDO.setDescription("系统初始部门");
|
||||
deptDO.setSort(1);
|
||||
deptDO.setStatus(DisEnableStatusEnum.ENABLE);
|
||||
baseMapper.insert(deptDO);
|
||||
return deptDO.getId();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -19,6 +19,7 @@ package top.continew.admin.system.service.impl;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alicp.jetcache.anno.Cached;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -28,15 +29,20 @@ import top.continew.admin.common.constant.SysConstants;
|
||||
import top.continew.admin.common.enums.DisEnableStatusEnum;
|
||||
import top.continew.admin.system.enums.MenuTypeEnum;
|
||||
import top.continew.admin.system.mapper.MenuMapper;
|
||||
import top.continew.admin.system.mapper.RoleMapper;
|
||||
import top.continew.admin.system.model.entity.MenuDO;
|
||||
import top.continew.admin.system.model.entity.RoleDO;
|
||||
import top.continew.admin.system.model.entity.RoleMenuDO;
|
||||
import top.continew.admin.system.model.query.MenuQuery;
|
||||
import top.continew.admin.system.model.req.MenuReq;
|
||||
import top.continew.admin.system.model.resp.MenuResp;
|
||||
import top.continew.admin.system.service.MenuService;
|
||||
import top.continew.admin.system.service.RoleMenuService;
|
||||
import top.continew.starter.cache.redisson.util.RedisUtils;
|
||||
import top.continew.starter.core.constant.StringConstants;
|
||||
import top.continew.starter.core.util.validation.CheckUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -50,6 +56,9 @@ import java.util.Set;
|
||||
@RequiredArgsConstructor
|
||||
public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuResp, MenuResp, MenuQuery, MenuReq> implements MenuService {
|
||||
|
||||
private final RoleMenuService roleMenuService;
|
||||
private final RoleMapper roleMapper;
|
||||
|
||||
@Override
|
||||
public Long create(MenuReq req) {
|
||||
String title = req.getTitle();
|
||||
@@ -90,12 +99,17 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuRes
|
||||
RedisUtils.deleteByPattern(CacheConstants.ROLE_MENU_KEY_PREFIX + StringConstants.ASTERISK);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cached(key = "'ALL' + #tenantId", name = CacheConstants.ROLE_MENU_KEY_PREFIX)
|
||||
public List<MenuResp> listAll(Long tenantId) {
|
||||
return super.list(new MenuQuery(DisEnableStatusEnum.ENABLE), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> listPermissionByUserId(Long userId) {
|
||||
return baseMapper.selectPermissionByUserId(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cached(key = "#roleId", name = CacheConstants.ROLE_MENU_KEY_PREFIX)
|
||||
public List<MenuResp> listByRoleId(Long roleId) {
|
||||
if (SysConstants.SUPER_ROLE_ID.equals(roleId)) {
|
||||
@@ -107,6 +121,63 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuRes
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void menuInit(List<MenuDO> menuList, Long oldParentId, Long newParentId) {
|
||||
List<MenuDO> children = menuList.stream().filter(menuDO -> menuDO.getParentId().equals(oldParentId)).toList();
|
||||
for (MenuDO menuDO : children) {
|
||||
Long oldId = menuDO.getId();
|
||||
menuDO.setId(null);
|
||||
menuDO.setParentId(newParentId);
|
||||
save(menuDO);
|
||||
menuInit(menuList, oldId, menuDO.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteTenantMenus(List<MenuDO> menuList) {
|
||||
if (!menuList.isEmpty()) {
|
||||
List<Long> delIds = new ArrayList<>();
|
||||
for (MenuDO menuDO : menuList) {
|
||||
MenuDO tMenu = getOne(Wrappers.query(MenuDO.class)
|
||||
.eq(menuDO.getType().equals(MenuTypeEnum.BUTTON.getValue()), "CONCAT(title,permission)", menuDO
|
||||
.getTitle() + menuDO.getPermission())
|
||||
.eq(!menuDO.getType().equals(MenuTypeEnum.BUTTON.getValue()), "name", menuDO.getName()));
|
||||
if (tMenu != null) {
|
||||
delIds.add(tMenu.getId());
|
||||
}
|
||||
}
|
||||
if (!delIds.isEmpty()) {
|
||||
//菜单删除
|
||||
delete(delIds);
|
||||
//绑定关系删除
|
||||
roleMenuService.remove(Wrappers.lambdaQuery(RoleMenuDO.class).in(RoleMenuDO::getMenuId, delIds));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTenantMenu(MenuDO menu, MenuDO pMenu) {
|
||||
Long pId = 0l;
|
||||
if (pMenu != null) {
|
||||
MenuDO tPMenu = getOne(Wrappers.query(MenuDO.class)
|
||||
.eq(pMenu.getType().equals(MenuTypeEnum.BUTTON.getValue()), "CONCAT(title,permission)", pMenu
|
||||
.getTitle() + pMenu.getPermission())
|
||||
.eq(!pMenu.getType().equals(MenuTypeEnum.BUTTON.getValue()), "name", pMenu.getName()));
|
||||
pId = tPMenu.getId();
|
||||
}
|
||||
menu.setId(null);
|
||||
menu.setParentId(pId);
|
||||
//菜单新增
|
||||
save(menu);
|
||||
//管理员绑定菜单
|
||||
RoleDO roleDO = roleMapper.selectOne(Wrappers.lambdaQuery(RoleDO.class)
|
||||
.eq(RoleDO::getCode, SysConstants.TENANT_ADMIN_CODE));
|
||||
RoleMenuDO roleMenuDO = new RoleMenuDO();
|
||||
roleMenuDO.setRoleId(roleDO.getId());
|
||||
roleMenuDO.setMenuId(menu.getId());
|
||||
roleMenuService.save(roleMenuDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 标题是否存在
|
||||
*
|
||||
|
@@ -23,6 +23,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import top.continew.admin.system.mapper.RoleMenuMapper;
|
||||
import top.continew.admin.system.model.entity.RoleMenuDO;
|
||||
import top.continew.admin.system.service.RoleMenuService;
|
||||
import top.continew.starter.data.service.impl.ServiceImpl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -36,7 +37,7 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class RoleMenuServiceImpl implements RoleMenuService {
|
||||
public class RoleMenuServiceImpl extends ServiceImpl<RoleMenuMapper, RoleMenuDO> implements RoleMenuService {
|
||||
|
||||
private final RoleMenuMapper baseMapper;
|
||||
|
||||
|
@@ -69,6 +69,8 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleRes
|
||||
CheckUtils.throwIf(this.isNameExists(name, null), "新增失败,[{}] 已存在", name);
|
||||
String code = req.getCode();
|
||||
CheckUtils.throwIf(this.isCodeExists(code, null), "新增失败,[{}] 已存在", code);
|
||||
// 防止租户添加超管
|
||||
CheckUtils.throwIf(SysConstants.SUPER_ROLE_CODE.equals(code), "新增失败,[{}] 禁止使用", code);
|
||||
// 新增信息
|
||||
Long roleId = super.create(req);
|
||||
// 保存角色和部门关联
|
||||
@@ -247,4 +249,24 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleRes
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化租户角色
|
||||
*
|
||||
* @return 角色ID
|
||||
*/
|
||||
@Override
|
||||
public Long initTenantRole() {
|
||||
RoleDO roleDO = new RoleDO();
|
||||
roleDO.setName("系统管理员");
|
||||
roleDO.setCode(SysConstants.TENANT_ADMIN_CODE);
|
||||
roleDO.setDataScope(DataScopeEnum.ALL);
|
||||
roleDO.setDescription("系统初始角色");
|
||||
roleDO.setSort(1);
|
||||
roleDO.setIsSystem(true);
|
||||
roleDO.setMenuCheckStrictly(false);
|
||||
roleDO.setDeptCheckStrictly(false);
|
||||
baseMapper.insert(roleDO);
|
||||
return roleDO.getId();
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.admin.system.service.impl;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import top.continew.admin.system.mapper.*;
|
||||
import top.continew.admin.system.mapper.user.UserMapper;
|
||||
import top.continew.admin.system.mapper.user.UserPasswordHistoryMapper;
|
||||
import top.continew.admin.system.mapper.user.UserSocialMapper;
|
||||
import top.continew.admin.system.model.entity.user.UserDO;
|
||||
import top.continew.admin.system.service.FileService;
|
||||
import top.continew.admin.system.service.TenantSysDataService;
|
||||
import top.continew.starter.extension.crud.model.entity.BaseIdDO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @description: 多租户系统数据接口
|
||||
* @author: 小熊
|
||||
* @create: 2024-12-02 20:12
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class TenantSysDataServiceImpl implements TenantSysDataService {
|
||||
|
||||
private final DeptMapper deptMapper;
|
||||
private final FileService fileService;
|
||||
private final LogMapper logMapper;
|
||||
private final MenuMapper menuMapper;
|
||||
private final MessageMapper messageMapper;
|
||||
private final MessageMapper messageUserMapper;
|
||||
private final NoticeMapper noticeMapper;
|
||||
private final RoleMapper roleMapper;
|
||||
private final RoleDeptMapper roleDeptMapper;
|
||||
private final RoleMenuMapper roleMenuMapper;
|
||||
private final UserMapper userMapper;
|
||||
private final UserPasswordHistoryMapper userPasswordHistoryMapper;
|
||||
private final UserRoleMapper userRoleMapper;
|
||||
private final UserSocialMapper userSocialMapper;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void clear() {
|
||||
//所有用户退出
|
||||
List<UserDO> userDOS = userMapper.selectList(null);
|
||||
for (UserDO userDO : userDOS) {
|
||||
StpUtil.logout(userDO.getId());
|
||||
}
|
||||
Wrapper dw = Wrappers.query().eq("1", 1);
|
||||
//部门清除
|
||||
deptMapper.delete(dw);
|
||||
//文件清除
|
||||
List<Long> fileIds = fileService.list().stream().map(BaseIdDO::getId).toList();
|
||||
if (!fileIds.isEmpty()) {
|
||||
fileService.delete(fileIds);
|
||||
}
|
||||
//日志清除
|
||||
logMapper.delete(dw);
|
||||
//菜单清除
|
||||
menuMapper.delete(dw);
|
||||
//消息清除
|
||||
messageMapper.delete(dw);
|
||||
messageUserMapper.delete(dw);
|
||||
//通知清除
|
||||
noticeMapper.delete(dw);
|
||||
//角色相关数据清除
|
||||
roleMapper.delete(dw);
|
||||
roleDeptMapper.delete(dw);
|
||||
roleMenuMapper.delete(dw);
|
||||
//用户数据清除
|
||||
userMapper.delete(dw);
|
||||
userPasswordHistoryMapper.delete(dw);
|
||||
userRoleMapper.delete(dw);
|
||||
userSocialMapper.delete(dw);
|
||||
}
|
||||
|
||||
}
|
@@ -23,10 +23,7 @@ import cn.hutool.core.io.file.FileNameUtil;
|
||||
import cn.hutool.core.io.resource.ResourceUtil;
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.EnumUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.*;
|
||||
import cn.hutool.extra.validation.ValidationUtil;
|
||||
import cn.hutool.http.ContentType;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
@@ -57,6 +54,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
import top.continew.admin.auth.service.OnlineUserService;
|
||||
import top.continew.admin.common.base.service.BaseServiceImpl;
|
||||
import top.continew.admin.common.constant.CacheConstants;
|
||||
import top.continew.admin.common.constant.RegexConstants;
|
||||
import top.continew.admin.common.constant.SysConstants;
|
||||
import top.continew.admin.common.context.UserContext;
|
||||
import top.continew.admin.common.context.UserContextHolder;
|
||||
@@ -80,8 +78,10 @@ import top.continew.admin.system.service.*;
|
||||
import top.continew.starter.cache.redisson.util.RedisUtils;
|
||||
import top.continew.starter.core.constant.StringConstants;
|
||||
import top.continew.starter.core.exception.BusinessException;
|
||||
import top.continew.starter.core.util.ExceptionUtils;
|
||||
import top.continew.starter.core.util.FileUploadUtils;
|
||||
import top.continew.starter.core.util.validation.CheckUtils;
|
||||
import top.continew.starter.core.util.validation.ValidationUtils;
|
||||
import top.continew.starter.extension.crud.model.query.PageQuery;
|
||||
import top.continew.starter.extension.crud.model.query.SortQuery;
|
||||
import top.continew.starter.extension.crud.model.resp.PageResp;
|
||||
@@ -734,6 +734,26 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserRes
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long initTenantUser(String username, String password, Long deptId) {
|
||||
//密码验证
|
||||
String rawPassword = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(password));
|
||||
ValidationUtils.throwIfNull(rawPassword, "密码解密失败");
|
||||
ValidationUtils.throwIf(!ReUtil
|
||||
.isMatch(RegexConstants.PASSWORD, rawPassword), "密码长度为 8-32 个字符,支持大小写字母、数字、特殊字符,至少包含字母和数字");
|
||||
UserDO userDO = new UserDO();
|
||||
userDO.setUsername(username);
|
||||
userDO.setNickname("系统管理员");
|
||||
userDO.setPassword(rawPassword);
|
||||
userDO.setGender(GenderEnum.UNKNOWN);
|
||||
userDO.setDescription("系统初始用户");
|
||||
userDO.setStatus(DisEnableStatusEnum.ENABLE);
|
||||
userDO.setIsSystem(true);
|
||||
userDO.setDeptId(deptId);
|
||||
baseMapper.insert(userDO);
|
||||
return userDO.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 ID 获取用户信息(数据权限)
|
||||
*
|
||||
|
Reference in New Issue
Block a user