yanghao 1 день назад
Родитель
Сommit
457b7bdbc7
1 измененных файлов с 16 добавлено и 27 удалено
  1. 16 27
      src/views/expert/list/index.vue

+ 16 - 27
src/views/expert/list/index.vue

@@ -798,6 +798,7 @@ type ExpertItem = {
   mobile?: string
   softwareSkills: number[]
   teams?: Array<{ id: number; teamName?: string }>
+  sort?: number // 同梯队同序列内的排序值
 }
 
 type ExpertGroup = {
@@ -813,7 +814,6 @@ const selectedTeam = ref('')
 const wordCloudVisible = ref(false)
 const drawerVisible = ref(false)
 const activeExpert = ref<ExpertProfile | null>(null)
-const expertOrderMap = ref<Record<string, number[]>>({})
 
 const resetQueryParams = () => ({
   deptId: undefined,
@@ -998,18 +998,19 @@ const tableData = computed<TableRow[]>(() => {
       )
       .join(' ')
       .toLowerCase()
+
     const cells: CellItem[] = rankOptions.value.map((option) => {
+      // 过滤出属于当前序列的专家
       const members = group.experts.filter((expert) =>
         (expert.expertRank || []).some((rank) => String(rank) === String(option.value))
       )
-      const order = expertOrderMap.value[`${group.echelonLabel}-${option.value}`]
-      const orderIndex = new Map((order || []).map((id, order) => [id, order]))
 
-      members.sort(
-        (left, right) =>
-          (orderIndex.get(left.id) ?? Number.MAX_SAFE_INTEGER) -
-          (orderIndex.get(right.id) ?? Number.MAX_SAFE_INTEGER)
-      )
+      // 同一梯队同一序列内,按 sort 字段升序排序
+      members.sort((left, right) => {
+        const leftSort = left.sort ?? Number.MAX_SAFE_INTEGER
+        const rightSort = right.sort ?? Number.MAX_SAFE_INTEGER
+        return leftSort - rightSort
+      })
 
       return { type: 'members', members }
     })
@@ -1029,7 +1030,7 @@ const tableData = computed<TableRow[]>(() => {
 })
 
 /**
- * 拖拽结束处理:前端完成视觉交换后,调用后端接口持久化
+ * 拖拽结束处理:前端完成视觉交换后,调用后端接口持久化
  */
 const handleExpertDragEnd = async (
   event: { oldIndex?: number; newIndex?: number },
@@ -1037,11 +1038,10 @@ const handleExpertDragEnd = async (
   cellIndex: number,
   members: ExpertItem[]
 ) => {
-  const oldIndex = event.oldIndex
-  const newIndex = event.newIndex
+  const { oldIndex, newIndex } = event
   if (oldIndex === undefined || newIndex === undefined || oldIndex === newIndex) return
 
-  // 1. 还原 SortableJS 已经先完成的“插入式移动”,改为仅交换两个专家
+  // 还原成仅交换两个专家(vuedraggable 默认是插入式移动,会打乱其他人的下标)
   const originalMembers = [...members]
   const [draggedMember] = originalMembers.splice(newIndex, 1)
   originalMembers.splice(oldIndex, 0, draggedMember)
@@ -1050,36 +1050,25 @@ const handleExpertDragEnd = async (
     originalMembers[oldIndex]
   ]
 
-  // 2. 更新本地 members 数组,保证 UI 立即反映交换结果
-  members.splice(0, members.length, ...originalMembers)
-
-  // 3. 记录当前单元格的顺序映射(用于后续排序参考)
-  const rankValue = rankOptions.value[cellIndex]?.value
-  const orderKey = `${row.teamName}-${rankValue}`
-  expertOrderMap.value[orderKey] = originalMembers.map((member) => member.id)
-
-  // 4. 调用后端接口,持久化排序结果
   const sourceMember = originalMembers[oldIndex]
   const targetMember = originalMembers[newIndex]
-
   if (!sourceMember || !targetMember) return
 
+  const rankValue = rankOptions.value[cellIndex]?.value
+
   try {
-    // 调用交换接口,传递两个专家的 ID 以及所在梯队、序列信息
-    // 注意:请根据实际后端 API 的参数定义调整以下字段
     await exchangeExpert({
       sourceId: sourceMember.id,
       targetId: targetMember.id,
-      // 可选:传递上下文信息,便于后端定位排序分组
       echelon: row.teamName,
       expertRank: rankValue
     })
-
     ElMessage.success('排序已保存')
   } catch (error) {
     console.error('排序保存失败:', error)
     ElMessage.error('排序保存失败,请重试')
-    // 5. 保存失败时回滚前端顺序(重新拉取列表数据)
+  } finally {
+    // 无论成功失败都重新拉取,确保前端展示与后端 sort 一致
     await getList()
   }
 }