| | |
| | | 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.collections.CollectionUtils; |
| | | 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 |
| | |
| | | @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); |
| | | } |
| | | |
| | |
| | | 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(CollectionUtils.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()); |
| | | menuWrapper.eq(MenuDO::getParentId, 0); |
| | | 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; |
| | | } |
| | | |
| | | } |