✨ feat(vscode): 看板底栏新增工单讨论 Tab 并支持系统气泡与 Gitea 评论同步

This commit is contained in:
cruldra committed 2026-09-29 04:23:57 +08:00
1 parent 8ecb40b330
commit df17821408
14 files changed
+1555 -2

No files matched your search

+83
View File
@@ -0,0 +1,83 @@
import type { GiteaComment } from '../../gitea/api'
import type { KanbanWebviewPanel } from '../KanbanPanel'
import { listIssueComments, postIssueComment } from '../../gitea/api'
import { systemCommentText } from '../../gitea/issueComment'
import { logger } from '../../logging/logger'
import { resolveRepoCtx, toast } from './handoffFlow'
export interface IssueChatComment {
id: number
author: string
authorName?: string
avatarUrl?: string
createdAt: string
body: string
systemText?: string
}
function toChat(comment: GiteaComment): IssueChatComment {
const systemText = systemCommentText(comment.body)
return {
id: comment.id,
author: comment.user?.login ?? '未知',
authorName: comment.user?.full_name || undefined,
avatarUrl: comment.user?.avatar_url || undefined,
createdAt: comment.created_at,
body: comment.body,
...(systemText ? { systemText } : {}),
}
}
async function pushComments(panel: KanbanWebviewPanel, issueNumber: number): Promise<void> {
const ctx = await resolveRepoCtx(panel)
if (!ctx)
return
const comments = await listIssueComments({
host: ctx.host,
token: ctx.token,
owner: ctx.owner,
repo: ctx.repo,
index: issueNumber,
})
panel.postMessage({
type: 'issue/comments-result',
issueNumber,
comments: comments.map(toChat),
})
}
export async function handleIssueComments(panel: KanbanWebviewPanel, issueNumber: number): Promise<void> {
try {
await pushComments(panel, issueNumber)
}
catch (err) {
const message = err instanceof Error ? err.message : String(err)
logger.add({ level: 'error', source: 'panel', message: `读取工单 #${issueNumber} 评论失败`, details: message })
panel.postMessage({ type: 'issue/comments-result', issueNumber, comments: [], error: message })
}
}
export async function handleIssueCommentPost(panel: KanbanWebviewPanel, issueNumber: number, body: string): Promise<void> {
const text = body.trim()
if (!text)
return
const ctx = await resolveRepoCtx(panel)
if (!ctx)
return
try {
await postIssueComment({
host: ctx.host,
token: ctx.token,
owner: ctx.owner,
repo: ctx.repo,
index: issueNumber,
body: text,
})
await pushComments(panel, issueNumber)
}
catch (err) {
const message = err instanceof Error ? err.message : String(err)
logger.add({ level: 'error', source: 'panel', message: `发表工单 #${issueNumber} 评论失败`, details: message })
toast(panel, 'error', `评论没发出去:${message}`)
}
}