feat: restore learning feedback and knowledge capabilities

This commit is contained in:
2026-07-18 00:50:11 +08:00
parent 876a23a123
commit 6bdc86e3fc
152 changed files with 30337 additions and 953 deletions
@@ -121,7 +121,7 @@ mobile-uni/
截至 2026-07-10,`mobile-uni/` 已是用户、主管、候选人三端的现役页面栈,旧 `mobile/` 仅作 MVP 兜底。三端均以登录身份和真实 API 驱动:员工完成训练、问师傅和成长回读;主管按后端组织范围进行团队、复盘和专项指派;候选人按真实面试/资料状态进入独立线性页面。H5 构建、真实浏览器主链路和接口回读均已完成验证,不使用前端 mock 掩盖业务状态。
正式试点尚未通过:组织同步 dry-run 的 3474 名上游员工中仅 1 名具备可用于移动端身份映射的手机号,另有 8 条疑似乱码;严格门禁在窗口 `2026-07-07..2026-07-10` 只识别到 1 名正式人员且无人完成 10 次训练。下一阶段优先补齐上游正式组织数据并执行联合试点验收,不继续把功能堆回首页或旧单页。
2026-07-15 更新:组织同步和手机号映射门槛已从上游数据问题中恢复,线上 `aihr_org_snapshot` 已覆盖为 3417 名员工,其中 3392 人可手机号映射,25 人手机号仍不可用,疑似乱码为 0。严格试点尚未通过的剩余原因不再是组织同步能力,而是需要在真实试点窗口产生训练、人工校准和 SOP 评审样本;旧窗口 `2026-07-07..2026-07-10` 仍不能作为业务验收证据。下一阶段优先组织 1–2 个项目、至少 20 名员工的联合试点验收,不继续把功能堆回首页或旧单页。
- 第一批用户侧主链路已落地到 `mobile-uni/`: 登录、今日页、问师傅、答案反馈、总结卡、对练页、个人页。
- 本机开发入口已切到 portless: `https://wygj-mobile-uni.localhost/h5/`。
@@ -179,8 +179,8 @@ mobile-uni/
- 员工今日页师傅气泡已移除固定姓名 fallback: 未登录显示“同事”,登录后按手机号尾号提示,不再把 seed 姓名暴露给真实用户。
- 员工今日页“查看全部”和小贴士箭头已接通动作: 分别进入练习页和带问题进入问师傅,不再保留看起来可点但无反馈的入口。
- 员工今日页未登录视图已收敛: 公开 home 的 `primary/review` 不再渲染成私人“今日安排”,改为登录提示;工具区未登录时显示为“常用入口”。
- 员工今日页问答入口文案已收敛: 当前 uni-app 首页只负责进入问师傅页,主按钮改为“问老师傅”,不再用“长按说话”暗示已实现录音交互。
- 员工今日页训练文案已收敛: 首页主任务从“3分钟语音练习”改为“3分钟情景练习”,不再承诺当前 uni-app 尚未提供的语音对练入口。
- 员工今日页问答入口仍有待收口:主按钮虽然改为“问老师傅”,副文案仍写“语音提问,快速解答”,但两个入口都只跳到当前仅有文字框的问师傅页;短期应改为文字问答口径,若补语音则复用现有 `services/speech.ts` 与 `/api/ai/asr`。
- 员工训练页当前已支持文字回答、浏览器录音转写和选择音频转写;首页主任务继续使用“3分钟情景练习”,避免把训练方式限制成只支持语音。
- 问师傅页已补登录守卫: 未登录检索会保留当前问题并跳登录,不再直接暴露“认证失败”。
- 移动端认证清理已收敛到共享 `clearAuth()`: 主动退出和 401/403 会同时清掉 token、clientId、手机号和登录回跳,避免旧手机号残留。
- 员工“我”页已补过期登录态反馈: 401/403 清理后会同步刷新当前页面为“未登录/去登录”,不再继续显示旧手机号和退出按钮。
@@ -254,7 +254,7 @@ mobile-uni/
- 主管权限已以后端组织快照为准: 只有在职“主管/项目经理”可访问团队、预警、复盘和指派接口;普通员工真实浏览器验证只显示“无主管权限”及返回员工端/切换账号,不泄露团队指标和表单草稿。
- 主管复盘写入已补事务和幂等: 仅 `待复盘 -> 已复盘` 的首次状态转换创建后续专项;并发重复请求通过行锁读取最终状态,不重复派发。
- 主管端已用真实项目经理账号验证组织范围: 本地正式快照返回 19 名团队成员、1 条待复盘、2 项待训练和 1 条低分预警;团队页、复盘页和指派页均读取真实接口,不补前端 mock。
- 正式组织快照中的不可读问号姓名在用户侧回退为手机号尾号或外部 ID 末尾标识,真实 ID 保持不变;开放组织 dry-run 已确认源接口自身仍返回 8 条疑似乱码,需由上游修复后再同步。
- 正式组织快照中的不可读问号姓名在用户侧回退为手机号尾号或外部 ID 末尾标识,真实 ID 保持不变;2026-07-15 开放组织 dry-run 已确认疑似乱码为 0,线上同步后剩余问题收敛为 25 名员工手机号不可用。
- 候选人端已完成线性页面栈拆分: 原 750 行长页收敛为候选首页、面试任务、补充资料、进度通知和岗前预习 5 个路由;首页只展示真实状态和办理入口,不再原地展开所有表单和结果。
- 候选人流程状态已抽成共享纯函数: 只根据当前候选人的正式面试记录和最新资料状态派生“待面试/待补资料/审核中/已通过”,不读取公开 home seed,不补前端 mock。
- 候选面试页继续复用真实 `/api/recruit/interview/start|answer|finish|records`: 浏览器以当前移动账号验证 `/start` 返回 3 道岗位题,未提交答案和评分,避免产生额外正式面试记录。
@@ -263,10 +263,10 @@ mobile-uni/
- 候选岗前预习页改为自然业务问题检索正式 SOP: 浏览器验证投诉预习返回正式答案、关键要点、注意事项,引用命中 `投诉处理 SOP v1.0`、`生活顾问的一天.mp4` 和正式课件,无前端示例答案。
- 演示预检已跟随页面栈更新: `scripts/demo-check.sh` 改为检查主管复盘详情和候选 4 个子路由,不再在旧主管首页查复盘表单标记;本地数据库连接不可用时非严格模式明确跳过样本、严格模式继续失败。
- 本地连接耗尽已处置: 清理未被 portless 使用的旧后端实例并重启本地 MySQL 后,连接稳定在约 `11/151`,当前 API HTTP 200;`dev.sh stop/restart` 已改为安全终止 portless 进程树,避免旧 Java/Vite 子进程继续占用连接池。
- 试点严格预检已改为正式批次口径: 必须指定起止日期,训练、校准和 SOP 评审只统计该时间窗;人员通过唯一手机号映射到在职组织,排除重复手机号和身份碰撞,完训定义为每人至少 10 次。`2026-07-07..2026-07-10` 实测开发活动身份 50 人、10 次完训 0 人,但正式组织仍为 `org_login=1/3001`、`org_pilot=1/20`、`org_ten_sessions=0/1`,所以严格模式正确失败。开放组织 dry-run 返回 `employees=3474 phone_linked=1 masked_phone=3473 suspect_text=8 synced=0`,且 dry-run 不访问本地表结构或写库,证明手机号和 8 条问号数据来自上游且本轮未覆盖快照。
- 管理端试点 CSV 已与严格预检统一口径: 必须选择起止日期,只导出窗口内唯一匹配正式组织的训练明细,完训按每人至少 10 次,校准必须关联正式试点会话。真实 API 返回正式试点 1 人/1 项目、10 次完训 `0/1`、校准 `0/20`、窗口内 SOP `2/2`,总闸门为 `false`;此前开发会话中的 20 条校准不再计入正式验收。
- 试点严格预检已改为正式批次口径: 必须指定起止日期,训练、校准和 SOP 评审只统计该时间窗;人员通过唯一手机号映射到在职组织,排除重复手机号和身份碰撞,完训定义为每人至少 10 次。2026-07-15 线上组织快照已具备 `employees=3417 phone_linked=3392 masked_phone=25 suspect_text=0`;旧窗口 `2026-07-07..2026-07-10` 仍因无人达到 10 次训练、缺少正式校准样本而失败,所以后续需用新试点窗口重跑,不能沿用开发活动数据。
- 管理端试点 CSV 已与严格预检统一口径: 必须选择起止日期,只导出窗口内唯一匹配正式组织的训练明细,完训按每人至少 10 次,校准必须关联正式试点会话。组织快照覆盖后 CSV 的人员映射能力已具备;下一步需在正式试点窗口产生真实训练、校准和 SOP 评审记录后重新导出,此前开发会话中的 20 条校准不再计入正式验收。
- 发布会正式候选题已重新走查: Q01-Q12 `12/12` 返回有效答案和依据,来源告警 `0`,向量状态 `450/450`;仍有 119 条 SOP 问答待业务评审,不把开发方走查替代业务签字。
- 下一阶段进入三端联合发布门槛: 复跑员工-主管-候选人角色切换、清理本地验证数据、核对正式组织姓名编码并完成 H5 发布前验收;不把本次页面拆分等同一期生产验收完成。
- 下一阶段进入三端联合试点门槛: 复跑员工-主管-候选人角色切换、清理本地验证数据、选择真实项目与员工样本并完成 H5 发布后验收;不把本次页面拆分等同一期生产验收完成。
## 7. 风险
@@ -274,4 +274,4 @@ mobile-uni/
- H5 路由和将来小程序路径不完全一致,页面命名要早期克制。
- 旧 H5 在 Alpha 前仍承担演示兜底,新工程未完成替换前不能下线旧入口。
- 如果后端某些接口仍要求管理端 token,需要后端补移动端认证口径,不能在新前端绕过认证。
- 当前本地组织快照存在部分不可读姓名,前端已做可识别展示兜底,但正式试点前仍需从开放组织同步源修复编码并重跑快照同步。
- 线上组织快照已完成开放组织覆盖同步并消除疑似乱码;剩余 25 名员工手机号不可用属于上游数据质量问题,不阻塞功能发布,但这些人员在修复前无法通过手机号自动映射身份。
+42 -5
View File
@@ -14,8 +14,8 @@
| 案例沉淀 `/knowledge/cases` | `GET /api/knowledge/case/capabilities`、`POST /api/knowledge/case/upload`、`/organize`、`/curate`、`GET /records`、`GET /records/{caseId}`、`POST /records/{caseId}/review`、`GET /records/{caseId}/media` | `/capabilities` 返回服务端判定的案例提交/查看能力,移动端不再向普通员工展示无权提交的素材表单;`/upload` 改为 multipart 真实语音上传并走 ASR,服务端只接受 MP3/WAV/M4A/WebM/OGG/AAC/FLAC,成功后原始音频写入 `sys_oss`,案例记录只保存 `mediaOssId` 供受保护媒体接口读取,不向客户端回传原始 `mediaUrl`;`/organize` 用真实转写调 chat 模型整理案例,未配置模型时按真实 transcript 本地结构化,并从背景外的真实摘要项提取学习点;APP 用户的项目范围从 `aihr_org_snapshot` 登录身份解析,上传、整理、入库、列表和详情均按项目范围校验,未完成正式组织映射时安全拒绝,不接受前端伪造项目范围;员工列表/详情只返回 `已入库` 案例,管理端系统用户保留全局运营视图;移动端和管理端案例详情通过受保护媒体接口回放原始音频,主管/项目负责人可提交脱敏点评;预渲染视频样片仍待正式媒体资产接入 |
| 案例媒体安全 | `GET /api/knowledge/case/records/{caseId}/media` | 案例详情只返回 `mediaOssId`,不返回原始 `sys_oss.url`;媒体下载会重复执行登录、后台角色或 APP 项目范围校验,再由服务端流式读取 OSS。管理端与 `mobile-uni` 通过鉴权 blob/temp 文件播放,关闭详情页时释放本地对象 URL |
| SOP知识库 `/knowledge/sop` | `POST /api/knowledge/search`、`POST /api/knowledge/answer-feedback`、`GET /api/knowledge/position-sop`、`GET /api/aihr/mobile/onboard/tasks`、`POST /api/aihr/mobile/onboard/tasks/{id}/complete`、`GET /api/aihr/mobile/qualification`、`POST /api/knowledge/doc/upload` | 已接入 MySQL Fulltext + Qdrant 混合召回、岗位学习适配摘要、OSS-first 文档上传、txt/md/PDF/Word/Excel/PPT 解析和 embedding 写入,失败回退 seed;搜索返回 `reviewId` 与 `promptVersion`,员工反馈回传并保存该评审批次,SOP 人工评审记录同时保留答案生成提示词版本,管理端可继续复核;员工学习页按当前 APP 身份读取正式岗前/入职任务,员工只能将本人处于“待完成/进行中”的任务确认完成,服务端按组织快照/手机号归属更新 `status/completed_time`,不接受前端身份参数;资格证据无正式数据时明确返回 `NOT_CONFIGURED`,不以 AI 分数代替上岗资格;`position-sop` 仍保留一期生活顾问学习导航语义 |
| 资料处理 `/knowledge/processing` | `GET /api/knowledge/processing/overview`、`POST /api/knowledge/doc/upload-async`、`GET /api/knowledge/doc/upload-items`、`POST /api/knowledge/doc/upload-items/{id}/retry`、`POST /api/knowledge/doc/import-local-task`、`GET /api/knowledge/doc/import-tasks`、`POST /api/knowledge/doc/import-tasks/{id}/cancel` | 已接入解析任务状态聚合;**批量上传走异步队列**:接口只暂存+入队即秒回,后台 worker(并发 2)逐条解析/归类/向量化;ZIP 在 worker 内安全解压后把支持的子文件继续入同一批次队列,页面按批次轮询进度、失败可单文件重试;服务端目录导入、进度轮询和任务取消保留,失败回退 seed |
| 组织人员同步 | `POST /api/aihr/org/sync` | 从开放组织同步系统的 `/api/open/v1/sync/snapshot` 拉取 `company/department/employee` 快照,分页参数使用 `limit`;员工手机号只落 `person_phone` 用于移动端身份映射,不在组织列表响应暴露;岗位识别 `position/job_title/post/job_name/role/title` 等字段。`dryRun` 必须显式传入 `true`(预检)或 `false`(写入),省略或传 `null` 直接拒绝,避免空请求意外写库;默认 `replaceExisting=true`,写入前必须先用 `{"dryRun":true}`;dry-run 不访问本地快照表、不执行 DDL/写库,返回 `phoneLinked/maskedPhone/suspectText/warnings` 且 `syncedCount=0`。非 dry-run 覆盖写入遇到员工被跳过、手机号不完整、脱敏手机号或疑似乱码时默认拒绝,只有确认 dry-run 结果后显式传 `allowPartialReplace=true` 才允许覆盖;重复 `ext_party_id` 始终拒绝写入,因为数据库唯一键会折叠重复身份;`replaceExisting=false` 不触发不完整快照覆盖闸门,但仍拒绝重复身份。2026-07-10 源接口实测 3474 人仅 1 个可用手机号、3473 个脱敏手机号、8 条疑似乱码,因此未执行覆盖同步,正式试点需上游先开放至少 20 名试点人员手机号 |
| 资料处理 `/knowledge/processing` | `GET /api/knowledge/processing/overview`、`POST /api/knowledge/doc/upload-async`、`GET /api/knowledge/doc/upload-items`、`POST /api/knowledge/doc/upload-items/{id}/retry` | 已接入解析任务状态聚合;页面只保留“批量导入”,接口暂存+入队即秒回,后台 worker(并发 2)逐条解析/归类/向量化;ZIP 在 worker 内安全解压后把支持的子文件继续入同一批次队列,页面按批次轮询进度、失败可单文件重试;不提供浏览器目录选择或服务端目录导入入口 |
| 组织人员同步 | `POST /api/aihr/org/sync` | 从开放组织同步系统的 `/api/open/v1/sync/snapshot` 拉取 `company/department/employee` 快照,分页参数使用 `limit`;员工手机号只落 `person_phone` 用于移动端身份映射,不在组织列表响应暴露;岗位识别 `position/job_title/post/job_name/role/title` 等字段。`dryRun` 必须显式传入 `true`(预检)或 `false`(写入),省略或传 `null` 直接拒绝,避免空请求意外写库;默认 `replaceExisting=true`,写入前必须先用 `{"dryRun":true}`;dry-run 不访问本地快照表、不执行 DDL/写库,返回 `phoneLinked/maskedPhone/suspectText/warnings` 且 `syncedCount=0`。非 dry-run 覆盖写入遇到员工被跳过、手机号不完整、脱敏手机号或疑似乱码时默认拒绝,只有确认 dry-run 结果后显式传 `allowPartialReplace=true` 才允许覆盖;重复 `ext_party_id` 始终拒绝写入,因为数据库唯一键会折叠重复身份;`replaceExisting=false` 不触发不完整快照覆盖闸门,但仍拒绝重复身份。2026-07-15 线上已用 `/api/open/v1` 前缀完成配置、dry-run 和覆盖同步:开放平台返回公司 17、部门 963、员工 3417;生产 `aihr_org_snapshot` 为 3417 行,`phoneLinked=3392`、`maskedPhone=25`、`suspectText=0`,在职 2943、离职 474。当前剩余 25 人手机号不可用属于上游数据质量问题;功能发布不再被组织同步能力阻塞 |
| 移动端手机号登录 | `GET /resource/sms/code`、`POST /auth/mobile/sms-login` | 已复用 sms4j 阿里云配置 `config1` 和 RuoYi `sms` 授权策略;短信发送成功后才写 Redis 验证码;手机号不存在时自动注册 `app_user`;`aihr.sms.dev-fixed-code` 非空时不真发短信、验证码固定(dev 默认 `123456`)。prod 默认关闭,试点期只有同时设置 `AIHR_SMS_DEV_FIXED_CODE` 与 `AIHR_SMS_PROD_FIXED_CODE_ENABLED=true` 才启用固定码。 |
| 用户侧三端首页 `mobile-uni` hash 路由;旧 `/h5/user`、`/h5/candidate`、`/h5/supervisor` 兼容重定向 | `GET /api/aihr/mobile/home/{role}` | 未登录请求只返回不读取租户业务统计的公开首屏 seed;已登录移动端请求自动携带 `Authorization/clientid`,才返回员工/主管真实统计;移动端本地 fallback 保演示 |
| 移动端登录后角色识别 | `GET /api/aihr/mobile/me` | 认证后按手机号匹配组织快照;`position_level` 为“主管/项目经理”时进入主管端,否则进入员工端;接口失败回退员工端 |
@@ -68,9 +68,9 @@ SOP 文档上传第三片已经落最小后端边界:
| 混合检索 | `POST /api/knowledge/search` | 先跑中文关键词 `LIKE` 打分和 MySQL Fulltext,再生成 query embedding 走 Qdrant,RRF 融合后交给 `category='rerank'` 模型(如硅基流动 bge-reranker-v2-m3)按语义相关性重排;rerank 未配置或失败保持 RRF 顺序,Qdrant 或外部向量接口不可用时保留关键词/全文检索。命中后若 chat 模型可用,自动生成结构化轻概要写入响应 `answer/keyPoints/cautions`(≤60字直答+3-6要点+0-3注意;temperature=0,15s 超时,硬约束不得编造、答不了明示无依据);概要失败回退片段原文拼接,检索不报错 |
| 检索总结卡 | `POST /api/knowledge/summary-card`(JSON `{queryText, category}`) | 按需生成信息图式总结卡 `{title, steps[], objections[], scripts[], reminders[]}`:复用检索命中片段(最多5条)调 chat 模型,temperature=0、30s 超时;无命中/无 chat 模型/生成失败均抛明确错误供前端重试,不兜假数据。移动端查SOP结果页「生成总结卡」按钮触发,底部弹层展示并可 TTS 朗读 |
| 解析状态聚合 | `GET /api/knowledge/processing/overview` | 聚合 `aihr_knowledge_attach.status`、fragment 数、embedding 数、`sys_oss.ext1.fileSize`,生成资料处理页指标、分类、任务、链路和事件列表 |
| 服务端目录导入 | `POST /api/knowledge/doc/import-local` | JSON `{ directory, category, limit }`;`directory` 只能是 `AIHR_IMPORT_ROOT` / `aihr.import.root` 下的相对目录,默认根目录为 `./.data/import`;逐文件复用上传解析链路,同步执行,保留给小批量/调试 |
| 服务端导入任务 | `POST /api/knowledge/doc/import-local-task`、`GET /api/knowledge/doc/import-tasks`、`POST /api/knowledge/doc/import-tasks/{id}/cancel` | 启动后台目录导入并返回任务;任务写入 `aihr_knowledge_import_task`,页面轮询查看总数、成功数、失败数、当前文件和进度;运行中任务可取消;重试当前按同目录重新启动一轮 |
| 批量异步上传 | `POST /api/knowledge/doc/upload-async`(multipart `file`+`category`+`batchId`)、`GET /api/knowledge/doc/upload-items?batchId=`、`POST /api/knowledge/doc/upload-items/{id}/retry` | 上传只做暂存(`aihr.upload.staging`,默认 `./.data/staging`)+ 写入 `aihr_knowledge_upload_item`(0待处理/1处理中/2完成/3失败)即返回;支持 ZIP ≤500MB,worker 限制最多 1000 个子文件、解压总量 ≤2GB,拒绝嵌套 ZIP/不安全路径并忽略未知格式;支持的子文件写回同一 batch 继续复用解析链路;完成/失败状态 CAS 写入,卡住 30 分钟(视频 120 分钟)由清扫重置,失败暂存文件保留 72h 供重试;同步接口 `POST /api/knowledge/doc/upload` 不支持 ZIP,保留给 SOP 页单文件即时预览 |
| 服务端目录导入(运维) | `POST /api/knowledge/doc/import-local` | JSON `{ directory, category, limit }`;`directory` 只能是 `AIHR_IMPORT_ROOT` / `aihr.import.root` 下的相对目录,默认根目录为 `./.data/import`;逐文件复用上传解析链路,同步执行,仅保留给运维/调试,不在资料处理页暴露 |
| 服务端导入任务(运维) | `POST /api/knowledge/doc/import-local-task`、`GET /api/knowledge/doc/import-tasks`、`POST /api/knowledge/doc/import-tasks/{id}/cancel` | 启动后台目录导入并返回任务;任务写入 `aihr_knowledge_import_task`,调用方可查询总数、成功数、失败数、当前文件和进度,运行中任务可取消;仅保留给运维/调试,不在资料处理页暴露 |
| 批量异步上传 | `POST /api/knowledge/doc/upload-async`(multipart `file`+`category`+`batchId`)、`GET /api/knowledge/doc/upload-items?batchId=`、`POST /api/knowledge/doc/upload-items/{id}/retry` | 上传只做暂存(`aihr.upload.staging`,默认 `./.data/staging`)+ 写入 `aihr_knowledge_upload_item`(0待处理/1处理中/2完成/3失败)即返回;支持 ZIP ≤500MB,worker 限制最多 1000 个子文件、解压总量 ≤2GB,拒绝嵌套 ZIP/不安全路径并忽略未知格式;ZIP 文件名优先按 UTF-8 解码,旧版中文 Windows ZIP 自动回退 GBK,仍无法解压时返回安全提示;同名子文件自动追加编号并以单条批量写入入队,避免目录扁平化覆盖和半批次入队;完成/失败状态 CAS 写入,卡住 30 分钟(视频 120 分钟)由清扫重置,失败暂存文件保留 72h 供重试;同步接口 `POST /api/knowledge/doc/upload` 不支持 ZIP,保留给 SOP 页单文件即时预览 |
| 视频解析 | 走批量异步上传,支持 `.mp4/.mov/.avi/.mkv/.webm/.m4v`,单文件 ≤500MB、时长 ≤60 分钟 | 依赖服务器 ffmpeg/ffprobe;抽音轨按 5 分钟分段调 asr 模型转写(`[mm:ss]` 时间戳),按 30s 间隔(≤40 帧)抽关键帧调 vision 模型提取画面文字(相邻重复画面去重);两类文本合并后走归类/切片/向量化;无 asr 且无 vision 结果时按「待处理」落库不报错;视频同时只加工 1 个 |
模型能力第二片已经落最小后端边界:
@@ -179,3 +179,40 @@ curl -fsS -X POST "$API_BASE/api/knowledge/doc/rebuild-vector-index" -H "Authori
```
浏览器验收仍按 [DEMO_ACCEPTANCE.md](DEMO_ACCEPTANCE.md) 的四条关键路径执行。
## 多租户知识空间统一问答
内部员工端、主管端和管理端统一调用:
```http
POST /api/knowledge/query
Authorization: Bearer <session-token>
Content-Type: application/json
{
"queryText": "漏水投诉第一步怎么处理?",
"spaceCodes": ["yc_property_sop"],
"limit": 5
}
```
内部有效空间由服务端按当前租户、SESSION 应用绑定和用户/角色授权求交集;请求体中的 `tenantId/userId/extPartyId` 不参与身份判断。员工本人和主管团队概况只允许使用固定数据工具:
```json
{"queryText":"我的训练概况","toolCode":"MY_PRACTICE_SUMMARY"}
{"queryText":"团队训练概况","toolCode":"TEAM_PRACTICE_SUMMARY"}
```
外部应用使用独立入口,不能调用数据工具:
```http
POST /api/open/knowledge/query
Authorization: Bearer <api-token>
Content-Type: application/json
{"queryText":"你们提供哪些服务?","spaceCodes":["mt_customer_service"],"limit":5}
```
成功响应包含 `requestId`、`answer`、`citations`、`usedSpaceCodes`、`noEvidence` 和兼容 `legacy` 数据。引用携带 `spaceCode/sourceType/docId/title/snippet/fragmentId`;客户端不得把无引用回答包装成有知识依据的正式答案。
空间、授权和应用管理接口统一位于 `/api/knowledge/admin`:`spaces`、`spaces/{id}/grants`、`spaces/{id}/documents`、`apps`、`apps/{id}/spaces`、`apps/{id}/rotate-token`。`DELETE /spaces/{id}/documents/{attachId}` 只解绑当前空间成员;其他空间仍引用同一 OSS 时原文件不会删除。仅知识平台管理角色可调用,API_TOKEN 创建或轮换后只返回一次明文。完整初始化、令牌保管、legacy 迁移与回滚步骤见 [KNOWLEDGE_PLATFORM_RUNBOOK.md](KNOWLEDGE_PLATFORM_RUNBOOK.md)。
+80 -5
View File
@@ -1,5 +1,23 @@
# BRD 功能审查与未完成项记录
## 现阶段总览(2026-07-15)
本节只回答当前 `mobile-uni` 三端交互输入与 BRD 的匹配程度,不替代 L0/L1、生产发布或正式试点验收。按 BRD v1.2 的最终多模态目标评估,当前约为 **60%–70%(部分匹配)**;按总纲阶段一“陪练”执行边界评估,约为 **80%–90%(核心链路基本匹配)**。区间是工程审查判断,不是 BRD 官方验收指标。
| 角色端 | 文字输入 | 语音输入 | 图片/视频输入 | BRD 判断 |
|---|---|---|---|---|
| 员工端 | 对练、每日三题、问师傅和复盘意见支持文字 | 对练、每日三题和问师傅均支持浏览器录音或选择音频后 ASR;案例素材支持音频上传;关键题目、回答、点评和总结卡支持播报 | 问师傅本地已支持图片/视频仅用于本次现场分析;对练仍无图像/视频情境输入 | 满足阶段一语音/文本主链路;问师傅多媒体已有本地最小实现,对练仍未满足 BRD 4.3.3 图像/视频情境输入;均未发布生产 |
| 候选人端 | 面试支持文字作答 | 面试支持录音转文字和选择音频 | 补充资料支持 PDF/Word/常见图片,但不是图片面试或多模态评分 | 满足 BRD 4.1 语音/文本作答;资料图片上传属于附加能力,不能冲抵 4.3.3 缺口 |
| 主管端 | 专项指派、复盘建议和后续训练原因支持文字 | 可回听员工训练录音,不支持主管录音输入 | 无图片/视频提交入口 | 符合当前“查看回放→写复盘→派训练”职责;BRD 未要求主管端同时具备三种输入 |
已匹配的输入链路:候选人语音/文本面试(BRD 4.1)、员工语音/文本对练与每日一练(4.3/4.4)、主管文字复盘与录音回听(4.4)、案例音频上传(4.6)。尚未闭合的终态要求:员工图像/视频情境输入和服务录像回放(4.3.3)、四川话/粤语等方言的真实样本与 `<=5s` 响应证据(6.5/L1-C)、员工个人文字/文件/图片/链接收藏与混合问答(4.8,明确属于阶段二)。
此前 `pages/user/today/index.vue` 显示“语音提问,快速解答”,但问师傅只有文字输入,形成前端承诺不一致。2026-07-17 本地已复用 `mobile-uni/src/services/speech.ts` 和现有 `/api/ai/asr` 恢复录音、转写与选择音频兜底,没有新增移动端专用 ASR 接口;正式 ASR 配置和真机麦克风权限仍待发布前验证。
审查证据来自当前源码与本地渲染控件;本轮未重新执行真实方言 ASR、图片上传、语音响应时延或生产环境端到端测试,因此这些能力继续标记为未验证。图片/视频情境输入已在 `AI陪练二期开发推进计划.md` 中明确为文本场景稳定后的独立评估项;个人知识空间按 `银城员工端APP分阶段实施总纲.md` 留在阶段二,不应拉入当前阶段一主线。
- 2026-07-15 管理端资料处理分页静态发布:已备份生产根目录至 `/opt/wygj/backups/www-20260715134936`,再同步 `frontend/dist/`;根目录同步未使用 `--delete`,因此未覆盖同目录的 `/h5`。线上 `processing-yUVzof10.js` SHA-256 与本地构建一致。真实管理员会话确认任务分页共 97 页、第二页仍展示 10 条,状态筛选后回到第一页;根站、H5 和租户接口均返回 `200`。本轮未发布后端、迁移数据库或写入业务数据。
- 2026-07-15 当前发布与资料导入复核:提交 `eacf1a0a` 已发布到线上,`release-preflight.sh` 通过资源/后端哈希、`16/16` schema、根站/H5/API 健康检查,`wygj-aihr.service` 为 `active`。使用真实管理员认证在生产验证 ZIP 异步资料链路:ZIP 入队后拆为 `2` 条队列记录,`2/2` 完成,生成 `1` 个文档和 `2` 个片段;测试队列、附件、片段和 OSS 对象已清理。当前生产 BRD 证据仍未达标:评分校准 `0` 条,SOP 评审 `0/14`,候选资料 `0` 条;组织快照为在职 `22` 条、`2` 个项目、主管/经理岗位 `7` 条,但手机号映射为 `0`。该结果证明“版本已发布、ZIP 功能可用”,不等于正式试点验收完成。
- 2026-07-15 发布 schema gate 回归:`RELEASE_VERIFY_REMOTE_SCHEMA=true` 的只读预检在保留两份 Figma 文档脏工作区的临时索引下正常运行,根站、租户和员工首页均为 `200`,随后准确拦截线上缺失的 8 张表:`aihr_candidate_employee_link`、`aihr_onboard_task`、`aihr_position_responsibility`、`aihr_practice_rubric`、`aihr_practice_rubric_dimension`、`aihr_practice_scenario`、`aihr_qualification_gate`、`aihr_sop_applicability`;未执行迁移或发布。
@@ -276,7 +294,7 @@
- 2026-07-14 测试租户 HTTP 回归:在本地临时建立 `codex-a`/`codex-b` 两个租户,用同一手机号分别登录并授予各自 `superadmin` 测试角色;两租户分别调用异步上传和目录导入接口。A 查询不到 B 的上传批次/导入任务,B 也查询不到 A;两个目录导入任务均完成 `1/1`。后台 worker 的队列加工、目录导入、任务进度和查询均保持租户隔离。测试产生的租户、用户、角色、知识库行和临时文件已清理为 0。该证据只覆盖本地测试环境,不替代正式组织同步和生产多租户验收。
- 2026-07-14 上传队列上下文收口:`AihrUploadQueueService` 的同步请求租户读取改为 `TenantHelper.getTenantId()`,动态租户上下文优先于登录态,避免重试/嵌套任务回退到错误租户;`AihrUploadQueueServiceTest` 已补对应源码契约断言。AIHR 定向测试与模块编译通过。
- 2026-07-14 发布前检查补齐:新增只读 `scripts/release-preflight.sh`,统一核验当前 commit、管理端/H5/后端产物存在性、入口 JS 和 SHA-256;传入 `RELEASE_REMOTE_URL` 时只做公开根站点与租户列表 HTTP 检查,不执行 SSH、rsync、服务重启或生产写入。`docs/DEV_SETUP.md` 已同步发布证据与回滚留痕要求。
- 2026-07-14 当前状态复核:本地 `ry-vue` 组织快照有 `3001` 条 active 记录,但手机号可映射仅 `1` 条、项目 `41` 个,不能作为正式 1–2 项目试点身份数据;线上根站、`/h5/` 和租户接口均返回 `200`,但线上管理端仍加载 `index-CJZ3Ax3Z.js`,本地现有构建产物为 `index-Cz1rtpOj.js`,且发布预检被两份已有未提交 Figma 文档阻断,因此未把最新本地提交宣称为已发布。
- 2026-07-14 当前状态复核:本地 `ry-vue` 组织快照有 `3001` 条 active 记录,但手机号可映射仅 `1` 条、项目 `41` 个,不能作为正式 1–2 项目试点身份数据;线上根站、`/h5/` 和租户接口均返回 `200`,但线上管理端仍加载 `index-CJZ3Ax3Z.js`,本地现有构建产物为 `index-Cz1rtpOj.js`,且发布预检被两份已有未提交 Figma 文档阻断,因此未把最新本地提交宣称为已发布。该组织身份结论已由 2026-07-15 线上组织同步闭环条目替代。
- 2026-07-14 BRD 公开导航回归:`GET /api/knowledge/position-sop` 明确是一期生活顾问学习导航摘要,不返回个人或项目私有数据;控制器补 `@SaIgnore` 后匿名请求返回 `200`,而同一控制器的 `POST /api/knowledge/search` 仍返回业务 `401`,保持“公开只读导航、登录后查询与反馈”的边界。同步完成跨租户异步上传成功路径回归:codex-a/codex-b 各上传独立文件并加工为 `status=2`,互查批次均为空;临时租户、用户、队列、知识库、OSS 与暂存文件已清理。
- 2026-07-14 BRD G3 仪表盘权限收口:`/api/aihr/dashboard/overview` 返回组织、训练、知识库、案例和候选资料统计,控制器新增显式 `@SaCheckLogin`;匿名请求业务返回 `401`,同时保留服务层按当前租户过滤。后续正式主管可见范围仍需组织快照和项目权限数据支撑。
- 2026-07-14 BRD G3 主管接口权限复核:移动端主管/团队/预警/派题/复盘接口对后台系统用户现在要求 `superadmin` 或 `hr_operator` 角色;APP 用户仍要求组织快照中的主管/项目经理身份。新增源码契约测试与 `demo-check` marker,避免普通后台账号越权读取团队训练数据或创建派题。
@@ -435,14 +453,14 @@
- 2026-07-14 BRD 门禁夹具同步:严格预检已将 SOP 正式样本限定为带 `requester_ext_party_id` 且能命中在职组织身份的提问记录;原 `demo-check-pilot-gates` 临时表仍是旧 6 列,导致 SOP 指标为空并无法真实覆盖新口径。现补齐主体与 `prompt_version` 字段,使用安全员工主体 `E` 验证 `sop_usable=1/1`、待评审数和窗口过滤,未改变业务数据。
- 2026-07-14 BRD 生产迁移回归固化:新增 `scripts/tests/aihr-schema-migrations.test.sh`,在临时 MySQL 库验证 SOP 主体/版本字段和组织入职日期迁移面对旧表、缺前置表时可安全执行且重复执行幂等;不写入开发库业务数据。
- 2026-07-14 BRD 生产迁移回归扩展:同一临时 MySQL 回归测试同时连续执行 `aihr_20260714_practice_evidence_mysql8.sql`,确认 `aihr_practice_audio` 与 `aihr_practice_calibration` 两张证据表可重复创建;不写入开发库业务数据。
- 2026-07-14 BRD 当前开发库审查快照:生活顾问启用场景 `12`、校准记录 `20`、已评审 SOP `2`,但住宅 SOP 文档仅 `3/5`、已入库案例 `2/20`,在职组织快照 `3001` 条中手机号可映射仅 `1` 条;这些数据不能作为正式试点通过,下一步优先补内容负责人确认的核心流程素材和正式组织身份映射,不用烟测记录替代。
- 2026-07-14 BRD 当前开发库审查快照:生活顾问启用场景 `12`、校准记录 `20`、已评审 SOP `2`,但住宅 SOP 文档仅 `3/5`、已入库案例 `2/20`,在职组织快照 `3001` 条中手机号可映射仅 `1` 条;这些数据不能作为正式试点通过,下一步优先补内容负责人确认的核心流程素材和正式组织身份映射,不用烟测记录替代。该组织身份映射结论已由 2026-07-15 线上组织同步闭环条目替代,内容/案例/正式试点样本风险仍需继续跟进。
- 2026-07-14 BRD 5.4 训练隐私边界补强:组织快照存在且默认关闭显示字段时,员工历史、主管复盘详情、任务列表和正式试点 CSV 明细不再直接返回历史 `trainee_name`,统一回退为“员工”;新产生的训练、每日题和错题再练记录也不再默认写入姓名,只有显式开启 `aihr.org-sync.store-display-fields` 才展示/保留名称。新增服务回归断言与 `demo-check` marker,保留稳定 `formal_ext_party_id`、项目和训练证据字段;该修复不替代历史显示字段清理、保留期和法务确认。
- 2026-07-14 BRD G3 组织快照缺失 fail-closed:主管团队接口此前在 `aihr_org_snapshot` 不存在时回退读取训练/派发表,生产迁移遗漏可能把历史姓名和非正式范围暴露给后台主管视图;现仅 `dev/local` profile 允许演示回退,其他 profile 在组织快照不可用时返回空团队并停止继续查询活动数据。新增“非 Demo 无快照直接为空”回归测试与 `demo-check` marker,不改变本地演示路径。
- 2026-07-14 BRD 5.4 隐私开关一致性修复:部分兼容查询此前只有在检测到组织快照表时才隐藏姓名,组织表暂缺时可能绕过 `store-display-fields=false`;现员工历史、任务/主管记录、复盘详情及无快照演示成员读取均统一由显示开关控制,默认关闭即返回“员工”。dev 配置仍显式开启用于演示,生产默认关闭;AIHR 全量真测试通过,未修改业务数据。
- 2026-07-14 BRD 严格门禁绕过修复:`AIHR_DEMO_CHECK_LIBRARY_ONLY=true` 仅允许测试加载脚本函数,和 `AIHR_PILOT_STRICT=true` 同时使用时现在直接失败,避免调试开关把正式试点检查静默跳过;新增回归断言,未修改业务数据。
- 2026-07-14 线上浏览器身份复核:使用数据库已有手机号 `13900001111` 和当前 dev 验证码规则登录 `https://peilian.njzhmj.top/h5/` 成功,但随后进入“确认岗位”页并提示“未从组织数据匹配到岗位”,说明线上手机号登录链路可用而正式组织岗位映射仍未闭合;本轮未点击岗位确认,不写入线上岗位数据。
- 2026-07-14 BRD 本轮线上只读复核:生产根站、`/h5/`、`/prod-api/auth/tenant/list` 和 `/prod-api/api/aihr/mobile/home/user` 均返回 `200`;线上仍加载管理端 `assets/index-CJZ3Ax3Z.js` 与 H5 `assets/index-D4-NrEpb.js`。当前本地 `HEAD=8d5cb3d6` 的隐私/组织快照修复尚未重新构建或发布,本轮未执行生产静态同步、后端重启或业务数据写入;线上手机号登录仍会进入“确认岗位”但无法匹配正式组织岗位,P0 组织同步缺口保持未完成。
- 2026-07-14 BRD 5.4 组织快照响应字段复核:`OrgPersonRow` 不包含 `person_phone`,手机号只用于服务端身份映射、过滤和统计;`/api/aihr/org/snapshot` 仍要求 `superadmin/hr_operator`,`store-display-fields=false` 时姓名和部门返回空值。当前未发现新的手机号响应泄露,因此不新增重复脱敏代码;正式组织同步、手机号覆盖率和历史字段治理仍保持 P0 未完成。
- 2026-07-14 BRD 本轮线上只读复核:生产根站、`/h5/`、`/prod-api/auth/tenant/list` 和 `/prod-api/api/aihr/mobile/home/user` 均返回 `200`;线上仍加载管理端 `assets/index-CJZ3Ax3Z.js` 与 H5 `assets/index-D4-NrEpb.js`。当前本地 `HEAD=8d5cb3d6` 的隐私/组织快照修复尚未重新构建或发布,本轮未执行生产静态同步、后端重启或业务数据写入;线上手机号登录仍会进入“确认岗位”但无法匹配正式组织岗位。该 P0 组织同步缺口已由 2026-07-15 线上组织同步闭环条目替代,本条只保留当时线上资源状态。
- 2026-07-14 BRD 5.4 组织快照响应字段复核:`OrgPersonRow` 不包含 `person_phone`,手机号只用于服务端身份映射、过滤和统计;`/api/aihr/org/snapshot` 仍要求 `superadmin/hr_operator`,`store-display-fields=false` 时姓名和部门返回空值。当前未发现新的手机号响应泄露,因此不新增重复脱敏代码;正式组织同步和手机号覆盖率已由 2026-07-15 线上同步闭环补齐,历史字段治理仍需独立跟进。
- 2026-07-14 BRD 发布预检复核:在隔离干净工作树按当前 `HEAD=8f2ace4a` 重新构建管理端、`mobile-uni` H5 和后端 jar,`release-preflight.sh` 的产物新鲜度、根站和租户业务码检查通过;本地管理端主资源 `index-CX4fynEb.js`(SHA-256 `c800022a22e82e81782da590cfec81145852014a6521f7521775720e0f1087fe`)与 H5 `index-C1WoTt0t.js`(SHA-256 `bfb07609acecde3678ed18bf48ce022f36596c6b946e076436fe242cf3e15675`)均与线上 `index-CJZ3Ax3Z.js` / `index-D4-NrEpb.js` 不一致,预检按预期停止;本轮未执行生产静态同步、后端重启或业务数据写入。
- 2026-07-14 BRD G3 OSS 元数据租户隔离修复:SOP 文档去重、处理概览和文件解析元数据此前通过 `JdbcTemplate` 仅按 `sys_oss.oss_id` 读取/更新,未显式约束 `sys_oss.tenant_id`;现统一要求 `sys_oss.tenant_id = aihr_knowledge_attach.tenant_id` 或当前租户,避免跨租户 OSS 元数据被误读/覆盖。新增 `AihrSopSeedServiceTest` 契约断言与 `demo-check` marker;未修改业务数据或生产环境。
- 2026-07-14 BRD G3 Qdrant 共享 collection 隔离修复:重建单租户向量索引此前会删除整个共享 Qdrant collection,并用全局点数与当前租户 MySQL 数量比较;现改为按当前租户 payload filter 删除和统计点数,保留其他租户向量。新增回归契约与 `demo-check` marker;未修改业务数据或生产环境。
@@ -456,4 +474,61 @@
- 2026-07-15 BRD G3 候选人面试操作角色边界修复:`/api/recruit/interview/start`、`answer`、`finish` 此前只要求登录,普通后台系统用户可绕过 HR/管理员权限创建或完成面试;现统一限制为 APP 候选人本人或 `superadmin/hr_operator`,候选人会话仍按本人手机号绑定。新增源码契约测试和 `demo-check` marker;尚未发布生产。
- 2026-07-15 BRD G3 面试未知会话状态边界修复:系统用户调用 `answer` 携带不存在或已失效的 `sessionId` 此前会返回“已暂存”而不暴露会话无效;现统一要求会话存在且属于当前租户,`finish` 保留 HR 管理端既有的兼容性创建逻辑。新增服务回归测试和 `demo-check` marker;尚未发布生产。
- 2026-07-15 BRD 发布状态只读复核:生产根站、`/h5/`、`/prod-api/auth/tenant/list` 和 `/prod-api/api/aihr/mobile/home/user` 均返回 HTTP `200`,`wygj-aihr.service` 为 `active`;生产 H5 仍加载 `index-CDn6TrX8.js`,本地最新候选人面试权限/未知会话修复提交 `217edb09` 尚未证明已发布。本轮仅执行 HTTP、服务状态和 H5 资源只读检查,未同步静态资源、重启后端、执行迁移或写入生产业务数据。
# 2026-07-15 BRD G3/G6 训练语音原始地址暴露收紧:ASR/TTS 成功响应此前可直接返回 `sys_oss.url`,训练历史、主管复盘和管理端复盘在缺少 `audioOssId` 时也会回退播放原始 `audioUrl`;现统一只回传受保护 OSS 编号,服务端持久化/响应仅保留 `data:audio/*` 内联降级,客户端也拒绝 HTTP 音频地址直接播放。TTS 仍写入 `sys_oss`,旧移动端通过内联 data URL 保持可播放;已补源码契约测试和两端回放边界,未修改生产资源或生产数据。
- 2026-07-15 BRD G3/G6 训练语音原始地址暴露收紧:ASR/TTS 成功响应此前可直接返回 `sys_oss.url`,训练历史、主管复盘和管理端复盘在缺少 `audioOssId` 时也会回退播放原始 `audioUrl`;现统一只回传受保护 OSS 编号,服务端持久化/响应仅保留 `data:audio/*` 内联降级,客户端也拒绝 HTTP 音频地址直接播放。TTS 仍写入 `sys_oss`,旧移动端通过内联 data URL 保持可播放;已补源码契约测试和两端回放边界,未修改生产资源或生产数据。
- 2026-07-15 BRD 4.6/P0 组织同步线上闭环:生产 `/opt/wygj/config/wygj.env` 已配置开放组织同步变量并备份为 `/opt/wygj/config/wygj.env.bak-orgsync-20260715141150`,`wygj-aihr.service` 重启后租户接口和员工首页 API 均返回业务成功;线上执行 `POST /prod-api/api/aihr/org/sync` dry-run 与覆盖同步成功,开放平台返回公司 17、部门 963、员工 3417,生产 `aihr_org_snapshot` 为 3417 行、手机号可映射 3392、手机号不可用 25、疑似乱码 0、在职 2943、离职 474。本轮未替换 jar 或静态资源;25 名员工手机号不可用是上游数据问题,不阻塞组织同步功能发布,但正式试点仍需真实训练、校准和 SOP 评审样本。
## 2026-07-16 多租户知识平台第一版实施结论
需求与实施依据:
- 需求方案:`docs/superpowers/specs/2026-07-16-multi-tenant-knowledge-platform-design.md`
- 实施计划:`docs/superpowers/plans/2026-07-16-multi-tenant-knowledge-platform.md`
- 运维与验收:`docs/KNOWLEDGE_PLATFORM_RUNBOOK.md`
- 第一版边界:银城、美途作为独立租户;租户内支持多个知识空间;调用应用与知识空间建立多对多授权;登录用户实际可访问空间取“应用授权空间”和“用户/角色授权空间”的交集;第一版不做跨租户共享、集团账号天然穿透、跨空间去重和图谱化编排。
### 完成度分层
| 层级 | 结论 | 证据与边界 |
|---|---|---|
| 开发完成 | 是 | 已完成知识空间、主体授权、应用、令牌、统一问答、查询审计、数据工具、文档成员关系、单空间解绑、管理端、员工端调用迁移、初始化与验收脚本;后端全量 AIHR 测试 `166/166`,管理端测试 `7/7`,移动端测试 `57/57`,相关构建与类型检查通过。 |
| 本地联调可用 | 是 | 本地银城/美途双租户真实 HTTP 验证 `18/18`;验证租户隔离、授权交集、未授权 `403`、停用/过期令牌、限流、来源引用、无证据语义、员工与团队数据工具、同一 OSS 多空间成员关系及仅解绑当前空间。数据库复核确认美途应用已停用且令牌清空、银城公共空间成员已解绑、物业空间成员和 OSS 对象仍保留、解绑审计已记录。 |
| 线上生效 | 否 | 本轮未执行生产数据库迁移、应用初始化、后端发布、静态资源同步或生产密钥写入;不能用本地通过替代线上发布证据。 |
| 正式试点验收 | 否 | 尚缺知识空间业务负责人、正式角色矩阵、各空间首批内容清单和标准问题、可信调用端清单、生产密钥托管、日志保留期、容量与告警阈值以及业务签字;因此不能宣称正式试点完成。 |
### 功能需求逐项审计
| # | 需求 | 工程结论 | 证据或剩余条件 |
|---:|---|---|---|
| 1 | 银城、美途空间和应用按租户隔离 | 通过 | 双租户 HTTP 正反例、数据库 tenant 归属和跨租户 `403` 通过。 |
| 2 | 银城三个首批空间、美途一个空间具备稳定编码、负责人、授权和验证题单 | 部分通过 | 四个稳定编码和工程授权已初始化;业务负责人、正式内容清单和每空间标准题单待提交,因此不满足正式试点。 |
| 3 | 应用与空间多对多 | 通过 | `aihr_knowledge_app_space`、管理接口、初始化脚本和合同测试通过。 |
| 4 | 内部有效范围为应用授权与主体授权交集 | 通过 | 授权服务单测和真实未授权请求验证通过,空交集在检索前拒绝。 |
| 5 | 美途名片应用只能访问美途客户咨询空间 | 通过(本地) | 测试令牌只绑定 `mt_customer_service`;访问银城空间返回 `403`,联调结束后应用已停用并清空令牌。 |
| 6 | 显式越权空间返回 `403`,省略空间只查询有效范围 | 通过 | 真实 HTTP 与服务测试均覆盖。 |
| 7 | 回答包含空间和文档引用,无依据返回 `noEvidence=true` | 通过 | 银城、美途正例及无依据用例通过。 |
| 8 | 同文件多空间独立检索,单空间解绑不影响另一空间和 OSS | 通过 | 非生产专用文件完成破坏性解绑验证;公共空间成员移除,物业空间成员和原 OSS 仍各保留 `1` 个引用,管理审计有 `2` 条 `UNBIND/DOCUMENT` 记录。 |
| 9 | 本人/团队数据工具按服务端身份和管理范围执行,外部应用禁用工具 | 通过 | 员工、主管正例及员工越权、外部应用调用反例通过。 |
| 10 | 旧 `/api/knowledge/search` 保持兼容且不再搜索租户全库 | 通过 | 旧入口已收口到统一授权查询服务,客户端合同测试和服务测试通过。 |
安全矩阵中的错误/停用/过期令牌、限流 `429`、伪造 `tenantId/userId/extPartyId`、员工团队工具越权、外部应用数据工具越权和无有效空间零召回均已由自动化或本地真实 HTTP 覆盖。Qdrant `aihr_knowledge` 当前健康,`points_count=450`;查询过滤源码与服务测试同时要求当前租户和有效 `knowledgeIds`。
### 第一批空间初始化建议
- 银城:`yc_public_policy`(公共制度与通用政策)、`yc_property_sop`(物业服务 SOP)、`yc_management_ops`(经营分析与管理制度)。前三个空间已完成工程初始化;具体负责人、受众、首批文件和标准问题仍须业务确认。
- 美途:`mt_customer_service`(客户咨询知识)。已完成独立租户与独立空间的工程初始化;不得绑定银城空间或复用银城调用应用。
- `yc_finance` 暂不作为第一批工程默认空间,待财务负责人、数据库字段白名单、聚合口径和审计要求明确后再启用,避免知识文档权限被误当成结构化数据权限。
### 安全结论
- 多个空间的主要价值是内容治理和最小授权,不是仅靠“分库”自动获得安全;所有表、检索、向量 payload、查询日志和 OSS 元数据都以租户为硬边界,空间授权作为租户内第二层边界。
- 外部应用仅保存令牌哈希,明文只在创建/轮换时返回一次;停用、过期、越权和超限均拒绝请求。
- 同一文档可在同租户多个空间形成独立成员关系,解析和向量加工复用;解绑只删除当前空间的附件/片段/向量成员,最后一个引用解除后才清理 OSS,第一版不做跨空间内容去重。
- 结构化数据工具不继承文档空间权限,按工具白名单、调用主体、当前租户和本人/团队范围重新校验;第一版不开放任意 SQL 或任意数据库直连。
### 上线前硬门槛
1. 业务确认四个首批空间的负责人、受众、内容清单、有效期和每空间至少 10 个标准问题。
2. 银城、美途分别确认应用清单、部署位置、回调来源、负责人和生产令牌托管方式;生产令牌不得写入仓库、聊天记录或日志。
3. 在测试环境执行版本化迁移、初始化、双租户验收、令牌轮换/吊销、限流与审计查询,并留存完整结果。
4. 确认查询日志保留期、问题哈希策略、Qdrant 容量、失败率与延迟告警阈值、备份恢复和回滚窗口。
5. 生产发布须单独授权,按运维手册执行备份、迁移、发布、初始化、验收和回滚演练;完成线上 HTTP/数据库/Qdrant 证据链后,才能把“线上生效”改为“是”。
+31 -3
View File
@@ -38,8 +38,13 @@ mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aih
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260714_daily_drill_score_mode_mysql8.sql
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260714_sop_requester_identity_mysql8.sql
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260715_knowledge_feedback_mysql8.sql
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260716_knowledge_space_platform_mysql8.sql
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260714_org_hire_date_mysql8.sql
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260715_position_sop_qualification_mysql8.sql
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260717_practice_assignment_batch_mysql8.sql
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260717_learning_closure_mysql8.sql
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260717_practice_five_position_catalog_mysql8.sql
mysql --default-character-set=utf8mb4 "$DB_NAME" < backend/script/sql/update/aihr_20260717_web_ai_question_reward_mysql8.sql
```
顺序原因:场景补充依赖三张场景/Rubric 基础表;五维迁移依赖场景和 Rubric;岗位/SOP/任务/资格迁移只补正式数据契约,不写业务行,也不代表岗位适用范围、任务规则或资格标准已经获得 HR 确认。住宅 SOP 和 Prompt 迁移只补内置内容,不代表内容已完成业务复核。
@@ -53,9 +58,17 @@ SELECT table_name
FROM information_schema.tables
WHERE table_schema = DATABASE()
AND table_name IN (
'aihr_practice_scenario', 'aihr_practice_rubric', 'aihr_practice_rubric_dimension',
'aihr_practice_scenario', 'aihr_practice_rubric', 'aihr_practice_rubric_dimension', 'aihr_learning_question',
'aihr_practice_audio', 'aihr_practice_audio_upload', 'aihr_practice_calibration',
'aihr_knowledge_gap', 'aihr_knowledge_answer_feedback',
'aihr_knowledge_space_grant', 'aihr_knowledge_app', 'aihr_knowledge_app_space',
'aihr_knowledge_query_log', 'aihr_knowledge_admin_audit',
'aihr_practice_question_feedback',
'aihr_onboard_exam', 'aihr_onboard_exam_target', 'aihr_onboard_exam_question',
'aihr_onboard_exam_attempt', 'aihr_onboard_exam_answer',
'aihr_web_search_provider', 'aihr_web_ai_query_audit',
'aihr_community_question', 'aihr_community_answer',
'aihr_incentive_rule', 'aihr_points_ledger',
'aihr_candidate_material', 'aihr_interview_result', 'aihr_candidate_employee_link',
'aihr_position_responsibility', 'aihr_sop_applicability',
'aihr_onboard_task', 'aihr_qualification_gate'
@@ -68,8 +81,11 @@ WHERE table_schema = DATABASE()
AND (
(table_name = 'aihr_case_record' AND column_name IN ('media_oss_id', 'media_url', 'learning_points', 'supervisor_comment'))
OR (table_name = 'aihr_practice_session' AND column_name IN ('dim_task_completion', 'dim_response_timeliness', 'response_latency_ms', 'annotations_json', 'review_advice', 'incentive_point', 'satisfaction_score', 'satisfaction_comment'))
OR (table_name = 'aihr_practice_assignment' AND column_name IN ('score', 'score_mode'))
OR (table_name = 'aihr_practice_scenario' AND column_name IN ('content_version', 'content_hash'))
OR (table_name = 'aihr_practice_assignment' AND column_name IN ('score', 'score_mode', 'due_date', 'request_key', 'content_version', 'question_snapshot', 'reference_answer_snapshot', 'content_hash'))
OR (table_name = 'aihr_sop_answer_review' AND column_name IN ('prompt_version', 'requester_ext_party_id'))
OR (table_name = 'aihr_knowledge_info' AND column_name IN ('code', 'space_type', 'sensitivity_level', 'status'))
OR (table_name = 'aihr_knowledge_upload_item' AND column_name = 'space_codes_json')
OR (table_name = 'aihr_org_snapshot' AND column_name = 'hire_date')
OR (table_name = 'aihr_candidate_material' AND column_name IN ('reviewer', 'reviewed_time'))
OR (table_name = 'aihr_interview_result' AND column_name IN ('questions_json', 'reviewed_score', 'review_status', 'reviewer', 'review_note', 'reviewed_time'))
@@ -84,9 +100,21 @@ SELECT COUNT(*) AS built_in_prompt_templates
FROM aihr_prompt_template
WHERE tenant_id = '000000'
AND code IN ('summary_card', 'sop_answer', 'mentor_rewrite', 'review_annotation', 'prep_card', 'supervision_image_analysis_maintenance');
SELECT position, COUNT(*) AS scenario_count, SUM(enabled = 0) AS disabled_pending_review
FROM aihr_practice_scenario
WHERE tenant_id = '000000'
GROUP BY position
ORDER BY position;
SELECT question_type, COUNT(*) AS question_count, SUM(enabled = 0) AS disabled_pending_review
FROM aihr_learning_question
WHERE tenant_id = '000000'
GROUP BY question_type
ORDER BY question_type;
```
预期是三张场景/Rubric 表、三张证据表、两张知识治理表、三张候选人/面试表和四张岗位/SOP/任务/资格契约表均存在,会话证据字段为 `8/8`,候选资料审核字段为 `2/2`,面试复核字段为 `6/6`,字段查询覆盖所有列,内置 Prompt 数量为 `6`。岗位/SOP/任务/资格表为空是允许的;这只证明 schema/seed 迁移完成,不证明正式岗位规则、资格 gating 或试点完成。
预期是三张场景/Rubric 表、岗位题库、训练反馈表、五张考试表、两张全网检索表、问题榜/激励六张表、三张证据表、知识平台治理表、三张候选人/面试表和四张岗位/SOP/任务/资格契约表均存在;会话证据字段为 `8/8`,专项批量/内容快照字段为 `8/8`,候选资料审核字段为 `2/2`,面试复核字段为 `6/6`,字段查询覆盖所有列,内置 Prompt 数量为 `6`。五个岗位各有 `20` 个场景,`daily/special` 各有 `100` 道题;其中 `14` 个未完成正式审核的高风险场景及其 `28` 道题保持禁用。岗位/SOP/任务/资格表为空是允许的;这只证明 schema/seed 迁移完成,不证明正式岗位规则、资格 gating 或试点完成。
## 迁移后应用回归
+2 -2
View File
@@ -20,7 +20,7 @@
| 4 | 三角色对练 `/train/practice` | 开始对练 → 填入参考回复或输入真实回复 → 继续一轮 → 结束并评分 | 已完成闭环、导师改写、新增对练记录;数据库已启用 chat 模型时,客户回复与评分为真实 LLM 生成(回复不再是固定台词,分数随话术变化),未配置时使用本地剧本兜底 |
| 5 | 案例沉淀 `/knowledge/cases` | 上传真实语音 → ASR 转写 → AI 整理 → 送审 → 入库 → 查看案例详情/回放原始音频 | 已完成语音转写、原始音频 OSS 留痕、整理、入库、学习点、主管点评和按项目权限查看持久化转写/摘要详情;预渲染视频样片仍未接入,不把音频回放当作“查看样片”完成证据 |
| 6 | SOP知识库 `/knowledge/sop` | 上传 txt/md/PDF/Word/Excel/PPT 文档或使用 seed 文档 → 检索 → 生成训练题 | 已完成闭环、引用 SOP 原文片段、训练题已生成 |
| 7 | 资料处理 `/knowledge/processing` | 打开页面 → 查看解析任务 → 查看处理链路 → 可选点“服务端导入”导入 `.data/import` 下少量样例 | 可看到资料总量、等待/解析中/完成/失败、片段数、向量化状态和事件列表 |
| 7 | 资料处理 `/knowledge/processing` | 打开页面 → 查看解析任务 → 查看处理链路 → 点“批量导入”选择少量文件或 ZIP | 可看到资料总量、等待/解析中/完成/失败、片段数、向量化状态、批次进度和事件列表;页面不出现“选择目录”“服务端导入” |
## AI陪练二期增量脚本
@@ -34,7 +34,7 @@
试点正式验收前,用 `AIHR_PILOT_TENANT_ID=000000 AIHR_PILOT_START_DATE=2026-07-07 AIHR_PILOT_END_DATE=2026-07-10 AIHR_PILOT_STRICT=true ./scripts/demo-check.sh` 检查 M5 样本闸门,租户和日期替换为本批试点的真实值。闸门只统计目标租户、该时间窗内的数据;正式试点人员必须通过唯一手机号映射到在职组织快照,达到 10 次已完成对练的人数需覆盖试点人员的 80% 以上。校准样本、AI/人工分档一致率和 SOP 可用率未达标时同样失败,不用静态演示 marker 或历史 seed 数据代替真实试点数据。
2026-07-10 本地快照(时间窗 `2026-07-07..2026-07-10`):场景 `12/12`、开发活动身份 `50` 人,但达到 10 次对练者 `0` 人;窗口内能关联正式试点会话的校准样本为 `0/20`,因此分档一致率暂不可验收;已评审 SOP `2/2` 可用,另有 `119` 条待评审。严格预检当前**失败**于正式组织人员门槛:3001 名本地在职人员只有 1 名具备唯一可用手机号,活动数据也只有 1 人能唯一匹配正式组织,且该人员达到 10 次对练的数量为 `0/1`。开发数据和非正式会话校准不能替代正式试点人员;补齐上游手机号并重新同步前,不得宣称一期业务验收完成。
2026-07-15 线上组织同步快照:开放平台返回 17 个公司、963 个部门、3417 名员工;生产 `aihr_org_snapshot` 已覆盖为 3417 行,其中 3392 人具备可用于手机号登录映射的号码,25 人手机号仍不可用,疑似乱码为 0,在职 2943 人、离职 474 人。组织同步能力和“至少 20 名正式人员可映射”的发布门槛已具备;25 人属于上游数据质量问题,不阻塞功能发布。严格试点验收仍必须用真实批次窗口产生训练、人工校准和 SOP 评审样本;旧窗口 `2026-07-07..2026-07-10` 没有人达到 10 次对练,不能作为一期业务验收完成证据。
## 录屏兜底
+20 -4
View File
@@ -50,7 +50,7 @@ portless
Qdrant 默认本地无需配置;远端或自定义 collection 可用 `AIHR_QDRANT_URL`、`AIHR_QDRANT_COLLECTION`、`AIHR_QDRANT_API_KEY` 覆盖。服务端资料导入根目录可用 `AIHR_IMPORT_ROOT` 或 `-Daihr.import.root` 覆盖。组织人员同步可用 `AIHR_ORG_SYNC_BASE_URL` 指向外部开放平台 `/api/open/v1` 前缀,并配置 `AIHR_ORG_SYNC_ACCESS_TOKEN` 或 `AIHR_ORG_SYNC_CLIENT_ID`/`AIHR_ORG_SYNC_CLIENT_SECRET`;业务请求会用 client secret 生成 HMAC-SHA256 hex 签名。移动端手机号登录的短信模板 ID、阿里云 AccessKey、Secret 和短信签名都通过环境变量注入;本地放根目录 `.env.local`,`scripts/dev-backend.sh` 会自动加载。若开放平台凭证放在 `backend/.env`,启动脚本也会加载该文件,并把 `client_id`/`client_secret` 映射为组织同步实际读取的 `AIHR_ORG_SYNC_CLIENT_ID`/`AIHR_ORG_SYNC_CLIENT_SECRET`。
组织同步写入前先运行只读预检:`node scripts/verify-demo-questions.mjs --org-dry-run`。dry-run 不检查或变更本地快照表结构,也不写数据库;输出只包含人数、手机号覆盖、脱敏数、疑似乱码数和警告,不输出员工姓名。只有 `phone_linked` 能覆盖至少 20 名正式试点人员且上游修复疑似乱码后,才切换管理端组织同步为写入模式。
组织同步写入前先运行只读预检:`node scripts/verify-demo-questions.mjs --org-dry-run`。dry-run 不检查或变更本地快照表结构,也不写数据库;输出只包含人数、手机号覆盖、脱敏数、疑似乱码数和警告,不输出员工姓名。2026-07-15 当前开放平台数据已满足写入条件:3417 名员工中 3392 人可手机号映射,疑似乱码为 0;仍有 25 人手机号不可用,确认后可用 `allowPartialReplace=true` 覆盖写入。
正式试点预检必须指定当前批次租户和时间窗,例如:`AIHR_PILOT_TENANT_ID=000000 AIHR_PILOT_START_DATE=2026-07-07 AIHR_PILOT_END_DATE=2026-07-10 AIHR_PILOT_STRICT=true ./scripts/demo-check.sh`。脚本只接受安全租户编号和 `YYYY-MM-DD` 日期,只统计目标租户窗口内完成的训练、校准和 SOP 评审;人员先按唯一手机号映射到在职组织快照,完训口径为每人至少 10 次已完成对练。
@@ -79,8 +79,11 @@ AIHR_ORG_SYNC_SIGNING_SECRET=
AIHR_AI_RUNTIME_ENABLED=true
AIHR_AI_CHAT_ENABLED=true
AIHR_AI_SPEECH_ENABLED=true
AIHR_WEB_AI_SECRET_KEY=replace-with-at-least-16-random-characters
```
`AIHR_WEB_AI_SECRET_KEY` 用于加密数据库中的全网检索访问密钥,必须配置为至少 16 位的独立随机值;缺失或长度不足时不能保存或读取提供方密钥。全网检索提供方只接受公网 HTTPS 地址,且每次修改地址或密钥后都必须重新连接测试,测试成功后才能启用。
`application-dev.yml` 只保留占位和默认值,不提交真实短信密钥。dev 环境不配阿里云短信也能登录移动端:验证码固定 `123456`。
## 启动步骤
@@ -121,12 +124,12 @@ AIHR_AI_SPEECH_ENABLED=true
- `aihr_practice_mysql8.sql` 已导入;移动端员工训练记录落 `aihr_practice_session`,用于训练历史、主管待复盘列表和能力画像聚合
- `aihr_interview_result_mysql8.sql` 已纳入 reset 脚本;AI 面试评分完成后结果落 `aihr_interview_result`
- `aihr_candidate_material_mysql8.sql` 已纳入;候选人端补充资料文件写 `sys_oss`/MinIO,关系落 `aihr_candidate_material`
- `aihr_org_snapshot_mysql8.sql` 已纳入 reset 脚本;组织人员本地 seed(2 个住宅项目 22 人,项目经理/主管/一线三层)支撑演示,外部开放组织系统配置完成后用 `POST /api/aihr/org/sync` 拉取 `company/department/employee` 快照并覆盖本地 `aihr_org_snapshot`
- `aihr_org_snapshot_mysql8.sql` 已纳入 reset 脚本;组织人员本地 seed(2 个住宅项目 22 人,项目经理/主管/一线三层)支撑演示,外部开放组织系统配置完成后用 `POST /api/aihr/org/sync` 拉取 `company/department/employee` 快照并覆盖本地 `aihr_org_snapshot`。2026-07-15 生产已完成该配置和覆盖同步,线上快照为 3417 名员工。
- 组织同步生产默认关闭 `aihr.org-sync.store-display-fields`,不把外部姓名/部门写入或返回组织人员展示快照;开发环境显式打开该开关仅用于 Demo。项目范围、岗位和外部主体 ID仍用于权限与身份映射。
- 本地组织 seed 带演示手机号,可用 `13900000103` 验证员工端自动识别物业管家岗位,用 `13900000202` 验证主管端项目范围
- SOP 知识库支持 `.txt/.md/.markdown/.pdf/.doc/.docx/.xls/.xlsx/.ppt/.pptx` 上传到 MinIO 后解析入库,接口为 `POST /api/knowledge/doc/upload`,单文件上限 100MB;管理端上传请求单独放宽到 180s,PDF 解析/归类/向量化较慢时不要改全局 axios 超时。资料处理中心异步接口另支持 `.zip`(≤500MB),后台安全解压后逐文件入队;最多 1000 个子文件、解压总量 ≤2GB,不支持嵌套 ZIP
- 视频(`.mp4/.mov/.avi/.mkv/.webm/.m4v`,≤500MB、≤60 分钟)只走资料处理中心批量导入(异步队列):ffmpeg 抽音轨分段调 asr 转写 + 抽关键帧调 vision 提取画面文字,合并后归类切片入库,片段带 `[mm:ss]` 时间戳;**依赖服务器安装 ffmpeg/ffprobe**(macOS `brew install ffmpeg`,Linux `apt install ffmpeg`)
- 服务端目录导入接口为 `POST /api/knowledge/doc/import-local-task`,只读取导入根目录下的相对目录,后台逐文件复用同一上传解析链路;`POST /api/knowledge/doc/import-tasks/{id}/cancel` 可取消运行中任务;`POST /api/knowledge/doc/import-local` 保留为同步调试接口。
- 服务端目录导入接口为 `POST /api/knowledge/doc/import-local-task`,只读取导入根目录下的相对目录,后台逐文件复用同一上传解析链路;`POST /api/knowledge/doc/import-tasks/{id}/cancel` 可取消运行中任务;`POST /api/knowledge/doc/import-local` 保留为同步调试接口。这组接口仅供运维/调试,不在资料处理页提供入口。
- 启用 `aihr_model_config.category='vector'` 的模型配置后,上传会同步写入片段 embedding,并尽力 upsert 到 Qdrant;模型配置页可查看 Qdrant 维度、点数和片段向量数,并在维度不一致时重建索引;未配置或 Qdrant 不可用时只走 MySQL Fulltext/seed fallback,不影响检索。
- 后端 `ruoyi-admin` 已完成 Maven 打包,并通过 portless 暴露为 `https://wygj-api.localhost/`
- AIHR 真跑测试必须显式关闭父 POM 的默认跳测:`mvn -f backend/pom.xml -pl ruoyi-modules/ruoyi-aihr -am -DskipTests=false test`;普通 `mvn ... test` 只适合编译/打包检查。
@@ -151,6 +154,19 @@ TOKEN=<登录后 access_token>
curl -fsS https://wygj-api.localhost/api/knowledge/doc/vector-index-status -H "Authorization: Bearer $TOKEN"
```
## 线上管理端静态发布
线上根站由 Caddy 从服务器 `/opt/wygj/www` 提供;同一目录下的 `/h5` 是移动端静态资源。只改管理端静态资源时无需重启后端,但必须先备份整个目录,并且同步根目录时不能使用 `--delete`,以免删除移动端资源。
```bash
npm --prefix frontend run build:prod
ssh YCWY 'ts=$(date +%Y%m%d%H%M%S); mkdir -p /opt/wygj/backups; cp -a /opt/wygj/www /opt/wygj/backups/www-$ts; echo /opt/wygj/backups/www-$ts'
rsync -az frontend/dist/ YCWY:/opt/wygj/www/
curl -k -s https://peilian.njzhmj.top/ | sed -n '1,20p'
```
发布后以管理员真实会话回归受影响页面;如需核对指定资源,可比较本地构建文件和远端对应文件的 SHA-256。该流程不发布后端、不迁移数据库,也不覆盖 `/opt/wygj/www/h5`。
## 线上移动端静态发布
线上 `peilian.njzhmj.top` 由 Caddy 服务,`/h5*` 映射到服务器 `/opt/wygj/www/h5`,并 fallback 到 `/h5/index.html`。只改移动端静态资源时无需重启后端。
@@ -201,7 +217,7 @@ RELEASE_REMOTE_URL=https://peilian.njzhmj.top RELEASE_VERIFY_REMOTE_MATCH=true R
- 三角色对练:进入 `/train/practice`,点击“开始对练” → 完成两轮真实或参考回复 → “结束并评分”,应看到“已完成闭环”“导师改写”和新增对练记录。
- 案例沉淀:进入 `/knowledge/cases`,上传真实语音 → “AI 整理” → “送审” → “入库”,应看到“已完成闭环”和新增案例记录;上传必须先完成 ASR 转写。
- SOP知识库:进入 `/knowledge/sop`,可上传 txt/md/PDF/Word/Excel/PPT 文档入库;点击“检索” → “生成训练题”,应看到“已完成闭环”、命中数据库 SOP 原文片段和训练题;数据库不可用时页面回退 seed。
- 资料处理:进入 `/knowledge/processing`,应看到资料总量、解析任务表、处理链路、规则与风险;可用少量文件验证“批量导入/选择目录/服务端导入”。**批量导入走异步队列**:提交即返回,页面出现“本次批量上传”进度面板(排队/加工中/完成/失败 + 单条重试),后台 worker 并发 2 逐条解析入库;暂存目录默认 `./.data/staging`(`aihr.upload.staging` 覆盖)。服务端导入读取 `./.data/import` 下的相对目录,启动后台任务并在页面显示进度,运行中任务可点“取消”;目录导入的重试粒度是同目录重新导入,批量上传的重试粒度是单文件。
- 资料处理:进入 `/knowledge/processing`,应看到资料总量、解析任务表、处理链路、规则与风险;页面只保留“批量导入”和“刷新”,不应出现“选择目录”“服务端导入”或目录导入任务面板。**批量导入走异步队列**:提交即返回,页面出现“本次批量上传”进度面板(排队/加工中/完成/失败 + 单条重试),后台 worker 并发 2 逐条解析入库;支持多文件和 ZIP,暂存目录默认 `./.data/staging`(`aihr.upload.staging` 覆盖)。
- uni-app 员工端:进入 `https://wygj-mobile-uni.localhost/h5/#/pages/user/today/index`,手机号登录(dev 验证码固定 `123456`)。今日页进入问师傅、练习、案例素材和个人页;练习页应能完成开始练习、提交回应、结束评分、每日三题提交,个人页同步训练历史和成长证据包。每日三题正式按组织快照 `hire_date` 判断入职三个月窗口;本地 Demo 若快照尚无该字段,仅由 `dev/local` profile 且 `application-dev.yml` 的 `aihr.practice.allow-legacy-daily-drill-fallback=true` 启用训练次数回退,生产 profile 即使误传环境变量也强制关闭。
- 移动端登录后若组织快照接口返回 `401/403`,只降级为手动岗位确认,不应清除手机号登录态;岗位确认页仍需允许员工选择“生活顾问”后继续进入业务页。
- uni-app 主管端:进入 `https://wygj-mobile-uni.localhost/h5/#/pages/supervisor/index/index`,应看到团队概览、团队画像、团队预警、指派专项、待复盘和复盘详情;从团队画像派专项后,最近专项应立即回读新记录。
+20 -4
View File
@@ -148,15 +148,31 @@
## 全文件设计一致性审计(2026-07-14)
### 正式画板逐页视觉验收标准(强制)
以下项目必须基于该画板当次生成并人工查看的截图逐项确认;只枚举图层、节点或组件不算视觉验收:
1. **信息架构一致**:同一页面的状态稿、字号稿和角色变体必须保持相同的已批准模块、字段语义和主顺序;状态变化不能删除功能。
2. **版面与栅格一致**:检查左右留白、卡片宽度、对齐线、模块间距、卡片内边距和同类组件尺寸,不能只看画板总宽高。
3. **文字真实可读**:检查字体、字号、行高、换行、截断和长文案;员工端可见正文不得低于 12px,大字/超大字必须逐稿截图,不允许只改变量后推断通过。
4. **滚动与固定层安全**:检查首屏、内容末尾、空状态和长内容;固定底栏、吸顶区和安全区不得遮住内容,末尾必须有可滚出的底部占位。
5. **交互状态唯一**:Tab、筛选、按钮、单选和步骤状态的图标、文字、背景与描边必须表达同一个 active/disabled/loading/error 状态。
6. **内容与组件可信**:示例数据应能区分列表行和指标含义;重复占位文案、错位头像、未命名组件和失真的组件覆盖都不能按高保真通过。
7. **可访问性风险可见检查**:检查对比度风险、最小触控区、焦点可见性设计、缩放回流和状态提示;读屏顺序、键盘操作和动态播报仍须在真实实现中验证。
8. **证据分开记录**:结构检查、截图视觉检查、功能实现、浏览器验证、发布和生产验证分别记录,任一项缺失不得用一个 `[x]` 代替。
- [x] 建立 Figma 首屏“00|设计索引与审计”(Figma `101:3`)
- [x] 79 个页面、71 张正式画板均有内容,无重复页面名和空业务页
- [x] 默认图层名清零,文字溢出清零,画板内容越界清零
- [x] 当前计数已重新发布:81 个顶层页面、78 张顶层 `Screen/` 正式画板;“我”页删除 1 张冗余冲突稿后,78 张画板均已重新导出当次截图并逐张人工检查
- [x] 默认图层名和根级越界已清零:当前 78 张画板中名为 `Frame` 的图层为 0、不可滚动的根级内容越界为 0;`21:3` 已增加 108px 底部安全占位,`79:674`、`79:706`、`115:210` 已补足画板高度并重新截图复核
- [x] 字体统一为 `LXGW WenKai TC` Regular/Bold
- [x] 管理端画板统一为 1440px 宽、最低 960px 高
- [x] 896 个精确匹配颜色补充变量绑定,整体填充变量绑定率约 50%
- [x] 品牌主红统一为 `#E60012`,员工端与管理端变量已对齐
- [x] 正式画板和设计规范中的可见文字最低 12px,字号调整后无裁切和越界
- [x] 当前 78 张画板可见文字最低字号复扫无小于 12px 的文本;`178:960`、`178:2` 的 6 处 11px 指标文字及排行榜头像缩放产生的小字号均已修正
- [x] `页面|我`(Figma `4:16`)已修为标准/大字/超大字三张同构画板:节点 `7:2`、`253:131`、`253:188` 使用相同模块、字段和顺序,统一 20px 左右留白、360px 卡片和唯一“我”选中态;三稿均启用纵向滚动、固定底栏并保留 108px 内容末尾安全占位,截图复核未见首屏重叠或文字越界
- [x] 长文案与数据组件已做截图驱动修复:个人 AI 助理、晋升、开放问题榜、积分荣誉等页面的横向裁切已改为真实换行;排行榜头像不再压住姓名,6 行姓名已改为可区分示例;荣誉徽章不再重复“徽章名称”占位文案;AI 教练周节奏行高由 100px 收紧为 56px,去除异常大段留白
- [x] 管理端 `90:2`、`91:2`、`93:940`、`95:858` 的指标、状态和表格元数据已消除字符级换行,并重新生成截图检查
- [x] 员工端「页面|今日」已完成首页高保真复核:按「参考稿|今日」收口为紧凑纵向结构,保留品牌头部、师傅 Hero、问答卡、今日安排、我的地图和底部 Tab
- [x] 问答卡横向内容垂直居中,左右图片容器统一为 `64×64`,右侧聊天气泡保持居中且文案不溢出
- [x] 师傅 Hero 的提示气泡复用组件库 `Communication/Chat Bubble`;品牌标记复用现有品牌资源,不为页面重复绘制图标
- [ ] 代码实现阶段验证真实对比度、键盘焦点、状态播报和读屏顺序
- [ ] 代码实现阶段仍须对照同尺寸 Figma 截图验证真实对比度、键盘焦点、状态播报、读屏顺序、滚动末尾、键盘弹起和长数据回流;Figma 截图通过不等于实现或生产通过
+25 -26
View File
@@ -1,13 +1,12 @@
# Figma 页面实现矩阵
更新时间:2026-07-13
更新时间:2026-07-17
## 统计口径
- Figma 当前索引:78 个页面、70 张正式画板。
- `docs/FIGMA_DESIGN_INVENTORY.md` 的历史清单记录为 79 个页面、71 张正式画板,属于设计索引更新前的数字。
- Figma 文件 API 当前实际暴露 1 个顶层页面 `101:2`(设计索引与审计);“78 个页面”是索引中的审计统计值,不是 78 个可单独定位的 Figma 顶层页面。
- 因此不能凭空补出 8 个页面名称或 node id;本表按可定位、可验收的 70 张正式业务画板建立。
- Figma 索引 `101:3` 仍声明 78 个页面、70 张正式画板;该数字已经落后于当前文件。
- 2026-07-17 通过 Figma 插件逐页切换并重新导出当次截图,实际确认 **81 个顶层页面、78 张顶层 `Screen/` 正式画板**;“我”页修复时已删除 1 张冗余冲突稿。78 张截图均已人工检查,不再沿用此前 63 页/59 张的限流中间结果。
- 索引没有说明如何从 78 张 `Screen/` 画板排除为 70 张“正式画板”,因此本表继续保留产品页面映射,但不把 70 当作可复算的当前总数;完整设计质量结论见 `FIGMA需求覆盖与版本偏差审计-20260717.md`。
- `[x]` 只表示 Figma 画板已完成,不表示代码或线上已完成。
- `已实现`:仓库存在对应页面,并有真实业务接口或明确的降级链。
- `部分实现`:有入口或局部状态,但没有完成 Figma 对应的完整业务闭环。
@@ -20,7 +19,7 @@
这两份文档不是同一张验收表:
- 本矩阵回答“Figma 设计的页面在代码/线上完成到什么程度”,覆盖 MVP、二期、阶段二/三和已取消设计。
- 二期计划回答“生活顾问 AI 陪练阶段一的工程闭环和 M5 试点条件是否满足”,不要求实现全部 70 张 Figma 正式画板。
- 二期计划回答“生活顾问 AI 陪练阶段一的工程闭环和 M5 试点条件是否满足”,不要求实现索引原口径下的全部 70 张 Figma 正式画板。
- 因此,矩阵中的“未实现”不等于二期延期;个人 AI 助理、开放问题榜、积分/荣誉、完整偏好体系等属于计划明确暂缓的阶段二/三范围。
- 矩阵中的“已实现”也不等于 M5 业务验收通过;评分校准、SOP 评审、正式组织身份和真实试点数据仍以严格预检为准。
@@ -40,20 +39,20 @@
| 优先级 | 项目 | 需要什么才能继续 |
|---|---|---|
| P0 | 线上包与角色路由 | 生产服务、根站、H5 和公开业务接口正常,但线上仍加载上一发布批次资源;当前 `HEAD=0bfaee7d` 的管理端/H5/后端 hash 尚未与线上对齐,本轮未执行发布。认证态员工/主管/管理端回归仍需正式 OTP 或测试账号,主管正式角色仍需正式组织数据验证。 |
| P0 | 线上包与角色路由 | 生产服务、根站、H5 和公开业务接口正常;2026-07-15 已单独发布管理端资料处理分页并以真实管理员会话回归。该静态发布不代表当前分支 H5 或后端已对齐线上;认证态员工/主管回归仍需正式 OTP 或测试账号,主管正式角色仍需正式组织数据验证。 |
| P1 | 案例学习/视频详情 | 原始音频 `mediaUrl/mediaOssId` 已形成真实留痕和回放;学习点已从真实摘要提取并持久化,主管点评已有受保护接口和两端展示;仍需业务提供一期预渲染视频样片,并确定相关训练场景字段后再完成视频详情页面。 |
| P1 | 正式组织数据 | 用正式员工、项目和试点时间窗口验证团队量化、成长证据和 M5 导出;不使用本地 smoke 样本替代。 |
| P2 | 三期页面 | 个人 AI 助理、开放问题榜、积分/荣誉、完整七维偏好、独立 AI 教练编排按阶段二/三单独立项。 |
## 70 张正式业务画板矩阵
## 业务画板实现矩阵(原索引 70 张口径)
| # | 页面/状态 | Figma 位置 | 代码路径 | 当前实现 | 是否修正 |
|---:|---|---|---|---|---|
| 1 | 员工端:今日 | — | `mobile-uni/src/pages/user/today/index.vue` | [x] 已实现 | 本地源码已对齐;历史线上包已用员工账号完成浏览器回归,当前分支最新修复尚未重新发布 |
| 2 | 员工端:练入口 | — | `mobile-uni/src/pages/user/practice/index.vue` | [x] 已实现 | 已验证场景首屏、最近练过、每日三题和独立练习入口;蓝白视觉已复核 |
| 3 | 员工端:问 | — | `mobile-uni/src/pages/user/sop/index.vue` | [x] 已实现 | 已验证搜索、引用、反馈状态和总结卡 |
| 4 | 员工端:我 | — | `mobile-uni/src/pages/user/profile/index.vue` | [x] 已实现 | 已验证登录、岗位、成长摘要、训练历史和详情入口 |
| 1 | 员工端:今日 | `23:3` | `mobile-uni/src/pages/user/today/index.vue` | [x] 已实现 | 本地源码已对齐;历史线上包已用员工账号完成浏览器回归,当前分支最新修复尚未重新发布 |
| 2 | 员工端:练入口 | `22:3` | `mobile-uni/src/pages/user/practice/index.vue` | [x] 已实现 | 已验证场景首屏、最近练过、每日三题和独立练习入口;蓝白视觉已复核 |
| 3 | 员工端:问 | `21:3` | `mobile-uni/src/pages/user/sop/index.vue` | [x] 本地已实现并浏览器验证;Figma 已修 | 已实际验证文字查询、引用、反馈、语音输入/选音频入口、回答和总结卡播报、无模型原文总结卡、PNG 下载成功提示;Figma 已增加 108px 末尾安全占位,真实手机键盘、麦克风与文件权限仍待发布前复验 |
| 4 | 员工端:我 | `4:16`(标准 `7:2` / 大字 `253:131` / 超大字 `253:188`) | `mobile-uni/src/pages/user/profile/index.vue` | [x] 本地已实现并逐档视觉验证;Figma 视觉已修 | 三档 Figma 与代码均保持同一功能结构;全局标准/大字/超大字已持久化,400×900 的三档个人页及关键页超大字截图已复核,无横向溢出、底栏遮挡或卡片重叠;真实设备触控和读屏仍待验收 |
| 5 | 训练前预习卡 | `53:2` | `mobile-uni/src/pages/user/practice/index.vue` | [x] 已实现 | 已验证预习卡、开始练习与真实对话状态;视觉已复核 |
| 6 | 正式语音对练 | `54:2` | `mobile-uni/src/pages/user/practice/index.vue` | [x] 已实现 | 已验证文字提交、情绪/信任、求助和录音入口;失败保留文本降级 |
| 7 | 训练完成结果 | `55:2` | `mobile-uni/src/pages/user/practice/index.vue` | [x] 已实现 | 已验证两轮真实提交、评分结果和主管待复盘更新;视觉已复核 |
@@ -62,7 +61,7 @@
| 10 | 主管待复盘列表 | `58:2` | `mobile-uni/src/pages/supervisor/reviews/index.vue` | [x] 已实现 | 已验证真实待复盘列表、低分优先和详情跳转 |
| 11 | 主管复盘详情 | `59:2` | `mobile-uni/src/pages/supervisor/review/index.vue` | [x] 已实现 | 已验证评分明细、对话、标注、建议、贡献分和标记已复盘 |
| 12 | 员工能力详情 | `61:2` | `mobile-uni/src/pages/supervisor/team/index.vue` | [x] 已实现 | 已验证点击成员展示最新评分、训练次数、待复盘数量、真实训练趋势和成长证据;400px 主管画布、蓝白卡片、层级和间距已复核;未虚构 Figma 未提供的数据 |
| 13 | 训练任务派发 | `61:530` | `mobile-uni/src/pages/supervisor/assign/index.vue` | [x] 已实现 | 已验证按项目范围选择员工、场景、原因并真实创建专项任务 |
| 13 | 训练任务派发 | `61:530` | `mobile-uni/src/pages/supervisor/assign/index.vue` | [x] 本地已实现并真实提交验证 | 已按项目团队姓名多选、最多 100 人、当天/明天/3天/7天、逐人结果和幂等批量接口对齐;浏览器向 2 名成员提交返回 2/2 成功,仍未发布生产 |
| 14 | 派发进度与预警 | `62:2` | `mobile-uni/src/pages/supervisor/assign/index.vue` | [x] 已实现 | 已验证真实派发进度计数(待训练/已完成/低分再练)和低分训练预警;400px 主管画布、表单/列表/进度卡层级已复核;截止时间与下滑趋势暂无后端字段,未伪造 |
| 15 | 候选人面试首页 | `67:2` | `mobile-uni/src/pages/candidate/index/index.vue` | [x] 已实现 | 已修正 |
| 16 | 候选人面试答题 | `68:2` | `mobile-uni/src/pages/candidate/interview/index.vue` | [x] 已实现 | 已修正 |
@@ -77,11 +76,11 @@
| 25 | 提示词模板管理 | `73:2` | `frontend/src/views/system/prompts.vue` | [x] 已实现 | 已按 Figma 独立工作台实现模板列表、名称/代码/输出文体/系统提示词/模板/变量编辑、保存草稿、保存并启用;真实浏览器已验证编辑保存、新增启用、刷新持久化,临时样本已清理 |
| 26 | 人工评分校准/指标导出 | `74:2` | `frontend/src/views/train/reviews.vue`、`frontend/src/views/train/practice.vue` | [x] 已实现 | 已按 Figma 补齐日期窗口、岗位/组织范围、校准样本指标卡和独立 CSV 导出;真实浏览器已验证页面加载、导出下载和复盘校准表单,正式试点数据仍需真实样本 |
| 27 | SOP 回答结果 | `79:11` | `mobile-uni/src/pages/user/sop/index.vue` | [x] 已实现 | 已按 Figma 补齐「师傅回答/我的问题/答案卡/引用依据/反馈」层级,保留真实检索、引用和反馈接口;浏览器已验证登录、真实答案展示和“有用”反馈状态 |
| 28 | SOP 好评/差评反馈 | `79:674` | `mobile-uni/src/pages/user/sop/index.vue` | [x] 已实现 | 已按 Figma 语义对齐为「有帮助/没解决」双按钮,保留真实反馈接口、提交后状态提示与按钮锁定;浏览器已验证真实搜索、点击反馈、结果提示和两个按钮 disabled。Figma 中的「收藏」当前无后端持久化接口,未添加假按钮 |
| 28 | SOP 好评/差评反馈 | `79:674` | `mobile-uni/src/pages/user/sop/index.vue` | [x] 已实现;Figma 已修 | 已按 Figma 语义对齐为「有帮助/没解决」双按钮,保留真实反馈接口、提交后状态提示与按钮锁定;浏览器已验证真实搜索、点击反馈、结果提示和两个按钮 disabled。Figma 已补足画板高度并重新截图复核;其中「收藏」当前仍无后端持久化接口,未添加假按钮 |
| 29 | SOP 后台待复核 | `80:655` | `frontend/src/views/knowledge/sop.vue` | [x] 已实现 | 已补真实答案反馈待复核队列、待复核/已复核筛选、状态展示与「标记已复核」动作;浏览器已验证刷新加载临时待复核样本、点击复核后从待办移除并清理测试数据 |
| 30 | SOP 知识库管理 | `81:2` | `frontend/src/views/knowledge/sop.vue` | [x] 已实现 | 已修正 |
| 31 | 异步资料处理队列 | `81:750` | `frontend/src/views/knowledge/processing.vue` | [x] 已实现 | 已修正;ZIP 支持已随当前批次发布,仍需真实资料和权限账号回归 |
| 32 | 案例语音上传 | `79:706` | `mobile-uni/src/pages/user/cases/index.vue`、`frontend/src/views/knowledge/cases.vue` | [x] 已实现 | 已修正 |
| 31 | 异步资料处理队列 | `81:750` | `frontend/src/views/knowledge/processing.vue` | [x] 已实现 | ZIP 异步入队已在生产复核;解析任务列表已于 2026-07-15 发布前端分页(10/20/50 条),真实管理员会话已验证翻页与筛选复位。 |
| 32 | 案例语音上传 | `79:706` | `mobile-uni/src/pages/user/cases/index.vue`、`frontend/src/views/knowledge/cases.vue` | [x] 已实现;Figma 已修 | 功能已实现;Figma 已补足上传表单所需高度并重新截图复核,真实实现仍需验证录音、文件选择和长文件名状态 |
| 33 | 案例 AI 整理结果 | `79:734` | `frontend/src/views/knowledge/cases.vue` | [x] 已实现 | 已修正 |
| 34 | 案例审核/筛选/发布 | `82:2` | `frontend/src/views/knowledge/cases.vue` | [x] 已实现 | 已修正 |
| 35 | 案例学习/视频详情 | `80:2` | `mobile-uni/src/pages/user/learning/index.vue`、`cases/index.vue` | 部分实现 | 已补 `caseId`、按项目权限校验的案例详情 API、原始音频 OSS 留痕/回放、员工端转写/摘要详情、学习点和主管点评查看;仍缺预渲染视频样片与相关训练场景契约,暂不把音频回放标成完整视频详情 |
@@ -98,10 +97,10 @@
| 46 | 员工工作量化看板 | `89:9` | `frontend/src/views/competency/growth.vue` | 按二期计划已实现;按 Figma 部分对齐 | 已有训练时长、贡献度、测评分、等级、证据包、预警和派发;完整三期量化指标暂不补 |
| 47 | 主管团队量化看板 | `89:776` | `mobile-uni/src/pages/supervisor/team/index.vue` | 按二期计划已实现;按 Figma 部分对齐 | 已有团队成员、风险、训练记录、成长证据和按项目范围聚合的团队错题本;完整团队经营指标仍需正式组织数据 |
| 48 | HR/运营绩效看板 | `90:2` | — | 未实现 | 未修正,三期 |
| 49 | 工作积分排行榜 | `90:91` | — | 未实现 | 未修正,三期 |
| 49 | 工作积分排行榜 | `90:91` | — | 未实现;Figma 已修 | 三期;排行榜行组件已按真实尺寸缩放头像,6 行改为可区分姓名并重新截图复核;代码仍未实现,不进入当前阶段主线 |
| 50 | 等级/晋升条件/进度 | `90:867` | `frontend/src/views/competency/growth.vue` | 按二期计划已实现;按 Figma 部分对齐 | 已有初/中/高级成长路径和评级证据包;正式晋升申请/审核属于后续范围 |
| 51 | 破格晋升申请/审核 | `91:2` | — | 未实现 | 未修正,三期 |
| 52 | 荣誉墙/成长档案导出 | `91:765` | — | 未实现 | 未修正,三期 |
| 52 | 荣誉墙/成长档案导出 | `91:765` | — | 未实现;Figma 已修 | 徽章示例已去除重复占位文案,等级文案字符级换行已修;仍属三期,代码未实现 |
| 53 | 七维回复风格调节 | `93:6` | `mobile-uni/src/pages/user/practice/index.vue` | 按二期计划已实现首期形态;按 Figma 部分对齐 | 已有训练内“再严肃/更温柔/更细致/更专业”重生成;偏好持久化和七维设置属于后续范围 |
| 54 | 优化前后结果对比 | `93:824` | — | 未实现 | 未修正,三期 |
| 55 | 个人 AI 偏好设置 | `93:857` | — | 未实现 | 未修正,三期 |
@@ -112,14 +111,14 @@
| 60 | 问题审核/激励规则 | `95:858` | — | 未实现 | 未修正,阶段二 |
| 61 | AI 教练训练计划 | `97:5` | `mobile-uni/src/pages/supervisor/assign/index.vue` | 按二期计划已实现;按 Figma 部分对齐 | 已用主管派发、低分再练、每日三题和成长证据承载;独立 AI 教练编排属于后续范围 |
| 62 | 自动场景任务/自动复盘 | `97:778` | `mobile-uni/src/pages/user/practice/index.vue`、`supervisor/review/index.vue` | 按二期计划已实现基础闭环;按 Figma 部分对齐 | 已有训练、评分、标注、复盘和再练;自动编排/自动复盘报告不属于当前二期必做 |
| 63 | 积分/徽章/荣誉中心 | `97:823` | — | 未实现 | 未修正,三期 |
| 64 | 企业发布申请 | — | — | 未实现 | 未修正,阶段二 |
| 65 | 个人 AI 助理发布记录 | — | — | 未实现 | 未修正,阶段二 |
| 66 | 个人 AI 助理报告大纲 | — | — | 未实现 | 未修正,阶段二 |
| 67 | 个人 AI 助理 PPT 生成 | — | — | 未实现 | 未修正,阶段二 |
| 68 | 企业知识发布审核列表 | — | — | 未实现 | 未修正,阶段二 |
| 69 | 企业知识发布审核详情 | — | — | 未实现 | 未修正,阶段二 |
| 70 | 个人 AI 助理运营/紧急审计 | — | — | 未实现 | 未修正,阶段二 |
| 63 | 积分/徽章/荣誉中心 | `97:823` | — | 未实现;Figma 已修 | 徽章示例、积分标签和规则入口的字符级换行已修并重新截图复核;仍属三期,代码未实现 |
| 64 | 企业发布申请 | `42:2` | — | 未实现 | 未修正,阶段二 |
| 65 | 个人 AI 助理发布记录 | `44:2` | — | 未实现 | 未修正,阶段二 |
| 66 | 个人 AI 助理报告大纲 | `44:229` | — | 未实现 | 未修正,阶段二 |
| 67 | 个人 AI 助理 PPT 生成 | `45:2` | — | 未实现 | 未修正,阶段二 |
| 68 | 企业知识发布审核列表 | `46:2` | — | 未实现 | 未修正,阶段二 |
| 69 | 企业知识发布审核详情 | `47:2` | — | 未实现 | 未修正,阶段二 |
| 70 | 个人 AI 助理运营/紧急审计 | `48:2` | — | 未实现 | 未修正,阶段二 |
## 已取消而不应补做
@@ -0,0 +1,259 @@
# Figma 需求覆盖与版本偏差审计
> 日期:2026-07-17
> Figma 文件:[银城员工端与个人 AI 助理设计](https://www.figma.com/design/30hFiKtieGYraOZvJPJcPd)
> 对照范围:历史可运行移动端 `mobile/`、已确认业务文档、Figma 实际画板、当前权威工程 `mobile-uni/`。
> 验证边界:本轮通过 Figma 插件只读检查实际节点,没有修改设计稿;代码结论来自当前工作树,不代表已经发布到线上。
## 1. 审计结论
客户对问题原因的判断**基本成立,但根因不只是“Figma 少画了功能”**。真正的问题是此前没有规定功能事实源、视觉事实源和实现事实源的优先级,导致“对标 Figma”被错误理解成“Figma 画了什么就只做什么”。
Figma 当前存在五类风险:
1. **需求遗漏导致版本回退**:历史可运行版已有的问师傅语音输入、回答播报、总结卡播报,没有在对应 Figma 闭环中完整表达。若只照画板开发,旧能力会自然消失。
2. **视觉完成被误当成功能完成**:Figma 索引写着“设计冻结完成”,但该冻结只覆盖页面、图层、字体、越界和颜色一致性,不代表历史需求全部进入画板,也不代表接口和业务闭环完成。
3. **阶段混放导致范围误判**:阶段一陪练、阶段二个人 AI 助理/开放问题榜、三期量化和游戏化共存于同一文件和同一索引,缺少醒目的阶段、批准状态和本期状态标记。Codex 既可能漏做旧功能,也可能把后续页面提前拉入当前主线。
4. **同页变体已经发生结构漂移**:同一个页面的“可编辑/标准/大字/超大字”并非相同内容的字号变化,而是模块、数据、顺序和导航状态不同,无法判断哪张才是开发基线。
5. **设计审计结论自身已经失真**:索引页数和画板数无法复算,默认图层名、小字号、越界与遮挡并未清零,连“页面对照审计”画板本身也发生裁切,因此“设计冻结完成”不能继续作为研发放行结论。
所以,今后不能再把 Figma 单独作为功能需求真值。正确口径是:**业务文档决定做什么,Figma 决定怎么呈现,代码和运行证据决定实际做到了什么。**
## 2. Figma 实际证据
本轮直接读取了以下正式节点:
| Figma 节点 | 实际内容 | 审计判断 |
|---|---|---|
| `4:16` 页面|我 | 包含 `7:2` 可编辑版和标准/大字/超大字三张字号版;可编辑版与字号版信息架构不同,超大字版与底栏重叠 | 字号需求已经进入 Figma,但四张画板不能视为同一页面的有效变体;详见第 9 节 |
| `101:3` 设计索引与一致性审计 | 标注“78 原页面、70 正式画板、0 空业务页、设计冻结完成”;冻结说明集中在页面、图层、字体、溢出和颜色 | 这是**视觉与文件卫生审计**,不是需求覆盖审计;没有需求 ID、来源版本、阶段和实现状态 |
| `23:3` 员工端今日 | 明确同时展示“问老师傅·语音提问,快速解答”和“打字问”;还展示学习中心、工作上报 | Figma 明确承诺了语音入口;同时把阶段二/三入口放进阶段一首页,容易造成范围混淆 |
| `54:2` 正式语音对练 | 有“按住说话”和切换文字输入,包含情绪/信任、SOP 求助、红线和风格重生成 | 训练语音设计较完整,但不能代替问师傅、题目、点评等其他页面的语音覆盖 |
| `61:530` 主管训练任务派发 | 明确显示 3 名员工、多选删除、训练类型、专项包、截止时间、任务目标和“确认派发给 3 人” | 多人派发和截止时间已经是明确 Figma 要求;当前实现只有单人、场景和原因 |
| `79:11` SOP 回答结果 | 有问题、结论、三步操作、可用话术、引用、视频、有帮助/没解决/收藏 | 对应画板没有回答播报、总结卡播报和下载图片控件;只照此画板会遗漏历史语音优势和新增下载要求 |
| `95:6` 开放问题榜 | 有“今天遇到什么难题了”“有奖征问题”、热门/待回答/有悬赏/我参与的和奖励规则 | 设计本身完整,但业务总纲明确属于阶段二;不能因为 Figma 已画就算当前阶段缺陷 |
还有两处文件内部口径冲突:
- `FIGMA_DESIGN_INVENTORY.md` 顶部仍把员工端“问”和“我”标记为 `[-]`,说明业务状态不完整;同一文件后部却写“设计冻结完成”。
- `FIGMA_IMPLEMENTATION_MATRIX.md` 曾把训练任务派发行标为“已实现”,当时 `mobile-uni/src/pages/supervisor/assign/index.vue` 只有单员工选择、没有截止时间。2026-07-17 晚间已补多人、截止快捷项和批量接口,矩阵已改为记录本地验证事实,仍不等同于生产发布。
## 3. 四方功能对照
| 功能 | 历史可运行版/文档要求 | Figma 表达 | 当前实现 | 客观结论与动作 |
|---|---|---|---|---|
| 问师傅语音输入 | 旧 `mobile/src/App.vue` 有语音录制/选择音频并转写;产品方案也明确“语音提问” | 首页 `23:3` 明确写“语音提问”,但未形成完整提问、转写、失败和重试状态画板 | 本地已恢复录音、转写、选择音频兜底,继续复用 `speech.ts` 与 `/api/ai/asr` | **确认回退已在代码恢复,未发布**:Figma 仍需补录音、识别、失败和文件兜底状态 |
| SOP 回答播报 | 旧版有“听一遍” | `79:11` 无播报控件 | 本地已补回答播报,未证明线上已发布 | **Figma 遗漏、代码本地恢复**:先保留功能,再补设计,不得为了贴图删掉 |
| 总结卡播报 | 旧版有总结卡 TTS;总纲写“语音播报(能力已有)” | 对应清单/画板未体现完整播报状态 | 本地已补总结卡播报 | **Figma 遗漏、代码本地恢复**:补播放/停止/生成失败状态 |
| 总结卡下载图片 | 旧版无充分证据;本轮客户新增 | Figma 未体现下载控件 | 本地已补 PNG 下载,无聊天模型时按真实 SOP 原文降级生成;浏览器已触发下载成功提示 | **新增需求已本地实现,未发布**:仍需补 iOS/Android H5 下载状态设计与真机验收 |
| 全局字号调节 | 未找到旧版开关;客户为老年员工新增明确要求 | `4:16` 已修为标准/大字/超大字三张同构画板 | 本地已实现全局三档、持久化与响应式自增高;400×900 已逐档截图复核 | **新增无障碍需求已本地实现并视觉验证,未发布**:继续做真机触控、键盘和读屏验收 |
| 主管多人派发 | 未证明旧版可运行;客户本轮再次明确 | `61:530` 明确选择 3 人并批量确认 | 本地已支持姓名多选、最多 100 人、逐人结果、幂等请求与失败隔离;真实提交 2/2 成功 | **Figma 需求已本地实现,未发布**:生产继续验证大团队权限与超时重试 |
| 截止时间/快捷日期 | 历史计划要求训练任务有截止时间;客户细化为今天/明天/3天/7天 | `61:530` 有精确截止时间,没有快捷日期控件 | 本地已增加 `dueDate` 及当天/明天/3天/7天快捷项,并在逐人结果显示到期日 | **部分被 Figma 覆盖的需求已本地实现,未发布**:补设计状态并复验时区边界 |
| 每日题每日变化/专项不重复 | 文档要求覆盖岗位常见场景和动态训练 | Figma 主要画页面结果,没有内容版本、日期派发、去重和降级规则 | 本地每日题已扩为 7 组 21 题,按日期、岗位和员工身份轮换,同日稳定、相邻日不重复 | **非视觉型缺口已完成第一阶段修复,未发布**:继续扩正式岗位题库和内容版本审计 |
| 生成题目、AI 回复、点评播报 | 语音优先原则支持;不能证明旧版全部覆盖 | 对应画板没有形成全链路播报覆盖表 | 本地已覆盖每日题、AI 回复、点评、参考答案、训练结果与候选面试;无 TTS 模型时 H5 已验证设备语音降级 | **需求覆盖已在代码补齐,未发布**:Figma 仍需形成内容类型/播放状态矩阵 |
| 主管切换学习端 | 客户明确主管也要学习;历史目标支持角色兼任 | Figma 分别画员工端和主管端,没有双模式切换入口及权限说明 | 本地已实现“工作台/学习端”双向切换,显示模式变化但组织角色保持主管;已用主管登录态验证 | **代码已本地实现,Figma 仍未覆盖,未发布**:补入口、返回路径与权限说明画板 |
| 岗位差异化内容 | 总纲要求岗位→SOP→场景→学习内容映射 | Figma 有多个岗位/角色页面,但没有展示内容分发规则和岗位覆盖表 | 当前主要仍围绕生活顾问 | **功能规则缺口,P1**:用岗位内容矩阵验收,不用“页面不同”代替“内容不同” |
| 问 AI(全网) | 旧版无;会议基线是企业内部知识 | 本轮检查的设计索引和相关问答画板未见独立外部 AI 入口、来源和免责声明 | 当前无全网检索 | **新增范围**:单独立项,与问师傅分入口、分数据外发、分引用和免责声明 |
| 图片/视频提问 | 历史文档列为新增/后置情境能力 | `79:11` 有回答侧视频内容,但没有提问附件上传流程 | 本地已补本次查询的图片/视频附件分析 | **设计与实现顺序倒置**:先补权限、PII 外发、大小/失败状态设计,再决定是否发布 |
| 开放问题榜/有奖问答 | 总纲明确阶段二,阶段一只积累 `knowledge_gap` | `95:6` 等画板已完整设计 | 当前没有业务闭环 | **不是当前版本误删**:保留为阶段二,不得因“Figma 已完成”提前宣称上线或拉入 P0 |
| 个人 AI 助理/个人资料库 | 2026-07-11 新增,明确阶段二 | Figma 已有完整画板组 | 当前未实现 | **阶段混放风险**:从当前阶段一研发指令中排除,另建阶段二验收表 |
## 4. 根因判断
问题链路更准确地描述为:
```text
历史需求和旧版能力没有先形成可追踪清单
→ Figma 主要完成视觉与页面状态,遗漏非视觉规则和部分旧交互
→ Figma 又把多个阶段放在同一索引,且标记“设计冻结完成”
→ 给 Codex 的指令只写“对标 Figma”
→ Codex 把 Figma 当成功能全集
→ 已画但后置的能力被误判为当前范围,没画的旧能力被误判为可以删除
```
因此,本次问题属于**需求追踪和指令约束失败**,不是单一前端页面实现失误。
## 5. 今后的事实源优先级
| 决策问题 | 第一事实源 | 第二事实源 | 禁止做法 |
|---|---|---|---|
| 本期做什么、哪些不能做 | 已确认 BRD、分阶段总纲、版本功能对比清单 | 客户确认的变更单 | 看到 Figma 画板就自动纳入当前阶段 |
| 功能怎么交互、页面怎么呈现 | 已标注需求 ID 和阶段的 Figma 正式画板 | 现有设计变量与组件 | 用 Figma 缺失作为删除旧功能的依据 |
| 当前代码有什么 | `mobile-uni/`、后端接口和测试 | 历史 `mobile/` 仅作版本回溯 | 用旧版截图代替当前实现判断 |
| 线上是否生效 | 生产包、真实账号、真实接口和浏览器回归 | 发布记录与构建 hash | 把“本地已写”表述成“客户已可用” |
发生冲突时:
- 功能范围:已确认业务文档和变更单高于 Figma。
- 视觉交互:本期正式 Figma 高于开发者自由发挥,但不能覆盖已确认功能。
- 线上状态:真实运行证据高于源码、文档和设计稿。
- 无法判断时:标记冲突并请求产品确认,不允许自行删功能或跨阶段扩张。
## 6. Figma 必须补的需求追踪层
不要求重画全部页面,先在索引和关键画板增加以下字段:
| 字段 | 示例 | 用途 |
|---|---|---|
| 需求 ID | `ASK-VOICE-001` | 与版本功能清单和验收用例一一对应 |
| 来源 | 旧版可运行 / BRD §4.3 / 2026-07-17 客户新增 | 防止把客户记忆、规划和已交付混为一谈 |
| 阶段 | 阶段一 P0 / 阶段二 / 三期 | 防止 Codex 把后续画板拉入当前主线 |
| 状态 | 已批准 / 待确认 / 已取消 | 区分正式需求和概念设计 |
| 功能覆盖 | 完整 / 部分 / 未覆盖 | “画板完成”不能代替“需求完整” |
| 实现状态 | 未开发 / 本地已实现 / 已发布 / 生产已验证 | 避免设计状态与工程状态串线 |
| 依赖 | ASR、TTS、组织身份、正式内容 | 让页面背后的接口和业务数据可验收 |
需要优先补画或补状态的页面:
1. 问师傅语音录制、识别中、失败、选择音频兜底。
2. SOP 回答和总结卡的播放、停止、失败、下载状态。
3. 主管多人选择、截止快捷项、逐人派发结果。
4. 修正已有标准/大字/超大字画板:保持模块、数据语义、顺序和 Tab 状态一致,只允许字号、行高和容器高度变化。
5. 主管“工作台/学习端”双模式。
6. “问师傅(企业知识)”与“问 AI(外部信息)”的来源、权限和风险区分。
## 7. 给 Codex 的新指令模板
后续每轮 UI 开发至少带上以下约束:
```text
功能事实源:<BRD/版本功能清单的章节与需求 ID>
视觉事实源:<Figma 文件与 node id>
本次阶段:<阶段一/P0 等>
本次必须保留的历史能力:<语音输入、播报、降级链等>
本次明确不做:<阶段二/三页面>
冲突规则:Figma 未画不等于可以删除;Figma 已画不等于本期必须开发。
验收:功能、视觉、接口、真实账号、发布状态分别记录。
```
仅写“按照 Figma 还原”是不合格指令,因为它无法约束版本连续性、接口规则、阶段边界和线上状态。
## 8. 立即执行顺序
1. 先让客户确认《员工端版本功能对比与功能对齐清单》中的“确认回退/历史规划/新增需求”分类。
2. 给确认项分配需求 ID,并把阶段、来源和功能覆盖状态回写到 Figma 索引。
3. 先做 P0:问师傅语音输入、关键内容播报全覆盖、每日题/专项版本和去重。
4. 再做 P1:多人派发、截止时间、主管学习端、岗位内容映射、字号三档。
5. 开放问题榜、个人 AI 助理和全网 AI 分别按阶段二或新增专项推进,不与阶段一修复混包。
6. 每一批完成后分别记录“本地实现、功能验证、视觉验证、已发布、生产验证”,不再用一个“完成”覆盖所有状态。
## 9. 补充抽查:`页面|我` 不是有效的字号变体组
客户抽查的 Figma 页面为 `4:16`。插件读取后确认以下问题:
| 问题 | 可编辑版 `7:2` | 字号版 `178:959` / `196:45` / `196:104` | 严重性 |
|---|---|---|---|
| 信息架构不同 | 显示与辅助 → 成长摘要 → 成长路径 → 成长证据包 → 最近练过 | 成长摘要 → 成长记录 → 显示与辅助 → 账号与安全 | **阻塞**:不是同一页面的字号变体 |
| 指标语义不同 | 4 个指标实例全部显示“综合能力”,截图值均为 86 | 成长分 81、训练次数 3、主管建议 1 | **阻塞**:组件属性未正确覆盖,示例数据也不一致 |
| 功能数量不同 | 有成长路径、证据包、最近训练 | 三项全部消失,新增成长记录和账号安全 | **阻塞**:切换字号不能改变功能集合 |
| 超大字布局 | 无对应等价结构 | 账号卡 `y=728, h=104`,底栏从 `y=802` 开始,垂直重叠 30px | **阻塞**:与“字号调整后无裁切和越界”的审计结论冲突 |
| 底栏状态 | “我”高亮 | 字号版截图出现“今日”图标红色、“我”文字红色 | **高**:两个 Tab 同时呈现 active 状态 |
| 水平网格 | 主要卡片 `x=20, w=368`,左右留白为 20/12 | 主要卡片 `x=20, w=360`,左右留白为 20/20 | **中**:同页网格不一致 |
| 长内容承载 | 画板已设为纵向滚动且固定 2 个底栏节点,但最后一张卡片到底部没有预留 92px 安全区,最大滚动位置仍会被底栏覆盖 | 字号版同样是纵向滚动;超大字内容本身未超过画板高度,因而无法滚动消除账号卡与底栏的 30px 覆盖 | **高**:滚动属性存在,但底部安全区和超大字初始布局仍错误 |
当前 `mobile-uni/src/pages/user/profile/index.vue` 又是第三套结构:账号、岗位身份、成长摘要、成长证据包和最近练过均来自真实接口,但没有字号选择。这意味着现在不能任选 Figma 四张画板中的一张强行还原,否则必然删除现有功能或产生新的布局回退。
该页应立即标记为 **设计阻塞/不可开发**,整改只需要一个最小方案:
1. 先确认唯一功能结构,保留所有已批准且当前真实可用的模块。
2. 只维护一套 Auto Layout/组件结构,三档字号通过文本样式或变量模式切换,不再复制三张独立页面。
3. 三档字号使用相同字段、相同示例数据、相同模块顺序和唯一 active Tab。
4. 内容区允许滚动,固定底栏前预留底栏高度和安全区;以超大字版无重叠作为验收下限。
5. 修正后再让 Codex实现;修正前不得把 `4:16` 写进“正式视觉基线”。
### 9.1 `页面|我` 修复结果(2026-07-17)
已按当前真实功能和新增字号需求修复 Figma 正式画板,不再保留四张互相冲突的开发基线:
- 标准 `7:2`、大字 `253:131`、超大字 `253:188` 均包含账号、岗位身份、显示与辅助、成长摘要、训练画像、成长路径、成长证据包和最近训练,模块名称、字段语义和顺序一致。
- 三张画板统一为 400×886、左右 20px、卡片宽 360px;摘要示例值统一为训练综合分 78、已训练 3、待复盘 2、分钟 0。
- 三档分别应用“员工端字号”变量的标准/大字/超大字模式;字号选择卡的当前值和选中项同步切换,不再局部保留标准字号。
- 三张画板均为纵向滚动、固定 2 个底部节点,并在内容末尾增加 108px 安全占位;超大字不再与底栏重叠,底栏只高亮“我”。
- 修复前四张画板已复制为隐藏备份,根节点为 `251:119`、`251:299`、`251:358`、`251:417`。
- 修复后逐张重新生成 400×886 截图并人工查看,同时复核直接子节点网格、文字越界、字体族、最小字号和固定层;三稿首屏均未发现重叠或裁切。
因此 `4:16` 的状态先由“设计阻塞”调整为 **Figma 视觉已修**;随后代码恢复批次已实现全局字号和持久化并完成本地视觉复核,详见 10.5。两者均不代表已经发布。
## 10. 全文件批量质量审计(2026-07-17)
本轮不是继续抽样,而是先枚举根级页面,再逐页切换以绕过 Figma 跨页懒加载,最终确认当前文件包含 **81 个顶层页面、78 张以 `Screen/` 命名的顶层正式画板**。修复“我”页时已删除 1 张冗余冲突稿;随后为当前 78 张画板重新生成当次截图并逐张做人工视觉复核。检查项包括信息架构、栅格、字号与换行、固定底栏与安全区、长文案裁切、组件缩放、示例数据可信度、active/disabled 状态和管理端字符级换行。
### 10.1 文件级数字不一致
| 项目 | 索引 `101:3` 声明 | 插件逐页实测 | 判断 |
|---|---:|---:|---|
| 顶层页面 | 78 | 81 | 索引已过期,少计 3 页 |
| 正式画板 | 70 | 78 张当前 `Screen/` 画板 | 索引排除规则仍未写明,但当前总数可复算 |
| 默认图层名 | 0 | 修复前当前全量复扫为 10 个;重命名后为 0 | 当前已清零,早期“25 个/5 页”来自过期中间快照 |
| 可见文字最低字号 | 12px | 修复后 78 张画板中小于 12px 的可见文本为 0 | 当前达成;同时修复了头像缩放引入的 11.8px 文本 |
| 根级内容越界 | 0 | 修复后不可滚动根画板的直接内容越界为 0 | 当前达成;仍需在真实实现中验证滚动、键盘和动态数据 |
已修正的 6 处 11px 文字分别位于:
- `178:960` 主管端“我的工作台”:团队成员、待复盘、风险预警。
- `178:2` 员工端“学习首页”:待完成、今日完成、知识引用。
### 10.2 已确认的真实视觉缺陷
| 页面 / 节点 | 插件与截图证据 | 分级 | 处理 |
|---|---|---|---|
| 页面|我 `4:16` | 修复前四张字号画板结构漂移、指标错误、双 active、超大字重叠和末尾安全区不足;2026-07-17 已修为 `7:2` / `253:131` / `253:188` 三张同构稿并逐张截图复核 | **Figma 视觉已修;代码本地已实现并复核** | 发布后补真实设备触控、键盘、读屏和长数据回流验证,不再使用隐藏旧稿 |
| 页面|问 `21:3` | 修复前空回答态被固定底栏遮住 | **Figma 已修** | 内容末尾已增加 108px 安全占位并重新截图;真实实现仍验证长回答、键盘与滚动末尾 |
| SOP 反馈 `79:674` | 修复前底部说明被裁 6px | **Figma 已修** | 画板高度由 832 增至 860,完整说明已重新截图复核 |
| 案例语音上传 `79:706` | 修复前上传表单被裁 48px | **Figma 已修** | 画板高度由 860 增至 932,上传区完整显示并重新截图复核 |
| 工作积分排行榜 `90:91` | 修复前 6 行头像压住姓名,且全部使用“银城一号” | **Figma 已修;三期未实现** | 主行组件头像已按真实尺寸缩放,姓名改为可区分示例并重新截图复核 |
| 页面对照审计 `115:210` | 修复前末节被裁 116px | **Figma 已修** | 画板高度由 2200 增至 2364,末节完整显示并重新截图复核 |
逐图检查还发现并修正了:`87:770` / `87:815` / `87:865`、`90:867`、`93:824`、`95:782` / `95:826`、`97:5` / `97:823` 的横向裁切或错误换行;`90:2`、`91:2`、`93:940`、`95:858` 的指标、状态与表格元数据字符级换行;`91:765`、`97:823` 的徽章占位文案和荣誉页标签换行;`97:5` 周节奏列表的 100px 异常行高已收紧为 56px,画板高度由 1346px 收紧为 1056px。其余重复状态词(如“待复盘”“查看详情”)经截图复核属于正常列表结构,没有按缺陷计数。
### 10.3 对研发排期的影响
- **可以继续按业务文档开发**:没有列入上表的当前阶段页面;Figma 仍只负责视觉,不负责补齐算法、权限和接口规则。
- **已作为视觉实现基线并本地落地**:`4:16` 字号三档已修为同构稿;代码已补全局字号切换和持久化,真实设备的长内容/键盘/底栏与读屏仍待发布前验证。
- **当前阶段 Figma 截断缺陷已修**:`21:3`、`79:674`、`79:706` 可作为新的视觉参考,但代码仍须以真实同尺寸截图和交互状态完成二次验收。
- **后续阶段暂不进入当前主线**:工作积分、荣誉中心、个人 AI 助理、开放问题榜等虽已修复确定性视觉错误,功能仍按阶段二/三管理。
- **索引必须更新后才能重新冻结**:当前真实口径为 81 页/78 张 `Screen/` 画板,结构复扫结果为默认 `Frame` 0、小于 12px 文本 0、根级越界 0;索引仍写 78/70,不能继续作为文件总数事实源。
### 10.4 修复后的再次复检边界
本轮将逐页视觉验收标准提升为“当次截图 + 版面 + 状态 + 可访问性风险”联合检查,不再把节点存在或图层数量当成视觉通过。调用额度恢复后,已重新枚举 81 个顶层页面、78 张当前 `Screen/` 画板,为 78 张画板逐一生成截图并人工检查;确定性缺陷修正后,又对 20 张受影响画板生成修复后截图复核,并对排行榜、荣誉墙和积分荣誉中心做第二轮细节截图复核。
当前完成层级必须严格区分:
- **Figma 结构复核**:78 张画板,默认 `Frame` 0、小于 12px 文本 0、不可滚动根级越界 0。
- **Figma 视觉复核**:78 张当次截图已逐张查看;本轮发现的裁切、头像重叠、占位数据和字符级换行已修并复截图。
- **代码实现/浏览器复核**:本轮没有修改移动端或管理端代码,不能把 Figma 修复写成代码已对齐;同尺寸实现截图、滚动、键盘、长数据、触控和读屏仍需单独验证。
- **发布/生产验证**:本轮未发布,不改变现网完成状态。
### 10.5 后续代码恢复与浏览器复核(2026-07-17 晚间)
上述“本轮没有修改代码”仅描述 Figma 设计修复批次。随后已完成一轮独立的代码恢复和浏览器复核:
- 以 400×900 视口对登录、员工今日、问师傅、练习、我的三级字号、主管工作台/学习端和专项派发进行当次截图检查;同时实际操作登录、身份模式切换、姓名多选、快捷日期、批量提交、SOP 查询、设备语音降级、总结卡生成与图片下载。
- “我”页三级字号保持同一功能结构,页面通过全局模式缩放和响应式布局自增高;超大字下关键页未见横向溢出、底栏遮挡或卡片重叠。
- 主管派发已用 2 名真实团队成员完成 2/2 成功提交;主管学习端已由主管登录态进入员工首页并可返回工作台。
- 总结卡在无聊天模型配置时只摘录相关 SOP 原文并标注来源,排除低相关片段;浏览器已显示下载成功提示。
- TTS 模型未配置时,H5 已从后端 TTS 自动切换到设备语音,按钮从“语音播报”进入“停止播报”,随后可手动停止。
该批次的完成层级为 **本地实现、自动化验证、浏览器交互验证和视觉验证**;仍未发布、未做生产验证,也未完成真实手机上的麦克风/相册权限与读屏验收。
## 11. 代码实现的逐页视觉复核(2026-07-18)
本轮在 Figma 文件质量审计之后,又对真实运行代码执行了独立视觉和交互验收,避免把“画板已修”误写成“代码已对齐”:
- 员工端覆盖今日、练习、问师傅、个人页、学习、全网 AI、问题榜/详情/发布、积分和考试;另覆盖超大字及 430px 宽度状态。
- 主管端覆盖工作台、团队、专项派发、个人页、考试列表、组卷和成绩页。
- 管理端使用真实登录后覆盖常见难题、问题榜运营抽屉和全网 AI 配置页,并实际点击问题记录打开审核详情。
- 运行结果共 24 个移动端状态和 3 个管理端页面:均无页面级横向溢出、控制台错误、失败请求或可见加载错误。
- 人工截图复核发现并修复了代码中的确定性问题:11px 业务文字、SOP 步骤号/问答徽标 8–10px、输入框盒模型溢出,以及问题榜四个筛选标签在标准/超大字下被裁切。
- Figma `95:6`、`95:782`、`95:826`、`95:858` 的问题榜/详情/最佳答案/管理稿已与真实实现逐项对照;代码保留相同信息层级,同时以当前组织身份、积分分账和审核接口为功能事实源。
当次证据保存在 `.data/visual-audit-20260718/runtime/`:`contact-employee-standard.png`、`contact-employee-accessibility.png`、`contact-supervisor.png` 和 `contact-admin.png`。这些证据只证明本地运行与视觉验证,仍不等于发布和生产验证。
## 12. 关联文档
- [员工端版本功能对比与功能对齐清单-20260717.md](员工端版本功能对比与功能对齐清单-20260717.md)
- [FIGMA_DESIGN_INVENTORY.md](FIGMA_DESIGN_INVENTORY.md)
- [FIGMA_IMPLEMENTATION_MATRIX.md](FIGMA_IMPLEMENTATION_MATRIX.md)
- [银城员工端APP分阶段实施总纲.md](银城员工端APP分阶段实施总纲.md)
- [20260708/数字师傅学练问报整合方案.md](20260708/数字师傅学练问报整合方案.md)
+189
View File
@@ -0,0 +1,189 @@
# 多租户知识空间平台运行手册
## 1. 适用范围与安全边界
本手册用于银城与美途作为两个独立 SaaS 租户的知识空间初始化、内容迁移、授权、外部应用联调和回滚。租户、调用应用和知识空间是三层独立边界:内部用户的有效查询范围取“当前租户 + 当前调用应用绑定空间 + 用户/角色授权空间”的交集;外部应用只能访问其所属租户内显式绑定的空间。
禁止把集团账号、公司名称、客户端传入的 `tenantId/userId/extPartyId` 当作授权依据。禁止在浏览器、小程序包、日志、工单或文档中保存 API_TOKEN。回滚优先停用应用或解绑空间,不删除知识数据、附件或 OSS 对象。
## 2. 初始化前确认
### 2.1 确认生产租户 ID
先只读查询生产库,不凭公司简称猜租户 ID:
```sql
select tenant_id, company_name, status, del_flag
from sys_tenant
where del_flag = '0'
order by tenant_id;
```
由业务负责人确认银城、美途分别对应的 `tenant_id` 和公司全称,并确认二者不同。执行脚本还会再次查询并打印 `tenant_id:company_name`,操作者必须核对后才继续。
### 2.2 备份与迁移
先备份数据库,再执行 `backend/script/sql/update/aihr_20260716_knowledge_space_platform_mysql8.sql`。迁移可重复执行,但生产仍应先在结构副本验证。执行后至少核对:
```sql
show tables like 'aihr_knowledge_%';
show create table aihr_knowledge_info;
show create table aihr_knowledge_app;
show create table aihr_knowledge_space_grant;
```
## 3. 幂等初始化
先 dry-run,不连接数据库、不输出密码或令牌:
```bash
./scripts/provision-knowledge-platform.sh \
--silver-tenant-id '<银城租户ID>' \
--meitu-tenant-id '<美途租户ID>' \
--dry-run
```
确认输出恰好包含银城 3 个空间、美途 1 个空间、3 个应用及预期绑定后,再实际执行:
```bash
AIHR_DB_HOST='<数据库地址>' \
AIHR_DB_PORT='3306' \
AIHR_DB_NAME='ry-vue' \
AIHR_DB_USER='<账号>' \
AIHR_DB_PASSWORD='<从安全环境注入>' \
./scripts/provision-knowledge-platform.sh \
--silver-tenant-id '<银城租户ID>' \
--meitu-tenant-id '<美途租户ID>' \
--confirm
```
不设置 `AIHR_DB_HOST` 时,脚本使用本地 `wygj-mysql` 容器。脚本是幂等 upsert,可重复执行;它不会生成 API_TOKEN,也不会把现有细粒度知识库改名、搬迁或删除。
执行后核对:
```sql
select tenant_id, code, name, space_type, sensitivity_level, status
from aihr_knowledge_info
where code in ('yc_public_policy','yc_property_sop','yc_management_ops','mt_customer_service')
order by tenant_id, code;
select tenant_id, app_code, auth_type, internal_client_key, status, rate_limit_per_minute
from aihr_knowledge_app
where app_code in ('yc_admin','yc_mobile','mt_card_miniapp')
order by tenant_id, app_code;
```
`mt_card_miniapp` 初始化后必须是 `DISABLED` 且 `token_hash` 为空;银城与美途之间不得存在应用—空间绑定。
## 4. 空间、授权与应用管理
管理端“知识空间”页面提供空间、主体授权和调用应用管理。空间编码创建后不可修改;停用空间会让检索立即失去该空间,但不删除资料。`MANAGE` 授权可以给用户或角色,`READ` 只决定主体能否读;SESSION 应用与主体授权取交集。
外部美途应用的启用顺序固定为:
1. 核对只绑定 `mt_customer_service`。
2. 核对空间只含批准对外发布的内容。
3. 设置合理的每分钟限流和过期时间。
4. 在管理端轮换令牌;明文只显示一次。
5. 立即写入小程序云函数、API 网关或可信后端的密钥系统。
6. 确认后端联调通过,再把应用状态改为 `ACTIVE`。
轮换令牌后旧令牌立即失效。发生泄露或暂停联调时,先把应用改为 `DISABLED`;需要恢复时重新轮换,不复用曾暴露的明文。前端、小程序源码和用户设备绝不能直接持有令牌。
## 5. 内容导入与 legacy 空间迁移
### 5.1 新内容导入
在 SOP 或资料处理页显式选择一个或多个可管理空间。多空间上传只解析一次、复用同一个 OSS 对象,但为每个空间建立独立附件成员关系和检索片段。解绑或停用一个空间不得影响另一个空间的内容。
导入后核对:
```sql
select a.tenant_id, k.code, a.doc_id, a.name, a.oss_id, a.status,
count(f.id) fragment_count
from aihr_knowledge_attach a
join aihr_knowledge_info k
on k.tenant_id = a.tenant_id and k.id = a.knowledge_id
left join aihr_knowledge_fragment f
on f.tenant_id = a.tenant_id and f.knowledge_id = a.knowledge_id and f.doc_id = a.doc_id
group by a.tenant_id, k.code, a.doc_id, a.name, a.oss_id, a.status
order by a.id desc;
```
空间解绑会先删除当前成员、片段和向量点;只有跨租户附件引用计数为零时才尝试删除 OSS。对象存储删除失败不会恢复已解绑成员,而是留下可审计的孤立对象,按下列查询确认后由独立清理流程处理:
```sql
select o.oss_id, o.tenant_id, o.original_name
from sys_oss o
left join aihr_knowledge_attach a
on a.tenant_id = o.tenant_id and a.oss_id = o.oss_id
where a.id is null and o.ext1 in ('aihr-knowledge','aihr-knowledge-staging');
```
### 5.2 细粒度 SOP 迁入 `yc_property_sop`
现有“投诉处理 SOP、催缴沟通 SOP、报修跟进 SOP”等 `legacy_*` 空间不直接改名。按以下顺序执行:
1. 业务负责人导出现有空间的文件清单,逐项标记目标空间、密级、版本日期、维护人和是否允许复用。
2. 通过多空间导入或 OSS 成员复用把批准内容加入 `yc_property_sop`,保留原 legacy 成员关系。
3. 对新空间至少运行 10 个标准问题,逐题核对答案、文件标题、引用片段和空间编码。
4. 核对新应用只绑定新空间,legacy 空间不向新应用授权。
5. 业务确认后把不再使用的 legacy 空间改为 `DISABLED`,观察查询日志一个完整业务周期。
6. 若出现缺失,重新启用 legacy 空间或恢复应用绑定;不要搬回附件、删除片段或清理 OSS。
## 6. 查询、日志与限流观察
内部统一入口为 `POST /api/knowledge/query`,外部入口为 `POST /api/open/knowledge/query`。外部请求使用 `Authorization: Bearer <API_TOKEN>`。查询日志只保存问题哈希、有效空间、来源类型、状态、耗时和提示版本,不保存完整问题或令牌。
```sql
select tenant_id, app_id, status, source_types, count(*) calls,
round(avg(latency_ms)) avg_latency_ms, max(create_time) last_time
from aihr_knowledge_query_log
group by tenant_id, app_id, status, source_types
order by last_time desc;
```
重点观察 `REJECTED`、`FAILED`、`NO_EVIDENCE`、连续 `429` 和异常高耗时。外部应用的限流依赖 Redis;Redis 不可用时外部查询应失败关闭并返回服务不可用,不能绕过限流继续调用。
## 7. 验证与发布闸门
自动合同测试:
```bash
bash scripts/tests/provision-knowledge-platform.test.sh
node --test scripts/tests/knowledge-platform-security.test.mjs
```
真实环境验证器从环境变量读取令牌,绝不写入命令脚本或仓库:
```bash
AIHR_BASE_URL='https://wygj-api.localhost' \
AIHR_SILVER_ADMIN_TOKEN='<管理端登录令牌>' \
AIHR_SILVER_EMPLOYEE_TOKEN='<员工登录令牌>' \
AIHR_SILVER_SUPERVISOR_TOKEN='<主管登录令牌>' \
AIHR_MEITU_APP_TOKEN='<美途应用令牌>' \
AIHR_MEITU_QUERY='<已确认能命中公开内容的美途标准题>' \
node scripts/verify-knowledge-platform.mjs
```
在预先导入了同一测试文件到 `yc_public_policy` 与 `yc_property_sop` 的非生产环境,可额外执行破坏性解绑验证;它会删除公共制度空间中的测试成员,因此必须使用专用测试文件:
```bash
AIHR_VERIFY_UNBIND=true \
AIHR_SHARED_DOC_NAME='<专用测试文件名>' \
AIHR_SHARED_DOC_QUERY='<测试文件唯一标记>' \
node scripts/verify-knowledge-platform.mjs
```
只有工程回归、真实 HTTP 正反例、数据库租户归属、Qdrant tenant+knowledge 过滤和每空间标准题都通过,才可标记“联调可用”。生产发布、真实内容负责人/授权矩阵签字和试点样本未完成时,不得标记“线上生效”或“正式试点验收”。
## 8. 回滚
按影响最小顺序处理:
1. 停用 `mt_card_miniapp` 或对应 SESSION 应用。
2. 解绑错误空间或把有问题的新空间置为 `DISABLED`。
3. 客户端临时回到兼容 `/api/knowledge/search`,该入口仍经过统一授权服务。
4. 恢复旧应用绑定或重新启用 legacy 空间。
不要删除新表,不删除查询审计,不把附件移动回旧空间,不清理 OSS,不回滚已经写入的稳定空间编码。数据库和静态资源发布仍遵循项目既有备份与发布口径。
+8 -3
View File
@@ -6,27 +6,32 @@
| 文档 | 用途 |
|---|---|
| [DEV_SETUP.md](DEV_SETUP.md) | 本地端口、账号、启动步骤、基础链路验证、移动端 H5 静态发布 |
| [DEV_SETUP.md](DEV_SETUP.md) | 本地端口、账号、启动步骤、基础链路验证、管理端与移动端 H5 静态发布 |
| [FIGMA_DESIGN_INVENTORY.md](FIGMA_DESIGN_INVENTORY.md) | Figma 页面节点索引、设计批次范围、取消项和全文件一致性审计结果 |
| [FIGMA_DESIGN_SYSTEM_GUIDE.md](FIGMA_DESIGN_SYSTEM_GUIDE.md) | 员工端通用视觉元素、业务元素、状态映射和 LLM 组页规则 |
| [FIGMA_IMPLEMENTATION_MATRIX.md](FIGMA_IMPLEMENTATION_MATRIX.md) | 70 张正式画板与代码/线上实现状态、二期边界和剩余动作 |
| [FIGMA_ONLINE_DELTA.md](FIGMA_ONLINE_DELTA.md) | Figma 目标与线上 H5 实测差异矩阵、当前实施边界和验收口径 |
| [FIGMA需求覆盖与版本偏差审计-20260717.md](FIGMA需求覆盖与版本偏差审计-20260717.md) | 旧版功能、已确认需求、Figma 实际画板与当前实现的四方对照,以及防止遗漏旧功能和误拉后续阶段的事实源规则 |
| [DEMO_ACCEPTANCE.md](DEMO_ACCEPTANCE.md) | 一期 MVP 演示脚本、录屏兜底、MVP 演示流验收清单 |
| [API_INTEGRATION.md](API_INTEGRATION.md) | 后端 API 对接顺序、正式试点 CSV、移动端训练记录/复盘详情、候选资料上传/审核、SOP 上传解析接口 |
| [KNOWLEDGE_PLATFORM_RUNBOOK.md](KNOWLEDGE_PLATFORM_RUNBOOK.md) | 银城/美途知识空间初始化、授权、令牌、内容迁移、监控验证和安全回滚手册 |
| [RUOYI_AI_INCREMENTAL_MIGRATION.md](RUOYI_AI_INCREMENTAL_MIGRATION.md) | 从 `ageerle/ruoyi-ai` 分片迁移知识库、模型能力、文档解析、Qdrant/RAG 和 chat 的执行边界 |
| [superpowers/specs/2026-07-16-multi-tenant-knowledge-platform-design.md](superpowers/specs/2026-07-16-multi-tenant-knowledge-platform-design.md) | 银城/美途独立租户、多知识空间、多调用应用统一问答、授权交集、受控数据工具和安全验收的完整需求方案 |
| [superpowers/plans/2026-07-16-multi-tenant-knowledge-platform.md](superpowers/plans/2026-07-16-multi-tenant-knowledge-platform.md) | 多租户多知识空间统一问答平台按 schema、授权、检索、上传、数据工具、管理端、多端联调和发布拆分的实施计划 |
| [AI人力资源系统项目规划方案与AI接口说明.md](AI人力资源系统项目规划方案与AI接口说明.md) | 对外会议版口径、数字师傅定位、AI 接口和供应商规划 |
| [银城员工端APP分阶段实施总纲.md](银城员工端APP分阶段实施总纲.md) | 三阶段总纲:陪练 → 大喇叭+知识学习平台(含学模块、开放问题榜、员工个人 AI 助理) → 北森对接;身份三轴模型与防遗漏分发策略 |
| [个人AI助理阶段二专项TechSpec.md](个人AI助理阶段二专项TechSpec.md) | 员工个人知识空间的物理分域、数据模型、API、检索融合、权限、安全、删除和测试规格 |
| [个人AI助理阶段二开发推进计划.md](个人AI助理阶段二开发推进计划.md) | 个人 AI 助理阶段二按 P0/P1 拆分的逐任务实施、测试、提交和试点闸门 |
| [AI陪练二期开发推进计划.md](AI陪练二期开发推进计划.md) | 总纲阶段一执行文档:AI 陪练从 MVP 演示闭环推进到管家(生活顾问)岗位试点可用;区分工程就绪与正式业务试点证据 |
| [BRD_IMPLEMENTATION_AUDIT.md](BRD_IMPLEMENTATION_AUDIT.md) | BRD 功能、权限、迁移、线上资源和未完成项的证据记录;不替代正式发布验收 |
| [员工端版本功能对比与功能对齐清单-20260717.md](员工端版本功能对比与功能对齐清单-20260717.md) | 历史可运行版、历史需求/设计、当前 `mobile-uni`、本地待发布修复与客户逐条反馈的版本对比和优先级 |
| [BRD_IMPLEMENTATION_AUDIT.md](BRD_IMPLEMENTATION_AUDIT.md) | 顶部维护现阶段结论与三端输入/BRD 匹配矩阵,下方保留功能、权限、迁移、线上资源和未完成项证据;不替代正式发布验收 |
| [BRD_PRODUCTION_MIGRATION_RUNBOOK.md](BRD_PRODUCTION_MIGRATION_RUNBOOK.md) | AIHR BRD 生产 schema/内置内容迁移顺序、只读核验和发布后回归口径 |
| [20260708/uni-app用户侧前端重建计划.md](20260708/uni-app用户侧前端重建计划.md) | 当前用户侧 `mobile-uni/` 重建计划、三端页面拆分、portless 入口、真实浏览器验证和验收进展 |
| [20260708/数字师傅学练问报整合方案.md](20260708/数字师傅学练问报整合方案.md) | 产品定义(学练问报+问题榜+学分晋升+个人 AI 助理)、半年会发布会方案分层及客户需求逐项处置对照 |
| [20260708/发布会演示候选题单.md](20260708/发布会演示候选题单.md) | 2026-07-08 发布会演示候选题单,作为产品讨论留档,不作为阶段一开发入口 |
| [基于AI的银城员工端APP项目立项与开发规划会议-2026年07月07日-来自【Get 笔记】.md](基于AI的银城员工端APP项目立项与开发规划会议-2026年07月07日-来自【Get%20笔记】.md) | 2026-07-07 立项会纪要原文(总纲的输入源,只作留档) |
| [20260708/企业内部AI培训学习APP产品需求与发布会内容讨论(纪要)](20260708/) | 2026-07-08 产品讨论纪要原文及客户"第三版"docx(整合方案的输入源,只作留档) |
| [open-org-sync-api-design-v1.md](open-org-sync-api-design-v1.md) | 开放组织同步系统 `/open/v1` 接口设计,`POST /api/aihr/org/sync` 的外部契约 |
| [open-org-sync-api-design-v1.md](open-org-sync-api-design-v1.md) | 开放组织同步系统 `/api/open/v1` 接口设计,`POST /api/aihr/org/sync` 的外部契约 |
| [物业AI人力资源系统业务需求文档BRD.md](物业AI人力资源系统业务需求文档BRD.md) | 业务需求、范围边界、角色、风险与验收 |
| [物业AI人力资源系统开发规格TechSpec.md](物业AI人力资源系统开发规格TechSpec.md) | 工程结构、数据模型、页面路由、API 和核心实现规格 |
| [BACKLOG.md](BACKLOG.md) | 需求池与延后事项(B1–B8:数据权限/人设语音/生成图片/生成视频/员工画像/视觉检索/数字师傅) |
+5 -5
View File
@@ -17,7 +17,7 @@
| 2. 模型能力 | `chat_provider / chat_model` 改造为 `aihr_model_*`,最小 OpenAI-compatible 调用边界 | 多模型市场、图像、SSE、成本看板 | 模型列表可查;数据库配置后可调用 `/chat/completions` |
| 3. 文档解析 | 文本/Markdown/PDF/Word/Excel/PPT loader、OSS-first 上传与分片 | 异步重试队列、图片智能分析 | txt/md/PDF/Word/Excel/PPT 文件可落 OSS 并解析为 fragment |
| 4. 检索与 embedding | MySQL Fulltext + OpenAI-compatible embedding + Qdrant 最小向量召回 | Milvus/Weaviate 全量适配、独立向量库后台 | 同一问题返回带分数片段,配置 vector 模型后片段有 embedding,Qdrant 可用时参与 RRF 融合 |
| 5. 资料处理状态 | 解析任务状态页、资料分类、处理链路、多文件/目录选择上传、服务端后台目录导入任务 | 单失败文件重试、分布式队列 | 能查看等待解析/解析中/已完成/失败、片段数、向量化状态并导入 MVP 样例文件 |
| 5. 资料处理状态 | 解析任务状态页、资料分类、处理链路、多文件/ZIP 异步上传、单文件重试、服务端运维目录导入接口 | 分布式队列 | 能查看等待解析/解析中/已完成/失败、片段数、向量化状态,并从页面批量导入 MVP 样例文件 |
| 6. RAG 回答 | 带引用回答、训练题生成 | 多模型市场、成本看板 | SOP 页面展示真实引用 |
| 7. Chat | 最小会话、消息、引用来源 | 多智能体、工作流、MCP、Skills | 可围绕 SOP 连续追问 |
@@ -72,9 +72,9 @@
- 新增后端 API:`GET /api/knowledge/processing/overview`。
- 新增前端页面:`/knowledge/processing`,菜单名“资料处理”;`SOP知识库` 菜单保持独立不改名。
- 页面聚合展示资料总量、已完成、处理中、失败、资料分类、解析任务表、处理链路、规则风险和事件列表。
- 批量导入先复用 `POST /api/knowledge/doc/upload`,支持多文件和浏览器目录选择。
- 新增 `POST /api/knowledge/doc/import-local-task`、`GET /api/knowledge/doc/import-tasks` 和 `POST /api/knowledge/doc/import-tasks/{id}/cancel`,只读取 `AIHR_IMPORT_ROOT` / `aihr.import.root` 下的相对目录,写入 `aihr_knowledge_import_task` 后后台逐文件复用上传解析链路,页面轮询进度并支持取消运行中任务;`POST /api/knowledge/doc/import-local` 保留同步调试。
- 页面聚合展示资料总量、已完成、处理中、失败、资料分类、解析任务表、处理链路、规则风险和事件列表;解析任务表按当前筛选结果前端分页,默认 10 条/页,可切换 20/50 条,筛选或刷新时回到第一页。
- 页面批量导入走 `POST /api/knowledge/doc/upload-async`,支持多文件和 ZIP,按批次轮询并可单文件重试;不提供浏览器目录选择。
- `POST /api/knowledge/doc/import-local-task`、`GET /api/knowledge/doc/import-tasks`、`POST /api/knowledge/doc/import-tasks/{id}/cancel` 和同步 `POST /api/knowledge/doc/import-local` 仅保留为运维/调试接口,不在资料处理页暴露。
## 当前第六片
@@ -92,5 +92,5 @@
- 工作流、多智能体、MCP、Skills
- 全量模型管理后台
- 完整流式 chat 与消息持久化
- 单失败文件重试、导入任务暂停、分布式队列
- 导入任务暂停、分布式队列
- 大规模资料的异步向量重建进度条
+74 -72
View File
@@ -1,5 +1,7 @@
# 开放平台组织与预算同步 API 设计方案 v1
> 线上前缀修正(2026-07-15):当前域名 `https://wuye.meihe.cc` 只有 `/api/*` 会代理到后端开放平台;实际接入必须使用 `https://wuye.meihe.cc/api/open/v1`。不要使用 `https://wuye.meihe.cc/open/v1`,否则可能命中前端 SPA 或 nginx,返回 HTML 而不是开放接口 JSON。
## 1. 文档目标
本文档用于定义本系统对外开放的组织与预算同步方案,覆盖以下对象:
@@ -47,7 +49,7 @@
### 3.2 架构原则
- 对外统一入口:全部走 `backend` 的 `/open/v1/*`
- 对外统一入口:全部走 `backend` 的 `/api/open/v1/*`
- 内外账号隔离:外部系统不用内部员工登录账号
- 事件通知最小化:通知消息只传事件元信息,不传完整业务数据
- 数据主动拉取:业务明细通过开放接口主动拉取
@@ -68,7 +70,7 @@
↓
订阅者收到消息
↓
7天内调用 /open/v1/sync/changes 或对象接口主动拉取
7天内调用 /api/open/v1/sync/changes 或对象接口主动拉取
↓
记录同步任务、同步明细、游标、审计日志
↓
@@ -470,66 +472,66 @@ X-Nonce
开放平台统一前缀:
```text
/open/v1
/api/open/v1
```
### 9.1 认证接口
- `POST /open/v1/auth/token`
- `POST /open/v1/auth/refresh`
- `GET /open/v1/auth/me`
- `POST /api/open/v1/auth/token`
- `POST /api/open/v1/auth/refresh`
- `GET /api/open/v1/auth/me`
### 9.2 订阅管理接口
- `POST /open/v1/subscriptions`
- `GET /open/v1/subscriptions`
- `GET /open/v1/subscriptions/{subscription_id}`
- `PATCH /open/v1/subscriptions/{subscription_id}`
- `POST /open/v1/subscriptions/{subscription_id}/enable`
- `POST /open/v1/subscriptions/{subscription_id}/disable`
- `POST /api/open/v1/subscriptions`
- `GET /api/open/v1/subscriptions`
- `GET /api/open/v1/subscriptions/{subscription_id}`
- `PATCH /api/open/v1/subscriptions/{subscription_id}`
- `POST /api/open/v1/subscriptions/{subscription_id}/enable`
- `POST /api/open/v1/subscriptions/{subscription_id}/disable`
### 9.3 事件通知接口
- `GET /open/v1/events`
- `GET /open/v1/events/{event_id}`
- `POST /open/v1/events/{event_id}/ack`
- `POST /open/v1/events/{event_id}/nack`
- `GET /api/open/v1/events`
- `GET /api/open/v1/events/{event_id}`
- `POST /api/open/v1/events/{event_id}/ack`
- `POST /api/open/v1/events/{event_id}/nack`
### 9.4 数据拉取接口
- `GET /open/v1/sync/changes`
- `GET /open/v1/sync/snapshot`
- `GET /open/v1/groups/{id}`
- `GET /open/v1/companies/{id}`
- `GET /open/v1/departments/{id}`
- `GET /open/v1/employees/{id}`
- `GET /open/v1/budget-versions/{id}`
- `GET /open/v1/budget-subjects/{id}`
- `GET /open/v1/budget-items/{id}`
- `GET /open/v1/budget-plans/{id}`
- `GET /api/open/v1/sync/changes`
- `GET /api/open/v1/sync/snapshot`
- `GET /api/open/v1/groups/{id}`
- `GET /api/open/v1/companies/{id}`
- `GET /api/open/v1/departments/{id}`
- `GET /api/open/v1/employees/{id}`
- `GET /api/open/v1/budget-versions/{id}`
- `GET /api/open/v1/budget-subjects/{id}`
- `GET /api/open/v1/budget-items/{id}`
- `GET /api/open/v1/budget-plans/{id}`
### 9.5 同步任务接口
- `POST /open/v1/sync/jobs`
- `GET /open/v1/sync/jobs/{job_id}`
- `POST /open/v1/sync/jobs/{job_id}/complete`
- `POST /api/open/v1/sync/jobs`
- `GET /api/open/v1/sync/jobs/{job_id}`
- `POST /api/open/v1/sync/jobs/{job_id}/complete`
### 9.6 补数申请接口
- `POST /open/v1/replay-requests`
- `GET /open/v1/replay-requests`
- `GET /open/v1/replay-requests/{request_id}`
- `POST /open/v1/replay-requests/{request_id}/cancel`
- `POST /open/v1/replay-requests/{request_id}/approve`
- `POST /open/v1/replay-requests/{request_id}/reject`
- `POST /open/v1/replay-requests/{request_id}/execute`
- `POST /api/open/v1/replay-requests`
- `GET /api/open/v1/replay-requests`
- `GET /api/open/v1/replay-requests/{request_id}`
- `POST /api/open/v1/replay-requests/{request_id}/cancel`
- `POST /api/open/v1/replay-requests/{request_id}/approve`
- `POST /api/open/v1/replay-requests/{request_id}/reject`
- `POST /api/open/v1/replay-requests/{request_id}/execute`
### 9.7 追踪与审计接口
- `GET /open/v1/traces/{trace_id}`
- `GET /open/v1/audits`
- `GET /open/v1/subscriptions/{subscription_id}/deliveries`
- `GET /open/v1/subscriptions/{subscription_id}/sync-records`
- `GET /api/open/v1/traces/{trace_id}`
- `GET /api/open/v1/audits`
- `GET /api/open/v1/subscriptions/{subscription_id}/deliveries`
- `GET /api/open/v1/subscriptions/{subscription_id}/sync-records`
---
@@ -537,7 +539,7 @@ X-Nonce
### 10.1 获取令牌
`POST /open/v1/auth/token`
`POST /api/open/v1/auth/token`
请求示例:
@@ -565,11 +567,11 @@ X-Nonce
### 10.2 刷新令牌
`POST /open/v1/auth/refresh`
`POST /api/open/v1/auth/refresh`
### 10.3 查询当前应用
`GET /open/v1/auth/me`
`GET /api/open/v1/auth/me`
返回内容:
@@ -587,7 +589,7 @@ X-Nonce
### 11.1 创建订阅
`POST /open/v1/subscriptions`
`POST /api/open/v1/subscriptions`
请求示例:
@@ -633,7 +635,7 @@ X-Nonce
### 11.2 查询订阅列表
`GET /open/v1/subscriptions`
`GET /api/open/v1/subscriptions`
支持筛选:
@@ -643,8 +645,8 @@ X-Nonce
### 11.3 启停订阅
- `POST /open/v1/subscriptions/{subscription_id}/enable`
- `POST /open/v1/subscriptions/{subscription_id}/disable`
- `POST /api/open/v1/subscriptions/{subscription_id}/enable`
- `POST /api/open/v1/subscriptions/{subscription_id}/disable`
---
@@ -652,7 +654,7 @@ X-Nonce
### 12.1 拉取事件列表
`GET /open/v1/events`
`GET /api/open/v1/events`
查询参数:
@@ -685,7 +687,7 @@ X-Nonce
### 12.2 事件确认收到
`POST /open/v1/events/{event_id}/ack`
`POST /api/open/v1/events/{event_id}/ack`
请求示例:
@@ -698,7 +700,7 @@ X-Nonce
### 12.3 事件确认失败
`POST /open/v1/events/{event_id}/nack`
`POST /api/open/v1/events/{event_id}/nack`
请求示例:
@@ -715,7 +717,7 @@ X-Nonce
### 13.1 增量拉取
`GET /open/v1/sync/changes`
`GET /api/open/v1/sync/changes`
查询参数:
@@ -758,7 +760,7 @@ X-Nonce
### 13.2 全量快照拉取
`GET /open/v1/sync/snapshot`
`GET /api/open/v1/sync/snapshot`
查询参数:
@@ -779,35 +781,35 @@ X-Nonce
#### 集团
`GET /open/v1/groups/{id}`
`GET /api/open/v1/groups/{id}`
#### 公司
`GET /open/v1/companies/{id}`
`GET /api/open/v1/companies/{id}`
#### 部门
`GET /open/v1/departments/{id}`
`GET /api/open/v1/departments/{id}`
#### 员工
`GET /open/v1/employees/{id}`
`GET /api/open/v1/employees/{id}`
#### 预算版本
`GET /open/v1/budget-versions/{id}`
`GET /api/open/v1/budget-versions/{id}`
#### 预算科目
`GET /open/v1/budget-subjects/{id}`
`GET /api/open/v1/budget-subjects/{id}`
#### 预算项
`GET /open/v1/budget-items/{id}`
`GET /api/open/v1/budget-items/{id}`
#### 预算计划
`GET /open/v1/budget-plans/{id}`
`GET /api/open/v1/budget-plans/{id}`
### 13.4 单对象接口通用参数
@@ -821,7 +823,7 @@ X-Nonce
### 14.1 创建同步任务
`POST /open/v1/sync/jobs`
`POST /api/open/v1/sync/jobs`
用途:
@@ -853,11 +855,11 @@ X-Nonce
### 14.2 查询同步任务
`GET /open/v1/sync/jobs/{job_id}`
`GET /api/open/v1/sync/jobs/{job_id}`
### 14.3 回报同步结果
`POST /open/v1/sync/jobs/{job_id}/complete`
`POST /api/open/v1/sync/jobs/{job_id}/complete`
请求示例:
@@ -932,7 +934,7 @@ X-Nonce
### 16.3 发起补数申请
`POST /open/v1/replay-requests`
`POST /api/open/v1/replay-requests`
请求示例:
@@ -963,29 +965,29 @@ X-Nonce
### 16.4 查询补数申请
`GET /open/v1/replay-requests`
`GET /api/open/v1/replay-requests`
### 16.5 查询补数申请详情
`GET /open/v1/replay-requests/{request_id}`
`GET /api/open/v1/replay-requests/{request_id}`
### 16.6 取消补数申请
`POST /open/v1/replay-requests/{request_id}/cancel`
`POST /api/open/v1/replay-requests/{request_id}/cancel`
### 16.7 审批补数申请
#### 批准
`POST /open/v1/replay-requests/{request_id}/approve`
`POST /api/open/v1/replay-requests/{request_id}/approve`
#### 驳回
`POST /open/v1/replay-requests/{request_id}/reject`
`POST /api/open/v1/replay-requests/{request_id}/reject`
### 16.8 执行补数
`POST /open/v1/replay-requests/{request_id}/execute`
`POST /api/open/v1/replay-requests/{request_id}/execute`
执行方式:
@@ -999,7 +1001,7 @@ X-Nonce
### 17.1 查询链路追踪
`GET /open/v1/traces/{trace_id}`
`GET /api/open/v1/traces/{trace_id}`
返回应包含:
@@ -1014,7 +1016,7 @@ X-Nonce
### 17.2 查询审计日志
`GET /open/v1/audits`
`GET /api/open/v1/audits`
可按以下条件筛选:
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,556 @@
# 多租户多知识空间统一问答平台需求与总体方案
> 版本:v1.0
>
> 日期:2026-07-16
>
> 需求来源:客户关于“多个独立知识库、多个调用端、数据安全与数据库查询”的讨论,以及《物业AI人力资源系统业务需求文档BRD》
>
> 项目归属:《银城员工端 APP 分阶段实施总纲》阶段二的平台化能力
>
> 实施边界:本方案不改变当前阶段一 AI 陪练验收口径,也不把方案评审或演示可用表述为正式试点验收完成。
## 1. 结论摘要
本次需求不是简单的“再建几个知识库”,而是把现有知识问答能力升级为一个可服务多个公司的多租户知识平台:
1. **公司是最高隔离边界。** 银城、美途分别作为独立租户,账号、知识、应用、检索、日志和数据工具默认互不可见。
2. **知识空间是租户内的内容与授权单元。** 同一租户可按业务或受众建立多个知识空间,例如公共制度、物业业务 SOP、管理运营、客户咨询。
3. **调用应用与知识空间是多对多关系。** 一个应用可使用多个空间,一个空间也可供员工端、主管端、管理端等多个应用使用。
4. **用户或角色与知识空间也是独立的多对多关系。** 对内部登录用户,最终可检索范围是“应用获授权空间”与“用户/角色获授权空间”的交集。
5. **所有端复用同一套问答能力和响应契约。** 内部端和外部端因认证边界不同保留两个入口,但共用授权解析、检索、生成、引用和审计服务。
6. **知识文件和实时业务数据分两条链路。** 文件进入 RAG 知识检索;员工训练记录等实时数据只能通过预定义、受控的数据工具读取,不允许模型生成或执行任意 SQL。
7. **第一版不做跨租户共享。** 即使银城与美途存在集团或合作关系,也默认互相不可见;未来共享必须经过明确授权、脱敏、复制或发布流程。
8. **同一原始文件可以属于多个知识空间。** OSS 原文件只保存一份,每个空间保留独立的成员关系、片段和检索权限;解绑某个空间不得影响其他空间。
## 2. 需求背景与讨论解读
客户原始表达包含四层诉求:
- “再加几个独立库”:希望按公司、业务和受众划分可见内容。
- “给别的系统提供接口”:希望名片小程序、员工端、主管端、管理端等多个入口复用问答能力。
- “限定调用哪个库”:希望每个入口只能查询被授权的知识范围。
- “不用担心数据安全、行业问题”:希望通过隔离、权限和受控数据访问降低泄露风险。
其中前三点已经形成明确产品模型,第四点需要更准确地表述:**多知识空间有助于安全,但空间拆分本身不等于安全完成。** 真正的安全控制需要同时覆盖租户、应用、用户/角色、空间、项目/组织范围、数据行列权限、接口认证和审计日志。
客户后续确认“知识空间跟可访问的接口是多对多关系”“好多端需要调用问答”,说明其已理解并确认多端复用和应用—空间多对多这一核心方向。以下细节属于本方案给出的工程化定案:双入口共享服务、授权取交集、外部应用密钥、数据工具白名单、日志最小化和同文件多空间成员模型。
### 2.1 当前确认状态
| 层级 | 已形成的结论 | 当前性质 |
|---|---|---|
| 租户 | 银城、美途分别作为独立租户 | 已确认 |
| 多端 | 名片小程序、员工端、主管端、管理端等多个端需要调用问答 | 已确认 |
| 应用授权 | 调用应用与知识空间建立多对多关系 | 已确认 |
| 跨公司 | 第一版不做跨租户共享 | 已确认 |
| 首批空间 | 银城 3 个、美途 1 个上线,其他空间有内容和负责人后再启用 | 本方案建议,纳入第一版基线 |
| 主体授权 | 内部范围取应用授权与用户/角色授权交集 | 为满足数据安全必须采用的工程规则 |
| 外部认证 | 外部端使用独立应用令牌、内部端沿用登录态,底层共用 query service | 本方案工程定案 |
| 数据查询 | 第一版只开放本人训练概况、团队训练概况两个固定工具 | 本方案建议,纳入第一版基线 |
客户已确认的是产品方向,不等于空间内容清单、具体角色 key、负责人、外部密钥保管和标准题已经完成业务验收;这些仍按第 17 节作为正式试点准入材料。
## 3. 目标与非目标
### 3.1 业务目标
1. 支持银城、美途等多个公司使用同一平台,但数据与权限相互隔离。
2. 支持每个租户按业务、受众和敏感级别建立多个知识空间。
3. 支持多个应用统一调用问答能力,并为每个应用配置可访问空间。
4. 支持内部员工按角色、人员、项目或组织范围取得不同知识权限。
5. 支持答案带来源引用、无依据时明确提示,避免跨空间引用和无依据生成。
6. 支持同一文件一次存储、授权到多个空间,降低重复上传和维护成本。
7. 首版复用银城现有组织、训练与主管数据,提供两个安全的结构化数据查询工具。
8. 提供空间、授权、应用和查询审计的管理能力。
### 3.2 第一版非目标
- 不做跨租户实时检索、集团账号天然读取子公司数据或跨租户联合统计。
- 不做员工个人知识空间;个人 AI 助理继续按独立专项 TechSpec 和计划实施。
- 不接工资、薪酬、银行账户、完整人事档案、财务明细等高敏数据。
- 不接美途订单、客户交易流水或任意业务数据库。
- 不允许自然语言生成 SQL、任意 SQL、任意表名或任意字段查询。
- 不做知识空间之间的自动去重、自动合并或自动同步。
- 不为每个租户单独部署一套应用、MySQL 或 Qdrant;首版采用共享基础设施上的逻辑隔离。
- 不开放浏览器或小程序前端直连平台密钥。
- 不把本方案的完成等同于生产发布或正式试点验收。
## 4. 概念模型
### 4.1 核心对象
| 对象 | 定义 | 第一版示例 |
|---|---|---|
| 租户 Tenant | 公司级最高安全、运营和审计边界 | 银城、美途 |
| 知识空间 Space | 租户内独立的内容集合和授权单元 | 公共制度、物业业务 SOP、美途客户咨询 |
| 调用应用 App | 调用统一问答能力的业务入口 | 员工端、主管端、管理端、名片小程序 |
| 访问主体 Principal | 被授予空间权限的人或角色 | employee、supervisor、finance、指定用户 |
| 文档成员 Attachment | 原始文档在某个空间中的成员关系 | 同一制度文件同时进入公共制度和管理运营 |
| 数据工具 Data Tool | 受控读取实时结构化数据的固定服务 | 我的训练概况、团队训练概况 |
| 查询日志 Query Log | 不保存敏感正文的调用审计记录 | 应用、用户、空间、耗时、结果状态 |
### 4.2 边界层级
```mermaid
flowchart TD
T["租户:公司级隔离"] --> A["调用应用授权"]
T --> P["用户/角色授权"]
T --> S["知识空间"]
A --> X["应用允许的空间集合"]
P --> Y["主体允许的空间集合"]
X --> I["内部最终范围:X 与 Y 的交集"]
Y --> I
S --> I
I --> R["按 tenant_id + knowledge_id 检索"]
R --> O["带引用答案"]
```
租户内的项目、部门、岗位不是新租户,而是组织或数据范围。知识空间负责内容边界,项目/部门范围负责回答“谁能看哪些项目数据”;两者不能互相替代。
### 4.3 授权计算规则
内部登录用户:
```text
effectiveSpaceIds
= tenantSpaceIds
∩ appGrantedSpaceIds
∩ principalGrantedSpaceIds
```
外部匿名应用:
```text
effectiveSpaceIds
= tenantSpaceIds
∩ appGrantedSpaceIds
```
补充规则:
1. 客户端传入 `spaceCodes` 只能缩小服务端算出的范围,不能扩大范围。
2. 明确请求了未授权空间时返回 403,不静默扩大或替换为其他空间。
3. 没有任何有效空间时不执行 MySQL、Qdrant 或 LLM 查询,直接返回无权限。
4. 所有 MySQL 和 Qdrant 查询必须同时带 `tenant_id` 与有效 `knowledge_id` 集合。
5. 管理员拥有“配置空间”的权限,不代表天然拥有“读取全部空间正文”的权限;读取仍按显式授权。
## 5. 租户方案与安全考虑
### 5.1 租户划分
| 租户 | 定位 | 默认策略 |
|---|---|---|
| 银城 | 物业员工、主管、HR、财务和管理层使用的企业内部知识与业务数据 | 只允许银城身份和银城应用访问 |
| 美途 | 客户咨询和后续内部业务知识 | 只允许美途身份和美途应用访问 |
银城、美途即使由同一集团管理,也保持独立租户,原因如下:
1. **法人和责任边界不同。** 两家公司对员工信息、客户信息和经营资料承担不同的数据管理责任。
2. **最小权限。** 集团管理关系不能自动推导出每个账号有权读取所有子公司原文。
3. **降低事故影响面。** 一个租户的密钥泄漏、错误授权或导入失误不能扩大到另一个租户。
4. **便于审计追责。** 每次访问可明确归属到哪个公司、哪个应用和哪个主体。
5. **便于独立运营。** 两家公司可分别配置知识负责人、密钥轮换、限流、下线和数据保留策略。
6. **适应组织变化。** 后续新增公司、独立交付、合同终止或组织调整时,不需要拆分已混合的数据。
第一版跨租户访问固定为默认拒绝。未来如果出现集团共享需求,推荐使用“发布脱敏副本到目标租户”的方式,并保留来源、审批人、版本和撤回记录;不推荐直接让一个租户在线检索另一个租户的原始空间。
## 6. 第一批知识空间建设建议
### 6.1 银城首批上线空间
| 空间名称 | 建议编码 | 内容范围 | 初始使用者/应用 | 第一批状态 |
|---|---|---|---|---|
| 公共制度 | `yc_public_policy` | 公司制度、员工应知、员工权益、行政通知、公开流程 | 员工、主管、HR;员工端和管理端 | 必建、上线 |
| 物业业务 SOP | `yc_property_sop` | 管家、客服、保洁、保安、工程、收费等岗位流程与标准 | 员工、主管、培训/品质;员工端、主管端、管理端 | 必建、上线 |
| 管理运营 | `yc_management_ops` | 项目管理、巡检、培训、品质、复盘、团队管理方法 | 主管、项目经理、HR/培训/品质;主管端和管理端 | 必建、上线 |
| 财务专业 | `yc_finance_professional` | 财务制度、预算规则、报销和结算规范 | 财务角色;管理端 | 有真实内容和负责人后启用 |
| 经营决策 | `yc_business_decision` | 经营分析口径、管理报告、决策参考 | 高管及明确授权人员;管理端 | 有脱敏规则和负责人后启用 |
首批业务验收以前三个上线空间为准。财务专业、经营决策不是把同一批普通制度换个名字重复入库;只有在内容清单、负责人、密级和角色授权同时明确后才启用。
### 6.2 美途首批上线空间
| 空间名称 | 建议编码 | 内容范围 | 初始使用者/应用 | 第一批状态 |
|---|---|---|---|---|
| 美途客户咨询 | `mt_customer_service` | 服务介绍、常见问题、业务流程、公开价格口径、客户沟通话术 | 名片小程序;后续客服工作台 | 必建、上线 |
| 美途内部工作 | `mt_internal_work` | 内部流程、员工工作指引 | 美途内部员工应用 | 第一版不建 |
| 美途管理 | `mt_management` | 经营和团队管理资料 | 主管/管理层 | 第一版不建 |
| 美途财务 | `mt_finance` | 财务制度和内部财务资料 | 财务角色 | 第一版不建 |
美途客户咨询空间只能放可对外回答的内容。内部制度、客户隐私、合同原件、交易明细不得通过“同一问题看起来相近”而混入该空间。
### 6.3 角色与空间建议
| 主体 | 默认可读空间 | 附加限制 |
|---|---|---|
| 银城普通员工 | 公共制度 + 与岗位相关的物业业务 SOP | 项目相关内容按本人项目范围过滤 |
| 银城主管/项目经理 | 公共制度 + 物业业务 SOP + 管理运营 | 团队数据限本人管理范围 |
| HR/培训/品质 | 公共制度 + 物业业务 SOP + 管理运营 | 仅限职能授权范围,不能天然读取财务或经营原文 |
| 财务 | 公共制度 + 财务专业 | 财务空间启用后显式授予 |
| 高管 | 公共制度 + 管理运营 + 经营决策 | 默认看汇总;原始明细仍需单独授权 |
| 美途名片小程序 | 美途客户咨询 | 外部匿名应用,无用户角色扩权能力 |
这些是默认授权模板,不代替业务负责人对具体人员、岗位和项目范围的确认。
### 6.4 内容治理要求
每个上线空间必须具备:
- 一名业务负责人和一名内容维护人;
- 明确的内容准入范围与禁止内容;
- 初始文件清单和版本日期;
- 密级:`PUBLIC`、`INTERNAL`、`CONFIDENTIAL` 三选一;
- 适用角色、应用和项目范围;
- 更新周期和失效内容处理规则;
- 至少 10 个标准问题及预期引用,用于上线前验证。
## 7. 统一问答能力
### 7.1 入口与复用方式
| 场景 | API | 认证 | 说明 |
|---|---|---|---|
| 内部员工端、主管端、管理端 | `POST /api/knowledge/query` | 现有 Sa-Token 登录态 | 解析租户、用户、角色、`clientKey` 和项目范围 |
| 美途名片小程序等外部应用 | `POST /api/open/knowledge/query` | Bearer 应用令牌 | 只使用应用授权空间,不接受用户或角色扩权 |
两个入口共用 `AihrKnowledgeQueryService`,因此“统一接口”的准确含义是:统一请求/响应契约和统一业务能力,而不是强行让内部用户登录令牌与外部应用密钥共用一个认证入口。
### 7.2 请求契约
```json
{
"queryText": "装修施工人员进入小区需要什么手续?",
"spaceCodes": ["yc_property_sop"],
"category": "sop",
"position": "生活顾问",
"source": "mobile_uni_sop",
"limit": 5,
"toolCode": null
}
```
约束:
- `queryText` 必填,去首尾空白后 1–1000 字。
- `spaceCodes` 可不传;不传表示在有效授权范围内检索,传入表示进一步收窄。
- `limit` 默认 5,范围 1–10。
- `toolCode` 为空时执行知识问答;传入时只允许第一版白名单工具。
- `category/position/source` 保留兼容和分析用途,不能决定或扩大授权空间。
### 7.3 响应契约
```json
{
"requestId": "01JZZ...",
"queryText": "装修施工人员进入小区需要什么手续?",
"answer": "根据《装修人员进场管理 SOP》……",
"citations": [
{
"spaceCode": "yc_property_sop",
"sourceType": "DOCUMENT",
"docId": "doc_123",
"title": "装修人员进场管理 SOP",
"snippet": "施工人员进场前应完成……",
"fragmentId": 456
}
],
"usedSpaceCodes": ["yc_property_sop"],
"noEvidence": false,
"promptVersion": "knowledge-query-v1",
"legacy": {
"reference": "装修人员进场管理 SOP",
"docs": [],
"snippets": []
}
}
```
响应要求:
1. 每条文档结论必须能定位到被授权空间的引用。
2. 没有足够依据时返回 `noEvidence=true` 和明确提示,不用其他租户、其他空间或模型常识补齐公司规则。
3. 数据工具结果的 `sourceType` 为 `DATA_TOOL`,引用工具编码和统计窗口,不伪装成文档片段。
4. `requestId` 贯穿认证、授权、检索、LLM 和审计日志。
### 7.4 查询处理流程
```text
认证内部会话或外部应用令牌
→ 锁定 tenantId 与 appId
→ 内部用户解析角色、组织、项目范围
→ 计算有效知识空间集合
→ 校验请求是否仅收窄范围
→ 知识问答:MySQL Fulltext + Qdrant 混合召回
→ 数据工具:调用固定 service,并执行本人/团队范围检查
→ Rerank(可用时)
→ LLM 仅使用已授权证据生成答案
→ 返回引用与无依据标记
→ 写入最小化查询日志
```
### 7.5 现有接口兼容
现有 `POST /api/knowledge/search` 暂保留,作为兼容包装器转发到新查询服务。必须修正现有 `category=sop` 可能变成租户内全库检索的行为:兼容请求只能映射到当前主体已获授权的银城物业业务 SOP 等空间,不能将空分类当作“搜索全部空间”。
## 8. 实时数据库查询方案
### 8.1 为什么不能把数据库直接当知识库
文档知识适合切片、向量检索和引用;训练记录、人员状态等实时结构化数据具有强身份、行权限和时效要求。如果让模型直接访问数据库或生成 SQL,空间授权无法阻止它读取错误的表、行或字段,也无法稳定审计查询目的。
因此第一版采用“数据工具”模式:每个工具有固定编码、固定参数、固定 service、固定权限和固定返回字段。
### 8.2 第一版数据工具
| 工具编码 | 用途 | 数据来源 | 权限 |
|---|---|---|---|
| `MY_PRACTICE_SUMMARY` | 查询本人指定窗口内的训练次数、最近训练和能力摘要 | 复用 `AihrMobileSeedService.practiceHistory(extPartyId)` | 仅本人;服务端从登录态取身份 |
| `TEAM_PRACTICE_SUMMARY` | 查询本人管理团队的完训、待复盘和汇总 | 复用 `AihrMobileSeedService.practiceTeam(supervisorExtPartyId)` | 仅主管;服务端解析主管范围 |
第一版由客户端快捷入口显式传 `toolCode`。不从任意自然语言自动决定并执行数据库查询,不接工资、财务、美途订单或其他任意表。
### 8.3 工具安全规则
1. 请求体不接受 `tenantId`、`userId`、`extPartyId`、`supervisorExtPartyId`。
2. 身份和数据范围只从服务端登录态与组织快照取得。
3. 工具返回 DTO,不返回数据库字段全集、SQL、堆栈或内部主键集合。
4. 外部 API_TOKEN 应用第一版不得调用任何数据工具。
5. 工具失败不回退到模型猜测或 seed 假数据。
6. 审计日志记录工具编码、窗口和结果状态,不记录个人训练原文。
## 9. 数据模型
### 9.1 复用 `aihr_knowledge_info` 作为知识空间
在现有表上新增:
| 字段 | 类型 | 说明 |
|---|---|---|
| `code` | varchar(100) | 租户内稳定编码,`UNIQUE(tenant_id, code)` |
| `space_type` | varchar(30) | `BUSINESS` / `MANAGEMENT` / `PUBLIC` / `EXTERNAL` |
| `sensitivity_level` | varchar(30) | `PUBLIC` / `INTERNAL` / `CONFIDENTIAL` |
| `status` | varchar(20) | `DRAFT` / `ACTIVE` / `DISABLED` |
继续复用原有 `tenant_id`、`name`、设置与片段关系。客户端和授权表使用稳定 `code`,不再以可修改的中文名称作为接口主键。
### 9.2 `aihr_knowledge_space_grant`
| 字段 | 说明 |
|---|---|
| `id/tenant_id/knowledge_id` | 主键、租户和空间 |
| `principal_type` | `ROLE` 或 `USER` |
| `principal_value` | 角色 key 或用户 ID 字符串 |
| `permission` | `READ` 或 `MANAGE` |
| `status` | `ACTIVE` / `DISABLED` |
| `create_by/create_time/update_by/update_time` | 审计字段 |
唯一约束:`(tenant_id, knowledge_id, principal_type, principal_value, permission)`。
### 9.3 `aihr_knowledge_app`
| 字段 | 说明 |
|---|---|
| `id/tenant_id` | 应用主键和所属租户 |
| `app_code` | 全局唯一、稳定编码 |
| `app_name` | 应用名称 |
| `auth_type` | `SESSION` 或 `API_TOKEN` |
| `internal_client_key` | 内部端对应现有 `LoginUser.clientKey`,外部端为空 |
| `token_hash` | 外部应用完整令牌的 SHA-256,仅保存摘要 |
| `status` | `ACTIVE` / `DISABLED` |
| `rate_limit_per_minute` | 应用级动态限流 |
| `expires_time` | 令牌到期时间,可空 |
| 审计字段 | 创建、更新、轮换人员和时间 |
应用令牌建议格式为 `ak_<appCode>_<32字节随机值>`。明文仅在创建或轮换成功后显示一次,服务端只保存完整令牌 SHA-256,并使用常量时间比较。令牌只能保存在美途小程序云函数或业务后端,不能写进小程序包或浏览器 JavaScript。
### 9.4 `aihr_knowledge_app_space`
字段:`id/tenant_id/app_id/knowledge_id/create_by/create_time`。唯一约束:`(tenant_id, app_id, knowledge_id)`。应用和空间必须属于同一租户,服务端在写入时双重校验。
### 9.5 `aihr_knowledge_query_log`
保存:`request_id`、`tenant_id`、`app_id`、内部用户 ID(可空)、问题摘要哈希、使用空间编码、来源类型、结果状态、耗时、模型和 prompt 版本、创建时间。
默认不保存完整问题、完整答案、训练明细和文档正文。业务若以后要求质检原文,必须另行确定脱敏、权限和保存期限,不能直接扩大本表。
### 9.6 同一文件属于多个空间
第一版不新增抽象的文档—空间关系表,直接复用 `aihr_knowledge_attach` 作为空间成员关系:
- 同一 OSS 原文件可以对应多条 attach 记录;每条记录属于一个 `knowledge_id`。
- 同一空间内同名约束继续由 `(knowledge_id, name)` 保证。
- 不同空间的 attach 可复用相同 `oss_id`,但使用各自 `doc_id`/片段/权限。
- 解除某空间成员关系时,仅删除该空间的 attach、fragment 和 Qdrant points。
- 只有不存在其他 attach 引用同一 `oss_id` 时,才允许删除原始 OSS 对象。
- 脱敏、改写或裁剪后的版本视为新文件、新 hash 和新版本,不能假装与原文件完全相同。
异步上传队列增加 `space_codes_json`,支持一次上传选择多个目标空间。解析和 embedding 只调用一次,生成结果再分别持久化到各空间,避免重复付费调用模型。
## 10. 应用、角色与身份解析
### 10.1 内部应用
现有 `sys_client` 和 `LoginUser.clientKey` 用于识别内部调用端。新增 `aihr_knowledge_app` 保存与知识平台有关的应用策略,例如:
| app_code | auth_type | internal_client_key | 场景 |
|---|---|---|---|
| `yc_admin` | SESSION | `pc` | 银城管理端 |
| `yc_mobile` | SESSION | `app` | 银城员工/主管端 |
| `mt_card_miniapp` | API_TOKEN | 空 | 美途名片小程序后端 |
同一 `clientKey` 若在不同租户使用,按 `tenant_id + internal_client_key` 解析,不能跨租户命中应用。
### 10.2 内部主体
- `SYS_USER`:从 `LoginUser.rolePermission` 解析角色授权。
- `APP_USER`:从组织快照和岗位级别解析业务角色;普通人员至少映射 `employee`,主管/项目负责人映射 `supervisor`。
- 用户级授权:按服务端登录用户 ID 叠加,但仍受应用授权限制。
- 项目范围:继续复用组织同步数据,不接受客户端自报项目编码扩权。
## 11. 检索与向量隔离
### 11.1 MySQL Fulltext
所有召回 SQL 必须包含:
```sql
WHERE f.tenant_id = :tenantId
AND f.knowledge_id IN (:effectiveKnowledgeIds)
```
禁止继续只用知识库中文名称或空分类控制范围。
### 11.2 Qdrant
第一版继续使用共享 collection `aihr_knowledge`,payload 已包含 `tenant_id` 和 `knowledge_id`。查询过滤固定为:
```text
must:
tenant_id == currentTenantId
knowledge_id match any effectiveKnowledgeIds
```
如果 Qdrant 客户端尚不支持 `match.any`,先实现该过滤结构;不得为了省事去掉 `knowledge_id` 条件。应用请求不触发跨 collection 或跨租户合并。
### 11.3 生成约束
- LLM 输入仅包含已授权、重排后的证据。
- system prompt 明确公司制度类问题不得依靠模型常识补齐。
- 引用结果在返回前再次核对 `tenant_id + knowledge_id`。
- 外部应用使用专用 prompt,禁止输出内部操作说明、内部人员信息或“可能存在”的内部内容。
## 12. 管理端方案
新增管理页面 `/knowledge/spaces`,菜单名“知识空间”,包含三个页签:
1. **知识空间**:查看、创建、编辑、启停;显示租户、编码、密级、文档数、片段数、负责人和状态。
2. **空间授权**:按角色或指定用户配置 READ/MANAGE,展示实际生效范围。
3. **调用应用**:创建内部/外部应用、绑定空间、配置限流、轮换或停用令牌;明文令牌只显示一次。
现有 SOP 知识库页和资料处理页改为以空间为目标:
- 搜索时使用服务端授权范围,可选择授权内空间做收窄。
- 同步单文件上传可选择一个或多个空间。
- 异步批量上传记录保存目标空间集合。
- 管理端不得仅靠隐藏下拉选项实现权限;服务端必须重新校验 MANAGE 权限。
移动端不暴露任意空间选择器,避免用户误认为“看见空间名称就有权限”。页面继续以“问师傅”等业务语言呈现,空间选择由服务端按应用、角色和岗位自动计算。
## 13. 外部应用安全
1. 外部接口必须使用 HTTPS。
2. Bearer 令牌只能由服务端、云函数或可信后端持有。
3. 每个应用独立令牌、独立授权空间、独立限流和独立停用开关。
4. 使用现有 Redis 限流能力按 `appId` 控制每分钟请求数;超限返回 429。
5. 认证失败统一返回 401,不泄露 appCode 是否存在、令牌是否过期等内部细节。
6. 停用或到期应用不得检索、调用 LLM 或数据工具。
7. 轮换令牌生成新摘要并使旧令牌立即失效;第一版不保留双令牌宽限期。
8. 外部响应不返回 OSS 原始地址、内部用户 ID、数据库主键或管理字段。
9. 对外客户咨询设置长度限制、超时、并发、敏感词和输出脱敏。
## 14. 审计、监控与运维
### 14.1 必备指标
- 按租户、应用统计请求量、成功率、无依据率、P50/P95 延迟。
- 按知识空间统计命中量、零命中问题和引用分布。
- 按错误类型统计认证失败、无权限、限流、检索失败、模型失败。
- 跟踪外部应用令牌到期时间和最近使用时间。
- 跟踪同一文件多空间成员数和孤立 OSS 数量。
### 14.2 安全审计事件
- 应用创建、令牌创建/轮换/停用;
- 空间创建、启停、密级变化;
- 应用—空间和主体—空间授权变化;
- 明确请求未授权空间;
- 数据工具调用和拒绝;
- 跨租户 ID 组合、无有效空间仍尝试查询等异常。
## 15. 验收标准
### 15.1 功能验收
1. 银城、美途各自登录或调用时,只能列出本租户空间和应用。
2. 银城首批三个空间、美途客户咨询空间均有唯一编码、负责人、授权和验证题单。
3. 一个内部应用可绑定多个空间;一个空间可同时绑定多个内部应用。
4. 内部用户的最终范围严格等于应用授权与主体授权交集。
5. 美途名片小程序只能命中 `mt_customer_service`,不能访问银城或美途内部预留空间。
6. 显式传未授权 `spaceCodes` 返回 403;不传时只在有效空间内查询。
7. 回答包含空间编码和文档引用;无证据时返回 `noEvidence=true`。
8. 同一文件加入两个空间后,两边均能独立检索;从一个空间解绑不影响另一个空间和 OSS 原文件。
9. 本人训练工具不能查询他人;主管工具只能返回本人管理范围;外部应用调用工具被拒绝。
10. 原 `/api/knowledge/search` 兼容现有员工端,但不再因 `category=sop` 搜索租户全部空间。
### 15.2 安全验收
至少覆盖以下自动化和真实 API 反例:
| 测试 | 预期 |
|---|---|
| 银城 token + 美途 spaceCode | 403,MySQL/Qdrant/LLM 均未执行 |
| 美途 app token + 银城 spaceCode | 403 |
| 员工端 app 已授权、用户角色未授权 | 403 或空有效范围 |
| 用户已授权、当前 app 未授权 | 403 或空有效范围 |
| 禁用/过期/错误 app token | 401 |
| 超过应用限流 | 429 |
| APP_USER 请求其他 extPartyId | 服务端忽略请求值并按本人身份处理 |
| 普通员工调用团队训练工具 | 403 |
| 外部应用调用任一数据工具 | 403 |
| 删除一个空间的文件成员关系 | 其他空间仍可检索,OSS 不被删除 |
### 15.3 交付成熟度
验收结论必须分开记录:
- **开发完成**:代码、迁移、自动化测试和构建通过。
- **联调可用**:银城内部端与美途测试应用完成真实 HTTP 联调。
- **线上生效**:生产迁移、配置、部署、健康检查和回归完成。
- **正式试点验收**:业务负责人确认内容清单、授权矩阵、标准题命中、日志和运营指标。
任一前置层完成都不能替代后续层。
## 16. 发布与迁移策略
1. 先上线 schema 与后端兼容层,默认不开启任何外部应用。
2. 为现有细粒度 SOP 知识库补齐 `legacy_*` 稳定编码,先保留为回滚基线,不直接把“投诉处理 SOP”等旧库改名冒充新的“物业业务 SOP”空间。
3. 创建银城三个空间和美途客户咨询空间,按业务确认后的源文件清单重新导入或复用 OSS 成员关系;迁移前后核对 attach、fragment 和 Qdrant payload 数量。新空间验证通过前保持调用应用禁用,验证通过后再停用不再使用的 legacy 空间。
4. 配置内部应用、角色授权并做反向越权测试。
5. 切换管理端和移动端到新 `/query`,原 `/search` 保持兼容。
6. 为美途创建测试 API_TOKEN,在云函数/后端保存,完成限流和错误令牌测试。
7. 观察无依据率、跨空间拒绝、模型错误和 P95 延迟后,再启用生产外部应用。
8. 发布失败时先停用对应 `aihr_knowledge_app`,内部兼容接口可继续服务;数据库迁移只做前向修复,不破坏已有文档和片段。
## 17. 业务上线前必须提交的材料
以下不是系统设计缺口,而是正式试点必须由业务侧提交的准入材料:
1. 四个首批上线空间的负责人、维护人和审批人名单。
2. 每个空间的初始文件清单、版本日期、密级和禁止内容清单。
3. 银城角色—空间—应用授权矩阵,并确认主管、HR/培训/品质、高管的具体角色 key。
4. 美途名片小程序的可信服务端或云函数部署位置、密钥保管人和轮换责任人。
5. 每个空间至少 10 个标准问题、预期答案要点和预期引用。
6. 查询日志保留周期、外部接口日调用量预估和每分钟限流值。
在这些材料缺失时,可以完成开发和联调,但不能宣布正式试点验收完成。
@@ -0,0 +1,128 @@
# 下一步工作计划(BRD 对齐版)
> 版本:v2.1(2026-07-15 二次修订:发布前只跑本地预检、remote match+schema 移到发布后;案例底线补齐算术;CER 阈值归 B4 确认;B7 按生产实测字段改写)
> 基准:《物业AI人力资源系统业务需求文档BRD.md》v1.2(唯一事实源)
> 阶段边界:《银城员工端APP分阶段实施总纲.md》阶段一(陪练)+ 2026-07-08《数字师傅学练问报整合方案》定案
> 现状证据:《BRD_IMPLEMENTATION_AUDIT.md》2026-07-15 最新条目 + 本日生产只读复核
> 时间锚点:半年会产品发布(须带一线真实使用数据)→ 2026-09 收费季前试点可用
---
## 0. 当前基线(2026-07-15 生产实测)
**已完成**(不再列入待办):
- 生产已发布至 `eacf1a0a` 批次并有后续静态增量,线上 H5 = `index-rPeDLbpR.js`;发布预检通过资源/后端哈希与健康检查。
- 生产 schema **16/16 齐备**,内置 Prompt **6/6**,生活顾问启用场景 **14 条**(含服务推介/增值 1、日常服务 1)。
- **组织同步已线上闭环**:开放平台拉取公司 17 / 部门 963 / 员工 3417;`aihr_org_snapshot` 3417 行,手机号可映射 **3392**,在职 2943。主管身份与项目数据权限的数据基础已就位。
**真实缺口**(本计划的全部工作对象):
- 正式试点证据全部为 0:评分校准 0/20、SOP 人工评审 0/14、案例 0/20、满意度 0、候选资料 0(L1-B/C/D)。
- SOP 文档仅 3/5,缺服务推介/增值与日常服务两类的真实业务内容确认(4.3.4、L1-B)。
- 方言 ASR 零实测(9.1 MVP 阻塞项、L1-C ≤5s)。
- 仓库有 17 个已跟踪修改 + 2 个未跟踪文件未收拢,发布预检拒绝任何脏工作区,当前修复批次无法发布。
- 25 名员工手机号不可用(上游数据问题,不阻塞,需反馈开放平台)。
- PII 出境条款、成本计量契约、HR 学分规则等外部输入未闭合(G3/G6、4.5)。
**结论:最大阻塞已从"发布与组织数据"转移到"试点圈定(B3)与内容/评审样本"。** 所有新增页面/功能默认冻结(守 MVP 切割线,BRD 附录 C 头号风险 = 范围失控)。
---
## 1. 主线 A:锁定发布批次,原子发布(本周内)
目标:把 `eacf1a0a` 之后累积的修复(G3 脱敏补强、案例音频收紧、岗位-SOP 收口等)作为一个命名 release batch 发布,线上 = release commit。
| # | 任务 | 依据 | 完成定义 | 期限 |
|---|---|---|---|---|
| A1 | 收拢工作区:对当前 17 个已跟踪修改按内容分批提交(后端服务/测试、文档、前端各一批),2 个未跟踪文件(本计划、`processing-import-ui.test.sh`)一并提交或显式移出;形成命名 release commit | `release-preflight.sh` 拒绝任何脏工作区 | `git status --porcelain` 为空;release commit 落字 | 07-16 |
| A2 | 确定发布窗口 + 备份/回滚责任人 | 12.1、Runbook 前置条件 1 | 窗口时间、执行人、回滚人三项落字 | 07-16 |
| A3 | **一次原子切换**:锁定提交 → 干净 worktree 构建三端 → **本地预检**(`release-preflight.sh` 不带 remote 开关;发布前线上还是旧版本,remote match 必然失败)→ DB/静态资源/后端备份 → 同步静态资源与后端、重启。**当前批次未包含 SQL 迁移;若收拢后出现新迁移,从本批次拆出并按 Runbook 单独执行** | 6.3、L1-C、preflight 脚本 71–72 行开关耦合 | 本地预检通过 → 发布完成;任一步失败按备份回滚,当天不重试第二次 | 07-17 |
| A4 | **发布后远端复检与回归**:`RELEASE_REMOTE_URL=https://peilian.njzhmj.top RELEASE_VERIFY_REMOTE_MATCH=true RELEASE_VERIFY_REMOTE_BACKEND=true RELEASE_VERIFY_REMOTE_SCHEMA=true ./scripts/release-preflight.sh`(此时线上=本地构建,match 可通过)+ 认证态浏览器回归(员工/主管/管理端各 1 条路径,正式 OTP)+ 非 strict `./scripts/demo-check.sh` 输出数据现状(**strict 门禁留到 B3 窗口确定后**,strict 模式强制要求 `AIHR_PILOT_START_DATE/END_DATE`) | 10.2、`demo-check.sh` 参数约束 | 远端静态资源、后端 hash 与 schema 复检通过;三端认证态回归留证;数据缺口清单留档审计记录 | 07-17 |
---
## 2. 主线 B:外部输入催办清单(今天发出,B3 为最大阻塞)
每项需在发出时填负责人与回复期限;到兜底触发日仍无答复即升级 HR 负责人(BRD 第 13 章"集成负责人指派"至今未闭合)。
| # | 需要的输入 | 提供方 | 负责人 | 回复期限 | 兜底触发日 | 阻塞的 BRD 条款 | 不给的后果 |
|---|---|---|---|---|---|---|---|
| B3 | **试点项目圈定(1–2 个住宅项目)+ 窗口起止日期 + ≥20 名员工名单**(组织数据已就位,可直接从 3392 条手机号映射中圈人) | HR 负责人 | 待指派 | 07-18 | 07-22 | 10.2-D | M5 全部指标无分母;半年会没有"真实使用数据" |
| B2 | 补 2 份真实 SOP 文档(现 3/5),并由业务确认全部五类核心流程的成功条件、价格/取消规则、回访口径;随后完成 14 条场景/SOP 的人工评审(现 0/14) | 内容负责人/HR | 待指派 | 07-20 | 07-24 | 4.3.4、L1-B(SOP≥5) | SOP 覆盖与 RAG 可用率(≥80%)无法验收 |
| B9 | **历史案例批量提供**:试点前 **≥20 条**历史案例语音/材料入库并脱敏审核,不依赖试点新增量补齐验收底线;试点期继续按"每周每项目 1 条"采集新案例 | 各项目负责人 | 待指派 | 07-22 | 07-25 | 4.6、L1-B(案例≥20) | 案例库验收必然失败 |
| B4 | 方言 ASR 厂商选型(**阶段一只选 1 种方言**,按试点区域确认;BRD 9.1 只要求 1 条路径)+ 费用授权 + **同时确认 CER 达标阈值**(BRD 只定了 ≤5s 响应,识别准确率的验收线需业务拍板,否则 C3 实测无法判定"达标") | 技术组+HR | 待指派 | 07-20 | 07-24 | 4.3.3、9.1、L1-C | MVP 阻塞项零实测,且测了也无法判定通过 |
| B5 | 案例讲解视频预渲染样片 1 条(半年会素材;**不阻塞案例上传闭环验收**——L0-4 只要求"语音上传→AI 整理") | 业务 | 待指派 | 07-31 | 08-05 | 4.6、9.1 | 半年会演示缺 1 条示范视频(止损线内最低配置) |
| B6 | 大模型/ASR/TTS 供应商 PII 留存与跨境条款确认(音频本体、图片本体外发部分) | 法务/安全 | 待指派 | 07-24 | 07-31 | G3、G6、F3 | 生产前闸门无法关闭 |
| B7 | 组织快照最小字段清单与保留期:生产实测姓名 0、部门 0(展示字段默认关已生效),但 `project_name` 仍保留 3417 行;需法务/安全核对 `project_name`、`person_phone` 等仍保留字段是否在最小清单内,及历史清理范围 | 法务/安全 | 待指派 | 07-24 | 07-31 | 5.4(只存 party_id 硬约束) | P0 存储边界无法关闭 |
| B8 | 认证等级/学分规则契约(初/中/高级条件、学分来源与分值、防刷) | HR | 待指派 | 07-31 | 08-07 | 4.5、10.2-A | 成长页只能继续挂"规则待配置、不生效" |
| B10 | 25 名员工手机号不可用 → 反馈开放平台修数(低优先级,不阻塞) | 开放平台 | 待指派 | 07-31 | — | 5.4 | 25 人无法登录 APP |
追办顺序:**B3 → B9 → B2 → B4**,其余并行。
---
## 3. 主线 C:工程收尾(小、快、不开新战线)
| # | 任务 | 依据 | 完成定义 | 期限 |
|---|---|---|---|---|
| C1 | "问师傅"文案对齐:`pages/user/today/index.vue` 的"语音提问,快速解答"**直接改为符合现状的文字**(语音问答入 backlog,届时复用 `speech.ts` + `/api/ai/asr`,不新增接口) | 4.7、2026-07-15 审计 | 首页承诺与 SOP 页能力一致 | 07-16(随 A1 批次发布) |
| C2 | 主管身份与项目数据权限验收:组织数据已就位,用正式主管账号认证态验证——本项目团队可见、跨项目不可见、训练记录/待复盘按项目过滤 | 5.4、G3、L1-B | 认证态回归留证写入审计记录 | 07-18 |
| C3 | 方言实测(B4 选型后):**1 种方言**,固定样本集(≥20 条真实短音频),记录字错率(CER)与单轮响应 P95(≤5s,L1-C);CER 与 B4 确认的阈值比对——**阈值未确认前只记录数据、不判定达标** | 4.3.3、9.1、L1-C | 样本数、CER、P95 三项数据落审计记录;CER ≤ B4 阈值且 P95 ≤5s 才在验收表标"通过" | B4+3 天 |
| C4 | LLM/ASR/TTS 调用计量:待 B6/财务给出计费字段与单价后,新增租户范围 `llm_call_log`(模块/模型/token/延迟/费用)+ 月度上限告警与自动降级;此前维持手动断路器,不硬编码价格 | 6.3、G6 | 有持久化计量与可配置上限 | B6 后一周内 |
| C5 | 案例入库流水线支援 B9:批量导入入口复用现有上传/整理/筛选链路,脱敏门禁逐条通过;不为批量导入新做页面 | 4.6、L1-B | ≥20 条历史案例状态"已入库"且脱敏扫描 0 命中 | 07-25 |
---
## 4. 主线 D:正式试点与 L1 验收(B3 就位后启动,目标 8 月中出证据包)
按 BRD 10.2 四组验收逐项闭合,全部以严格门禁 + 正式窗口数据为准,**禁止 seed/烟测/演示账号冒充**(审计第 5 节完成定义)。
| 周次 | 动作 | 闭合的验收项 |
|---|---|---|
| 试点第 0 周(预备) | 试点名单在组织快照中逐一核对(手机号可登录);SOP 5 流程入库 + 14 条评审完成(B2);**历史案例 ≥20 条入库审核完成(B9/C5)**;员工开通与培训动员(配 G4 激励沟通) | L1-B:SOP≥5、组织导入、项目级权限 |
| 试点第 1–2 周 | ≥20 名员工真实对练(人均目标 10 次);每日一练推送;主管完成复盘与派发闭环;同步采集满意度(1–5 分);案例按"每周每项目 1 条"继续新增 | L1-A 育闭环;L1-D 人均次数/完训率/满意度 |
| 试点第 2 周起 | 人工校准 ≥20 条,计算 AI/人工分档一致率(目标 ≥70%);统计 RAG 可用回答率(目标 ≥80%);抽查人工复核可否决 AI 分的证据(G1/G2) | L1-C 一致率/可用率;G1/G2 |
| 试点收口 | 案例库 ≥20 条(存量+增量,脱敏门禁通过);`GET /api/train/practice/export` 按窗口导出正式 CSV;以试点窗口日期跑 `AIHR_PILOT_STRICT=true AIHR_PILOT_START_DATE=<起> AIHR_PILOT_END_DATE=<止> ./scripts/demo-check.sh` 全绿;形成 L1 验收证据包 | L1 全项;半年会"真实使用数据" |
**半年会演示止损线**(07-08 定案):只保「生活顾问的一天」主线,实操**问 + 练**两个模块;陪练 + 总结卡 + 1 条示范视频为最低配置,其余全部可砍。
---
## 5. 明确不做(守边界,防范围失控)
| 项 | 依据 |
|---|---|
| 个人 AI 助理/个人知识空间(文字/图片/文件/链接收藏、混合问答、PPT) | BRD 4.8 明确阶段二;有独立 TechSpec 与推进计划 |
| 员工端图片/视频训练输入(4.3.3 终态缺口) | 《AI陪练二期开发推进计划》约定文本场景稳定后独立评估;届时只落有业务目的的场景(拍照报修、品检) |
| 开放问题榜、积分/排行榜/荣誉墙运营化 | 总纲阶段二;07-08 定案排行榜默认关 |
| 师徒关系/拜师池/带徒福利 | 业务已否决(07-08) |
| G5 情绪树洞 | 业务/法务/安全决策未定,在匿名边界与零落库合同明确前保持未实现,不用陪练情绪数据冒充 |
| 企微/钉钉/工单集成、SSO、知识图谱、多项目类型 | D2/D4/D8 既定决策不变 |
---
## 6. 里程碑总览
```
07-15(今日) B 催办清单发出(B3 置顶) + C1 文案修改
07-16 A1 收拢工作区成 release commit + A2 发布窗口落字
07-17 A3 原子发布(预检→备份→切换→回归) + A4 结构回归与数据缺口留档
07-18 C2 主管身份/项目权限认证态验收(组织数据已就位,不依赖外部)
07-18~07-25 B2 SOP 补齐与评审 / B9+C5 历史案例 ≥20 条入库 / C3 方言实测(依赖 B4)
07-28~08-08 D 试点窗口(1–2 项目、≥20 人、2 周;以 B3 实际答复为准)
08-11~08-15 L1 证据包收口:strict 门禁全绿(带试点窗口日期)+ CSV 导出
半年会前 「生活顾问的一天」演示彩排 ×2 + 录屏兜底(沿用 BRD 11.2 彩排纪律)
2026-09 前 收费季试点可用状态确认
```
## 7. 风险与止损
1. **B3 试点圈定拖延是当前最大单点风险**(组织数据已就位,决策成本已最低):07-22 仍无答复,升级 HR 负责人;试点每晚一周,半年会"真实使用数据"窗口就少一周。
2. **案例 20 条**:依赖 B9 存量导入;若试点前不足 20 条,立即提高采集频率(每项目每周 2–3 条)并如实下调收口预期,不用未脱敏或演示数据凑数。
3. **发布失败**:A3 原子流程任一步失败即按备份回滚,当天不重试第二次,先归因。
4. **范围失控**(BRD 附录 C 头号风险):任何新页面/新功能请求一律进 `docs/BACKLOG.md`;每周对照本计划复盘一次偏差。
5. **方言不达标**:若 CER/P95 不达标,按 BRD 9.2 止损——保"1 条方言路径可演示",验收表如实标注差距,不虚标通过。
6. **计划保鲜**:《BRD_IMPLEMENTATION_AUDIT.md》条目非严格时序,引用前须以"生产只读复核 + 线上实测"确认基线;本计划每次执行前先校验第 0 节事实是否仍成立。
---
*本计划由工程侧起草,v2.1 已按 Codex 审查修订;B 表负责人/期限需业务方确认后生效。执行进展回写《BRD_IMPLEMENTATION_AUDIT.md》,本文件只改计划不记证据。*
@@ -0,0 +1,201 @@
# 员工端版本功能对比与功能对齐清单
> 日期:2026-07-17
> 范围:截至 2026-07-17 09:46 收到的客户反馈,重点比较历史可运行移动端、历史需求/设计、当前 `mobile-uni` 实现和本地待发布修复。
> 重要边界:本清单核对的是仓库源码和项目文档,不等同于线上生产版本验收。本轮未重新核验线上 H5,因此“当前实现”不能直接表述为“线上已生效”。
>
> Figma 需求覆盖专项审计见:[FIGMA需求覆盖与版本偏差审计-20260717.md](FIGMA需求覆盖与版本偏差审计-20260717.md)。该审计确认:Figma 只能作为视觉与交互事实源,不能单独替代功能需求和阶段边界。
## 1. 先给结论
客户所说的“主要功能被删完了”不能原样认定为事实,但反映了真实的版本连续性问题。当前反馈实际混合了四类情况:
1. **确认回退**:历史可运行移动端确实有、切换到 `mobile-uni` 后缺失或弱化,例如“问师傅”语音提问、SOP 回答和总结卡语音播报。
2. **历史规划未完成**:需求文档或 Figma 已设计,但没有证据证明曾形成可运行版本,例如开放问题榜/有奖问答、完整课程考试、主管批量派发等。
3. **新增或扩大范围**:本轮才明确增加,例如“问 AI(全网)”、总结卡下载图片、生成题目与点评逐条播报、主管一键切换学员身份。
4. **正确收口或体验缺陷**:岗位不应由员工随意切换,这是权限纠正,不是删功能;“提交没反应”“录音归属错误”“快捷问题错位”属于缺陷,不应包装成功能调整。
因此,后续不能再用“旧版/新版”两个模糊概念沟通。必须按本清单逐项确认:**旧版是否真有、历史是否承诺、当前是否实现、是否已经发布**。
## 2. 对比口径
| 对比层 | 本清单定义 | 主要证据 | 能证明什么 |
|---|---|---|---|
| 历史可运行版 | 仓库保留的旧移动端 `mobile/` | `mobile/src/App.vue`、`mobile/src/data/*` | 能证明旧源码里实际存在过的交互 |
| 历史需求/设计 | BRD、分阶段总纲、推进计划、会议纪要、Figma 清单 | 本文末尾“证据来源” | 能证明功能被提出、规划或设计过,不能单独证明已经开发上线 |
| 当前开发版 | 当前权威用户侧工程 `mobile-uni/` | `mobile-uni/src/pages/*`、后端 `ruoyi-aihr` | 能证明当前工作树的实现状态 |
| 本地修复版 | 当前工作树里尚未发布的反馈修复 | `git diff` 与相关测试 | 只能表述为“本地已修”,不能表述为“客户已可用” |
| 线上生产版 | `https://peilian.njzhmj.top/h5/` 的真实部署 | 线上资源、认证账号、真实接口和浏览器回归 | 本轮未复核,暂不下结论 |
状态说明:
- **保留**:当前仍有等价主链路。
- **部分保留**:有基础能力,但范围、内容或角色未覆盖完整。
- **确认回退**:历史可运行源码里有,当前权威工程缺失。
- **本地已修未发布**:当前工作树已补,但尚未完成线上发布验证。
- **历史规划未实现**:需求/设计里有,没有证据证明旧版真正交付。
- **新增需求**:本轮扩大了原有范围,应重新评估安全、成本和排期。
- **待确认**:现有证据不能支持客户记忆或开发方判断,需要原版本包、旧链接或验收记录。
### 2.1 本轮恢复结果(2026-07-17 晚间,本地未发布)
本轮已按“功能真实可用 + 同尺寸视觉复核”执行,不再只检查页面结构:
- 恢复问师傅语音录制与选择音频兜底,继续复用 `/api/ai/asr`;恢复 SOP 回答、总结卡、每日题、参考答案、AI 对话、训练结果和候选人面试内容播报。TTS 优先走 `/api/ai/tts`,本地未配置 TTS 模型时 H5 自动降级到设备语音,并已实际切换到“停止播报”状态。
- 恢复总结卡生成与 PNG 下载。无对话模型时只摘录检索命中的 SOP 原文,并标明来源,不编造推荐话术或异议答案;本地已实际生成并触发下载成功提示。
- 恢复主管“工作台/学习端”切换,切换只改变显示模式,不修改组织系统中的主管身份;已用主管真实登录态进入员工今日页并返回主管工作台。
- 恢复主管按姓名多选、当天/明天/3 天内/7 天内快捷截止日期和逐人派发结果;已向 2 名团队成员真实提交,接口返回 2/2 成功。
- 每日题从固定 3 题改为 7 组共 21 题,按日期、岗位和员工身份确定性轮换;同一员工同一天稳定、相邻日期不重复,仍保持每日 3 题。
- 全局字号恢复标准/大字/超大字三档并持久化;员工端关键页已在 400×900 下逐档截图,超大字页验证了换行、卡片自增高、底栏安全区和无横向溢出。
上述段落记录的是 2026-07-17 晚间的中间状态。用户随后要求“一并实现”,最终状态以 2.2 为准;第 3–5 节保留为需求来源与实施前差距快照,不再代表当前工作树完成度。
### 2.2 全量实现结果(2026-07-18,本地未发布)
| 客户反馈能力 | 本轮落地结果 | 本地证据 |
|---|---|---|
| 不同角色、岗位内容与主管学习 | 员工/候选人/主管独立入口继续保留;主管可在工作台和学员模式间切换且不改变组织身份;岗位、项目和人员范围由组织数据约束 | 角色深链、主管学员模式、岗位只读和团队范围测试通过 |
| 问师傅语音、生成内容播报 | 语音录制、音频选择兜底、ASR、TTS/设备语音降级恢复;每日题、参考答案、评分点评、候选题目、问题内容支持播报 | H5 交互和服务调用已验证 |
| 图片/视频与总结卡下载 | 问师傅支持仅本次查询使用的图片/视频附件;总结卡可生成并下载 PNG,来源继续可追溯 | 浏览器交互已验证 |
| 全局字号 | 标准/大字/超大字三档全局持久化;可见业务文字最低 12px,输入框采用 `border-box`,问题榜四个筛选标签在窄屏完整显示 | 400×900、430px 和超大字状态逐页截图复核 |
| 训练题变化、反馈与常见难题 | 每日三题按日期、岗位和员工身份轮换;每日题/专项支持有用与无用反馈;主管和管理端可按岗位、时间范围、次数/人数/均分查看难题并一键派专项 | 真实 API 创建专项成功,管理端页面已登录复核 |
| 指派专项 | 显示真实姓名,支持最多 100 人多选,提供当天/明天/3 天内/7 天内快捷截止日期;批量提交具有请求幂等和逐人结果 | 真实 API 指派和超时重进机制已验证 |
| 开放问题榜、有奖征问题/答案 | 已实现提问、全员回答、审核、最佳答案、积分规则、积分/学习学分双账户和后台运营;奖励明确不是现金且不能提现 | 真实 API 完成提问→回答→审核→最佳答案→发奖,重复选优不重复发奖 |
| 完整岗位考试 | 已实现主管选择岗位、项目、真实员工多选、组卷、发布、截止日期和成绩查询;员工可答题、播报、提交、查看逐题结果;提交具备幂等重放 | 真实 API 发布考试并完成 100 分提交;同请求重放返回相同记录和时间 |
| 问 AI(全网) | 与企业问师傅分入口、分接口、分提示;仅允许已测试启用的 HTTPS 提供方,禁用或未配置时明确不可用且不生成假答案 | 能力探测、禁用查询、安全边界和管理页已验证;真实外部回答待配置正式密钥后验证 |
| “点提交没反应”、录音串号、快捷标签错位 | 已补明确错误/加载状态、账号与页面代次隔离、旧请求回写保护;修正提交/输入宽度与筛选标签布局 | 自动化测试、真实浏览器请求和逐页截图均通过 |
最终本地完成层级为:**已实现、自动化验证、真实 API 验证、浏览器交互验证、逐页视觉验证**。尚未执行生产发布,因此不能表述为“客户线上已可用”。“员工每天赚钱”按已批准的积分/学习学分落地,没有擅自实现现金、提现、预算或税务流程。
## 3. 核心功能版本矩阵
### 3.1 角色、岗位与学习
| 功能 | 历史可运行版 | 历史要求/设计 | 当前开发版 | 客观判断 | 建议 |
|---|---|---|---|---|---|
| 员工、候选人、主管看到不同页面 | 旧版已有三类角色入口与不同首页 | BRD 和 Figma 均要求分角色 | `mobile-uni` 仍有员工、候选人、主管独立页面 | **保留**,不是整体删除 | 继续用正式账号做三角色回归,不用截图代替权限验证 |
| 不同岗位看到不同内容 | 旧版有岗位标签和部分展示差异,业务内容仍以生活顾问为主 | 总纲要求按条线/岗位分发,第一波生活顾问,项目经理第二波 | 当前员工岗位来自组织身份,但训练派发仍固定查询“生活顾问”场景 | **部分保留**,岗位身份已接,岗位内容尚未完整产品化 | P1 建岗位→场景→SOP→每日题映射,先明确“四保一服”首批岗位清单 |
| 主管同时作为学员学习 | 没有找到稳定的双身份切换证据 | 客户本轮明确提出“主管也要学习” | 本地已增加“工作台/学习端”显式切换,组织角色保持主管;已用主管登录态双向切换 | **新增需求,本地已实现并交互验证,未发布** | 发布后用正式主管账号复验工作台权限正例/反例 |
| 员工自行切换岗位 | 旧版存在演示性岗位切换痕迹 | 正式口径要求岗位来自人力/组织系统 | 本地已移除员工自由切换,改为 HR 组织同步只读 | **正确收口**,不应恢复随意切换 | 保持只读;提供“岗位有误,联系 HR”入口和同步状态 |
| 岗前/入职任务 | 旧版没有形成正式任务闭环证据 | BRD 一期要求岗位 SOP、岗前/入职任务和资格门禁 | 当前有员工岗前任务、完成回写和资格状态页面,但正式规则/数据未配置 | **部分实现** | HR 提供正式任务与资格规则后再验收,不用空表或 seed 宣称完成 |
| 主管/经理配置岗位入职测试 | 未找到旧版已实现证据 | 阶段二“学”模块要求课程、考试、截止时间;BRD 有上岗资格 | 当前无主管/经理端出题、组卷、发布考试闭环 | **历史规划未实现/待确认** | 让客户提供曾用旧链接或验收截图;若确认要做,纳入学模块专项 |
| 全局字号调节 | 未找到旧版字号开关 | Figma `4:16` 已修为标准/大字/超大字三张同构画板 | 本地已实现全局三档、持久化和页面响应式自增高;400×900 逐档及关键页超大字已截图复核 | **新增无障碍需求,本地已实现并视觉验证,未发布** | 发布后补真实 iOS/Android 与 375–430px 触控、键盘和读屏复验 |
### 3.2 “问师傅”、语音与多媒体
| 功能 | 历史可运行版 | 历史要求/设计 | 当前开发版 | 客观判断 | 建议 |
|---|---|---|---|---|---|
| 问师傅文字提问 | 旧版有 SOP 搜索 | 一期核心 | 当前保留,查询企业授权知识空间并显示引用 | **保留** | 继续保持“有依据才回答”,不兜造假答案 |
| 问师傅语音提问 | 旧版明确有“语音提问/选择语音”并走 ASR | 产品方案明确“问”支持语音提问 | 本地已恢复录音、停止录音、转写和选择音频兜底,复用 `speech.ts` 与 `/api/ai/asr` | **确认回退已在本地恢复,未发布** | 发布前补正式 ASR 配置和真机麦克风权限/弱网复验 |
| SOP 回答语音播报 | 旧版回答有“听一遍” | 历史要求 TTS,产品强调语音优先 | 本地已补“语音播报” | **本地已修未发布** | 发布后用真实 TTS 配置验证播放、停止、失败提示 |
| 总结卡语音播报 | 旧版有总结卡 TTS | 总纲明确“长文总结卡 + 语音播报(能力已有)” | 本地已补总结卡播报 | **本地已修未发布** | 与回答播报共用控制器,避免同时播放 |
| “每个文字都能点播报” | 旧版能确认的是回答与总结卡播报,不能证明每段文字逐字可点 | 设计原则是话术大字+语音,并非所有文字元素都可播 | 当前只对答案、总结卡、每日题、AI 对话等关键内容提供播报 | **客户表述扩大** | 对业务关键内容提供统一播报按钮,不做所有 UI 文本逐元素点击 |
| 生成题目/AI 对话/点评播报 | 未找到旧版完整覆盖证据 | 语音优先原则支持该方向 | 本地已覆盖每日题题干、AI 角色回复、点评、参考答案、训练结果和候选面试内容 | **新增增强,本地已实现并构建验证,未发布** | 发布后逐页验证播放、停止、切换内容时释放音频和设备语音降级 |
| 员工作答语音转文字 | 旧版已有训练语音能力方向 | 一期明确 ASR→文本→提交→评分 | 当前每日题和对练支持录音/选音频、转写后编辑提交 | **保留** | 发布后验证录音权限、账号归属和弱网降级 |
| 录音“不属于当前账号” | 不属于产品功能 | 无历史需求差异 | 本地已修请求身份/归属处理,提交失败也补可见提示 | **缺陷,本地已修未发布** | 用两个真实账号交叉验证自己的录音可提交、他人资源不可读 |
| 提交按钮无反应 | 不属于产品功能 | 无历史需求差异 | 本地增加失败 toast 和输入区域/按钮可见性修正 | **缺陷,本地已修未发布** | 仍需手机端真实点击回归,不能只靠单测关闭 |
| 问师傅上传图片/视频 | 旧版问师傅未确认有此能力 | BRD/缺口文档把图片/视频情境列为新增或后置能力 | 本地已增加图片/视频仅用于本次现场分析,不写入共享知识库 | **历史规划项,本地已补最小版未发布** | 先验收大小限制、权限、PII 外发和失败提示,再决定是否留存 |
| 总结卡下载图片 | 未找到旧版证据 | 历史文档强调总结卡,没有明确图片下载验收 | 本地已补 PNG 下载;无聊天模型时可基于真实命中原文生成,并已实际触发下载成功提示 | **新增需求,本地已功能与视觉验证,未发布** | 发布后验证 iOS/Android H5 下载、文件名和相册/文件权限 |
| 问 AI(全网) | 旧版没有 | 2026-07-08 会议明确当时是“不联网的内部知识” | 当前问师傅只查授权的企业/个人知识空间,不是公网搜索 | **新增范围** | 单独立项为“外部 AI”,与问师傅分入口、分来源、分免责声明;先评估版权、错误信息和数据外发 |
### 3.3 练习、每日题与内容变化
| 功能 | 历史可运行版 | 历史要求/设计 | 当前开发版 | 客观判断 | 建议 |
|---|---|---|---|---|---|
| 场景对练、提交、AI 评分 | 旧版有演示主链路 | 一期核心 | 当前文字/语音作答、AI 评分、记录、低分再练均在 | **保留并增强** | 用正式场景和人工校准验证,不用 seed 结果代替业务验收 |
| “专项”的定义 | 旧版主要是主管给员工派场景 | 计划中专项=按岗位/短板派发的训练任务或训练营 | 当前实现为“主管给一名员工派一个训练场景”,不是固定的一道题 | **功能在,但产品解释不清** | 页面改名为“专项训练任务”,显示场景、对象、原因、截止时间和内容版本 |
| 同一专项每次内容不同 | 旧版没有内容版本/去重保证 | 历史目标是 AI 控制生成、动态难度与多场景 | 当前真 LLM 可让对话变化,但 seed 降级与场景锚点可能重复;没有题目版本和去重契约 | **部分实现** | P0 加 `content_version`/题目快照/最近使用去重,保留 seed 降级但不可每天原样重复 |
| 每日三题每天变化 | 未找到旧版动态题库闭环 | 总纲要求 3 个月覆盖 100 个常见场景 | 本地已扩为 7 组共 21 题,按日期、岗位和员工身份轮换;同日稳定、相邻日不重复 | **明确缺口已完成第一阶段修复,未发布** | 后续继续把正式岗位题库扩到 100 个常见场景,并保留题目快照与版本审计 |
| 选择岗位/条线生成题目和参考答案 | 未找到旧版已实现证据 | 历史要求按岗位推题,后续 AI 辅助出题 | 当前没有主管按条线生成题库的完整入口 | **历史规划未实现** | P1 先做审核式生成:选择岗位→生成草稿→人工确认→版本化发布 |
| 学员评价题目有用/无用 | 旧版 SOP 答案已有赞/踩,不等于训练题评价 | 二期计划明确问答打勾/打叉 | 当前 SOP 答案可反馈;每日题/专项题没有逐题有用/无用 | **部分实现** | P1 复用反馈模型到训练题,区分“答案准确性”和“题目有用性” |
| 管理端按常见难题排序 | 旧版主管端有薄弱项/风险展示 | BRD 要求错题、团队短板、专项派发 | 当前主管团队已有错题聚合、次数/人数/均分等数据,但运营排序闭环不完整 | **部分实现** | P1 增加按出现次数、涉及人数、低分程度排序,并支持一键生成专项 |
| 训练后整体满意度 | 旧版没有完整正式窗口证据 | 试点要求收集反馈 | 当前有 1–5 分满意度和意见 | **保留/新增完成** | 与“逐题有用性”分开统计,避免一个指标代替另一个 |
### 3.4 主管派发、激励与问题榜
| 功能 | 历史可运行版 | 历史要求/设计 | 当前开发版 | 客观判断 | 建议 |
|---|---|---|---|---|---|
| 指派时显示员工姓名 | 旧版多为演示数据 | 正式权限要求稳定组织身份 | 本地已改为从当前项目在职人员中选择姓名,不再手填人员编号 | **本地已修未发布** | 生产需正式组织同步和项目权限数据,不能用本地姓名 seed 验收 |
| 一次多选人员 | 未找到旧版已实现证据 | Figma 有“人员/岗位/场景/截止时间”,但不证明已开发 | 本地已支持按姓名多选、最多 100 人、单次批量接口和逐人结果,超时重进可复用幂等请求 ID | **新增需求,本地已实现并真实提交 2/2 成功,未发布** | 发布后以大团队验证 100 人上限、权限、超时重试和逐人失败隔离 |
| 简化字段、默认值 | 未找到旧版完整证据 | 属于交互优化 | 当前已有默认场景/默认原因,但表单仍偏技术化 | **体验改进** | 保留对象、场景、截止时间三项必填,其他默认折叠 |
| 今天/明天/3天内/7天内快捷日期 | 未找到旧版已实现证据 | Figma 明确有截止时间 | 本地已增加 `dueDate`、四个快捷项和逐人到期结果;3 天内真实派发显示 2026-07-20 | **历史设计细化已在本地实现,未发布** | 发布后复验时区、当天边界和后台准确日期 |
| 有奖征问题/有奖答案 | 旧版没有可运行证据 | 2026-07-08 已定为阶段二“开放问题榜”,有双入口、全员作答、最佳答案和奖励 | 当前阶段一没有问题榜 UI/业务闭环 | **历史规划未实现,不是当前版误删** | P2 按阶段二单独实施,不应临时塞进“问师傅”页 |
| “员工每天可以赚钱” | 旧版没有 | 历史口径是积分/悬赏/学分分账,奖励规则需后台配置,并未批准现金日结 | 当前没有现金收益闭环 | **新增且有运营/财务风险** | 先由业务确认积分、礼品或现金及税务/预算规则,研发不直接实现“赚钱”文案 |
## 4. 客户逐条反馈归类
| 客户反馈 | 归类 | 当前结论 |
|---|---|---|
| “不同岗位看到的页面不一样?” | 能力确认 | 三角色页面不同;不同员工岗位内容只部分覆盖,不能笼统回答“都不一样” |
| “有奖征问题和征答案放哪里了?” | 历史阶段二规划 | 设计和总纲里有,当前阶段一未实现;应作为开放问题榜,不塞进问师傅 |
| “字体能调大吗?有很多老年人” | 新增无障碍需求 | 没有旧版字号开关证据;大字设计不等于可调字号 |
| “原来很多优点都没了,例如每个文字语音播报” | 部分属实、部分扩大 | 旧版可确认回答/总结卡 TTS,不能确认所有文字可点;关键播报已在本地恢复/扩展 |
| “录音不属于当前账号” | 缺陷 | 本地已修,待双账号和线上验证 |
| “点提交没反应” | 缺陷 | 本地补错误反馈,待真机回归 |
| “快捷问题错位” | 视觉缺陷 | 需要按正式 Figma/手机宽度做视觉验收,不能只看 DOM 顺序判断已修 |
| “要能上传图片和视频” | 历史规划/本地最小实现 | 已做仅本次查询附件分析,未发布,不等于共享知识库上传 |
| “生成的问题也要语音播放” | 新增增强 | 本地已覆盖每日题/AI 对话,其他生成内容仍需统一核对 |
| “总结卡可以下载图片” | 新增增强 | 本地已补 PNG 下载,未发布 |
| “语音播报亮点全没了” | 确认回退 | 问师傅语音输入和关键输出播报均已在本地恢复;无 TTS 模型时 H5 已验证设备语音降级 |
| “岗位身份在哪里修改?” | 权限口径冲突 | 员工不应自行修改;本地已改为 HR 组织同步只读 |
| “指派要显示人名,不是编号” | 缺陷/体验 | 本地已改项目内在职员工姓名选择,依赖正式组织数据 |
| “增加问 AI(全网)” | 新增范围 | 当前会议基线是内部知识,不联网;需独立产品和安全决策 |
| “指派人员可多选、字段更简、快捷日期” | 新增 + 历史设计细化 | 本地已完成姓名多选、字段收敛、四档快捷日期、逐人结果和幂等批量提交 |
| “专项是什么?今天明天会不会同一道题?” | 产品定义/内容机制 | 专项是场景任务;当前无题目版本和去重保证,客户担忧成立 |
| “主管也要学习、不同岗位内容不同” | 历史目标 + 当前缺口 | 主管学习端切换本地已实现且不改组织角色;全岗位内容矩阵仍未完成,不能把生活顾问内容冒充全岗位覆盖 |
| “每天题目不一样、学员评有用无用” | 历史目标 + 新机制 | 每日题已本地改为 21 题按人按日轮换;SOP 有赞踩,训练题逐题有用/无用仍未实现 |
| “岗位入职测试保留在主管/经理角色” | 待确认 | 当前只有员工任务/资格与候选人面试;未找到旧版主管端考试配置证据 |
## 5. 优先级建议
### P0:先恢复版本连续性和可用性
1. 恢复“问师傅”语音输入,解决首页“语音提问”文案与实际能力不一致。
2. 完成回答、总结卡、每日题、AI 对话、评分点评的统一播报验收。
3. 真机复验录音归属、提交反馈、附件上传、总结卡下载。
4. 建每日题/专项的内容快照、版本号和去重规则,停止固定三题反复出现。
5. 用正式组织账号验证岗位只读、员工姓名派发和项目范围权限。
### P1:补齐阶段一产品完整性
1. 主管“工作台/学习端”双模式。
2. 岗位→场景→SOP→每日题的统一映射,明确首批岗位内容清单。
3. 指派多人、截止时间和快捷日期;每人生成独立任务记录。
4. 训练题有用/无用反馈、团队常见难题排序和一键派专项。
5. 全局字号三档与老年用户真机可读性验收。
### P2:按原阶段二单独立项
1. 开放问题榜、有奖征问题、全员回答、最佳答案、激励规则。
2. 完整课程、考试、题库、截止时间和成绩留档。
3. “问 AI(全网)”外部信息能力;必须与内部问师傅分来源和权限。
4. 现金型奖励需业务、财务、法务先确认,不作为普通前端功能直接上线。
## 6. 对客户的建议回复
> 之前的功能要求文档和旧版源码已经找到,并已按“旧版实际有过、历史规划但未上线、本轮新增”三类逐项对齐。问师傅语音输入、回答/总结卡播报等确认回退已在本地恢复;同时补齐了三级字号、总结卡图片下载、主管学习端、批量派发/快捷日期和每日题轮换。有奖问答、完整学习考试和问 AI 全网仍分别属于后续阶段或新增专项,不会因为 Figma 已画就混入当前版本。岗位继续以人力系统身份为准,员工不能随意改岗。当前结论是“本地实现并完成相应功能/视觉验证”,尚未发布生产。
## 7. 对齐与验收流程
1. **客户确认分类**:逐项确认“旧版真有/历史规划/新增需求/不再需要”。
2. **冻结对比基线**:给旧版源码、当前开发包和目标版本各自标记 commit、构建时间和访问地址。
3. **先修 P0**:只处理确认回退和阻断缺陷,不同时扩张阶段二范围。
4. **测试版验收**:按账号、岗位、页面、操作、期望结果记录,不再用聊天截图代替验收单。
5. **发布后复核**:本地完成、构建通过、线上资源同步、正式账号验证分别记录,不合并成一个“已完成”。
## 8. 证据来源
- 当前工程边界:[README.md](../README.md)、[AGENTS.md](../AGENTS.md)。
- 当前实现与试点事实:[BRD_IMPLEMENTATION_AUDIT.md](BRD_IMPLEMENTATION_AUDIT.md)、[FIGMA_IMPLEMENTATION_MATRIX.md](FIGMA_IMPLEMENTATION_MATRIX.md)。
- 阶段边界:[银城员工端APP分阶段实施总纲.md](银城员工端APP分阶段实施总纲.md)、[AI陪练二期开发推进计划.md](AI陪练二期开发推进计划.md)。
- 产品定案:[20260708/数字师傅学练问报整合方案.md](20260708/数字师傅学练问报整合方案.md)、[2026-07-08 产品讨论纪要](20260708/企业内部AI培训学习APP产品需求与发布会内容讨论-2026年07月08日-来自【Get%20笔记】.md)。
- 业务原始范围:[物业AI人力资源系统业务需求文档BRD.md](物业AI人力资源系统业务需求文档BRD.md)、[legacy/物业AI陪练系统一期建设实施方案.md](legacy/物业AI陪练系统一期建设实施方案.md)。
- 设计状态:[FIGMA_DESIGN_INVENTORY.md](FIGMA_DESIGN_INVENTORY.md)、[H5_REDESIGN.md](H5_REDESIGN.md)。注意:Figma 清单中的 `[x]` 只证明设计画板或对应页面状态,不能单独证明线上功能已交付。
- 历史可运行源码:`mobile/src/App.vue`(问师傅语音输入约 1009–1017 行、回答播报约 1021–1027 行、回答/总结卡 TTS 约 1804–1894 行)。
- 当前权威源码:`mobile-uni/src/pages/user/*`、`mobile-uni/src/pages/supervisor/*`、`mobile-uni/src/services/position.ts`、`backend/ruoyi-modules/ruoyi-aihr/`。
## 9. 尚需补齐的证据
- 客户口中的“上一版”具体访问地址、安装包、发布时间或 commit 尚未确认;当前只能用仓库保留的 `mobile/` 作为历史可运行源码基线。
- “主管/经理曾能配置岗位入职测试”“每个文字都能点播报”暂未找到足够旧版证据,需要旧录屏或验收单确认。
- 当前本地反馈修复尚未发布,线上是否仍是旧资源、本地修复是否在 iOS/Android H5 上工作,需在发布窗口单独验证。
@@ -181,7 +181,7 @@ mobile/
| `/train/mistakes` | 错题本 | P1 |
| `/knowledge/sop` | SOP 库(住宅类检索→引用→训练题) | P0跑通 |
| `/knowledge/cases` | **案例库(英雄路径B:语音上传→整理)** | P0跑通 |
| `/knowledge/processing` | 资料处理(解析状态、处理链路、浏览器/服务端导入) | P1已提前落地 |
| `/knowledge/processing` | 资料处理(解析状态、处理链路、多文件/ZIP 批量导入) | P1已提前落地 |
| `/system/model` | 模型配置(供应商 Key/Base URL/模型启停/测试、向量库状态与重建) | P1已提前落地 |
| `/competency/radar` | 能力雷达图 | P1 |
| `/competency/cert` | 认证/激励 | P1 |
@@ -268,7 +268,7 @@ POST /api/ai/score req:{ rubricId, dialogue } resp:{ dimensions, co
- 同步:`POST /api/sync/pull`(拉取组织人员,MVP 可读快照文件)
- 知识检索(RAG):`POST /api/knowledge/search` → `{ queryText, category, answer, reference, docs[], snippets[], training[], records[] }`
- 知识上传解析:`POST /api/knowledge/doc/upload` → `multipart/form-data { file, category }`,支持 `.txt/.md/.markdown/.pdf/.doc/.docx/.xls/.xlsx/.ppt/.pptx`、100MB 内;先落 `sys_oss` 并绑定 `aihr_knowledge_attach.oss_id`,返回 `{ docId, ossId, fileName, category, fragments, snippets[] }`;管理端上传请求 timeout 为 180s。
- 服务端目录导入:`POST /api/knowledge/doc/import-local-task` → `{ directory, category, limit }`,只允许读取 `AIHR_IMPORT_ROOT` / `aihr.import.root` 下的相对目录,写入后台导入任务并逐文件复用上传解析链路;`GET /api/knowledge/doc/import-tasks` 返回任务进度列表;`POST /api/knowledge/doc/import-tasks/{id}/cancel` 取消运行中任务;`POST /api/knowledge/doc/import-local` 保留同步调试。
- 服务端目录导入:`POST /api/knowledge/doc/import-local-task` → `{ directory, category, limit }`,只允许读取 `AIHR_IMPORT_ROOT` / `aihr.import.root` 下的相对目录,写入后台导入任务并逐文件复用上传解析链路;`GET /api/knowledge/doc/import-tasks` 返回任务进度列表;`POST /api/knowledge/doc/import-tasks/{id}/cancel` 取消运行中任务;`POST /api/knowledge/doc/import-local` 保留同步调试。这组接口仅供运维/调试,不在 `/knowledge/processing` 页面暴露。
- 资料处理状态:`GET /api/knowledge/processing/overview` → 聚合附件状态、片段数、向量化状态、分类、处理链路和事件列表。
- 片段向量化:同一上传接口在 `category=vector` 模型配置可用时调用 OpenAI-compatible `/embeddings`,写入 `embedding_json/embedding_model/embedding_time`,并尽力 upsert 到 Qdrant;未配置或 Qdrant 不可用不阻塞上传。
- 向量库状态与重建:`GET /api/knowledge/doc/vector-index-status` 返回当前 vector 模型维度、Qdrant collection 维度、点数和片段向量数;`POST /api/knowledge/doc/rebuild-vector-index` 清空旧 embedding、删除 collection,并按当前 vector 模型重建。外部 embedding 成功但 Qdrant 维度不一致时不降级为本地 hash。