set-tenant-menu.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <template>
  2. <el-dialog v-model="state.showDialog" destroy-on-close :title="innerTitle" append-to-body draggable width="780px">
  3. <div>
  4. <el-tree
  5. ref="permissionTreeRef"
  6. :data="state.permissionTreeData"
  7. node-key="id"
  8. show-checkbox
  9. highlight-current
  10. default-expand-all
  11. check-on-click-node
  12. :expand-on-click-node="false"
  13. :props="{ class: customNodeClass }"
  14. :default-checked-keys="state.checkedKeys"
  15. />
  16. </div>
  17. <template #footer>
  18. <span class="dialog-footer">
  19. <el-button @click="onCancel" size="default">取 消</el-button>
  20. <el-button type="primary" @click="onSure" size="default" :loading="state.sureLoading">确 定</el-button>
  21. </span>
  22. </template>
  23. </el-dialog>
  24. </template>
  25. <script lang="ts" setup>
  26. import { ref, reactive, getCurrentInstance, computed } from 'vue'
  27. import { TenantListOutput, PermissionSaveTenantPermissionsInput } from '/@/api/admin/data-contracts'
  28. import { PermissionApi } from '/@/api/admin/Permission'
  29. import { ElTree } from 'element-plus'
  30. import { listToTree } from '/@/utils/tree'
  31. import { cloneDeep } from 'lodash-es'
  32. const props = defineProps({
  33. title: {
  34. type: String,
  35. default: '',
  36. },
  37. })
  38. const innerTitle = computed(() => {
  39. return props.title ? props.title : state.name ? `设置【${state.name}】菜单权限` : '设置菜单权限'
  40. })
  41. const state = reactive({
  42. showDialog: false,
  43. loading: false,
  44. sureLoading: false,
  45. permissionTreeData: [],
  46. id: 0 as number | undefined,
  47. name: '' as string | undefined | null,
  48. checkedKeys: [],
  49. })
  50. const { proxy } = getCurrentInstance() as any
  51. const permissionTreeRef = ref<InstanceType<typeof ElTree>>()
  52. const getTenantPermissionList = async () => {
  53. const res = await new PermissionApi().getTenantPermissionList({ tenantId: state.id })
  54. state.checkedKeys = res?.success ? (res.data as never[]) : []
  55. }
  56. // 打开对话框
  57. const open = async (tenat: TenantListOutput) => {
  58. state.id = tenat.id
  59. state.name = tenat.name
  60. proxy.$modal.loading()
  61. await onQuery()
  62. await getTenantPermissionList()
  63. proxy.$modal.closeLoading()
  64. state.showDialog = true
  65. }
  66. // 关闭对话框
  67. const close = () => {
  68. state.showDialog = false
  69. }
  70. const onQuery = async () => {
  71. state.loading = true
  72. const res = await new PermissionApi().getPermissionList()
  73. if (res.data && res.data.length > 0) {
  74. state.permissionTreeData = listToTree(cloneDeep(res.data))
  75. } else {
  76. state.permissionTreeData = []
  77. }
  78. state.loading = false
  79. }
  80. const customNodeClass = (data: any) => {
  81. return data.row ? 'is-penultimate' : ''
  82. }
  83. // 取消
  84. const onCancel = () => {
  85. state.showDialog = false
  86. }
  87. // 确定
  88. const onSure = async () => {
  89. state.sureLoading = true
  90. const permissionIds = permissionTreeRef.value?.getCheckedKeys(true)
  91. const input = { tenantId: state.id, permissionIds: permissionIds } as PermissionSaveTenantPermissionsInput
  92. const res = await new PermissionApi().saveTenantPermissions(input, { showSuccessMessage: true }).catch(() => {
  93. state.sureLoading = false
  94. })
  95. state.sureLoading = false
  96. if (res?.success) {
  97. state.showDialog = false
  98. }
  99. }
  100. defineExpose({
  101. open,
  102. close,
  103. })
  104. </script>
  105. <script lang="ts">
  106. import { defineComponent } from 'vue'
  107. export default defineComponent({
  108. name: 'admin/tenant/components/set-tenant-menu',
  109. })
  110. </script>
  111. <style scoped lang="scss">
  112. :deep(.el-dialog__body) {
  113. padding: 5px 10px;
  114. }
  115. :deep(.is-penultimate) {
  116. .el-tree-node__children {
  117. padding-left: 65px;
  118. white-space: pre-wrap;
  119. line-height: 100%;
  120. .el-tree-node {
  121. display: inline-block;
  122. }
  123. .el-tree-node__content {
  124. padding-left: 12px !important;
  125. padding-right: 12px;
  126. .el-tree-node__expand-icon.is-leaf {
  127. display: none;
  128. }
  129. }
  130. }
  131. }
  132. </style>