🐛 fix(vscode): 移交只对负责人显示;接管后审查会话立即可点
Claude-Session: https://claude.ai/code/session_011cEyL6k351U2BzX1Qmygph
This commit is contained in:
@@ -152,17 +152,8 @@ export async function handleHandoffStart(panel: KanbanWebviewPanel, issueNumber:
|
||||
return
|
||||
}
|
||||
|
||||
// 前置复查:webview 按钮的显示条件可能已经过期(并发移交、工单已被拖到
|
||||
// 完成),用刚读到的最新 state 再判一次 canStartHandoff,避免重复移交。
|
||||
const knownColumns: IssueColumn[] = ['todo', 'in-progress', 'review', 'done']
|
||||
const column = knownColumns.includes(state.column as IssueColumn) ? (state.column as IssueColumn) : 'todo'
|
||||
if (!canStartHandoff({ source: 'gitea', column, handoffAttachmentId: str(state.handoffAttachmentId) })) {
|
||||
toast(panel, 'error', `#${issueNumber} 已在移交中或已完成,不能再次移交`)
|
||||
return
|
||||
}
|
||||
|
||||
// column 兜底成 'todo' 时挡不住「Gitea 已关闭但从没拖进看板」的工单——
|
||||
// 再拉一次远端 issue.state 兜底。
|
||||
// 先拉远端 issue:既要兜底「Gitea 已关闭但从没拖进看板」的工单,也要拿到
|
||||
// assignees 判断「是否我负责」——两者都得在 canStartHandoff 判定前就绪。
|
||||
const issue = await getIssue({ host, token, owner, repo, index: issueNumber })
|
||||
if (!issue) {
|
||||
toast(panel, 'error', `工单 #${issueNumber} 不存在或已删除`)
|
||||
@@ -173,6 +164,21 @@ export async function handleHandoffStart(panel: KanbanWebviewPanel, issueNumber:
|
||||
return
|
||||
}
|
||||
|
||||
// 前置复查:webview 按钮的显示条件可能已经过期(并发移交、工单已被拖到
|
||||
// 完成、指派已变更),用刚读到的最新 state + issue 再判一次 canStartHandoff,
|
||||
// 避免重复移交或抢别人的工单。
|
||||
const knownColumns: IssueColumn[] = ['todo', 'in-progress', 'review', 'done']
|
||||
const column = knownColumns.includes(state.column as IssueColumn) ? (state.column as IssueColumn) : 'todo'
|
||||
const assignees = (issue.assignees ?? []).map(a => a.login)
|
||||
if (!canStartHandoff({ source: 'gitea', column, handoffAttachmentId: str(state.handoffAttachmentId), assignees }, me)) {
|
||||
// 区分「不是我的工单」和「已在移交中/已完成」两种拒绝原因,措辞不同。
|
||||
const notMine = assignees.length > 0 && !(me !== undefined && assignees.includes(me))
|
||||
toast(panel, 'error', notMine
|
||||
? `#${issueNumber} 不是你负责的工单,不能移交`
|
||||
: `#${issueNumber} 已在移交中或已完成,不能再次移交`)
|
||||
return
|
||||
}
|
||||
|
||||
const branch = str(state.branch)
|
||||
const worktreePath = str(state.worktreePath)
|
||||
const sessions: HandoffSessions = {
|
||||
@@ -456,6 +462,10 @@ export async function handleHandoffAccept(panel: KanbanWebviewPanel, issueNumber
|
||||
})
|
||||
|
||||
// ④ 本机字段 + 清共享字段;⑤ 删附件(失败只 warn)
|
||||
// reviewSessionFileExists 是计算字段,board 只在启动时算一次(annotateReviewSessionFileExists);
|
||||
// 接管刚把 codex 会话文件装进本机,这里顺手算好一起下发,UI 不用等下次刷新才能点「审查会话」链接。
|
||||
const reviewSessionFileExists = !!manifest.sessions.reviewSessionId
|
||||
&& manifest.codex.some(c => c.id.toLowerCase() === manifest.sessions.reviewSessionId!.toLowerCase())
|
||||
const local = { sessions: manifest.sessions, profiles: manifest.profiles, worktreePath: worktreeAbs }
|
||||
await panel.mergeIssueState(issueNumber, handoffAcceptedStateExtra(local))
|
||||
try {
|
||||
@@ -469,7 +479,7 @@ export async function handleHandoffAccept(panel: KanbanWebviewPanel, issueNumber
|
||||
panel.postMessage({
|
||||
type: 'issue/patch',
|
||||
issueNumber,
|
||||
patch: handoffAcceptedUiPatch({ ...local, worktreeExists: !!worktreeAbs }),
|
||||
patch: handoffAcceptedUiPatch({ ...local, worktreeExists: !!worktreeAbs, reviewSessionFileExists }),
|
||||
})
|
||||
toast(panel, 'success', `已接管 #${issueNumber}(来自 ${manifest.from})${worktreeAbs ? `,worktree:${worktreeAbs}` : ''}`)
|
||||
logger.add({ level: 'info', source: 'panel', message: `接管 #${issueNumber} 完成`, details: JSON.stringify({ manifest, worktreeAbs }) })
|
||||
|
||||
Reference in New Issue
Block a user