role-permission.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <script setup lang="ts">
  2. import { reactive, onMounted, ref } from "vue";
  3. import { treeList as permissionTree } from "@/api/sys/permission";
  4. import * as roleApi from "@/api/sys/role";
  5. import { useRenderIcon } from "@/components/ReIcon/src/hooks";
  6. import { Result } from "@/api/base";
  7. import message from "@/utils/message";
  8. import { ElMessageBox, type ElTree } from "element-plus";
  9. const treeRef = ref<InstanceType<typeof ElTree>>();
  10. const pageData: any = reactive({
  11. isShow: false,
  12. title: "角色权限",
  13. treeLoading: false,
  14. role: {},
  15. rolePermission: [],
  16. permissionTree: []
  17. });
  18. const emits = defineEmits(["close", "ok"]);
  19. const open = (role: any) => {
  20. pageData.role = role;
  21. loadRolePermission();
  22. pageData.isShow = true;
  23. };
  24. const handleSelect = (all: boolean) => {
  25. all
  26. ? treeRef.value!.setCheckedNodes(pageData.permissionTree)
  27. : treeRef.value!.setCheckedNodes([]);
  28. };
  29. const handleExpand = (all: boolean) => {
  30. all
  31. ? foldAll(pageData.permissionTree, true)
  32. : foldAll(pageData.permissionTree, false);
  33. };
  34. const foldAll = (data: any, expanded: boolean) => {
  35. data.forEach((el: any) => {
  36. const node = treeRef.value!.store.nodesMap[el.id];
  37. if (node) {
  38. node.expanded = expanded;
  39. }
  40. el.children && el.children.length > 0 ? foldAll(el.children, expanded) : "";
  41. });
  42. };
  43. const _handleClose = () => {
  44. pageData.isShow = false;
  45. emits("close");
  46. };
  47. const handleConfirm = (close?: boolean) => {
  48. const keys = treeRef.value!.getCheckedKeys(true);
  49. ElMessageBox.confirm("确认是否更新授权", "更新授权", { type: "warning" })
  50. .then(() => {
  51. _updatePermission(keys, close);
  52. })
  53. .catch(() => {});
  54. };
  55. const _updatePermission = (permissionIds: any, close?: boolean) => {
  56. pageData.treeLoading = true;
  57. roleApi
  58. .updatePermission(pageData.role.id, permissionIds)
  59. .then((res: any) => {
  60. if (res.success) {
  61. message.success("更新授权成功");
  62. if (close) {
  63. _handleClose();
  64. } else {
  65. loadRolePermission();
  66. }
  67. } else {
  68. message.warning(res.message);
  69. }
  70. })
  71. .finally(() => {
  72. pageData.treeLoading = false;
  73. });
  74. };
  75. onMounted(() => {
  76. loadPermission();
  77. });
  78. const loadPermission = () => {
  79. permissionTree<any, any>({ enable: 1 }).then((res: any) => {
  80. if (res.success) {
  81. pageData.permissionTree = res.result;
  82. }
  83. });
  84. };
  85. const loadRolePermission = () => {
  86. pageData.treeLoading = true;
  87. roleApi
  88. .queryPermission(pageData.role.id)
  89. .then((res: Result<string[]>) => {
  90. if (res.success) {
  91. pageData.rolePermission = res.result;
  92. treeRef.value!.setCheckedKeys(res.result);
  93. } else {
  94. message.warning(res.message);
  95. }
  96. })
  97. .finally(() => {
  98. pageData.treeLoading = false;
  99. });
  100. };
  101. defineExpose({ open });
  102. defineOptions({ name: "RolePermission" });
  103. </script>
  104. <template>
  105. <el-drawer
  106. v-model="pageData.isShow"
  107. destroy-on-close
  108. modal
  109. :close-on-click-modal="false"
  110. :title="pageData.title"
  111. :before-close="_handleClose"
  112. class="el-drawer-header"
  113. >
  114. <div class="flex flex-col h-full">
  115. <el-form label-position="top">
  116. <el-form-item label="所拥有的权限:">
  117. <el-tree
  118. ref="treeRef"
  119. :data="pageData.permissionTree"
  120. :props="{ label: 'title', children: 'children' }"
  121. node-key="id"
  122. show-checkbox
  123. default-expand-all
  124. :check-strictly="false"
  125. style="width: 100%"
  126. v-loading="pageData.treeLoading"
  127. />
  128. </el-form-item>
  129. </el-form>
  130. </div>
  131. <template #footer>
  132. <div class="flex justify-between items-center">
  133. <div class="right">
  134. <el-dropdown trigger="click" placement="top">
  135. <el-button>
  136. 批量操作 <component :is="useRenderIcon('ep:arrow-up')"
  137. /></el-button>
  138. <template #dropdown>
  139. <el-dropdown-menu>
  140. <el-dropdown-item @click="handleSelect(true)"
  141. >全部勾选</el-dropdown-item
  142. >
  143. <el-dropdown-item @click="handleSelect(false)"
  144. >取消全部</el-dropdown-item
  145. >
  146. <el-dropdown-item @click="handleExpand(true)"
  147. >展开所有</el-dropdown-item
  148. >
  149. <el-dropdown-item @click="handleExpand(false)"
  150. >合并所有</el-dropdown-item
  151. >
  152. </el-dropdown-menu>
  153. </template>
  154. </el-dropdown>
  155. </div>
  156. <div class="left">
  157. <el-button @click="_handleClose">取消</el-button>
  158. <el-button type="primary" @click="handleConfirm(false)" plain
  159. >确认</el-button
  160. >
  161. <el-button type="primary" @click="handleConfirm(true)"
  162. >确认并关闭</el-button
  163. >
  164. </div>
  165. </div>
  166. </template>
  167. </el-drawer>
  168. </template>