diff --git a/README.md b/README.md index dc8421d..8f8c5d3 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ Vite 通常使用 http://localhost:5173。 } ``` -响应新增 `version/updated_at/is_deleted` 及关联、采集、审核字段;完整类型以 `/openapi.json` 和 `/docs` 为准。前端已接入登录/注册、Cookie 会话恢复、个人中心、账户设置、角色路由守卫、角色菜单、知识录入和来源登记/查询;文档、审核、完整分页和浏览器端 PostgreSQL 联调仍需按接口验收。 +响应新增 `version/updated_at/is_deleted` 及关联、采集、审核字段;完整类型以 `/openapi.json` 和 `/docs` 为准。前端已接入登录/注册、Cookie 会话恢复、个人中心、账户设置、角色路由守卫、角色菜单、知识录入和来源登记/查询;文档管理已接入创建、编辑、软删除、分页搜索及历史快照的真实接口。知识审核、来源的完整编辑/历史页面及浏览器端 PostgreSQL 联调仍需按接口验收。 ### 关键词检索基线 diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 7aeafef..a19aa2c 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -14,7 +14,7 @@ FastAPI + Pydantic |-- 来源获取 -> 人工核验 -> 文本切分 -> 生成向量 -> 发布版本 ``` -当前后端实现健康/数据库就绪检查、来源与文档管理、知识增删改查、分页筛选、人工审核、历史快照、认证会话/角色权限、文本/向量快照及独立关键词/向量/RRF 检索;问答仍为占位接口。数据库由 Alembic 显式迁移并启用 pgvector,DeepSeek RAG 待明确恢复后实现。前端已接入登录/注册、个人中心、账户设置、会话恢复、路由守卫和角色菜单;实验页不伪造数据,文档、审核、完整分页、浏览器 Cookie 与 PostgreSQL 联调仍需验收。 +当前后端实现健康/数据库就绪检查、来源与文档管理、知识增删改查、分页筛选、人工审核、历史快照、认证会话/角色权限、文本/向量快照及独立关键词/向量/RRF 检索;问答仍为占位接口。数据库由 Alembic 显式迁移并启用 pgvector,DeepSeek RAG 待明确恢复后实现。前端已接入登录/注册、个人中心、账户设置、会话恢复、路由守卫和角色菜单,以及文档的创建、编辑、软删除、分页搜索与历史快照;实验页不伪造数据,知识审核、来源的完整维护、浏览器 Cookie 与 PostgreSQL 联调仍需验收。 ## 阶段 2 数据边界 diff --git a/frontend/src/api.ts b/frontend/src/api.ts index a5e72cd..bd19cd7 100644 --- a/frontend/src/api.ts +++ b/frontend/src/api.ts @@ -15,6 +15,10 @@ export function reviewKnowledge(id:number,payload:{expected_version:number;verif export type DocumentItem={id:number;version:number;source_id:number;title:string;category:string;content:string;collected_at:string;notes:string;created_at:string;updated_at:string;is_deleted:boolean} export function getDocuments(q='',page=1,pageSize=20){return apiRequest<{items:DocumentItem[];total:number;page:number;page_size:number}>(`/api/documents?q=${encodeURIComponent(q)}&page=${page}&page_size=${pageSize}`)} export function createDocument(payload:{source_id:number;title:string;category:string;content:string;collected_at:string;notes?:string}){return apiRequest('/api/documents',{method:'POST',body:JSON.stringify(payload)},true)} +export function updateDocument(id:number,payload:{expected_version:number;title?:string;category?:string;content?:string;collected_at?:string;notes?:string}){return apiRequest(`/api/documents/${id}`,{method:'PATCH',body:JSON.stringify(payload)},true)} +export function deleteDocument(id:number,expectedVersion:number){return apiRequest(`/api/documents/${id}?expected_version=${expectedVersion}`,{method:'DELETE'},true)} +export type AuditItem={id:number;entity_type:string;entity_id:number;action:string;actor:string|null;notes:string;snapshot:Record;created_at:string} +export function getDocumentHistory(id:number,page=1,pageSize=20){return apiRequest<{items:AuditItem[];total:number;page:number;page_size:number}>(`/api/documents/${id}/history?page=${page}&page_size=${pageSize}`)} export type RetrievalHit={rank:number;knowledge_id:number;knowledge_version:number;document_id:number|null;document_version:number|null;source_id:number|null;source_version:number|null;source_name:string|null;source_url:string;title:string;category:string;snippet:string;snippet_start:number;snippet_end:number;score:number;matched_terms:string[]} export type RetrievalResult={run_id:string;query:string;mode:'keyword';status:'ok'|'no_evidence';top_k:number;category:string|null;query_terms:string[];corpus_size:number;corpus_fingerprint:string;total_hits:number;results:RetrievalHit[];elapsed_ms:number;created_at:string;config:{tokenizer:string;scorer:string;k1:number;b:number;title_weight:number;stopwords_version:string}} diff --git a/frontend/src/views/DocumentManagementView.vue b/frontend/src/views/DocumentManagementView.vue index 7433da8..f8094a7 100644 --- a/frontend/src/views/DocumentManagementView.vue +++ b/frontend/src/views/DocumentManagementView.vue @@ -1,10 +1,20 @@ -