RolePermissionDrawer.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <template>
  2. <BasicDrawer v-bind="$attrs" @register="registerDrawer" width="650px" destroyOnClose showFooter>
  3. <template #title>
  4. 角色权限配置
  5. <a-dropdown>
  6. <Icon icon="ant-design:more-outlined" class="more-icon" />
  7. <template #overlay>
  8. <a-menu @click="treeMenuClick">
  9. <a-menu-item key="checkAll">选择全部</a-menu-item>
  10. <a-menu-item key="cancelCheck">取消选择</a-menu-item>
  11. <div class="line"></div>
  12. <a-menu-item key="openAll">展开全部</a-menu-item>
  13. <a-menu-item key="closeAll">折叠全部</a-menu-item>
  14. <div class="line"></div>
  15. <a-menu-item key="relation">层级关联</a-menu-item>
  16. <a-menu-item key="standAlone">层级独立</a-menu-item>
  17. </a-menu>
  18. </template>
  19. </a-dropdown>
  20. </template>
  21. <BasicTree
  22. ref="treeRef"
  23. checkable
  24. :treeData="treeData"
  25. :checkedKeys="checkedKeys"
  26. :expandedKeys="expandedKeys"
  27. :selectedKeys="selectedKeys"
  28. :checkStrictly="checkStrictly"
  29. :clickRowToExpand="false"
  30. title="所拥有的的权限"
  31. @check="onCheck"
  32. @select="onTreeNodeSelect"
  33. >
  34. <template #title="{ slotTitle, ruleFlag }">
  35. {{ slotTitle }}
  36. <Icon v-if="ruleFlag" icon="ant-design:align-left-outlined" style="margin-left: 5px; color: red" />
  37. </template>
  38. </BasicTree>
  39. <!--右下角按钮-->
  40. <template #footer>
  41. <PopConfirmButton title="确定放弃编辑?" @confirm="closeDrawer" okText="确定" cancelText="取消">取消</PopConfirmButton>
  42. <a-button @click="handleSubmit(false)" type="primary" :loading="loading" ghost style="margin-right: 0.8rem">仅保存</a-button>
  43. <a-button @click="handleSubmit(true)" type="primary" :loading="loading">保存并关闭</a-button>
  44. </template>
  45. <RoleDataRuleDrawer @register="registerDrawer1" />
  46. </BasicDrawer>
  47. </template>
  48. <script lang="ts" setup>
  49. import { ref, computed, unref, onMounted } from 'vue';
  50. import { BasicDrawer, useDrawer, useDrawerInner } from '/src/components/Drawer';
  51. import { BasicTree, TreeItem } from '/src/components/Tree';
  52. import { PopConfirmButton } from '/@/components/Button';
  53. import RoleDataRuleDrawer from './RoleDataRuleDrawer.vue';
  54. import { queryTreeListForRole, queryRolePermission, saveRolePermission } from '../role.api';
  55. const emit = defineEmits(['register']);
  56. //树的信息
  57. const treeData = ref<TreeItem[]>([]);
  58. //树的全部节点信息
  59. const allTreeKeys = ref([]);
  60. //树的选择节点信息
  61. const checkedKeys = ref([]);
  62. const defaultCheckedKeys = ref([]);
  63. //树的选中的节点信息
  64. const selectedKeys = ref([]);
  65. const roleId = ref('');
  66. //树的实例
  67. const treeRef = ref(null);
  68. const loading = ref(false);
  69. //展开折叠的key
  70. const expandedKeys = ref<any>([]);
  71. //父子节点选中状态是否关联
  72. const checkStrictly = ref<boolean>(true);
  73. const [registerDrawer1, { openDrawer: openDataRuleDrawer }] = useDrawer();
  74. const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
  75. await reset();
  76. setDrawerProps({ confirmLoading: false, loading: true });
  77. roleId.value = data.roleId;
  78. //初始化数据
  79. const roleResult = await queryTreeListForRole();
  80. treeData.value = roleResult.treeList;
  81. allTreeKeys.value = roleResult.ids;
  82. expandedKeys.value = [];
  83. //初始化角色菜单数据
  84. const permResult = await queryRolePermission({ roleId: unref(roleId) });
  85. checkedKeys.value = permResult;
  86. defaultCheckedKeys.value = permResult;
  87. setDrawerProps({ loading: false });
  88. });
  89. /**
  90. * 点击选中
  91. */
  92. function onCheck(o) {
  93. checkedKeys.value = o.checked ? o.checked : o;
  94. }
  95. /**
  96. * 选中节点,打开数据权限抽屉
  97. */
  98. function onTreeNodeSelect(key) {
  99. if (key && key.length > 0) {
  100. selectedKeys.value = key;
  101. }
  102. openDataRuleDrawer(true, { functionId: unref(selectedKeys)[0], roleId: unref(roleId) });
  103. }
  104. /**
  105. * 数据重置
  106. */
  107. function reset() {
  108. treeData.value = [];
  109. allTreeKeys.value = [];
  110. checkedKeys.value = [];
  111. defaultCheckedKeys.value = [];
  112. selectedKeys.value = [];
  113. roleId.value = '';
  114. }
  115. /**
  116. * 获取tree实例
  117. */
  118. function getTree() {
  119. const tree = unref(treeRef);
  120. if (!tree) {
  121. throw new Error('tree is null!');
  122. }
  123. return tree;
  124. }
  125. /**
  126. * 提交
  127. */
  128. async function handleSubmit(exit) {
  129. let params = {
  130. roleId: unref(roleId),
  131. permissionIds: unref(getTree().getCheckedKeys()).join(','),
  132. lastpermissionIds: unref(defaultCheckedKeys).join(','),
  133. };
  134. //update-begin-author:taoyan date:2023-2-11 for: issues/352 VUE角色授权重复保存
  135. if (loading.value === false) {
  136. await doSave(params);
  137. } else {
  138. console.log('请等待上次执行完毕!');
  139. }
  140. if (exit) {
  141. // 如果关闭
  142. closeDrawer();
  143. } else {
  144. // 没有关闭需要重新获取选中数据
  145. const permResult = await queryRolePermission({ roleId: unref(roleId) });
  146. defaultCheckedKeys.value = permResult;
  147. }
  148. }
  149. // VUE角色授权重复保存 #352
  150. async function doSave(params) {
  151. loading.value = true;
  152. await saveRolePermission(params);
  153. setTimeout(() => {
  154. loading.value = false;
  155. }, 500);
  156. }
  157. //update-end-author:taoyan date:2023-2-11 for: issues/352 VUE角色授权重复保存
  158. /**
  159. * 树菜单选择
  160. * @param key
  161. */
  162. function treeMenuClick({ key }) {
  163. if (key === 'checkAll') {
  164. checkedKeys.value = allTreeKeys.value;
  165. } else if (key === 'cancelCheck') {
  166. checkedKeys.value = [];
  167. } else if (key === 'openAll') {
  168. expandedKeys.value = allTreeKeys.value;
  169. } else if (key === 'closeAll') {
  170. expandedKeys.value = [];
  171. } else if (key === 'relation') {
  172. checkStrictly.value = false;
  173. } else {
  174. checkStrictly.value = true;
  175. }
  176. }
  177. </script>
  178. <style lang="less" scoped>
  179. /** 固定操作按钮 */
  180. .jeecg-basic-tree {
  181. position: absolute;
  182. width: 618px;
  183. }
  184. //update-begin---author:wangshuai ---date:20230202 for:抽屉弹窗标题图标下拉样式------------
  185. .line {
  186. height: 1px;
  187. width: 100%;
  188. border-bottom: 1px solid #f0f0f0;
  189. }
  190. .more-icon {
  191. font-size: 20px !important;
  192. color: rgb(255, 255, 255);
  193. display: inline-flex;
  194. float: right;
  195. margin-right: 2px;
  196. cursor: pointer;
  197. }
  198. :deep(.jeecg-tree-header) {
  199. border-bottom: none;
  200. }
  201. //update-end---author:wangshuai ---date:20230202 for:抽屉弹窗标题图标下拉样式------------
  202. </style>