package com.iailab.module.system.service.app;
|
|
import cn.hutool.core.collection.CollUtil;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.iailab.framework.common.pojo.PageResult;
|
import com.iailab.framework.common.util.object.BeanUtils;
|
import com.iailab.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import com.iailab.framework.security.core.util.SecurityFrameworkUtils;
|
import com.iailab.framework.tenant.core.aop.TenantIgnore;
|
import com.iailab.module.system.api.app.dto.AppMenuRespDTO;
|
import com.iailab.module.system.controller.admin.app.vo.AppPageReqVO;
|
import com.iailab.module.system.controller.admin.app.vo.AppSaveReqVO;
|
import com.iailab.module.system.controller.admin.auth.vo.AuthPermissionInfoRespVO;
|
import com.iailab.module.system.convert.auth.AuthConvert;
|
import com.iailab.module.system.dal.dataobject.app.AppDO;
|
import com.iailab.module.system.dal.dataobject.permission.MenuDO;
|
import com.iailab.module.system.dal.dataobject.permission.RoleDO;
|
import com.iailab.module.system.dal.dataobject.permission.RoleMenuDO;
|
import com.iailab.module.system.dal.dataobject.tenant.TenantDO;
|
import com.iailab.module.system.dal.dataobject.tenant.TenantPackageDO;
|
import com.iailab.module.system.dal.mysql.app.AppMapper;
|
import com.iailab.module.system.dal.mysql.permission.MenuMapper;
|
import com.iailab.module.system.dal.mysql.permission.RoleMapper;
|
import com.iailab.module.system.dal.mysql.permission.RoleMenuMapper;
|
import com.iailab.module.system.dal.mysql.tenant.TenantMapper;
|
import com.iailab.module.system.dal.mysql.tenant.TenantPackageMapper;
|
import com.iailab.module.system.enums.permission.MenuTypeEnum;
|
import com.iailab.module.system.service.permission.MenuService;
|
import com.iailab.module.system.service.permission.PermissionService;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.lang3.ObjectUtils;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import javax.annotation.Resource;
|
import java.util.*;
|
|
import static com.iailab.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static com.iailab.framework.common.util.collection.CollectionUtils.convertSet;
|
import static com.iailab.framework.tenant.core.context.TenantContextHolder.getTenantId;
|
import static com.iailab.module.system.enums.ErrorCodeConstants.MENU_EXISTS_CHILDREN;
|
import static com.iailab.module.system.enums.ErrorCodeConstants.MENU_NOT_EXISTS;
|
|
/**
|
* @author PanZhibao
|
* @Description
|
* @createTime 2024年08月17日
|
*/
|
@Service
|
@Slf4j
|
public class AppServiceImpl implements AppService {
|
|
@Resource
|
private AppMapper appMapper;
|
|
@Resource
|
private MenuMapper menuMapper;
|
|
@Resource
|
private RoleMapper roleMapper;
|
|
@Resource
|
private RoleMenuMapper roleMenuMapper;
|
|
@Resource
|
private PermissionService permissionService;
|
|
@Resource
|
private TenantPackageMapper tenantPackageMapper;
|
|
@Resource
|
private TenantMapper tenantMapper;
|
|
@Resource
|
private MenuService menuService;
|
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
@TenantIgnore
|
public Long create(AppSaveReqVO createReqVO) {
|
AppDO app = BeanUtils.toBean(createReqVO, AppDO.class);
|
appMapper.insert(app);
|
// //为应用创建默认菜单并授权
|
dealAppMenu(1, app);
|
return app.getId();
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
@TenantIgnore
|
public Long update(AppSaveReqVO createReqVO) {
|
AppDO app = BeanUtils.toBean(createReqVO, AppDO.class);
|
appMapper.updateById(app);
|
// //修改默认菜单并授权
|
dealAppMenu(2, app);
|
return app.getId();
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
@TenantIgnore
|
public void delete(Long id) {
|
AppDO appDO = new AppDO();
|
appDO.setId(id);
|
dealAppMenu(3, appDO);
|
appMapper.deleteById(id);
|
}
|
|
@Override
|
public AppDO getInfo(Long id) {
|
return appMapper.selectById(id);
|
}
|
|
@Override
|
public PageResult<AppDO> getPage(AppPageReqVO pageReqVO) {
|
return appMapper.selectPage(pageReqVO);
|
}
|
|
@Override
|
public List<AppDO> getList() {
|
Long tenantId = getTenantId();
|
LambdaQueryWrapperX<MenuDO> menuDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>();
|
menuDOLambdaQueryWrapperX.eq(MenuDO::getParentId, 0)
|
.eq(MenuDO::getAppId, 0);
|
if (tenantId != 1) {
|
//非系统租户查租户套餐
|
TenantDO tenantDO = tenantMapper.selectById(tenantId);
|
TenantPackageDO tenantPackageDO = tenantPackageMapper.selectById(tenantDO.getPackageId());
|
menuDOLambdaQueryWrapperX.in(MenuDO::getId, tenantPackageDO.getMenuIds());
|
}
|
//查询系统应用菜单
|
// List<MenuDO> menuDOS = menuMapper.selectList(menuDOLambdaQueryWrapperX);
|
// List<AppDO> systemApps = convertMenuToApp(menuDOS);
|
List<AppDO> systemApps = new ArrayList<>();
|
List<AppDO> appDOS = appMapper.selectList();
|
//暂时先遍历处理应用菜单和应用类型
|
appDOS.stream().forEach(appDO -> {
|
List<MenuDO> menuDOS = menuMapper.selectList(new LambdaQueryWrapper<MenuDO>().eq(MenuDO::getParentId, 0)
|
.eq(MenuDO::getAppId, appDO.getId()));
|
appDO.setAppMenuId(menuDOS.get(0).getId());
|
appDO.setAppType(2);
|
});
|
systemApps.addAll(appDOS);
|
return systemApps;
|
}
|
|
@Override
|
public AppDO getAppByTenantId(Long tenantId) {
|
//暂时支持一个租户对应一个应用
|
List<AppDO> appDOS = appMapper.selectList(new LambdaQueryWrapper<AppDO>().eq(AppDO::getTenantId, tenantId));
|
if(ObjectUtils.isNotEmpty(appDOS)) {
|
return appDOS.get(0);
|
} else {
|
AppDO appDO = new AppDO();
|
appDO.setTenantId(tenantId);
|
appDO.setId(0L);
|
return appDO;
|
}
|
}
|
|
@Override
|
public List<AuthPermissionInfoRespVO.MenuVO> getAppMenu(Long id) {
|
MenuDO menuDO = menuMapper.selectById(id);
|
List<MenuDO> children = new LinkedList<>();
|
// 遍历每一层
|
Collection<Long> parentIds = Collections.singleton(id);
|
for (int i = 0; i < Short.MAX_VALUE; i++) { // 使用 Short.MAX_VALUE 避免 bug 场景下,存在死循环
|
// 查询当前层,所有的子应用菜单
|
List<MenuDO> menus = menuMapper.selectListByParentId(parentIds);
|
// 1. 如果没有子菜单,则结束遍历
|
if (CollUtil.isEmpty(menus)) {
|
break;
|
}
|
// 2. 如果有子应用菜单,继续遍历
|
children.addAll(menus);
|
parentIds = convertSet(menus, MenuDO::getId);
|
}
|
children = menuService.filterDisableMenus(children);
|
return AuthConvert.INSTANCE.buildMenuTree(children, id, menuDO.getPath());
|
|
}
|
|
private void dealAppMenu(Integer type, AppDO app){
|
String loginUserNickname = SecurityFrameworkUtils.getLoginUserNickname();
|
MenuDO menuDO = new MenuDO();
|
menuDO.setAppId(app.getId());
|
menuDO.setName(app.getAppName());
|
menuDO.setType(MenuTypeEnum.DIR.getType());
|
menuDO.setSort(app.getOrderNum());
|
menuDO.setPath("/" + app.getAppCode());
|
menuDO.setTenantId(app.getTenantId());
|
if(type == 1){
|
menuDO.setCreator(loginUserNickname);
|
menuDO.setCreateTime(app.getCreateTime());
|
menuDO.setIcon("fa-solid:border-none"); //默认icon
|
menuMapper.insert(menuDO);
|
// //内置租户角色分配菜单
|
// assignRoleMenu(menuDO.getId(), app.getTenantId());
|
} else if(type == 2){
|
LambdaUpdateWrapper<MenuDO> updateWrapper = new LambdaUpdateWrapper<>();
|
updateWrapper.eq(MenuDO::getAppId, app.getId());
|
updateWrapper.eq(MenuDO::getParentId, 0L);
|
List<MenuDO> menuDOS = menuMapper.selectList(updateWrapper);
|
if(menuDOS.size() > 0){
|
menuDO.setUpdater(loginUserNickname);
|
menuDO.setUpdateTime(app.getUpdateTime());
|
menuMapper.update(menuDO, updateWrapper);
|
} else {
|
menuDO.setCreator(loginUserNickname);
|
menuDO.setCreateTime(app.getCreateTime());
|
menuMapper.insert(menuDO);
|
// //内置租户角色分配菜单
|
// assignRoleMenu(menuDO.getId(), app.getTenantId());
|
}
|
} else if(type == 3){
|
//删除租户、角色权限
|
app = appMapper.selectById(app.getId());
|
LambdaQueryWrapperX<MenuDO> menuWrapper = new LambdaQueryWrapperX<>();
|
menuWrapper.eq(MenuDO::getAppId, app.getId());
|
menuWrapper.eq(MenuDO::getType, MenuTypeEnum.DIR.getType());
|
MenuDO menu = menuMapper.selectOne(menuWrapper);
|
TenantDO tenantDO = tenantMapper.selectById(app.getTenantId());
|
if(ObjectUtils.isNotEmpty(menu) && ObjectUtils.isNotEmpty(tenantDO)) {
|
TenantPackageDO tenantPackageDO = tenantPackageMapper.selectById(tenantDO.getPackageId());
|
Set<Long> menuIds = tenantPackageDO.getMenuIds();
|
menuIds.remove(menu.getId());
|
// 校验是否还有子菜单
|
if (menuMapper.selectCountByParentId(menu.getId()) > 0) {
|
throw exception(MENU_EXISTS_CHILDREN);
|
}
|
// 校验删除的菜单是否存在
|
if (menuMapper.selectById(menu.getId()) == null) {
|
throw exception(MENU_NOT_EXISTS);
|
}
|
// 标记删除
|
menuMapper.deleteById(menu.getId());
|
// 删除授予给角色的权限
|
permissionService.processMenuDeleted(menu.getId());
|
//删除菜单
|
menuMapper.delete(menuWrapper);
|
}
|
}
|
}
|
|
private void assignRoleMenu(Long menuId, Long tenantId) {
|
//查询内置租户管理员
|
LambdaQueryWrapperX<RoleDO> roleQueryWrapper = new LambdaQueryWrapperX<>();
|
roleQueryWrapper.eq(RoleDO::getCode, "tenant_admin");
|
roleQueryWrapper.eq(RoleDO::getTenantId, tenantId);
|
RoleDO roleDO = roleMapper.selectOne(roleQueryWrapper);
|
RoleMenuDO entity = new RoleMenuDO();
|
entity.setRoleId(roleDO.getId());
|
entity.setMenuId(menuId);
|
entity.setTenantId(tenantId);
|
roleMenuMapper.insert(entity);
|
TenantDO tenantDO = tenantMapper.selectById(tenantId);
|
TenantPackageDO tenantPackageDO = tenantPackageMapper.selectById(tenantDO.getPackageId());
|
Set<Long> menuIds = tenantPackageDO.getMenuIds();
|
menuIds.add(menuId);
|
tenantPackageMapper.updateById(tenantPackageDO);
|
}
|
|
private List<AppDO> convertMenuToApp(List<MenuDO> menuDOS) {
|
List<AppDO> appDOS = new ArrayList<>();
|
menuDOS.stream().forEach(menuDO -> {
|
AppDO appDO = new AppDO();
|
appDO.setAppName(menuDO.getName());
|
appDO.setOrderNum(menuDO.getSort());
|
appDO.setAppMenuId(menuDO.getId());
|
appDO.setAppType(1);
|
appDOS.add(appDO);
|
});
|
return appDOS;
|
}
|
|
public List<AppDO> selectBatchIds(List<Long> ids) {
|
List<AppDO> appDOS = appMapper.selectBatchIds(ids);
|
return appDOS;
|
}
|
|
}
|