SaasRoleMenuHandler.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. package com.persagy.account.manage;
  2. import java.util.ArrayList;
  3. import java.util.Comparator;
  4. import java.util.List;
  5. import java.util.Map;
  6. import java.util.stream.Collectors;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.stereotype.Component;
  9. import org.springframework.transaction.annotation.Transactional;
  10. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  11. import com.google.common.collect.Lists;
  12. import com.persagy.account.pojo.dto.SaasAccountRole;
  13. import com.persagy.account.pojo.dto.SaasFunction;
  14. import com.persagy.account.pojo.dto.SaasMenu;
  15. import com.persagy.account.pojo.dto.SaasProduct;
  16. import com.persagy.account.pojo.dto.SaasRole;
  17. import com.persagy.account.pojo.dto.SaasRoleMenu;
  18. import com.persagy.account.pojo.vo.auth.SaasMenuFunctionPageVO;
  19. import com.persagy.account.pojo.vo.auth.SaasMenuFunctionVO;
  20. import com.persagy.account.pojo.vo.menu.SaasMenuQueryVO;
  21. import com.persagy.account.pojo.vo.role.SaasRoleDeleteVO;
  22. import com.persagy.account.service.ISaasAccountRoleService;
  23. import com.persagy.account.service.ISaasFunctionService;
  24. import com.persagy.account.service.ISaasMenuService;
  25. import com.persagy.account.service.ISaasProductService;
  26. import com.persagy.account.service.ISaasRoleMenuService;
  27. import com.persagy.account.service.ISaasRoleService;
  28. import com.persagy.common.constant.SaasCommonConstant;
  29. import com.persagy.common.exception.BusinessException;
  30. import com.persagy.common.utils.StringUtil;
  31. import cn.hutool.core.collection.CollectionUtil;
  32. /**
  33. * 角色菜单管理
  34. *
  35. * @version
  36. * @description
  37. * @company persagy
  38. * @author zhangqiankun
  39. * @since 2021年3月15日: 上午10:49:15
  40. */
  41. @Component
  42. public class SaasRoleMenuHandler {
  43. @Autowired
  44. private SaasAuthHandler saasAuthHandler;
  45. @Autowired
  46. private ISaasRoleService saasRoleService;
  47. @Autowired
  48. private ISaasMenuService saasMenuService;
  49. @Autowired
  50. private SaasProductHandler saasProductHandler;
  51. @Autowired
  52. private ISaasProductService saasProductService;
  53. @Autowired
  54. private ISaasFunctionService saasFunctionService;
  55. @Autowired
  56. private ISaasRoleMenuService saasRoleMenuService;
  57. @Autowired
  58. private ISaasAccountRoleService saasAccountRoleService;
  59. /**
  60. * 获取菜单权限树,权限过滤,需要判断视角,1-集团视角,2-项目视角 项目ID存在即为项目视角
  61. *
  62. * @param queryVO
  63. * @return
  64. */
  65. public List<SaasMenu> querySaasMenuTree(SaasMenuQueryVO queryVO) {
  66. // 获取此账号对应的菜单范围
  67. Map<String, String> menuAuth = this.saasAuthHandler.validAccountAuth(queryVO.getAccountId(), queryVO.getGroupCode());
  68. if (StringUtil.isNotBlank(menuAuth.get(SaasCommonConstant.GROUP_CODE))) {
  69. queryVO.setGroupCode(menuAuth.get(SaasCommonConstant.GROUP_CODE));
  70. }
  71. // 添加数据访问控制,账号可见域,0-所有集团项目,1-单集团所有项目(此时,集团编码需存在),2-其他
  72. String accountType = menuAuth.get(SaasCommonConstant.ACCOUNT_TYPE);
  73. // 账号所属,0-运维系统,1-业务系统账号
  74. String accountBelong = menuAuth.get(SaasCommonConstant.ACCOUNT_BELONG);
  75. List<SaasMenu> menuTree = null;
  76. if (SaasCommonConstant.STR_STATUS_0.equals(accountType) && SaasCommonConstant.STR_STATUS_0.equals(accountBelong)) {
  77. // 如果是运维系统的账号,accountType为0的情况下查询所有菜单权限,其余情况走表关联查询,为1时,后续可添加
  78. menuTree = this.querySaasMenuTree(null, null, queryVO.getProjectId(), queryVO.getAppId(), true, queryVO.isMenu());
  79. } else {
  80. menuTree = this.querySaasMenuTree(queryVO.getAccountId(), queryVO.getGroupCode(), queryVO.getProjectId(), queryVO.getAppId(), false, queryVO.isMenu());
  81. }
  82. return menuTree;
  83. }
  84. /**
  85. * 查询账号菜单功能权限树,菜单定义和角色定义编码相同,所以这里应该同步传递
  86. *
  87. * @param accountId
  88. * @param groupCode
  89. * @param projectId
  90. * @param appId
  91. * @param isAdmin 是否为超管 true-是,此为系统超管
  92. * @param isMenu 是否仅查询出菜单树,true-是
  93. * @return 空集合或数据菜单树
  94. */
  95. public List<SaasMenu> querySaasMenuTree(String accountId, String groupCode, String projectId, String appId, boolean isAdmin, boolean isMenu) {
  96. // 1.获取此账号对应菜单集合
  97. List<SaasMenu> menuTree = null;
  98. if (isAdmin) {
  99. LambdaQueryWrapper<SaasMenu> queryWrapper = new SaasMenu.Builder().createQueryWrapper().appIdEq(appId).menuTypeEq(SaasCommonConstant.STR_STATUS_0).builderQueryWrapper();
  100. menuTree = this.saasMenuService.list(queryWrapper);
  101. } else {
  102. menuTree = this.saasMenuService.querySaasMenuTree(accountId, groupCode, appId, SaasCommonConstant.STATUS_1);
  103. }
  104. if (CollectionUtil.isEmpty(menuTree)) {
  105. return Lists.newArrayList();
  106. }
  107. // 2.转为菜单树
  108. List<SaasMenu> topMenus = new ArrayList<SaasMenu>();
  109. for (int i = menuTree.size() - 1; i >= 0; i--) {
  110. SaasMenu saasMenu = menuTree.get(i);
  111. if (StringUtil.isBlank(saasMenu.getParentId())) {
  112. topMenus.add(saasMenu);
  113. menuTree.remove(i);
  114. }
  115. }
  116. List<SaasMenu> parents = topMenus.stream().sorted(Comparator.comparing(SaasMenu::getMenuSort)).collect(Collectors.toList());
  117. this.setMenuChildrens(accountId, groupCode, projectId, menuTree, parents, isAdmin, !isMenu);
  118. return parents;
  119. }
  120. /**
  121. * 生成菜单树
  122. * @param accountId 为null时,isAdmin 为true
  123. * @param angle 1-集团视角,2-项目视角
  124. * @param groupCode
  125. * @param menuTree 为空时,会去查询,但是不会做权限过滤
  126. * @param parents
  127. * @param isAdmin 是否为超管 true-是
  128. * @param menuAndFun
  129. */
  130. public void setMenuChildrens(String accountId, String groupCode, String projectId, List<SaasMenu> menuTree, List<SaasMenu> parents, boolean isAdmin, boolean menuAndFun) {
  131. for (SaasMenu parent : parents) {
  132. if (StringUtil.isBlank(parent.getMenuId())) {
  133. parent.setMenuId(parent.getId());
  134. }
  135. if (StringUtil.isNotBlank(parent.getMenuUrl())) {
  136. this.saasProductHandler.queryMenuProductAuths(parent, accountId, groupCode, projectId, isAdmin, menuAndFun);
  137. }
  138. List<SaasMenu> childrens = null;
  139. if (menuTree == null) {
  140. LambdaQueryWrapper<SaasMenu> queryWrapper = new SaasMenu.Builder().createQueryWrapper().parentIdEq(parent.getId())
  141. .menuTypeEq(parent.getMenuType()).appIdEq(parent.getAppId()).builderQueryWrapper();
  142. childrens = this.saasMenuService.list(queryWrapper.orderByAsc(SaasMenu::getMenuSort));
  143. childrens = CollectionUtil.isEmpty(childrens) ? Lists.newArrayList() : childrens;
  144. } else {
  145. childrens = new ArrayList<SaasMenu>();
  146. for (int i = menuTree.size() - 1; i >= 0; i--) {
  147. SaasMenu saasMenu = menuTree.get(i);
  148. if (parent.getMenuId().equals(saasMenu.getParentId())) {
  149. childrens.add(saasMenu);
  150. menuTree.remove(i);
  151. }
  152. }
  153. }
  154. parent.setChildrens(childrens);
  155. this.setMenuChildrens(accountId, groupCode, projectId, menuTree, childrens, isAdmin, menuAndFun);
  156. }
  157. }
  158. /**
  159. * 删除角色,级联删除账号角色,角色菜单的关联关系
  160. *
  161. * @param deleteVO
  162. */
  163. @Transactional
  164. public boolean deleteSaasRole(SaasRoleDeleteVO deleteVO) {
  165. LambdaQueryWrapper<SaasRole> updateWrapper = new SaasRole.Builder().createQueryWrapper().idEq(deleteVO.getId())
  166. .validEq(SaasCommonConstant.STATUS_1).builderQueryWrapper();
  167. boolean result = this.saasRoleService.remove(updateWrapper);
  168. if (result) {
  169. // 1.级联删除账号和角色关联关系
  170. LambdaQueryWrapper<SaasAccountRole> accountRoleWrapper = new SaasAccountRole.Builder().createQueryWrapper().roleIdEq(deleteVO.getId()).builderQueryWrapper();
  171. this.saasAccountRoleService.remove(accountRoleWrapper);
  172. // 2.级联删除角色和菜单的关联关系
  173. LambdaQueryWrapper<SaasRoleMenu> roleMenuWrapper = new SaasRoleMenu.Builder().createQueryWrapper().roleIdEq(deleteVO.getId()).builderQueryWrapper();
  174. this.saasRoleMenuService.remove(roleMenuWrapper);
  175. }
  176. return result;
  177. }
  178. /**
  179. * 删除菜单,级联删除,角色、菜单、功能三者关联关系数据
  180. *
  181. * @param menuId
  182. * @param productId
  183. * @param updateProduct 是否更新产品关联菜单字段
  184. * @return
  185. */
  186. @Transactional
  187. public boolean deleteSaasMenu(String menuId, String productId, boolean updateProduct) {
  188. boolean result = this.saasMenuService.removeById(menuId);
  189. if (result) {
  190. if (updateProduct) {
  191. // 更新产品是否已关联菜单字段
  192. SaasProduct saasProduct = new SaasProduct();
  193. saasProduct.setId(productId);
  194. saasProduct.setProductMenu(SaasCommonConstant.STR_STATUS_0);
  195. result = this.saasProductService.updateById(saasProduct);
  196. }
  197. // 1.删除此菜单下功能
  198. LambdaQueryWrapper<SaasFunction> funWrapper = new SaasFunction.Builder().createQueryWrapper().menuIdEq(menuId).builderQueryWrapper();
  199. this.saasFunctionService.remove(funWrapper);
  200. // 2.删除此功能对应的菜单、角色关系数据
  201. LambdaQueryWrapper<SaasRoleMenu> roleMenuWrapper = new SaasRoleMenu.Builder().createQueryWrapper().menuIdEq(menuId).builderQueryWrapper();
  202. this.saasRoleMenuService.remove(roleMenuWrapper);
  203. }
  204. return result;
  205. }
  206. /**
  207. * 删除功能,级联删除菜单、功能关系
  208. *
  209. * @param funId
  210. * @return
  211. */
  212. @Transactional
  213. public boolean deleteSaasFunction(String funId) {
  214. LambdaQueryWrapper<SaasFunction> queryWrapper = new SaasFunction.Builder().createQueryWrapper().idEq(funId).builderQueryWrapper();
  215. boolean result = this.saasFunctionService.remove(queryWrapper);
  216. if (result) {
  217. // 1.删除此功能对应的菜单、角色关系数据
  218. LambdaQueryWrapper<SaasRoleMenu> roleMenuWrapper = new SaasRoleMenu.Builder().createQueryWrapper().functionIdEq(funId).builderQueryWrapper();
  219. this.saasRoleMenuService.remove(roleMenuWrapper);
  220. }
  221. return result;
  222. }
  223. /**
  224. * 先删后新增,仅删除此账号角色下的所有菜单功能点的关联关系,并重新新增
  225. *
  226. * @param batchVO
  227. * @return
  228. */
  229. @Transactional
  230. public boolean resetSaasRoleMenu(String groupCode, String roleId, List<SaasMenuFunctionVO> auths) {
  231. LambdaQueryWrapper<SaasRoleMenu> roleMenuWrapper = new SaasRoleMenu.Builder().createQueryWrapper().roleIdEq(roleId).builderQueryWrapper();
  232. this.saasRoleMenuService.remove(roleMenuWrapper);
  233. // 1.批量新增
  234. boolean result = this.saasRoleMenuService.batchCreateSaasRoleMenu(groupCode, roleId, auths);
  235. if (!result) {
  236. throw new BusinessException("重置角色菜单功能权限失败");
  237. }
  238. return result;
  239. }
  240. /**
  241. * 创建角色,同时添加菜单关联关系
  242. * @param saasRole
  243. * @param auths
  244. * @return
  245. */
  246. @Transactional
  247. public boolean createSaasRole(SaasRole saasRole, List<SaasMenuFunctionVO> auths) {
  248. // 1.创建角色信息
  249. boolean result = this.saasRoleService.save(saasRole);
  250. if (result && CollectionUtil.isNotEmpty(auths)) {
  251. // 2.删除并创建角色信息
  252. this.resetSaasRoleMenu(saasRole.getGroupCode(), saasRole.getId(), auths);
  253. }
  254. return result;
  255. }
  256. /**
  257. * 更新角色,同时更新菜单关联关系
  258. * @param saasRole
  259. * @param auths
  260. * @return
  261. */
  262. @Transactional
  263. public boolean updateSaasRole(SaasRole saasRole, List<SaasMenuFunctionVO> auths) {
  264. boolean result = this.saasRoleService.updateById(saasRole);
  265. if (result && CollectionUtil.isNotEmpty(auths)) {
  266. this.resetSaasRoleMenu(saasRole.getGroupCode(), saasRole.getId(), auths);
  267. }
  268. return result;
  269. }
  270. /**
  271. * 删除新增角色菜单页面关联关系
  272. * @param groupCode
  273. * @param roleId
  274. * @param auths
  275. * @return
  276. */
  277. @Transactional
  278. public boolean resetSaasRoleMenuPage(String groupCode, String roleId, List<SaasMenuFunctionPageVO> auths) {
  279. LambdaQueryWrapper<SaasRoleMenu> roleMenuWrapper = new SaasRoleMenu.Builder().createQueryWrapper().roleIdEq(roleId).builderQueryWrapper();
  280. this.saasRoleMenuService.remove(roleMenuWrapper);
  281. // 1.批量新增
  282. boolean result = this.saasRoleMenuService.batchCreateSaasRoleMenuPage(groupCode, roleId, auths);
  283. if (!result) {
  284. throw new BusinessException("重置角色菜单页面功能权限失败");
  285. }
  286. return result;
  287. }
  288. }