修复: 前端UX一致性(Dashboard状态映射/状态徽章全局/Knowledge下一条与失败反馈/Ideas筛选与错误条/ConfirmDialog安全/快捷菜单状态机/分页越界) + 后端校验(queue/count-list一致/软删拒改/父聚合/promote CAS/MCP状态机收口/update白名单剔除id/created_at) + 销账
This commit is contained in:
+26
-11
@@ -286,13 +286,20 @@ async function onDetailSave(payload: { id: string; data: { title: string; conten
|
||||
|
||||
// ===== 审核操作(收件箱) =====
|
||||
// P0-②:发布/拒绝/归档后自动选中下一条(而非清空详情),减少审核者来回点击
|
||||
// WK-2:index 须在 store 操作前快照(操作后 candidates 已 filter 移除 currentId,findIndex 恒 -1)
|
||||
// WK-3:操作失败(updateStatus/archive 返 false)toast 报错 + 中止推进(不 selectNext,不清详情)
|
||||
async function publishCurrent() {
|
||||
if (!detail.value) return
|
||||
const currentId = detail.value.knowledge.id
|
||||
const idx = store.candidates.findIndex(c => c.id === currentId)
|
||||
submitting.value = true
|
||||
try {
|
||||
await store.updateStatus(currentId, 'published')
|
||||
await selectNextCandidate(currentId)
|
||||
const ok = await store.updateStatus(currentId, 'published')
|
||||
if (!ok) {
|
||||
showToast(t('knowledge.err.updateStatusFailed'), 'error')
|
||||
return
|
||||
}
|
||||
await selectNextCandidate(idx)
|
||||
showToast(t('knowledge.publishedToast'), 'success')
|
||||
} finally {
|
||||
submitting.value = false
|
||||
@@ -302,10 +309,15 @@ async function publishCurrent() {
|
||||
async function rejectCurrent() {
|
||||
if (!detail.value) return
|
||||
const currentId = detail.value.knowledge.id
|
||||
const idx = store.candidates.findIndex(c => c.id === currentId)
|
||||
submitting.value = true
|
||||
try {
|
||||
await store.archive(currentId)
|
||||
await selectNextCandidate(currentId)
|
||||
const ok = await store.archive(currentId)
|
||||
if (!ok) {
|
||||
showToast(t('knowledge.err.archiveFailed'), 'error')
|
||||
return
|
||||
}
|
||||
await selectNextCandidate(idx)
|
||||
showToast(t('knowledge.rejectedToast'), 'info')
|
||||
} finally {
|
||||
submitting.value = false
|
||||
@@ -315,12 +327,17 @@ async function rejectCurrent() {
|
||||
async function archiveCurrent() {
|
||||
if (!detail.value) return
|
||||
const currentId = detail.value.knowledge.id
|
||||
const idx = store.candidates.findIndex(c => c.id === currentId)
|
||||
submitting.value = true
|
||||
try {
|
||||
await store.archive(currentId)
|
||||
const ok = await store.archive(currentId)
|
||||
if (!ok) {
|
||||
showToast(t('knowledge.err.archiveFailed'), 'error')
|
||||
return
|
||||
}
|
||||
// 知识库 tab 无「下一条」语义(library 不限 candidate),归档后清空详情
|
||||
if (topTab.value === 'inbox') {
|
||||
await selectNextCandidate(currentId)
|
||||
await selectNextCandidate(idx)
|
||||
} else {
|
||||
selectedId.value = null
|
||||
detail.value = null
|
||||
@@ -338,11 +355,9 @@ function pickNextCandidate(remaining: KnowledgeRecord[], currentIndex: number):
|
||||
return remaining[currentIndex] ?? remaining[currentIndex - 1] ?? null
|
||||
}
|
||||
|
||||
async function selectNextCandidate(currentId: string) {
|
||||
const before = store.candidates
|
||||
const idx = before.findIndex(c => c.id === currentId)
|
||||
const remaining = store.candidates // store 操作后已 filter 移除 currentId
|
||||
const next = idx >= 0 ? pickNextCandidate(remaining, idx) : null
|
||||
async function selectNextCandidate(currentIndex: number) {
|
||||
const remaining = store.candidates // 操作后已 filter 移除 currentId
|
||||
const next = currentIndex >= 0 ? pickNextCandidate(remaining, currentIndex) : null
|
||||
if (next) {
|
||||
await selectKnowledge(next.id)
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user