houzhongjian
2024-12-26 b482efaf698d5fd3920ff63ccde1c819f9eb34ba
提交 | 用户 | 时间
5f25e3 1 package com.iailab.module.system.service.app;
2
7da8f1 3 import cn.hutool.core.collection.CollUtil;
818a01 4 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
H 5 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
5f25e3 6 import com.iailab.framework.common.pojo.PageResult;
7 import com.iailab.framework.common.util.object.BeanUtils;
818a01 8 import com.iailab.framework.mybatis.core.query.LambdaQueryWrapperX;
H 9 import com.iailab.framework.security.core.util.SecurityFrameworkUtils;
10 import com.iailab.framework.tenant.core.aop.TenantIgnore;
7da8f1 11 import com.iailab.module.system.api.app.dto.AppMenuRespDTO;
5f25e3 12 import com.iailab.module.system.controller.admin.app.vo.AppPageReqVO;
13 import com.iailab.module.system.controller.admin.app.vo.AppSaveReqVO;
7da8f1 14 import com.iailab.module.system.controller.admin.auth.vo.AuthPermissionInfoRespVO;
H 15 import com.iailab.module.system.convert.auth.AuthConvert;
5f25e3 16 import com.iailab.module.system.dal.dataobject.app.AppDO;
818a01 17 import com.iailab.module.system.dal.dataobject.permission.MenuDO;
H 18 import com.iailab.module.system.dal.dataobject.permission.RoleDO;
19 import com.iailab.module.system.dal.dataobject.permission.RoleMenuDO;
20 import com.iailab.module.system.dal.dataobject.tenant.TenantDO;
21 import com.iailab.module.system.dal.dataobject.tenant.TenantPackageDO;
5f25e3 22 import com.iailab.module.system.dal.mysql.app.AppMapper;
818a01 23 import com.iailab.module.system.dal.mysql.permission.MenuMapper;
H 24 import com.iailab.module.system.dal.mysql.permission.RoleMapper;
25 import com.iailab.module.system.dal.mysql.permission.RoleMenuMapper;
26 import com.iailab.module.system.dal.mysql.tenant.TenantMapper;
27 import com.iailab.module.system.dal.mysql.tenant.TenantPackageMapper;
28 import com.iailab.module.system.enums.permission.MenuTypeEnum;
7da8f1 29 import com.iailab.module.system.service.permission.MenuService;
818a01 30 import com.iailab.module.system.service.permission.PermissionService;
5f25e3 31 import lombok.extern.slf4j.Slf4j;
b482ef 32 import org.apache.commons.collections.CollectionUtils;
818a01 33 import org.apache.commons.lang3.ObjectUtils;
5f25e3 34 import org.springframework.stereotype.Service;
818a01 35 import org.springframework.transaction.annotation.Transactional;
5f25e3 36
37 import javax.annotation.Resource;
818a01 38 import java.util.*;
H 39
40 import static com.iailab.framework.common.exception.util.ServiceExceptionUtil.exception;
7da8f1 41 import static com.iailab.framework.common.util.collection.CollectionUtils.convertSet;
818a01 42 import static com.iailab.framework.tenant.core.context.TenantContextHolder.getTenantId;
H 43 import static com.iailab.module.system.enums.ErrorCodeConstants.MENU_EXISTS_CHILDREN;
44 import static com.iailab.module.system.enums.ErrorCodeConstants.MENU_NOT_EXISTS;
5f25e3 45
46 /**
47  * @author PanZhibao
48  * @Description
49  * @createTime 2024年08月17日
50  */
51 @Service
52 @Slf4j
53 public class AppServiceImpl implements AppService {
54
55     @Resource
56     private AppMapper appMapper;
57
818a01 58     @Resource
H 59     private MenuMapper menuMapper;
60
61     @Resource
62     private RoleMapper roleMapper;
63
64     @Resource
65     private RoleMenuMapper roleMenuMapper;
66
67     @Resource
68     private PermissionService permissionService;
69
70     @Resource
71     private TenantPackageMapper tenantPackageMapper;
72
73     @Resource
74     private TenantMapper tenantMapper;
7da8f1 75
H 76     @Resource
77     private MenuService menuService;
818a01 78
5f25e3 79
80     @Override
818a01 81     @Transactional(rollbackFor = Exception.class)
H 82     @TenantIgnore
5f25e3 83     public Long create(AppSaveReqVO createReqVO) {
84         AppDO app = BeanUtils.toBean(createReqVO, AppDO.class);
85         appMapper.insert(app);
818a01 86 //        //为应用创建默认菜单并授权
H 87         dealAppMenu(1, app);
5f25e3 88         return app.getId();
89     }
90
91     @Override
818a01 92     @Transactional(rollbackFor = Exception.class)
H 93     @TenantIgnore
5f25e3 94     public Long update(AppSaveReqVO createReqVO) {
95         AppDO app = BeanUtils.toBean(createReqVO, AppDO.class);
96         appMapper.updateById(app);
818a01 97 //        //修改默认菜单并授权
H 98         dealAppMenu(2, app);
5f25e3 99         return app.getId();
100     }
101
102     @Override
818a01 103     @Transactional(rollbackFor = Exception.class)
H 104     @TenantIgnore
5f25e3 105     public void delete(Long id) {
818a01 106         AppDO appDO = new AppDO();
H 107         appDO.setId(id);
108         dealAppMenu(3, appDO);
5f25e3 109         appMapper.deleteById(id);
110     }
111
112     @Override
113     public AppDO getInfo(Long id) {
114         return appMapper.selectById(id);
115     }
116
117     @Override
118     public PageResult<AppDO> getPage(AppPageReqVO pageReqVO) {
119         return appMapper.selectPage(pageReqVO);
120     }
121
818a01 122     @Override
H 123     public List<AppDO> getList() {
124         Long tenantId = getTenantId();
125         LambdaQueryWrapperX<MenuDO> menuDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>();
126         menuDOLambdaQueryWrapperX.eq(MenuDO::getParentId, 0)
127                 .eq(MenuDO::getAppId, 0);
128         if (tenantId != 1) {
129             //非系统租户查租户套餐
130             TenantDO tenantDO = tenantMapper.selectById(tenantId);
131             TenantPackageDO tenantPackageDO = tenantPackageMapper.selectById(tenantDO.getPackageId());
132             menuDOLambdaQueryWrapperX.in(MenuDO::getId, tenantPackageDO.getMenuIds());
133         }
134         //查询系统应用菜单
135 //        List<MenuDO> menuDOS = menuMapper.selectList(menuDOLambdaQueryWrapperX);
136 //        List<AppDO> systemApps = convertMenuToApp(menuDOS);
137         List<AppDO> systemApps = new ArrayList<>();
138         List<AppDO> appDOS = appMapper.selectList();
139         //暂时先遍历处理应用菜单和应用类型
140         appDOS.stream().forEach(appDO -> {
141             List<MenuDO> menuDOS = menuMapper.selectList(new LambdaQueryWrapper<MenuDO>().eq(MenuDO::getParentId, 0)
142                     .eq(MenuDO::getAppId, appDO.getId()));
143             appDO.setAppMenuId(menuDOS.get(0).getId());
144             appDO.setAppType(2);
145         });
146         systemApps.addAll(appDOS);
147         return systemApps;
148     }
149
150     @Override
151     public AppDO getAppByTenantId(Long tenantId) {
152         //暂时支持一个租户对应一个应用
153         List<AppDO> appDOS = appMapper.selectList(new LambdaQueryWrapper<AppDO>().eq(AppDO::getTenantId, tenantId));
b482ef 154         if(CollectionUtils.isNotEmpty(appDOS)) {
818a01 155             return appDOS.get(0);
H 156         } else {
157             AppDO appDO = new AppDO();
158             appDO.setTenantId(tenantId);
159             appDO.setId(0L);
160             return appDO;
161         }
162     }
163
7da8f1 164     @Override
H 165     public List<AuthPermissionInfoRespVO.MenuVO> getAppMenu(Long id) {
166         MenuDO menuDO = menuMapper.selectById(id);
167         List<MenuDO> children = new LinkedList<>();
168         // 遍历每一层
169         Collection<Long> parentIds = Collections.singleton(id);
170         for (int i = 0; i < Short.MAX_VALUE; i++) { // 使用 Short.MAX_VALUE 避免 bug 场景下,存在死循环
171             // 查询当前层,所有的子应用菜单
172             List<MenuDO> menus = menuMapper.selectListByParentId(parentIds);
173             // 1. 如果没有子菜单,则结束遍历
174             if (CollUtil.isEmpty(menus)) {
175                 break;
176             }
177             // 2. 如果有子应用菜单,继续遍历
178             children.addAll(menus);
179             parentIds = convertSet(menus, MenuDO::getId);
180         }
181         children = menuService.filterDisableMenus(children);
182         return AuthConvert.INSTANCE.buildMenuTree(children, id, menuDO.getPath());
183
184     }
818a01 185
H 186     private void dealAppMenu(Integer type, AppDO app){
187         String loginUserNickname = SecurityFrameworkUtils.getLoginUserNickname();
188         MenuDO menuDO = new MenuDO();
189         menuDO.setAppId(app.getId());
190         menuDO.setName(app.getAppName());
191         menuDO.setType(MenuTypeEnum.DIR.getType());
192         menuDO.setSort(app.getOrderNum());
193         menuDO.setPath("/" + app.getAppCode());
194         menuDO.setTenantId(app.getTenantId());
195         if(type == 1){
196             menuDO.setCreator(loginUserNickname);
197             menuDO.setCreateTime(app.getCreateTime());
874287 198             menuDO.setIcon("fa-solid:border-none"); //默认icon
818a01 199             menuMapper.insert(menuDO);
7da8f1 200 //            //内置租户角色分配菜单
H 201 //            assignRoleMenu(menuDO.getId(), app.getTenantId());
818a01 202         } else if(type == 2){
H 203             LambdaUpdateWrapper<MenuDO> updateWrapper = new LambdaUpdateWrapper<>();
204             updateWrapper.eq(MenuDO::getAppId, app.getId());
205             updateWrapper.eq(MenuDO::getParentId, 0L);
206             List<MenuDO> menuDOS = menuMapper.selectList(updateWrapper);
207             if(menuDOS.size() > 0){
208                 menuDO.setUpdater(loginUserNickname);
209                 menuDO.setUpdateTime(app.getUpdateTime());
210                 menuMapper.update(menuDO, updateWrapper);
211             } else {
212                 menuDO.setCreator(loginUserNickname);
213                 menuDO.setCreateTime(app.getCreateTime());
214                 menuMapper.insert(menuDO);
7da8f1 215 //                //内置租户角色分配菜单
H 216 //                assignRoleMenu(menuDO.getId(), app.getTenantId());
818a01 217             }
H 218         } else if(type == 3){
219             //删除租户、角色权限
220             app = appMapper.selectById(app.getId());
221             LambdaQueryWrapperX<MenuDO> menuWrapper = new LambdaQueryWrapperX<>();
222             menuWrapper.eq(MenuDO::getAppId, app.getId());
223             menuWrapper.eq(MenuDO::getType, MenuTypeEnum.DIR.getType());
bb2880 224             menuWrapper.eq(MenuDO::getParentId, 0);
818a01 225             MenuDO menu = menuMapper.selectOne(menuWrapper);
H 226             TenantDO tenantDO = tenantMapper.selectById(app.getTenantId());
7da8f1 227             if(ObjectUtils.isNotEmpty(menu) && ObjectUtils.isNotEmpty(tenantDO)) {
H 228                 TenantPackageDO tenantPackageDO = tenantPackageMapper.selectById(tenantDO.getPackageId());
229                 Set<Long> menuIds = tenantPackageDO.getMenuIds();
230                 menuIds.remove(menu.getId());
231                 // 校验是否还有子菜单
232                 if (menuMapper.selectCountByParentId(menu.getId()) > 0) {
233                     throw exception(MENU_EXISTS_CHILDREN);
234                 }
235                 // 校验删除的菜单是否存在
236                 if (menuMapper.selectById(menu.getId()) == null) {
237                     throw exception(MENU_NOT_EXISTS);
238                 }
239                 // 标记删除
240                 menuMapper.deleteById(menu.getId());
241                 // 删除授予给角色的权限
242                 permissionService.processMenuDeleted(menu.getId());
243                 //删除菜单
244                 menuMapper.delete(menuWrapper);
818a01 245             }
H 246         }
247     }
248
249     private void assignRoleMenu(Long menuId, Long tenantId) {
250         //查询内置租户管理员
251         LambdaQueryWrapperX<RoleDO> roleQueryWrapper = new LambdaQueryWrapperX<>();
252         roleQueryWrapper.eq(RoleDO::getCode, "tenant_admin");
253         roleQueryWrapper.eq(RoleDO::getTenantId, tenantId);
254         RoleDO roleDO = roleMapper.selectOne(roleQueryWrapper);
255         RoleMenuDO entity = new RoleMenuDO();
256         entity.setRoleId(roleDO.getId());
257         entity.setMenuId(menuId);
258         entity.setTenantId(tenantId);
259         roleMenuMapper.insert(entity);
260         TenantDO tenantDO = tenantMapper.selectById(tenantId);
261         TenantPackageDO tenantPackageDO = tenantPackageMapper.selectById(tenantDO.getPackageId());
262         Set<Long> menuIds = tenantPackageDO.getMenuIds();
263         menuIds.add(menuId);
264         tenantPackageMapper.updateById(tenantPackageDO);
265     }
266
267     private List<AppDO> convertMenuToApp(List<MenuDO> menuDOS) {
268         List<AppDO> appDOS = new ArrayList<>();
269         menuDOS.stream().forEach(menuDO -> {
270             AppDO appDO = new AppDO();
271             appDO.setAppName(menuDO.getName());
272             appDO.setOrderNum(menuDO.getSort());
273             appDO.setAppMenuId(menuDO.getId());
274             appDO.setAppType(1);
275             appDOS.add(appDO);
276         });
277         return appDOS;
278     }
279
7da8f1 280     public List<AppDO> selectBatchIds(List<Long> ids) {
H 281         List<AppDO> appDOS = appMapper.selectBatchIds(ids);
282         return appDOS;
283     }
284
5f25e3 285 }