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