Quellcode durchsuchen

fix: 人选选择穿梭框组件切换部门不过滤已选中数据逻辑,优化布局样式

GoldenZqqq vor 9 Monaten
Ursprung
Commit
d03fdecc26
1 geänderte Dateien mit 76 neuen und 32 gelöschten Zeilen
  1. 76 32
      src/components/UserSelectForm/index.vue

+ 76 - 32
src/components/UserSelectForm/index.vue

@@ -1,25 +1,27 @@
 <template>
-  <Dialog v-model="dialogVisible" title="人员选择" width="900">
-    <el-row>
+  <Dialog v-model="dialogVisible" title="人员选择" width="800">
+    <el-row class="gap2" v-loading="formLoading">
       <el-col :span="6">
-        <el-tree
-          ref="treeRef"
-          :data="deptList"
-          :expand-on-click-node="false"
-          :props="defaultProps"
-          default-expand-all
-          highlight-current
-          node-key="id"
-          @node-click="handleNodeClick"
-        />
+        <ContentWrap class="h-1/1">
+          <el-tree
+            ref="treeRef"
+            :data="deptList"
+            :expand-on-click-node="false"
+            :props="defaultProps"
+            default-expand-all
+            highlight-current
+            node-key="id"
+            @node-click="handleNodeClick"
+          />
+        </ContentWrap>
       </el-col>
-      <el-col :span="17" :offset="1">
+      <el-col :span="17">
         <el-transfer
           v-model="selectedUserIdList"
           :titles="['未选', '已选']"
           filterable
           filter-placeholder="搜索成员"
-          :data="userList"
+          :data="transferUserList"
           :props="{ label: 'nickname', key: 'id' }"
         />
       </el-col>
@@ -47,62 +49,87 @@ const emit = defineEmits<{
 }>()
 const { t } = useI18n() // 国际
 const message = useMessage() // 消息弹窗
-
 const deptList = ref<Tree[]>([]) // 部门树形结构化
-const userList: any = ref([]) // 用户列表
+const allUserList = ref<UserApi.UserVO[]>([]) // 所有用户列表
+const filteredUserList = ref<UserApi.UserVO[]>([]) // 当前部门过滤后的用户列表
 const selectedUserIdList: any = ref([]) // 选中的用户列表
 const dialogVisible = ref(false) // 弹窗的是否展示
 const formLoading = ref(false) // 表单的加载中
-const activityId = ref() // 关联的主键编号 TODO @goldenzqqq:这个 activityId 有没可能不传递。在使用 @submitForm="xxx()" 时,传递的参数。目的是,更加解耦一些。
+const activityId = ref()
+
+// 计算属性:合并已选择的用户和当前部门过滤后的用户
+const transferUserList = computed(() => {
+  // 获取所有已选择的用户
+  const selectedUsers = allUserList.value.filter((user: any) =>
+    selectedUserIdList.value.includes(user.id)
+  )
+
+  // 获取当前部门过滤后的未选择用户
+  const filteredUnselectedUsers = filteredUserList.value.filter(
+    (user: any) => !selectedUserIdList.value.includes(user.id)
+  )
+
+  // 合并并去重
+  return [...selectedUsers, ...filteredUnselectedUsers]
+})
 
 /** 打开弹窗 */
 const open = async (id: number, selectedList?: any[]) => {
   activityId.value = id
-  // 重置表单
   resetForm()
 
-  // 加载相关数据
   deptList.value = handleTree(await DeptApi.getSimpleDeptList())
-  await getUserList()
-  // 设置选中的用户列表
-  selectedUserIdList.value = selectedList?.map((item: any) => item.id)
-
-  // 设置可见
+  // 初始加载所有用户
+  await getAllUserList()
+  // 初始状态下,过滤列表等于所有用户列表
+  filteredUserList.value = [...allUserList.value]
+  selectedUserIdList.value = selectedList?.map((item: any) => item.id) || []
   dialogVisible.value = true
 }
+/** 获取所有用户列表 */
+const getAllUserList = async () => {
+  try {
+    // @ts-ignore
+    const data = await UserApi.getSimpleUserList()
+    allUserList.value = data
+  } finally {
+  }
+}
 
-/** 获取用户列表 */
+/** 获取部门过滤后的用户列表 */
 const getUserList = async (deptId?: number) => {
+  formLoading.value = true
   try {
     // @ts-ignore
-    // TODO @芋艿:替换到 simple List
+    // TODO @芋艿:替换到 simple List 暂不支持 deptId 过滤
     const data = await UserApi.getUserPage({ pageSize: 100, pageNo: 1, deptId })
-    userList.value = data.list
+    // 更新过滤后的用户列表
+    filteredUserList.value = data.list
   } finally {
+    formLoading.value = false
   }
 }
 
 /** 提交选择 */
 const submitForm = async () => {
-  // 提交请求
-  formLoading.value = true
   try {
     message.success(t('common.updateSuccess'))
     dialogVisible.value = false
-    const emitUserList = userList.value.filter((user: any) =>
+    // 从所有用户列表中筛选出已选择的用户
+    const emitUserList = allUserList.value.filter((user: any) =>
       selectedUserIdList.value.includes(user.id)
     )
     // 发送操作成功的事件
     emit('confirm', activityId.value, emitUserList)
   } finally {
-    formLoading.value = false
   }
 }
 
 /** 重置表单 */
 const resetForm = () => {
   deptList.value = []
-  userList.value = []
+  allUserList.value = []
+  filteredUserList.value = []
   selectedUserIdList.value = []
 }
 
@@ -113,3 +140,20 @@ const handleNodeClick = (row: { [key: string]: any }) => {
 
 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 </script>
+
+<style lang="scss" scoped>
+:deep() {
+  .el-transfer {
+    display: flex;
+  }
+  .el-transfer__buttons {
+    display: flex !important;
+    flex-direction: column-reverse;
+    justify-content: center;
+    gap: 20px;
+    .el-transfer__button:nth-child(2) {
+      margin: 0;
+    }
+  }
+}
+</style>