优化: 会话状态键控与提示补全

- 队列清空/发送失败补提示,错误接入分类文案
- 审批超时气泡按会话归属,流守卫按会话清理
- 会话操作失败就近反馈,拖拽非法流转提示原因
This commit is contained in:
lxy
2026-10-03 16:27:39 +08:00
parent 8710a09be2
commit 31f7a9570b
6 changed files with 118 additions and 26 deletions
+25 -4
View File
@@ -2,7 +2,7 @@ import { ref } from 'vue'
import Sortable from 'sortablejs'
import { useI18n } from 'vue-i18n'
import { taskApi } from '@/api/task'
import { TASK_STATUS_TRANSITIONS } from '@/constants/project'
import { TASK_STATUS_TRANSITIONS, taskStatusLabel } from '@/constants/project'
import { useToast } from '../useToast'
export function useTaskKanban(opts: {
@@ -15,6 +15,8 @@ export function useTaskKanban(opts: {
let s: Sortable[] = []
let _dragId: string | null = null
let _executing = false
// 最近一次被拒的流转方向:onMove 只记录不提示(避免拖拽悬停过程误报),onEnd 弹回时消费并清空
let _rejected: { from: string; to: string } | null = null
function destroy() { s.forEach(x => x.destroy()); s = [] }
@@ -30,12 +32,16 @@ export function useTaskKanban(opts: {
onMove: (e) => {
const from = (e.from as HTMLElement).dataset.status ?? ''
const to = ((e.to as HTMLElement).closest('[data-status]') as HTMLElement)?.dataset.status ?? ''
if (from === to) return true
return TASK_STATUS_TRANSITIONS[from]?.includes(to) ?? false
if (from === to) { _rejected = null; return true }
const legal = TASK_STATUS_TRANSITIONS[from]?.includes(to) ?? false
// UX走查 P2-5:非法流转只记录方向;合法流转清掉旧拒绝,避免陈旧标记污染后续 onEnd 判断
_rejected = legal ? null : { from, to }
return legal
},
onStart: (e) => {
_dragId = (e.item as HTMLElement).dataset.taskId ?? null
_executing = false
_rejected = null
},
onEnd: async (e) => {
if (_executing) return
@@ -44,7 +50,22 @@ export function useTaskKanban(opts: {
const to = ((e.to as HTMLElement).closest('[data-status]') as HTMLElement)?.dataset.status
const id = _dragId
_dragId = null
if (!to || !from || to === from) { _executing = false; return }
if (!to || !from || to === from) {
// UX走查 P2-5:非法流转被 onMove 拒绝时卡片弹回原列(落点 to===from),
// 此处补一条原因 toast,替代原先的静默弹回(原因与父卡 tooltip 同源:状态机流转表)
if (_rejected) {
showToast(
t('tasks.kanban.illegalMove', {
from: t(taskStatusLabel(_rejected.from)),
to: t(taskStatusLabel(_rejected.to)),
}),
'error',
)
_rejected = null
}
_executing = false
return
}
if (!id) { _executing = false; return }
kanbanBusy.value = true
try {