/* * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the dreamlu.net developer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * Author: Chill 庄骞 (smallchill@163.com) */ package com.vci.ubcs.system.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.vci.ubcs.system.entity.*; import com.vci.ubcs.system.mapper.TenantMapper; import com.vci.ubcs.system.service.*; import com.vci.ubcs.system.user.entity.User; import com.vci.ubcs.system.user.enums.UserEnum; import com.vci.ubcs.system.user.feign.IUserClient; import lombok.RequiredArgsConstructor; import com.vci.ubcs.common.constant.CommonConstant; import org.springblade.core.cache.utils.CacheUtil; import org.springblade.core.log.exception.ServiceException; import org.springblade.core.mp.base.BaseServiceImpl; import org.springblade.core.tenant.TenantId; import org.springblade.core.tool.api.R; import org.springblade.core.tool.constant.BladeConstant; import org.springblade.core.tool.utils.Func; import org.springblade.core.tool.utils.StringUtil; import com.vci.ubcs.system.cache.ParamCache; import com.vci.ubcs.system.vo.TenantVO; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.*; import java.util.stream.Collectors; import static com.vci.ubcs.common.constant.TenantConstant.*; import static org.springblade.core.cache.constant.CacheConstant.SYS_CACHE; /** * 服务实现类 * * @author Chill */ @Service @RequiredArgsConstructor public class TenantServiceImpl extends BaseServiceImpl implements ITenantService { private final TenantId tenantId; private final IRoleService roleService; private final IMenuService menuService; private final IDeptService deptService; private final IPostService postService; private final IRoleMenuService roleMenuService; private final IDictBizService dictBizService; private final IUserClient userClient; private final IStrategyService strategyService; private final IUserPwdstrategyService userPwdstrategyService; /** * 获取是否允许自行控制三员是否开启 */ @Value("${ssa.ssa-enable}") private Boolean ssaEnable; /** * 获取默认三员管理员的名称 */ @Value("#{'${ssa.ssa-names}'.split(',')}") private List ssaNames; /** * 三员管理菜单配置 */ @Value("#{'${ssa.sys-menus}'.split(',')}") private List sysMenus; @Value("#{'${ssa.sec-menus}'.split(',')}") private List secMenus; @Value("#{'${ssa.audit-menus}'.split(',')}") private List auditMenus; @Override public IPage selectTenantPage(IPage page, Tenant tenant) { return page.setRecords(baseMapper.selectTenantPage(page, tenant)); } @Override public Tenant getByTenantId(String tenantId) { return getOne(Wrappers.query().lambda().eq(Tenant::getTenantId, tenantId)); } @Override @Transactional(rollbackFor = Exception.class) public boolean submitTenant(TenantVO tenant) { if (Func.isEmpty(tenant.getId())) { // 获取到未删除租户总数,生成新的租户id List tenants = baseMapper.selectList(Wrappers.query().lambda().eq(Tenant::getIsDeleted, BladeConstant.DB_NOT_DELETED)); List codes = tenants.stream().map(Tenant::getTenantId).collect(Collectors.toList()); String tenantId = getTenantId(codes); tenant.setTenantId(tenantId); // 配置为false,并且前端传输的参数为1(未选择开启)就不需要创建三员 if(!this.ssaEnable && tenant.getSsaEnable()==1){ // 不开启三员管理时直接创建一个最高权限的管理员 Role role = new Role(tenantId,BladeConstant.TOP_PARENT_ID,"超级管理员",1,"admin",BladeConstant.DB_NOT_DELETED); roleService.save(role); // 新建租户对应的角色菜单权限 saveRoleMenus(role, MENU_CODES); // 新建租户对应的默认部门 Dept dept = generateDept(tenantId, tenant); deptService.save(dept); // 新建租户对应的默认岗位 Post postInfo = generatePost(tenantId, 1, "admin", "管理员", 1); postService.save(postInfo); // 新建租户对应的默认业务字典 LinkedList dictBizs = new LinkedList<>(); List dictBizList = getDictBizs(tenantId, dictBizs); dictBizService.saveBatch(dictBizList); // 新建租户对应的默认管理用 User user = generateUser(tenantId, role, dept, postInfo); // 先保存租户 boolean temp = super.saveOrUpdate(tenant); // 创建用户 R result = userClient.saveUser(user); //生成用户密码策略管理记录 if (!result.isSuccess()) { throw new ServiceException(result.getMsg()); } return temp; }else { // 新建租户对应的默认角色 List roles = new ArrayList<>(); Role roleSys = new Role(tenantId,BladeConstant.TOP_PARENT_ID,"系统管理员",1,this.ssaNames.get(0),BladeConstant.DB_NOT_DELETED); Role roleSec = new Role(tenantId,BladeConstant.TOP_PARENT_ID,"安全管理员",2,this.ssaNames.get(1),BladeConstant.DB_NOT_DELETED); Role roleAudit = new Role(tenantId,BladeConstant.TOP_PARENT_ID,"审计管理员",3,this.ssaNames.get(2),BladeConstant.DB_NOT_DELETED); roles.add(roleSys); roles.add(roleSec); roles.add(roleAudit); roleService.saveBatch(roles); // 新建租户对应的角色菜单权限 saveRoleMenus(roleSys,this.sysMenus); //系统管理员角色菜单权限 saveRoleMenus(roleSec,this.secMenus); //安全管理员角色菜单权限 saveRoleMenus(roleAudit,this.auditMenus); //审计管理员角色菜单权限 // 新建租户对应的默认部门 Dept dept = generateDept(tenantId, tenant); deptService.save(dept); // 新建租户对应的默认岗位 Post postSys = generatePost(tenantId, 1, this.ssaNames.get(0), "系统管理员", 1); Post postSec = generatePost(tenantId,1,this.ssaNames.get(1),"安全管理员",4); Post postAudit = generatePost(tenantId,1,this.ssaNames.get(2),"审计管理员",5); postService.saveBatch(Arrays.asList(postSys,postSec,postAudit)); // 新建租户对应的默认业务字典 LinkedList dictBizs = new LinkedList<>(); List dictBizList = getDictBizs(tenantId, dictBizs); dictBizService.saveBatch(dictBizList); // 新建租户对应的默认管理用户 User userSys = generateUser(tenantId, roleSys, dept, postSys); User userSec = generateUser(tenantId,roleSec,dept,postSec); User userAudit = generateUser(tenantId,roleAudit,dept,postAudit); // 先保存租户 boolean temp = super.saveOrUpdate(tenant); // 创建用户 R result = userClient.saveUserList(Arrays.asList(userSys,userSec,userAudit)); if (!result.isSuccess()) { throw new ServiceException(result.getMsg()); } return temp; } } else { CacheUtil.clear(SYS_CACHE, tenant.getTenantId()); return super.saveOrUpdate(tenant); } } @Override @Transactional(rollbackFor = Exception.class) public boolean removeTenant(List ids) { List tenantIds = this.list(Wrappers.query().lambda().in(Tenant::getId, ids)) .stream().map(tenant -> Func.toStr(tenant.getTenantId())).distinct().collect(Collectors.toList()); CacheUtil.clear(SYS_CACHE, tenantIds); if (tenantIds.contains(BladeConstant.ADMIN_TENANT_ID)) { throw new ServiceException("不可删除管理租户!"); } boolean tenantTemp = this.deleteLogic(ids); R result = userClient.removeUser(StringUtil.join(tenantIds)); if (!result.isSuccess()) { throw new ServiceException(result.getMsg()); } return tenantTemp; } @Override public List> selectMaps(){ List> maps = listMaps(new QueryWrapper().select("TENANT_ID", "TENANT_NAME")); return maps; } @Override public boolean findIsOpen() { return this.ssaEnable; } /** * 创建租户下的默认岗位 * @param tenantId * @param sort */ private Post generatePost(String tenantId,Integer categ,String postCode,String postName,Integer sort){ Post post = new Post(); post.setTenantId(tenantId); post.setCategory(categ); post.setPostCode(postCode); post.setPostName(postName); post.setSort(sort); return post; } /** * 创建默认用户,并进行相关权限设置 */ private User generateUser(String tenantId, Role role, Dept dept, Post post){ User user = new User(); user.setTenantId(tenantId); user.setName(role.getRoleAlias()); user.setRealName(role.getRoleName()); user.setAccount(role.getRoleAlias()); user.setStrategyUpdateStatus(CommonConstant.TOP_PARENT_ID); user.setPwdUpdateTime(new Date()); // 获取参数配置的密码 String password = Func.toStr(ParamCache.getValue(PASSWORD_KEY), DEFAULT_PASSWORD); user.setPassword(password); user.setRoleId(String.valueOf(role.getId())); user.setDeptId(String.valueOf(dept.getId())); user.setPostId(String.valueOf(post.getId())); user.setBirthday(new Date()); user.setSex(1); user.setUserType(UserEnum.WEB.getCategory()); user.setIsDeleted(BladeConstant.DB_NOT_DELETED); return user; } /** * 保存用户对应的关联信息 * @param role */ private void saveRoleMenus(Role role,List stringMenus){ LinkedList userMenus = new LinkedList<>(); // 获取参数配置的默认菜单集合,逗号隔开 //List menuCodes = Func.toStrList(ParamCache.getValue(ACCOUNT_MENU_CODE_KEY)); List menus = getMenus((stringMenus), userMenus); List roleMenus = new ArrayList<>(); //创建所有菜单角色关联对象 menus.forEach(menu -> { roleMenus.add(new RoleMenu(menu.getId(),role.getId())); }); roleMenuService.saveBatch(roleMenus); } /** * 创建默认部门 * @param tenantId * @param tenant */ private Dept generateDept(String tenantId,Tenant tenant){ Dept dept = new Dept(); dept.setTenantId(tenantId); dept.setParentId(BladeConstant.TOP_PARENT_ID); dept.setAncestors(String.valueOf(BladeConstant.TOP_PARENT_ID)); dept.setDeptName(tenant.getTenantName()); dept.setFullName(tenant.getTenantName()); dept.setDeptCategory(1); dept.setSort(2); dept.setIsDeleted(BladeConstant.DB_NOT_DELETED); return dept; } private String getTenantId(List codes) { String code = tenantId.generate(); if (codes.contains(code)) { return getTenantId(codes); } return code; } private List getMenus(List codes, LinkedList menus) { codes.forEach(code -> { Menu menu = menuService.getOne(Wrappers.query().lambda().eq(Menu::getCode, code).eq(Menu::getIsDeleted, BladeConstant.DB_NOT_DELETED)); if (menu != null) { menus.add(menu); recursionMenu(menu.getId(), menus); } }); return menus; } private void recursionMenu(Long parentId, LinkedList menus) { List menuList = menuService.list(Wrappers.query().lambda().eq(Menu::getParentId, parentId).eq(Menu::getIsDeleted, BladeConstant.DB_NOT_DELETED)); menus.addAll(menuList); menuList.forEach(menu -> recursionMenu(menu.getId(), menus)); } private List getDictBizs(String tenantId, LinkedList dictBizs) { List dictBizList = dictBizService.list(Wrappers.query().lambda().eq(DictBiz::getParentId, BladeConstant.TOP_PARENT_ID).eq(DictBiz::getIsDeleted, BladeConstant.DB_NOT_DELETED)); dictBizList.forEach(dictBiz -> { Long oldParentId = dictBiz.getId(); Long newParentId = IdWorker.getId(); dictBiz.setId(newParentId); dictBiz.setTenantId(tenantId); dictBizs.add(dictBiz); recursionDictBiz(tenantId, oldParentId, newParentId, dictBizs); }); return dictBizs; } private void recursionDictBiz(String tenantId, Long oldParentId, Long newParentId, LinkedList dictBizs) { List dictBizList = dictBizService.list(Wrappers.query().lambda().eq(DictBiz::getParentId, oldParentId).eq(DictBiz::getIsDeleted, BladeConstant.DB_NOT_DELETED)); dictBizList.forEach(dictBiz -> { Long oldSubParentId = dictBiz.getId(); Long newSubParentId = IdWorker.getId(); dictBiz.setId(newSubParentId); dictBiz.setTenantId(tenantId); dictBiz.setParentId(newParentId); dictBizs.add(dictBiz); recursionDictBiz(tenantId, oldSubParentId, newSubParentId, dictBizs); }); } }