DeptConfigModal.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <template>
  2. <a-modal width="50%" v-model:visible="visible" :title="$t('permission.account.dept_config')" @cancel="handleCancel"
  3. @ok="editDeptHandleOk">
  4. <div style="display: flex;">
  5. <a-card class="card-body" :title="$t('permission.account.organization')" hoverable>
  6. <a-tree :data="dept_list" v-model:checked-keys="checked_keys" v-model:expanded-keys="expand_keys"
  7. :checkable="true" :check-strictly="true" :show-line="true" @check="onCheck" :fieldNames="{
  8. key: 'deptId',
  9. title: 'deptName',
  10. children: 'children',
  11. }">
  12. </a-tree>
  13. </a-card>
  14. <a-card class="card-body" :title="$t('permission.account.user_department')">
  15. <a-space wrap>
  16. <a-tag v-for="item of check_strictly" :key="item.deptId">
  17. {{ item.deptName }}
  18. </a-tag>
  19. </a-space>
  20. <a-divider />
  21. <div style="margin-bottom: 8px;">{{ $t('permission.account.department_roles') }}:</div>
  22. <a-space wrap>
  23. <a-tag v-for="item of check_strictly_dept_role" :key="item.roleId" color="arcoblue">
  24. {{ item.roleName }}
  25. </a-tag>
  26. </a-space>
  27. </a-card>
  28. </div>
  29. </a-modal>
  30. </template>
  31. <script setup>
  32. import { ref, toRefs, watch } from 'vue';
  33. // 定义组件的 props 和 emits
  34. const props = defineProps({
  35. visible: Boolean,
  36. dept_list: {
  37. type: Array,
  38. default: () => []
  39. },
  40. dept_detail: {
  41. type: Object,
  42. default: () => []
  43. }
  44. });
  45. const { visible, dept_list, dept_detail } = toRefs(props);
  46. const emit = defineEmits(['close', 'ok']);
  47. // 组件内部状态
  48. const checked_keys = ref([]);
  49. // 默认展开第一节
  50. const expand_keys = ref(['0']);
  51. const check_strictly = ref([]);
  52. const check_strictly_dept_role = ref([]);
  53. // 递归取消所有子节点的选择
  54. const cancelChildSelection = (node, selected_nodes) => {
  55. if (node.children && node.children.length > 0) {
  56. node.children.forEach(child => {
  57. const child_index = selected_nodes.findIndex(val => val.deptId === child.deptId);
  58. if (child_index !== -1) {
  59. // 取消子节点的选择
  60. selected_nodes.splice(child_index, 1);
  61. // 递归取消子节点的选择
  62. cancelChildSelection(child, selected_nodes);
  63. }
  64. });
  65. }
  66. }
  67. // FIXME:选择和取消选择的bug
  68. // 处理树形组件的勾选变化
  69. const onCheck = (new_checked_keys, event) => {
  70. const o = { deptId: event.node.deptId, deptName: event.node.deptName };
  71. if (event.checked) {
  72. // 添加部门角色
  73. event.node.roles.forEach((val) => {
  74. // 检查是否已经存在相同的 roleId,如果不存在则添加
  75. const exists = check_strictly_dept_role.value.some((role) => role.roleId === val.roleId);
  76. if (!exists) {
  77. check_strictly_dept_role.value.push(val);
  78. }
  79. });
  80. // 添加部门
  81. check_strictly.value.push(o);
  82. } else {
  83. // 移除部门
  84. const dept_index = check_strictly.value.findIndex((val) => val.deptId === event.node.deptId);
  85. check_strictly.value.splice(dept_index, 1);
  86. // 移除部门角色
  87. const role_index = check_strictly_dept_role.value.findIndex((val) => val.deptId === event.node.deptId);
  88. check_strictly_dept_role.value.splice(role_index, 1);
  89. // 递归取消所有子节点的选择
  90. cancelChildSelection(event.node, check_strictly.value);
  91. }
  92. };
  93. // 处理取消事件
  94. const handleCancel = () => {
  95. visible.value = false;
  96. emit('close');
  97. };
  98. // 处理确认事件
  99. const editDeptHandleOk = () => {
  100. emit('ok', checked_keys.value);
  101. };
  102. watch(() => props.dept_detail, (newVal) => {
  103. if (newVal.length > 0) {
  104. newVal.forEach(val => {
  105. if (!checked_keys.value.includes(val.deptId)) {
  106. check_strictly.value.push({
  107. deptId: val.deptId,
  108. deptName: val.deptName
  109. });
  110. checked_keys.value.push(val.deptId);
  111. expand_keys.value.push(val.deptId);
  112. }
  113. val.roles.forEach((role) => {
  114. // 判断是否存在同样的 roleId,如果不存在则添加
  115. if (!check_strictly_dept_role.value.some(item => item.roleId === role.roleId)) {
  116. check_strictly_dept_role.value.push({
  117. roleId: role.roleId,
  118. roleName: role.roleName,
  119. deptId: val.deptId
  120. });
  121. }
  122. });
  123. });
  124. } else {
  125. checked_keys.value = [];
  126. expand_keys.value = [];
  127. check_strictly.value = [];
  128. check_strictly_dept_role.value = [];
  129. }
  130. });
  131. </script>
  132. <style lang="css" scoped>
  133. .card-body {
  134. width: 460px;
  135. height: 500px;
  136. overflow-y: auto;
  137. }
  138. .card-body:first-child {
  139. margin-right: 16px;
  140. }
  141. </style>