GroupSelect.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <template>
  2. <div class="group-select-container">
  3. <el-select
  4. v-model="selectedGroups"
  5. multiple
  6. collapse-tags
  7. collapse-tags-tooltip
  8. :max-collapse-tags="2"
  9. placeholder="请选择分组"
  10. filterable
  11. @change="handleChange"
  12. :disabled="disabled"
  13. >
  14. <template #header>
  15. <el-checkbox v-model="checkAll" :indeterminate="indeterminate" @change="handleCheckAllChange">
  16. 全部分组
  17. </el-checkbox>
  18. </template>
  19. <el-option v-for="item in groupOptions" :key="item.id" :value="item.id" :label="item.name" />
  20. </el-select>
  21. <span @click="showGroupInfo" v-if="selectedGroups.length > 0" class="group-info-span"> 人员详情 </span>
  22. <el-dialog
  23. width="500"
  24. v-model="groupInfo"
  25. title="人员详情"
  26. align-center
  27. :close-on-click-modal="false"
  28. :destroy-on-close="true"
  29. class="customDialog--pushObject"
  30. >
  31. <Group :userGroupInfo="userGroupInfo" />
  32. </el-dialog>
  33. </div>
  34. </template>
  35. <script lang="ts" setup>
  36. import { ref, watch } from 'vue';
  37. import Group from './Group.vue';
  38. import type { UserGroupOption, UserGroupInfo } from '@/types/person-group/type';
  39. import { getUserGroupDetailByIds } from '@/api/system/person-group';
  40. const props = defineProps<{
  41. modelValue: number[];
  42. groupOptions: UserGroupOption[];
  43. disabled?: boolean;
  44. }>();
  45. const emit = defineEmits<{
  46. (e: 'update:modelValue', value: number[]): void;
  47. (e: 'change', value: number[]): void;
  48. }>();
  49. const selectedGroups = ref<number[]>([]);
  50. const groupInfo = ref(false);
  51. const userGroupInfo = ref<UserGroupInfo[]>([]);
  52. const showGroupInfo = () => {
  53. groupInfo.value = true;
  54. getUserGroupInfo();
  55. };
  56. const handleChange = (value: number[]) => {
  57. emit('update:modelValue', value);
  58. emit('change', value);
  59. };
  60. const getUserGroupInfo = async () => {
  61. const res = await getUserGroupDetailByIds(selectedGroups.value);
  62. userGroupInfo.value = res.map((item) => ({
  63. ...item,
  64. isExpand: false,
  65. isHidden: false,
  66. }));
  67. };
  68. const checkAll = ref(false);
  69. const indeterminate = ref(false);
  70. const handleCheckAllChange = () => {
  71. if (checkAll.value) {
  72. selectedGroups.value = props.groupOptions.map((item) => item.id);
  73. } else {
  74. selectedGroups.value = [];
  75. }
  76. handleChange(selectedGroups.value);
  77. };
  78. watch(
  79. () => [props.groupOptions, selectedGroups.value],
  80. ([newGroupOptions, newSelectedGroups]) => {
  81. if (newGroupOptions.length === 0) return;
  82. checkAll.value = newSelectedGroups.length === newGroupOptions.length;
  83. indeterminate.value = newSelectedGroups.length > 0 && newSelectedGroups.length < newGroupOptions.length;
  84. },
  85. );
  86. // 监听 props 中的 modelValue 变化,更新内部的 selectedGroups
  87. watch(
  88. () => props.modelValue,
  89. (newValue) => {
  90. selectedGroups.value = [...newValue];
  91. },
  92. { immediate: true },
  93. );
  94. </script>
  95. <style lang="scss" scoped>
  96. .group-select-container {
  97. position: relative;
  98. width: 100%;
  99. }
  100. .group-info-span {
  101. position: absolute;
  102. left: 0;
  103. bottom: -30px;
  104. cursor: pointer;
  105. font-size: 14px;
  106. color: $primary-color;
  107. }
  108. </style>