diff --git a/ui/src/api/docgen.js b/ui/src/api/docgen.js index c056e26..97b4f10 100644 --- a/ui/src/api/docgen.js +++ b/ui/src/api/docgen.js @@ -3,6 +3,11 @@ // 全部经 http.js 封装;默认读超时 600s 兜底(生成/编辑最长路径不早于 BFF 超时自断)。 import { get, post, patch, del } from './http.js'; +// 缺陷 #52:generate 兼容 200(旧同步契约)/202(新异步契约)两种响应形态。 +// 202 由 http.js 返回 payload(202 在 fetch 语义下非错误,body 直接透传); +// 旧 BFF 无 202 时直接返回同步产物——两者统一经 generate() 归一, +// chat.sendDocgen 按 `payload.task_id` 有无区分走轮询还是直接落块。 + /** * 上传入库(用户拖拽即走此路):multipart → vstore /ingest,入库主向量库持久可用。 * @param {File} file @@ -23,13 +28,25 @@ export function uploadLibrary(file, meta = {}, opts = {}) { } /** - * 同步生成(600s 兜底):前端落库消息与骨架后阻塞等待产物。 - * @returns {Promise<{ok:boolean, artifact:{artifact_id, title, template_name, status, ...}}>} + * 生成(600s 兜底读超时;兼容 200 同步 / 202 异步两种响应)。 + * @returns {Promise<{ok, task_id?, status?, artifact?, progress?, markdown?}>} + * 202 → {ok, task_id, status:"queued"};200 → 旧同步产物(artifact 内嵌)。 */ export function generate(payload) { return post('/api/docgen/generate', payload); } +/** 缺陷 #52:任务状态轮询(GET /api/docgen/tasks/{task_id}) + * → 200 {ok, task:{id, session_id, status, progress:[{section,title,state}], artifact|null, error}} */ +export function getTask(taskId) { + return get(`/api/docgen/tasks/${encodeURIComponent(taskId)}`); +} + +/** 缺陷 #52:会话级任务列表(GET /api/docgen/tasks?session_id=)——会话恢复时兜底查询 */ +export function listTasks(sessionId) { + return get('/api/docgen/tasks', { session_id: sessionId }); +} + /** 取 artifact 的 md 原文 */ export function getArtifactContent(artifactId) { return get(`/api/docgen/artifacts/${encodeURIComponent(artifactId)}/content`); diff --git a/ui/src/components/bench/DocPane.vue b/ui/src/components/bench/DocPane.vue index 35de946..3f3c74c 100644 --- a/ui/src/components/bench/DocPane.vue +++ b/ui/src/components/bench/DocPane.vue @@ -14,7 +14,7 @@ import { ref, computed, watch, nextTick, onMounted, onBeforeUnmount } from 'vue'; import { useDocgenStore } from '../../stores/docgen.js'; import { DG, BUILTIN_TEMPLATES } from '../../i18n/docgen.js'; -import { renderMarkdown, sanitizeHtml } from '../chat/markdown.js'; +import { renderMarkdownPlain, sanitizeHtml } from '../chat/markdown.js'; // FR-PRIV-006:「我的资料」管理面板(挂空态区顶部,UI_SPEC §9.2) import PrivateLibraryPane from './PrivateLibraryPane.vue'; @@ -67,7 +67,8 @@ function mountShadow() { inner = `
${sanitizeHtml(bodyFragment(docgen.html))}
`; } else { // 回退:客户端 md 渲染(旧制品/拉取失败) - inner = `
${renderMarkdown(docgen.md)}
`; + // 缺陷 #7b:md 回退预览不注入标题编号——序列化会把标题写回正本,编号不得进源文 + inner = `
${renderMarkdownPlain(docgen.md)}
`; } root.innerHTML = inner; if (editing.value) activateEditDom(); @@ -327,11 +328,17 @@ onBeforeUnmount(() => {