企业管理完成

This commit is contained in:
Vinjor 2024-08-03 17:59:07 +08:00
parent 30eafec000
commit 287dc7a8ec
32 changed files with 731 additions and 103 deletions

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.company.controller.admin;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
@ -9,6 +10,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import cn.iocoder.yudao.module.company.vo.CompanyReqVO;
import io.swagger.v3.oas.annotations.Parameter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
@ -25,6 +27,7 @@ import cn.iocoder.yudao.module.company.service.CompanyService;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
/**
@ -69,7 +72,7 @@ public class CompanyController {
@Operation(summary = "创建企业信息表(每个租户的下属企业信息)")
@PreAuthorize("@ss.hasPermission('base:company:create')")
public CommonResult<String> createCompany(@RequestBody CompanyRespVO companyRespVO) {
companyService.save(companyRespVO);
companyService.saveDataObj(companyRespVO);
return CommonResult.ok();
}
@ -82,8 +85,8 @@ public class CompanyController {
@PutMapping("/update")
@Operation(summary = "更新企业信息表(每个租户的下属企业信息)")
@PreAuthorize("@ss.hasPermission('base:company:update')")
public CommonResult<Boolean> updateCompany(@RequestBody Company company) {
companyService.updateById(company);
public CommonResult<Boolean> updateCompany(@RequestBody CompanyRespVO company) {
companyService.updateDataObj(company);
return CommonResult.ok();
}
@ -98,7 +101,7 @@ public class CompanyController {
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('base:company:delete')")
public CommonResult<Boolean> deleteCompany(@RequestParam("id") String id) {
companyService.removeById(id);
companyService.removeDataObj(id);
return success(true);
}
@ -114,7 +117,11 @@ public class CompanyController {
@PreAuthorize("@ss.hasPermission('base:company:query')")
public CommonResult<CompanyRespVO> getCompany(@RequestParam("id") String id) {
Company company = companyService.getById(id);
return success(BeanUtils.toBean(company, CompanyRespVO.class));
CompanyRespVO companyRespVO = BeanUtils.toBean(company, CompanyRespVO.class);
if(StringUtils.isNotEmpty(companyRespVO.getServiceCodes())){
companyRespVO.setServiceCodeArray(Arrays.asList(company.getServiceCodes().split(StrUtil.COMMA)));
}
return success(companyRespVO);
}
/**

View File

@ -64,7 +64,7 @@ public class Company extends TenantBaseDO {
private String business ;
/** 管理员登录账号 */
private String loginAccount ;
/** 关联的菜单编号(实际就是这个企业的用户登录后有哪些菜单权限) */
private String menuIds ;
/** 关联的服务编号(多个以英文逗号隔开)(实际就是这个企业的用户登录后有哪些系统权限) */
private String serviceCodes ;
}

View File

@ -28,4 +28,20 @@ public interface CompanyService extends IService<Company> {
* @param companyRespVO 企业对象
**/
void saveDataObj(CompanyRespVO companyRespVO);
/**
* 更新企业信息
* @author vinjor-M
* @date 9:56 2024/8/2
* @param companyRespVO 企业对象
**/
void updateDataObj(CompanyRespVO companyRespVO);
/**
* 删除企业
* @author vinjor-M
* @date 16:33 2024/8/3
* @param id 企业id
**/
void removeDataObj(String id);
}

View File

@ -1,6 +1,10 @@
package cn.iocoder.yudao.module.company.service.impl;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.module.company.entity.Company;
import cn.iocoder.yudao.module.company.vo.CompanyRespVO;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
@ -9,8 +13,11 @@ import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
import cn.iocoder.yudao.module.system.api.permission.RoleApi;
import cn.iocoder.yudao.module.system.api.permission.dto.RoleReqDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.system.api.user.dto.UserDTO;
import cn.iocoder.yudao.module.system.enums.permission.RoleCodeEnum;
import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.iocoder.yudao.module.company.vo.CompanyReqVO;
import org.springframework.beans.factory.annotation.Autowired;
@ -24,6 +31,14 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS;
import static java.util.Collections.singleton;
/**
@ -65,43 +80,88 @@ public class CompanyServiceImpl extends ServiceImpl<CompanyMapper, Company> impl
* @date 9:56 2024/8/2
**/
@Override
@Transactional(rollbackFor = Exception.class)
@DSTransactional // 多数据源使用 @DSTransactional 保证本地事务以及数据源的切换
public void saveDataObj(CompanyRespVO companyRespVO) {
/*1.保存企业信息*/
this.save(companyRespVO);
/*2.新增企业管理员角色和用户信息*/
/*3.新增企业部门信息*/
DeptRespDTO deptRespDTO = new DeptRespDTO();
deptRespDTO.setName(companyRespVO.getCorpName());
deptRespDTO.setStatus(CommonStatusEnum.ENABLE.getStatus());
// deptRespDTO.setLeaderUserId(userId);
deptApi.saveDept(deptRespDTO);
/*3.更新企业管理员所属部门信息*/
try {
/*1.保存企业信息*/
this.save(companyRespVO);
/*2.新增企业部门信息*/
DeptRespDTO deptRespDTO = new DeptRespDTO();
deptRespDTO.setName(companyRespVO.getCorpName());
deptRespDTO.setStatus(CommonStatusEnum.ENABLE.getStatus());
//上级部门为本租户顶级部门
DeptRespDTO parentDept = deptApi.getDeptByParentId(0L);
deptRespDTO.setParentId(parentDept.getId());
Long deptId = deptApi.saveDept(deptRespDTO);
/*3.新增企业管理员用户信息并配置角色*/
UserDTO userDTO = new UserDTO();
userDTO.setUsername(companyRespVO.getLoginAccount());
userDTO.setNickname(companyRespVO.getContactName());
userDTO.setDeptId(deptId);
userDTO.setPassword(companyRespVO.getPassword());
userDTO.setMobile(companyRespVO.getMobilePhone());
Long userId = adminUserApi.createUser(userDTO);
Set<String> roleCodes = new HashSet<>(Arrays.asList(companyRespVO.getServiceCodes().split(StrUtil.COMMA)));
permissionApi.assignUserRole(userId, roleCodes);
} catch (ServiceException e) {
throw exception(new ErrorCode(e.getCode(), e.getMessage()));
}
}
/**
* 更新企业信息
*
* @param companyRespVO 企业对象
* @author vinjor-M
* @date 9:56 2024/8/2
**/
@Override
@DSTransactional // 多数据源使用 @DSTransactional 保证本地事务以及数据源的切换
public void updateDataObj(CompanyRespVO companyRespVO) {
try {
//查出原有数据
Company oldCompany = this.getById(companyRespVO.getId());
if(!companyRespVO.getServiceCodes().equals(oldCompany.getServiceCodes())){
//服务发生变化变更企业管理员的角色权限
Set<String> roleCodes = new HashSet<>(Arrays.asList(companyRespVO.getServiceCodes().split(StrUtil.COMMA)));
//根据企业管理员登录账户查出userId
AdminUserRespDTO adminUserRespDTO = adminUserApi.getUserByUsername(oldCompany.getLoginAccount());
permissionApi.assignUserRole(adminUserRespDTO.getId(),roleCodes);
}
//正常更新数据
this.updateById(companyRespVO);
}catch (ServiceException e) {
throw exception(new ErrorCode(e.getCode(), e.getMessage()));
}
}
/**
* 删除企业
*
* @param id 企业id
* @author vinjor-M
* @date 16:33 2024/8/3
**/
@Override
@DSTransactional // 多数据源使用 @DSTransactional 保证本地事务以及数据源的切换
public void removeDataObj(String id) {
try {
Company company = this.getById(id);
/*1.查出本租户下与本企业名称相同的二级部门,并取出下级所有部门 */
DeptRespDTO parentDept = deptApi.getDeptByParentId(0L);
DeptRespDTO thisDept = deptApi.getDeptByParentIdAndName(parentDept.getId(),company.getCorpName());
List<DeptRespDTO> allChildDeptList = deptApi.getChildDeptList(thisDept.getId());
allChildDeptList.add(thisDept);
/*2.删除所有部门的用户和部门---这里挨个删除,为了记录日志和级联删除对应的权限 */
Set<Long> deptIds = convertSet(allChildDeptList, DeptRespDTO::getId);
List<AdminUserRespDTO> userRespDTOList = adminUserApi.getUserListByDeptIds(deptIds);
userRespDTOList.forEach(user->adminUserApi.deleteUser(user.getId()));
deptApi.deleteDept(deptIds);
/*3.删除本企业 */
this.removeById(id);
}catch (ServiceException e) {
throw exception(new ErrorCode(e.getCode(), e.getMessage()));
}
}
// private Long createUser(Long roleId, CompanyRespVO companyRespVO) {
// // 创建用户
// Long userId = adminUserApi.createUser(TenantConvert.INSTANCE.convert02(createReqVO));
// // 分配角色
// permissionService.assignUserRole(userId, singleton(roleId));
// return userId;
// }
//
// /**
// * 创建企业时自动创建企业管理员角色
// * @author vinjor-M
// * @date 10:22 2024/8/2
// * @param companyRespVO 企业对象
// **/
// private Long createRole(CompanyRespVO companyRespVO) {
// // 创建角色
// RoleReqDTO reqVO = new RoleReqDTO();
// reqVO.setName(RoleCodeEnum.COMPANY_ADMIN.getName()).setCode(RoleCodeEnum.COMPANY_ADMIN.getCode())
// .setSort(0).setRemark("系统自动生成");
// Long roleId = roleApi.createRole(reqVO, RoleTypeEnum.SYSTEM.getType());
// // 分配权限
// permissionApi.assignRoleMenu(roleId, companyRespVO.getMenuIds());
// return roleId;
// }
}

View File

@ -6,18 +6,23 @@ import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.util.List;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* 企业返回结果vo
* 企业返回结果或提交vo
* @author vinjor-M
* @date 17:37 2024/7/31
**/
@Data
public class CompanyRespVO extends Company {
/**
* 该企业分配的菜单权限
* 登录账户密码
*/
String menuIds;
String password;
/**
* 登录账户密码
*/
List<String> serviceCodeArray;
}

View File

@ -0,0 +1,11 @@
package cn.iocoder.yudao.framework.common.config;
/**
* 通用常量配置类
* @author vinjor-M
* @date 14:14 2024/8/2
**/
public interface CommonStr {
/** 默认点亮科技租户 --1 */
Long TENANT_ID=1L;
}

View File

@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 部门 API 接口
@ -21,6 +22,14 @@ public interface DeptApi {
*/
Long saveDept(DeptRespDTO deptRespDTO);
/**
* 批量删除部门
* @author vinjor-M
* @date 17:17 2024/8/3
* @param ids 部门ids
**/
void deleteDept(Set<Long> ids);
/**
* 获得部门信息
*
@ -29,6 +38,22 @@ public interface DeptApi {
*/
DeptRespDTO getDept(Long id);
/**
* 获得部门信息
*
* @param parentId 上级部门编号
* @return 部门信息
*/
DeptRespDTO getDeptByParentId(Long parentId);
/**
* 获得部门信息
*
* @param parentId 上级部门编号
* @param name 上级部门名称
* @return 部门信息
*/
DeptRespDTO getDeptByParentIdAndName(Long parentId,String name);
/**
* 获得部门信息数组
*

View File

@ -46,4 +46,12 @@ public interface PermissionApi {
*/
DeptDataPermissionRespDTO getDeptDataPermission(Long userId);
/**
* 设置用户角色
*
* @param userId 角色编号
* @param roleCodes 角色编号集合
*/
void assignUserRole(Long userId, Set<String> roleCodes);
}

View File

@ -2,7 +2,9 @@ package cn.iocoder.yudao.module.system.api.user;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.system.api.user.dto.UserDTO;
import javax.validation.Valid;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@ -15,6 +17,22 @@ import java.util.Map;
*/
public interface AdminUserApi {
/**
* 创建用户
* @author vinjor-M
* @date 15:27 2024/8/3
* @param userDTO 用户DTO
* @return java.lang.Long
**/
Long createUser(UserDTO userDTO);
/**
* 删除用户
*
* @param id 用户编号
*/
void deleteUser(Long id);
/**
* 通过用户 ID 查询用户
*
@ -23,6 +41,14 @@ public interface AdminUserApi {
*/
AdminUserRespDTO getUser(Long id);
/**
* 通过用户 登录账户 查询用户
*
* @param username 用户登录账户
* @return 用户对象信息
*/
AdminUserRespDTO getUserByUsername(String username);
/**
* 通过用户 ID 查询用户下属
*

View File

@ -0,0 +1,37 @@
package cn.iocoder.yudao.module.system.api.user.dto;
import lombok.Data;
@Data
public class UserDTO {
/**
* 用户id
*/
private Long id;
/**
* 用户账号
*/
private String username;
/**
* 用户昵称
*/
private String nickname;
/**
* 备注
*/
private String remark;
/**
* 部门编号
*/
private Long deptId;
/**
* 用户手机号码
*/
private String mobile;
/**
* 用户密码
*/
private String password;
}

View File

@ -13,6 +13,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* 部门 API 实现类
@ -36,12 +37,49 @@ public class DeptApiImpl implements DeptApi {
return deptService.createDept(deptSaveReqVO);
}
/**
* 批量删除部门
*
* @param ids 部门ids
* @author vinjor-M
* @date 17:17 2024/8/3
**/
@Override
public void deleteDept(Set<Long> ids) {
deptService.deleteDept(ids);
}
@Override
public DeptRespDTO getDept(Long id) {
DeptDO dept = deptService.getDept(id);
return BeanUtils.toBean(dept, DeptRespDTO.class);
}
/**
* 获得部门信息
*
* @param parentId 上级部门编号
* @return 部门信息
*/
@Override
public DeptRespDTO getDeptByParentId(Long parentId) {
DeptDO dept = deptService.getDeptByParentId(parentId);
return BeanUtils.toBean(dept, DeptRespDTO.class);
}
/**
* 获得部门信息
*
* @param parentId 上级部门编号
* @param name 上级部门名称
* @return 部门信息
*/
@Override
public DeptRespDTO getDeptByParentIdAndName(Long parentId, String name) {
DeptDO dept = deptService.getDeptByParentIdAndName(parentId,name);
return BeanUtils.toBean(dept, DeptRespDTO.class);
}
@Override
public List<DeptRespDTO> getDeptList(Collection<Long> ids) {
List<DeptDO> depts = deptService.getDeptList(ids);

View File

@ -39,4 +39,15 @@ public class PermissionApiImpl implements PermissionApi {
return permissionService.getDeptDataPermission(userId);
}
/**
* 设置用户角色
*
* @param userId 角色编号
* @param roleCodes 角色编号集合
*/
@Override
public void assignUserRole(Long userId, Set<String> roleCodes) {
permissionService.assignUserRoleByCodes(userId, roleCodes);
}
}

View File

@ -4,6 +4,8 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.system.api.user.dto.UserDTO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
@ -31,12 +33,48 @@ public class AdminUserApiImpl implements AdminUserApi {
@Resource
private DeptService deptService;
/**
* 创建用户
*
* @param userDTO 用户DTO
* @return java.lang.Long
* @author vinjor-M
* @date 15:27 2024/8/3
**/
@Override
public Long createUser(UserDTO userDTO) {
UserSaveReqVO userSaveReqVO = BeanUtils.toBean(userDTO, UserSaveReqVO.class);
return userService.createUser(userSaveReqVO);
}
/**
* 删除用户
*
* @param id 用户编号
*/
@Override
public void deleteUser(Long id) {
userService.deleteUser(id);
}
@Override
public AdminUserRespDTO getUser(Long id) {
AdminUserDO user = userService.getUser(id);
return BeanUtils.toBean(user, AdminUserRespDTO.class);
}
/**
* 通过用户 登录账户 查询用户
*
* @param username 用户登录账户
* @return 用户对象信息
*/
@Override
public AdminUserRespDTO getUserByUsername(String username) {
AdminUserDO user = userService.getUserByUsername(username);
return BeanUtils.toBean(user, AdminUserRespDTO.class);
}
@Override
public List<AdminUserRespDTO> getUserListBySubordinate(Long id) {
// 1.1 获取用户负责的部门

View File

@ -9,6 +9,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Set;
@Schema(description = "管理后台 - 租户 Response VO")
@Data
@ -40,7 +41,7 @@ public class TenantRespVO {
private String website;
@Schema(description = "租户套餐编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long packageId;
private Set<String> packageId;
@Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime expireTime;

View File

@ -11,6 +11,7 @@ import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;
import java.util.Set;
@Schema(description = "管理后台 - 租户创建/修改 Request VO")
@Data
@ -39,7 +40,7 @@ public class TenantSaveReqVO {
@Schema(description = "租户套餐编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "租户套餐编号不能为空")
private Long packageId;
private Set<String> packageId;
@Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "过期时间不能为空")

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.system.dal.dataobject.service;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
@ -12,14 +13,14 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
*
* @author 后台管理员
*/
@TableName("system_service_package")
@TableName(value = "system_service_package", autoResultMap = true)
@KeySequence("system_service_package_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
@NoArgsConstructor
public class ServicePackageDO extends BaseDO {
/**
@ -42,6 +43,7 @@ public class ServicePackageDO extends BaseDO {
/**
* 关联的菜单编号
*/
private String menuIds;
@TableField(typeHandler = JacksonTypeHandler.class)
private Set<Long> menuIds;
}

View File

@ -4,10 +4,13 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.*;
import java.time.LocalDateTime;
import java.util.Set;
/**
* 租户 DO
@ -67,7 +70,8 @@ public class TenantDO extends BaseDO {
* 关联 {@link TenantPackageDO#getId()}
* 特殊逻辑系统内置租户不使用套餐暂时使用 {@link #PACKAGE_ID_SYSTEM} 标识
*/
private Long packageId;
@TableField(typeHandler =JacksonTypeHandler.class)
private Set<String> packageId;
/**
* 过期时间
*/

View File

@ -22,6 +22,10 @@ public interface DeptMapper extends BaseMapperX<DeptDO> {
return selectOne(DeptDO::getParentId, parentId, DeptDO::getName, name);
}
default DeptDO selectByParentId(Long parentId) {
return selectOne(DeptDO::getParentId, parentId);
}
default Long selectCountByParentId(Long parentId) {
return selectCount(DeptDO::getParentId, parentId);
}

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.system.dal.mysql.permission;
import cn.iocoder.yudao.framework.common.config.CommonStr;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
@ -36,4 +37,11 @@ public interface RoleMapper extends BaseMapperX<RoleDO> {
return selectList(RoleDO::getStatus, statuses);
}
default List<RoleDO> selectListByCodes(@Nullable Collection<String> codes) {
return selectList(new LambdaQueryWrapperX<RoleDO>().in(RoleDO::getCode, codes).eq(RoleDO::getTenantId, CommonStr.TENANT_ID));
}
default List<RoleDO> selectListByCodesTenant(@Nullable Collection<String> codes) {
return selectList(new LambdaQueryWrapperX<RoleDO>().in(RoleDO::getCode, codes));
}
}

View File

@ -39,6 +39,14 @@ public interface DeptService {
*/
void deleteDept(Long id);
/**
* 批量删除部门
* @author vinjor-M
* @date 17:16 2024/8/3
* @param ids 部门ids
**/
void deleteDept(Set<Long> ids);
/**
* 获得部门信息
*
@ -46,6 +54,21 @@ public interface DeptService {
* @return 部门信息
*/
DeptDO getDept(Long id);
/**
* 获得部门信息
*
* @param parentId 上级部门编号
* @return 部门信息
*/
DeptDO getDeptByParentId(Long parentId);
/**
* 获得部门信息
*
* @param parentId 上级部门编号
* @param name 部门名称
* @return 部门信息
*/
DeptDO getDeptByParentIdAndName(Long parentId,String name);
/**
* 获得部门信息数组

View File

@ -90,6 +90,20 @@ public class DeptServiceImpl implements DeptService {
deptMapper.deleteById(id);
}
/**
* 批量删除部门
*
* @param ids 部门ids
* @author vinjor-M
* @date 17:16 2024/8/3
**/
@Override
@CacheEvict(cacheNames = RedisKeyConstants.DEPT_CHILDREN_ID_LIST,
allEntries = true) // allEntries 清空所有缓存因为操作一个部门涉及到多个缓存
public void deleteDept(Set<Long> ids) {
deptMapper.deleteByIds(ids);
}
@VisibleForTesting
void validateDeptExists(Long id) {
if (id == null) {
@ -156,6 +170,30 @@ public class DeptServiceImpl implements DeptService {
return deptMapper.selectById(id);
}
/**
* 获得部门信息
*
* @param parentId 上级部门编号
* @return 部门信息
*/
@Override
public DeptDO getDeptByParentId(Long parentId) {
return deptMapper.selectByParentId(parentId);
}
/**
* 获得部门信息
*
* @param parentId 上级部门编号
* @param name 部门名称
* @return 部门信息
*/
@Override
public DeptDO getDeptByParentIdAndName(Long parentId, String name) {
return deptMapper.selectByParentIdAndName(parentId, name);
}
@Override
public List<DeptDO> getDeptList(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {

View File

@ -63,6 +63,7 @@ public interface PermissionService {
* @param roleId 角色编号
* @return 菜单编号集合
*/
default Set<Long> getRoleMenuListByRoleId(Long roleId) {
return getRoleMenuListByRoleId(singleton(roleId));
}
@ -75,6 +76,14 @@ public interface PermissionService {
*/
Set<Long> getRoleMenuListByRoleId(Collection<Long> roleIds);
/**
* 获得角色们拥有的菜单编号集合----自定义
*
* @param roleId 角色编号
* @return 菜单编号集合
*/
Set<Long> getRoleMenuListByRoleIdCus(Long roleId);
/**
* 获得拥有指定菜单的角色编号数组从缓存中获取
*
@ -93,6 +102,15 @@ public interface PermissionService {
*/
void assignUserRole(Long userId, Set<Long> roleIds);
/**
* 设置用户角色-通过角色code
* @author vinjor-M
* @date 15:31 2024/8/3
* @param userId 用户id
* @param roleCodes 角色code 集合
**/
void assignUserRoleByCodes(Long userId, Set<String> roleCodes);
/**
* 处理用户删除时删除关联授权数据
*

View File

@ -7,6 +7,7 @@ import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
@ -35,6 +36,7 @@ import java.util.function.Supplier;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
import static javafx.scene.input.KeyCode.H;
/**
* 权限 Service 实现类
@ -190,6 +192,12 @@ public class PermissionServiceImpl implements PermissionService {
return convertSet(roleMenuMapper.selectListByRoleId(roleIds), RoleMenuDO::getMenuId);
}
@Override
@TenantIgnore
public Set<Long> getRoleMenuListByRoleIdCus(Long roleId) {
return convertSet(roleMenuMapper.selectListByRoleId(roleId), RoleMenuDO::getMenuId);
}
@Override
@Cacheable(value = RedisKeyConstants.MENU_ROLE_ID_LIST, key = "#menuId")
public Set<Long> getMenuRoleIdListByMenuIdFromCache(Long menuId) {
@ -208,7 +216,7 @@ public class PermissionServiceImpl implements PermissionService {
// 计算新增和删除的角色编号
Set<Long> roleIdList = CollUtil.emptyIfNull(roleIds);
Collection<Long> createRoleIds = CollUtil.subtract(roleIdList, dbRoleIds);
Collection<Long> deleteMenuIds = CollUtil.subtract(dbRoleIds, roleIdList);
Collection<Long> deleteRoleIds = CollUtil.subtract(dbRoleIds, roleIdList);
// 执行新增和删除对于已经授权的角色不用做任何处理
if (!CollectionUtil.isEmpty(createRoleIds)) {
userRoleMapper.insertBatch(CollectionUtils.convertList(createRoleIds, roleId -> {
@ -218,11 +226,28 @@ public class PermissionServiceImpl implements PermissionService {
return entity;
}));
}
if (!CollectionUtil.isEmpty(deleteMenuIds)) {
userRoleMapper.deleteListByUserIdAndRoleIdIds(userId, deleteMenuIds);
if (!CollectionUtil.isEmpty(deleteRoleIds)) {
userRoleMapper.deleteListByUserIdAndRoleIdIds(userId, deleteRoleIds);
}
}
/**
* 设置用户角色-通过角色code
*
* @param userId 用户id
* @param roleCodes 角色code 集合
* @author vinjor-M
* @date 15:31 2024/8/3
**/
@Override
public void assignUserRoleByCodes(Long userId, Set<String> roleCodes) {
//根据角色code查出对应的角色列表
List<RoleDO> roleDOList = roleService.getRoleListByCodesTenant(roleCodes);
Set<Long> roleIds = new HashSet<>();
roleDOList.forEach(item->roleIds.add(item.getId()));
this.assignUserRole(userId,roleIds);
}
@Override
@CacheEvict(value = RedisKeyConstants.USER_ROLE_ID_LIST, key = "#userId")
public void processUserDeleted(Long userId) {

View File

@ -40,6 +40,13 @@ public interface RoleService {
*/
void deleteRole(Long id);
/**
* 删除角色
*
* @param code 角色编号
*/
void deleteRole(String code);
/**
* 设置角色的数据权限
*
@ -73,6 +80,22 @@ public interface RoleService {
*/
List<RoleDO> getRoleList(Collection<Long> ids);
/**
* 获得角色列表--仅限于点亮科技租户
*
* @param codes 角色code数组
* @return 角色列表
*/
List<RoleDO> getRoleListByCodes(Collection<String> codes);
/**
* 获得角色列表--获取当前租户的
*
* @param codes 角色code数组
* @return 角色列表
*/
List<RoleDO> getRoleListByCodesTenant(Collection<String> codes);
/**
* 获得角色数组从缓存中
*

View File

@ -3,11 +3,13 @@ package cn.iocoder.yudao.module.system.service.permission;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RolePageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
@ -121,6 +123,19 @@ public class RoleServiceImpl implements RoleService {
LogRecordContext.putVariable("role", role);
}
/**
* 删除角色
*
* @param code 角色编号
*/
@Override
public void deleteRole(String code) {
//根据角色code查出对应角色id
RoleDO roleDO = roleMapper.selectByCode(code);
if(null!=roleDO){
this.deleteRole(roleDO.getId());
}
}
/**
* 校验角色的唯一字段是否重复
*
@ -202,6 +217,35 @@ public class RoleServiceImpl implements RoleService {
return roleMapper.selectBatchIds(ids);
}
/**
* 获得角色列表--仅限于点亮科技租户
*
* @param codes 角色code数组
* @return 角色列表
*/
@Override
@TenantIgnore
public List<RoleDO> getRoleListByCodes(Collection<String> codes) {
if (CollectionUtil.isEmpty(codes)) {
return Collections.emptyList();
}
return roleMapper.selectListByCodes(codes);
}
/**
* 获得角色列表--获取当前租户的
*
* @param codes 角色code数组
* @return 角色列表
*/
@Override
public List<RoleDO> getRoleListByCodesTenant(Collection<String> codes) {
if (CollectionUtil.isEmpty(codes)) {
return Collections.emptyList();
}
return roleMapper.selectListByCodesTenant(codes);
}
@Override
public List<RoleDO> getRoleListFromCache(Collection<Long> ids) {
if (CollectionUtil.isEmpty(ids)) {

View File

@ -60,7 +60,6 @@ public interface ServicePackageService {
* @return 服务套餐
*/
ServicePackageDO validServicePackage(String id);
/**
* 获得指定状态的服务套餐列表
*

View File

@ -1,7 +1,17 @@
package cn.iocoder.yudao.module.system.service.service;
import cn.iocoder.yudao.framework.common.config.CommonStr;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRule;
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO;
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.tenant.TenantService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
@ -30,16 +40,46 @@ public class ServicePackageServiceImpl implements ServicePackageService {
@Resource
private ServicePackageMapper servicePackageMapper;
@Resource
private RoleService roleService;
@Resource
private TenantService tenantService;
@Resource
private PermissionService permissionService;
@Override
public String createServicePackage(ServicePackageSaveReqVO createReqVO) {
// 插入
ServicePackageDO servicePackage = BeanUtils.toBean(createReqVO, ServicePackageDO.class);
servicePackageMapper.insert(servicePackage);
//自动在点亮科技租户创建对应的角色并赋予权限
TenantUtils.execute(CommonStr.TENANT_ID, () -> {
//依据角色编码删除原有角色
roleService.deleteRole(createReqVO.getId());
// 创建新角色并赋予权限
createRole(createReqVO);
});
// 返回
return servicePackage.getId();
}
/**
* 自动为新建的服务套餐创建角色并赋予权限
* @author vinjor-M
* @date 14:08 2024/8/2
* @param createReqVO 服务套餐对象
**/
private Long createRole(ServicePackageSaveReqVO createReqVO) {
// 创建角色
RoleSaveReqVO reqVO = new RoleSaveReqVO();
reqVO.setName(createReqVO.getName()+"业务管理员").setCode(createReqVO.getId())
.setSort(0).setRemark("系统自动生成");
Long roleId = roleService.createRole(reqVO, RoleTypeEnum.SYSTEM.getType());
// 分配权限
permissionService.assignRoleMenu(roleId, createReqVO.getMenuIds());
return roleId;
}
@Override
public void updateServicePackage(ServicePackageSaveReqVO updateReqVO) {
// 校验存在
@ -57,8 +97,8 @@ public class ServicePackageServiceImpl implements ServicePackageService {
public void deleteServicePackage(String id) {
// 校验存在
validateServicePackageExists(id);
// 校验正在使用--TODO 后续完善
// validateTenantUsed(id);
// 校验正在使用本服务的租户
validServicePackageUsed(id);
// 删除
servicePackageMapper.deleteById(id);
}
@ -69,6 +109,24 @@ public class ServicePackageServiceImpl implements ServicePackageService {
}
}
private void validServicePackageUsed(String id) {
if (tenantService.getTenantCountByPackageId(id) > 0) {
throw exception(TENANT_PACKAGE_USED);
}
}
@Override
public ServicePackageDO validServicePackage(String id) {
ServicePackageDO servicePackage = servicePackageMapper.selectById(id);
if (servicePackage == null) {
throw exception(SERVICE_PACKAGE_NOT_EXISTS);
}
if (servicePackage.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) {
throw exception(SERVICE_PACKAGE_DISABLE, servicePackage.getName());
}
return servicePackage;
}
@Override
public ServicePackageDO getServicePackage(String id) {
return servicePackageMapper.selectById(id);
@ -79,19 +137,6 @@ public class ServicePackageServiceImpl implements ServicePackageService {
return servicePackageMapper.selectPage(pageReqVO);
}
@Override
public ServicePackageDO validServicePackage(String id) {
// ServicePackageDO 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;
return null;
}
@Override
public List<ServicePackageDO> getServicePackageListByStatus(Integer status) {
return servicePackageMapper.selectListByStatus(status);

View File

@ -89,6 +89,14 @@ public interface TenantService {
*/
Long getTenantCountByPackageId(Long packageId);
/**
* 获得使用指定套餐的租户数量
*
* @param packageId 租户套餐编号
* @return 租户数量
*/
Long getTenantCountByPackageId(String packageId);
/**
* 获得使用指定套餐的租户数组
*

View File

@ -9,7 +9,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
import cn.iocoder.yudao.framework.tenant.config.TenantProperties;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptSaveReqVO;
@ -20,6 +23,7 @@ import cn.iocoder.yudao.module.system.convert.tenant.TenantConvert;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
import cn.iocoder.yudao.module.system.dal.dataobject.service.ServicePackageDO;
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO;
import cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantMapper;
@ -29,10 +33,12 @@ import cn.iocoder.yudao.module.system.service.dept.DeptService;
import cn.iocoder.yudao.module.system.service.permission.MenuService;
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.service.ServicePackageService;
import cn.iocoder.yudao.module.system.service.tenant.handler.TenantInfoHandler;
import cn.iocoder.yudao.module.system.service.tenant.handler.TenantMenuHandler;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
@ -40,9 +46,8 @@ import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
@ -66,7 +71,8 @@ public class TenantServiceImpl implements TenantService {
private TenantMapper tenantMapper;
@Resource
private TenantPackageService tenantPackageService;
@Lazy // 延迟避免循环依赖报错
private ServicePackageService servicePackageService;
@Resource
@Lazy // 延迟避免循环依赖报错
private AdminUserService userService;
@ -107,24 +113,50 @@ public class TenantServiceImpl implements TenantService {
// 校验租户域名是否重复
validTenantWebsiteDuplicate(createReqVO.getWebsite(), null);
// 校验套餐被禁用
TenantPackageDO tenantPackage = tenantPackageService.validTenantPackage(createReqVO.getPackageId());
Set<String> packageSet = createReqVO.getPackageId();
Set<Long> menuIds = new HashSet<>();
for (String packageId:packageSet){
ServicePackageDO servicePackageDO = servicePackageService.validServicePackage(packageId);
menuIds.addAll(servicePackageDO.getMenuIds());
}
// 创建租户
TenantDO tenant = BeanUtils.toBean(createReqVO, TenantDO.class);
tenantMapper.insert(tenant);
// 创建租户的管理员
TenantUtils.execute(tenant.getId(), () -> {
// 创建角色
Long roleId = createRole(tenantPackage);
// 创建用户并分配角色
Long roleId = createRole(menuIds);
// 创建租户管理员用户并分配角色
Long userId = createUser(roleId, createReqVO);
// 修改租户的管理员
tenantMapper.updateById(new TenantDO().setId(tenant.getId()).setContactUserId(userId));
//创建顶级部门
createDept(userId,createReqVO.getName(),createReqVO.getContactMobile());
//创建租户顶级部门
Long deptId = createDept(userId,createReqVO.getName(),createReqVO.getContactMobile());
//拉取本租户配置的服务套餐对应的角色和权限存入本租户对应信息
createServiceRole(createReqVO.getPackageId());
});
return tenant.getId();
}
/**
* 拉取本租户配置的服务套餐对应的角色和权限存入本租户对应信息
* @author vinjor-M
* @date 16:39 2024/8/2
* @param serviceCodeSet 服务标识
**/
private void createServiceRole(Set<String> serviceCodeSet){
//先查出这些服务在点亮租户下对应角色预先配置好的
List<RoleDO> roleDOList = roleService.getRoleListByCodes(serviceCodeSet);
for (RoleDO roleDO:roleDOList){
Set<Long> menuIds = permissionService.getRoleMenuListByRoleIdCus(roleDO.getId());
// 创建角色
RoleSaveReqVO reqVO = new RoleSaveReqVO();
reqVO.setName(roleDO.getName()).setCode(roleDO.getCode())
.setSort(0).setRemark("系统自动生成");
Long roleId = roleService.createRole(reqVO, RoleTypeEnum.SYSTEM.getType());
// 分配权限
permissionService.assignRoleMenu(roleId, menuIds);
}
}
private Long createDept(Long userId,String deptName,String phone){
DeptSaveReqVO deptSaveReqVO = new DeptSaveReqVO();
@ -144,14 +176,14 @@ public class TenantServiceImpl implements TenantService {
return userId;
}
private Long createRole(TenantPackageDO tenantPackage) {
private Long createRole(Set<Long> menuIds) {
// 创建角色
RoleSaveReqVO reqVO = new RoleSaveReqVO();
reqVO.setName(RoleCodeEnum.TENANT_ADMIN.getName()).setCode(RoleCodeEnum.TENANT_ADMIN.getCode())
.setSort(0).setRemark("系统自动生成");
Long roleId = roleService.createRole(reqVO, RoleTypeEnum.SYSTEM.getType());
// 分配权限
permissionService.assignRoleMenu(roleId, tenantPackage.getMenuIds());
permissionService.assignRoleMenu(roleId, menuIds);
return roleId;
}
@ -165,14 +197,19 @@ public class TenantServiceImpl implements TenantService {
// 校验租户域名是否重复
validTenantWebsiteDuplicate(updateReqVO.getWebsite(), updateReqVO.getId());
// 校验套餐被禁用
TenantPackageDO tenantPackage = tenantPackageService.validTenantPackage(updateReqVO.getPackageId());
Set<String> packageSet = updateReqVO.getPackageId();
Set<Long> menuIds = new HashSet<>();
for (String packageId:packageSet){
ServicePackageDO servicePackageDO = servicePackageService.validServicePackage(packageId);
menuIds.addAll(servicePackageDO.getMenuIds());
}
// 更新租户
TenantDO updateObj = BeanUtils.toBean(updateReqVO, TenantDO.class);
tenantMapper.updateById(updateObj);
// 如果套餐发生变化则修改其角色的权限
if (ObjectUtil.notEqual(tenant.getPackageId(), updateReqVO.getPackageId())) {
updateTenantRoleMenu(tenant.getId(), tenantPackage.getMenuIds());
updateTenantRoleMenu(tenant.getId(), menuIds);
}
//更新租户顶级部门名称
DeptDO deptDO = deptService.getTenantDeptTop(updateReqVO.getId());
@ -264,7 +301,20 @@ public class TenantServiceImpl implements TenantService {
@Override
public PageResult<TenantDO> getTenantPage(TenantPageReqVO pageReqVO) {
return tenantMapper.selectPage(pageReqVO);
PageResult<TenantDO> result = tenantMapper.selectPage(pageReqVO);
//查出所有服务
List<ServicePackageDO> list = servicePackageService.getServicePackageListByStatus(CommonStatusEnum.ENABLE.getStatus());
Map<String,String> map = list.stream().collect(Collectors.toMap(ServicePackageDO::getId,ServicePackageDO::getName));
result.getList().forEach(item->{
Set<String> strSet = new HashSet<>();
if(null!=item.getPackageId()){
for (String id :item.getPackageId()){
strSet.add(map.get(id));
}
}
item.setPackageId(strSet);
});
return result;
}
@Override
@ -282,6 +332,18 @@ public class TenantServiceImpl implements TenantService {
return tenantMapper.selectCountByPackageId(packageId);
}
/**
* 获得使用指定套餐的租户数量
*
* @param packageId 租户套餐编号
* @return 租户数量
*/
@Override
@TenantIgnore
public Long getTenantCountByPackageId(String packageId) {
return tenantMapper.selectCount(new LambdaQueryWrapper<TenantDO>().like(TenantDO::getPackageId,packageId));
}
@Override
public List<TenantDO> getTenantListByPackageId(Long packageId) {
return tenantMapper.selectListByPackageId(packageId);
@ -307,18 +369,20 @@ public class TenantServiceImpl implements TenantService {
}
// 获得租户然后获得菜单
TenantDO tenant = getTenant(TenantContextHolder.getRequiredTenantId());
Set<Long> menuIds;
Set<Long> menuIds = new HashSet<>();
if (isSystemTenant(tenant)) { // 系统租户菜单是全量的
menuIds = CollectionUtils.convertSet(menuService.getMenuList(), MenuDO::getId);
} else {
menuIds = tenantPackageService.getTenantPackage(tenant.getPackageId()).getMenuIds();
for (String packageId:tenant.getPackageId()){
menuIds.addAll(servicePackageService.getServicePackage(packageId).getMenuIds());
}
}
// 执行处理器
handler.handle(menuIds);
}
private static boolean isSystemTenant(TenantDO tenant) {
return Objects.equals(tenant.getPackageId(), TenantDO.PACKAGE_ID_SYSTEM);
return null==tenant.getPackageId();
}
private boolean isTenantDisable() {

View File

@ -74,6 +74,15 @@ public interface AdminUserService {
*/
void updateUserPassword(Long id, String password);
/**
* 修改用户所属部门
* @author vinjor-M
* @date 16:34 2024/8/2
* @param id 用户id
* @param deptId H部门id
**/
void updateUserDept(Long id,Long deptId);
/**
* 修改状态
*

View File

@ -207,6 +207,22 @@ public class AdminUserServiceImpl implements AdminUserService {
LogRecordContext.putVariable("newPassword", updateObj.getPassword());
}
@Override
public void updateUserDept(Long id, Long deptId) {
// 1. 校验用户存在
AdminUserDO user = validateUserExists(id);
// 2. 更新密码
AdminUserDO updateObj = new AdminUserDO();
updateObj.setId(id);
updateObj.setDeptId(deptId);
userMapper.updateById(updateObj);
// 3. 记录操作日志上下文
LogRecordContext.putVariable("user", user);
LogRecordContext.putVariable("newDept", updateObj.getDeptId());
}
@Override
public void updateUserStatus(Long id, Integer status) {
// 校验用户存在

View File

@ -27,9 +27,7 @@ import org.springframework.context.annotation.Import;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.*;
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
@ -153,7 +151,6 @@ public class TenantServiceImplTest extends BaseDbUnitTest {
TenantSaveReqVO reqVO = randomPojo(TenantSaveReqVO.class, o -> {
o.setContactName("芋道");
o.setContactMobile("15601691300");
o.setPackageId(100L);
o.setStatus(randomCommonStatus());
o.setWebsite("https://www.iocoder.cn");
o.setUsername("yunai");
@ -185,11 +182,12 @@ public class TenantServiceImplTest extends BaseDbUnitTest {
o.setStatus(randomCommonStatus());
o.setWebsite(randomString());
});
Set<String> set = new HashSet<>();
set.add("0");
// mock 套餐
TenantPackageDO tenantPackage = randomPojo(TenantPackageDO.class,
o -> o.setMenuIds(asSet(200L, 201L)));
when(tenantPackageService.validTenantPackage(eq(reqVO.getPackageId()))).thenReturn(tenantPackage);
// when(tenantPackageService.validTenantPackage(eq(reqVO.getPackageId()))).thenReturn(tenantPackage);
// mock 所有角色
RoleDO role100 = randomPojo(RoleDO.class, o -> o.setId(100L).setCode(RoleCodeEnum.TENANT_ADMIN.getCode()));
role100.setTenantId(dbTenant.getId());
@ -221,7 +219,9 @@ public class TenantServiceImplTest extends BaseDbUnitTest {
@Test
public void testUpdateTenant_system() {
// mock 数据
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(PACKAGE_ID_SYSTEM));
Set<String> set = new HashSet<>();
set.add("0");
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(set));
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
// 准备参数
TenantSaveReqVO reqVO = randomPojo(TenantSaveReqVO.class, o -> {
@ -259,7 +259,9 @@ public class TenantServiceImplTest extends BaseDbUnitTest {
@Test
public void testDeleteTenant_system() {
// mock 数据
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(PACKAGE_ID_SYSTEM));
Set<String> set = new HashSet<>();
set.add("0");
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(set));
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
// 准备参数
Long id = dbTenant.getId();
@ -346,9 +348,13 @@ public class TenantServiceImplTest extends BaseDbUnitTest {
@Test
public void testGetTenantListByPackageId() {
// mock 数据
TenantDO dbTenant1 = randomPojo(TenantDO.class, o -> o.setPackageId(1L));
Set<String> set = new HashSet<>();
set.add("1");
TenantDO dbTenant1 = randomPojo(TenantDO.class, o -> o.setPackageId(set));
tenantMapper.insert(dbTenant1);// @Sql: 先插入出一条存在的数据
TenantDO dbTenant2 = randomPojo(TenantDO.class, o -> o.setPackageId(2L));
Set<String> set2 = new HashSet<>();
set.add("2");
TenantDO dbTenant2 = randomPojo(TenantDO.class, o -> o.setPackageId(set2));
tenantMapper.insert(dbTenant2);// @Sql: 先插入出一条存在的数据
// 调用
@ -360,9 +366,13 @@ public class TenantServiceImplTest extends BaseDbUnitTest {
@Test
public void testGetTenantCountByPackageId() {
// mock 数据
TenantDO dbTenant1 = randomPojo(TenantDO.class, o -> o.setPackageId(1L));
Set<String> set = new HashSet<>();
set.add("1");
TenantDO dbTenant1 = randomPojo(TenantDO.class, o -> o.setPackageId(set));
tenantMapper.insert(dbTenant1);// @Sql: 先插入出一条存在的数据
TenantDO dbTenant2 = randomPojo(TenantDO.class, o -> o.setPackageId(2L));
Set<String> set2 = new HashSet<>();
set.add("2");
TenantDO dbTenant2 = randomPojo(TenantDO.class, o -> o.setPackageId(set2));
tenantMapper.insert(dbTenant2);// @Sql: 先插入出一条存在的数据
// 调用
@ -423,7 +433,9 @@ public class TenantServiceImplTest extends BaseDbUnitTest {
// mock 未禁用
when(tenantProperties.getEnable()).thenReturn(true);
// mock 租户
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(PACKAGE_ID_SYSTEM));
Set<String> set = new HashSet<>();
set.add("1");
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(set));
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
TenantContextHolder.setTenantId(dbTenant.getId());
// mock 菜单
@ -443,7 +455,9 @@ public class TenantServiceImplTest extends BaseDbUnitTest {
// mock 未禁用
when(tenantProperties.getEnable()).thenReturn(true);
// mock 租户
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(200L));
Set<String> set = new HashSet<>();
set.add("200");
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(set));
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
TenantContextHolder.setTenantId(dbTenant.getId());
// mock 菜单