feat: add project-scoped work assistant results

This commit is contained in:
2026-07-21 04:44:15 +08:00
parent 53b15e506c
commit 4536d607e3
75 changed files with 3281 additions and 507 deletions
@@ -8,9 +8,9 @@
**Tech Stack:** Spring Boot / Java 21、JdbcTemplate、Sa-Token、MySQL 8 Fulltext、Qdrant REST、MinIO/sys_oss、Apache Tika、uni-app Vue 3、TypeScript、Node test runner。
**交互设计基准:** [工作助手语音优先与确认记忆设计图](prototypes/personal-assistant-work-helper-voice-first-v2.png)。该图是 Task 10 的实现参考,不是当前生产截图;安全、权限、状态机和 API 冲突时以 [专项 TechSpec](个人AI助理阶段二专项TechSpec.md) 为准。
**交互设计基准:** [工作助手语音优先与确认记忆设计图](prototypes/personal-assistant-work-helper-voice-first-v2.png)。该图用于现有确认式采集的视觉回归,不是当前生产截图;安全、权限、状态机和 API 冲突时以 [专项 TechSpec](个人AI助理阶段二专项TechSpec.md) 为准。
**当前边界:** Task 10 的“记一下”已复用 `/api/knowledge/query`、`aihr_memory_candidate` 和 `aihr_assistant_capture` 完成本地闭环;本计划其余个人文件、网页、独立 `/ask`、分享和 PPT 任务仍未实施,不得按计划文本推断已完成。
**当前边界:** Task 10 的“记一下”已复用 `/api/knowledge/query`、`aihr_memory_candidate` 和 `aihr_assistant_capture` 完成实现并部署;本计划其余个人文件、网页、独立 `/ask`、分享和 PPT 任务仍未实施,不得按计划文本推断已完成。项目名称选择、项目化会话、来源追溯和今日工作成果不在本文件重复规划,统一以[《工作助手与今日工作成果迭代计划》](工作助手与今日工作成果迭代计划-20260721.md)为施工入口。
---
@@ -979,135 +979,12 @@ Expected: 单测 PASS;匿名请求业务响应为 401,接口没有 @SaIgnore
---
### Task 10: 将现有「问」页升级为工作助手并接入个人助理
### Task 10: 工作助手确认式采集(已完成,不重复施工)
**Design reference:** [personal-assistant-work-helper-voice-first-v2.png](prototypes/personal-assistant-work-helper-voice-first-v2.png)
实现时复用当前 `ChatComposer` 的默认语音模式和师傅回答的“语音条 → 转文字”形态,不重建第二套会话组件。设计图中的确认卡用于约束信息层级和关键动作;首屏不暴露三种内部资料域,来源在回答或保存结果中按实际命中展示。
**Files:**
- Create: mobile-uni/src/services/personal-assistant.ts
- Create: mobile-uni/src/pages/user/assistant/library.vue
- Create: mobile-uni/src/pages/user/assistant/capture.vue
- Create: mobile-uni/src/pages/user/assistant/item.vue
- Create: mobile-uni/src/pages/user/assistant/sessions.vue
- Create: mobile-uni/tests/personal-assistant.test.mjs
- Modify: mobile-uni/src/pages.json
- Modify: mobile-uni/src/pages/user/sop/index.vue
- Modify: mobile-uni/src/pages/user/web-ai/index.vue
- Modify: mobile-uni/src/types/api.ts
- [ ] **Step 1: 写失败的页面契约测试**
import test from 'node:test';
import assert from 'node:assert/strict';
import { readFile } from 'node:fs/promises';
const source = (path) => readFile(new URL(path, import.meta.url), 'utf8');
test('工作助手默认自动选择内部资料范围', async () => {
const page = await source('../src/pages/user/sop/index.vue');
assert.match(page, /工作助手/);
assert.match(page, /资料范围/);
assert.match(page, /自动/);
assert.match(page, /收藏资料/);
assert.match(page, /citation\.domain/);
});
test('一级入口只区分工作助手与查全网', async () => {
const internalPage = await source('../src/pages/user/sop/index.vue');
const webPage = await source('../src/pages/user/web-ai/index.vue');
assert.match(internalPage, /工作助手/);
assert.match(webPage, /查全网/);
assert.doesNotMatch(internalPage, /企业问师傅\s*\/\s*个人助理\s*\/\s*全网/);
});
test('个人资料页面包含状态、重试和删除', async () => {
const page = await source('../src/pages/user/assistant/item.vue');
assert.match(page, /PARSING|解析中/);
assert.match(page, /retryPersonalItem/);
assert.match(page, /deletePersonalItem/);
});
- [ ] **Step 2: 运行测试确认失败**
Run:
npm --prefix mobile-uni run test:unit
Expected: FAIL,现有「问」页尚未提供工作助手 AUTO 范围和简化后的一级入口。
- [ ] **Step 3: 实现 API 客户端**
personal-assistant.ts 固定使用现有 apiRequest:
export type InternalKnowledgeScope = 'PERSONAL' | 'PROJECT_SERVICE' | 'ENTERPRISE';
export const askPersonalAssistant = (payload: {
sessionId?: number;
queryText: string;
scopeMode: 'AUTO' | 'MANUAL';
scope: InternalKnowledgeScope[];
dateFrom?: string;
dateTo?: string;
itemIds?: number[];
outputFormat?: 'ANSWER' | 'ACTION_PLAN' | 'OUTLINE';
}) => apiRequest<PersonalAskResponse>({
url: '/api/aihr/personal-assistant/ask',
method: 'POST',
data: payload,
timeout: 45000
});
export const deletePersonalItem = (id: number) =>
apiRequest<{ cleanupJobId: number }>({
url: '/api/aihr/personal-assistant/items/' + id,
method: 'DELETE',
timeout: 15000
});
- [ ] **Step 4: 实现页面交互**
关键状态必须唯一:
const scopeMode = ref<'AUTO' | 'MANUAL'>('AUTO');
const manualScopes = ref<InternalKnowledgeScope[]>([]);
const queryText = ref('');
const asking = ref(false);
const answer = ref<PersonalAskResponse>();
const submitQuestion = async () => {
const question = queryText.value.trim();
if (!question || asking.value) return;
asking.value = true;
try {
answer.value = await askPersonalAssistant({
queryText: question,
scopeMode: scopeMode.value,
scope: scopeMode.value === 'MANUAL' ? manualScopes.value : [],
outputFormat: 'ACTION_PLAN'
});
} finally {
asking.value = false;
}
};
一级只显示“工作助手 / 查全网”。工作助手默认 `AUTO`,只在 PERSONAL / PROJECT_SERVICE / ENTERPRISE 三个内部授权域路由;“资料范围”放在输入区次级设置中。引用卡按 `citation.domain` 显示“我的资料 / 项目记录 / 企业 SOP”,让用户看得见实际来源。公网查询继续使用独立页面和接口,内部无命中时只能提示用户主动进入“查全网”,不得自动转发原问题或住户/项目内容。
- [ ] **Step 5: 运行移动端检查**
Run:
npm --prefix mobile-uni run test:unit
npm --prefix mobile-uni run typecheck
npm --prefix mobile-uni run build:h5
Expected: 全部 PASS;无新增横向滚动;页面路由存在。
- [ ] **Step 6: 提交**
git add mobile-uni/src/pages.json mobile-uni/src/pages/user/assistant mobile-uni/src/pages/user/sop/index.vue mobile-uni/src/pages/user/web-ai/index.vue mobile-uni/src/services/personal-assistant.ts mobile-uni/src/types/api.ts mobile-uni/tests/personal-assistant.test.mjs
git commit -m "feat(mobile): add personal assistant knowledge flow"
- 已复用 `ChatComposer`、`/api/knowledge/query`、`aihr_memory_candidate` 和 `aihr_assistant_capture` 完成确认式采集并部署。
- 当前生产能力、接口和限制以[专项 TechSpec](个人AI助理阶段二专项TechSpec.md)、[API 对接指南](API_INTEGRATION.md)和[BRD 功能审查](BRD_IMPLEMENTATION_AUDIT.md)为准。
- 本文件原有的页面脚手架、失败测试和重复实现步骤已删除,避免后续 Agent 创建第二套工作助手或把未实现的个人资料 API 当成现有接口。
- 后续项目选择、来源追溯、今日成果和主管项目视图只执行[工作助手迭代计划](工作助手与今日工作成果迭代计划-20260721.md)。
---