Files
prop-ai-hr/CHANGELOG.md
T

172 lines
37 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Changelog
本文件记录源码变更、生产发布与验证结果;每项明确标注完成层级。时间均为中国标准时间(CST,UTC+8)。
## Unreleased
- **2026-07-29,资料处理媒体任务恢复已发布并完成生产验证**:修复历史图片/视频在视觉输入不兼容或未提取到文字时长期停在“等待解析”的问题;图片在送入视觉模型前会按方向纠正、限制像素和体积并统一编码,异步队列只有生成至少一个片段才进入完成态,零片段会保留为可重试失败。新增 `POST /api/knowledge/doc/processing-tasks/{attachmentId}/retry`,可从当前租户原 OSS 对象重新暂存并入队;正式迁移 `aihr_20260729_media_reprocess_mysql8.sql` 增加 `source_attach_id` 和 `(tenant_id, source_attach_id, id)` 索引。生产已备份 schema、后端和完整站点,发布管理端与后端 JAR `5376b67b33b171b5c85e22cd6a2f20bbb0bc527fc50a223603d0aec3f6587bac`,移动 H5 未重发;发布脚本在重启后等待公开端点真实就绪再执行预检,服务为 `active`,根站、租户和移动首页均返回 HTTP 200。原卡住任务 `1133/1175/1308/1405` 从原文件重试为队列 `1185–1188`,四项均完成、各生成一个片段且向量存在;资料处理页显示“待重试 0”、Tika `1028/1028`、可引用资料 `1028`。该证据证明本次资料恢复和定向发布成功,不代表移动 H5 与当前工作树完整匹配,也不替代 Android 真机或正式试点验收。
- **2026-07-29,新增移动端 UI token 与渲染态审计,未发布静态资源**:`audit:ui-tokens` 以 `mobile-uni/src/styles/base.css` 为源扫描颜色、字阶、间距和圆角,`audit:ui-rendered` 在 390×844 的真实 Chrome 中审计 H5 构建的六个默认路由并保存截图。两项均把报告写入 Git 已忽略的 `output/ui-ux/`;本地实跑覆盖 53 个源码文件和 6 个渲染路由,渲染路由均无横向溢出或控制台错误,同时如实记录现有 palette 外颜色、孤立字号和非 token 圆角,不能把“脚本执行成功”解释为视觉债务已清零。
- **2026-07-29,移动端固定码认证与身份失败关闭收口,候选升级为 `0.1.13 (113)`,未发布生产**:生产验证只选择已存在 `app_user` 且双向唯一的在职组织主体;固定码请求、登录、非空项目范围、认证首页、训练历史/画像、五通道、我的反馈、大喇叭、考试、案例/全网只读入口、退出、旧令牌拒绝、等待防刷窗口后的再次获取和重新登录全部通过,应用日志确认两次验证码请求均命中“未真实发送短信”分支。脚本不输出手机号、固定码或令牌,不触发自动注册,不提交反馈、训练、附件、ASR/TTS 或 Agent 请求。后端 `/api/aihr/mobile/me` 与认证首页遇到身份缺失、组织查询异常、无在职身份或后台账号时改为失败关闭;前端角色和岗位加载失败清空缓存并展示明确错误,不再回退普通员工、陈旧岗位或公开首页。干净提交 `af8af2f6` 的统一 RC 已达到 `releaseEligible=true`:移动端 199 项、`ruoyi-aihr` 700 项、类型检查、H5/App、管理端构建、后端打包和 APK 深检全部通过,证据在 `output/aug1-rc/0.1.13-113-af8af2f6-frozen/`。DCloud 云端证书 APK 大小 `33,921,543` 字节、SHA-256 `FA2D2A6DC84AE759714E6D16D146C1E1552A0F3F53C046069422012361D1D0C0`,API 35、v2 测试签名、禁止明文 HTTP、包内业务资源/登录法务/身份失败关闭和敏感值深检通过;候选后端 JAR SHA-256 为 `93AD272118F6A28F88C2BFA305F5C450E163CBE22577FF5BE3E85B3BD3958DAD`,生产只读发布计划通过,现网仍为 `46C99CFF…`。当前双提交交付包 `bangdao-aug1-0.1.13-113-af8af2f6-ops46f4616b.zip` 大小 `192,948,093` 字节、SHA-256 `F6DF4AB2660A4D3523C7E9785C1F8B572770F1F795A841E2D95C88936A8AE9C0`,20 个条目及内部哈希逐项通过;严格门禁会校验固定码模式、5/5 场景、30/30 问题证据、五类负责人签认、每个直通角色至少两名有效处理人、生产场景版本/哈希、五通道正向授权/越权拒绝/一次正式回复,以及受控分发、法务例外和测试签名接受。包内 Go/No-Go 已指向当前包,旧 `ops9c53668c` ZIP 只作历史追溯。机器签认当前准确保持正式场景 `0/5`、问题证据 `0/30`、通道验收 `0/5`、负责人签认 `0/5`、受控分发 `PENDING`,五个处理角色有效绑定均为 `0`。本项未发布后端、H5、数据库或生产静态资源;固定码、登录和重新登录不再列为功能缺口。
- **2026-07-29,Android 法务交互按企业内测体验收口,候选升级为 `0.1.12 (112)`,未发布生产**:取消启动阶段的 DCloud 原生隐私确认,统一由登录页协议勾选承担同意门槛;协议默认未勾选,服务协议与隐私政策可点击查看,未勾选时发送验证码和登录均在请求前失败关闭。两个公开 HTTPS 地址进入版本化 `.env`,npm 与 HBuilderX 云打包共用;源码、App-Plus 产物和 APK 门禁同时检查 `prompt=none`、登录法务链接、未勾选拦截、网络安全与敏感值。DCloud 独立内测 APK `com.yincheng.wygj 0.1.12 (112)` 大小 `33,921,458` 字节,SHA-256 `DD24E5F20BC7C064F5059E538A1FAB7518DF46CBAB502F59A3629F0B1B1F5EBB`,API 35、v2 测试签名、`usesCleartextTraffic=false`;本机 Android 15/API 35 虚拟机全新安装后确认原生隐私层不可见、四项敏感权限未授权、无 Crash/ANR。干净提交 `b9e08789` 的统一 RC 为 `releaseEligible=true`:移动端 199 项、后端 698 项、类型检查、H5/App、管理端、后端打包和 APK 深检全部通过,证据位于 `output/aug1-rc/0.1.12-112-b9e08789-frozen/`。双提交交付包 `bangdao-aug1-0.1.12-112-b9e08789-ops6bf365d5.zip` 大小 `192,926,061` 字节、SHA-256 `E8014A0C5BD56B66B198710E75E2B8DDEC86002D1E3BC6CAF56FB3454A199C33`,14 个条目及内部哈希逐条通过;新后端 JAR `3F9F4506…` 的生产只读计划也通过目标、服务、公开入口、64/64 schema 和生产禁 DDL 检查,现网 JAR 仍为 `46C99CFF…`,未执行部署。当前 AVD 为 `x86_64`,APK 只含 `arm64-v8a/armeabi-v7a`,DCloud Weex 在跨架构转译时实际报 `spinWaitPeer timeout`、`sender is null` 和 IPC timeout;390×844 Playwright 验证仅作为布局、链接和请求前拦截的补充证据,不替代 App 运行或认证业务验收,也不因此修改发布 ABI、增加降级链或启用兜底内容。证据位于 `output/playwright/aug1-login-consent/`。本项没有发布后端、H5、数据库或新的生产静态资源。
- **2026-07-28 至 2026-07-29,前一版 Android 受控内测候选包与法务链路,历史总体 No-Go**:补齐登录页协议默认不勾选与法务地址失败关闭、App-Plus 原生隐私配置生成/校验、APK 包名/版本/API/签名/哈希/包内资源一致性/敏感值门禁、DCloud 云证书自定义基座和独立测试包流程;《服务协议》《隐私政策》静态页已部署到 `/legal/`,发布前整站备份为 `/opt/wygj/backups/www-20260728224710`。客户端法务校验已移除 App-Plus 不保证支持的浏览器 `URL` 构造器,测试验证码也不再以源码常量进入安装包;五个文件选择服务与九个消费页面进一步统一“用户取消/平台失败”分流,取消后不再残留上传或转写错误;直通车首次弱网加载失败后可原位重试,失败时清空旧通道并禁止提交。当时独立 APK `com.yincheng.wygj 0.1.10 (110)` 的 `targetSdkVersion=35`,SHA-256 为 `20CB16B4E9D024DBF5EEEF577BFBA3B4DF5E5E78B597BABB99CB7450C7AE5034`;Android 原生网络安全配置经 APK 反编译确认 `usesCleartextTraffic=false`、`networkSecurityConfig` 引用和系统证书信任配置均已进入安装包。本机 `Medium_Phone` Android 15/API 35 虚拟机已完成从 `0.1.9` 保留数据覆盖升级和冷启动,真实显示原生隐私弹窗,四项敏感权限保持未授权且未见 FATAL/ANR;`0.1.6` 已在 vivo V2443A(Android 15)完成覆盖安装和冷启动。代码候选提交 `dc20b920` 已在干净工作区通过统一 RC 门禁,`releaseEligible=true`:移动端 198 项测试、类型检查、H5/App 构建、管理端构建、`ruoyi-aihr` 698 项全量测试、后端打包及 APK 强化门禁全部通过;最小交付包 SHA-256 为 `4BAA79B2CA2C4D486B6194288D90022D5F994A4D8C8E05D7C2DDD87F9BF5B3B7`,解压后 9 个文件、其中 8 个载荷逐文件复验通过。只读生产预检确认根站、租户接口、移动首页和 64/64 schema 门禁通过,但生产后端模块、管理端和移动 H5 与本地候选仍不一致;用户隐私选择、权限反例、认证态核心业务和正式内容也未完成,故当时 Go/No-Go 为 **No-Go**。本项没有新增生产发布、服务重启、数据库或静态资源变更。
- **2026-07-29,发布预检支持定向后端/schema 范围和冻结物核验,未发布**:`release-preflight.sh` 不再把远端后端或 schema 核验强制绑定到管理端/H5 静态匹配;定向后端发布可只启用 `RELEASE_VERIFY_REMOTE_BACKEND=true RELEASE_VERIFY_REMOTE_SCHEMA=true`,且只要求本地后端 JAR 新鲜。完整包口径仍必须同时启用远端静态、后端和 schema 三项。新增范围回归脚本,校验缺少 `RELEASE_REMOTE_URL` 时失败关闭、定向模式不回退为静态耦合、完整模式命令仍保留;`feece9bb` 再新增 `RELEASE_ARTIFACT_COMMIT` 与 `RELEASE_LOCAL_BACKEND_PATH`,允许从后续文档提交上安全地核验冻结提交及其实际候选 JAR。提交 `566f222e` 后只重建后端并实跑生产只读定向预检:输出没有管理端/H5 哈希,根站、租户、移动首页、64/64 schema 和生产禁 DDL 门禁通过,最终仅因现网/候选 AIHR 模块哈希 `15f5513a…` / `c93460e8…` 不同而按预期失败。随后以 `dc20b920` 和发布 ZIP 解压 JAR 再跑后端只读预检,确认候选整包哈希 `8c676f2f…`,仍仅在同一模块差异处失败;这证明范围和冻结物选择正确,不代表后端已经发布。本项没有执行生产同步、重启或数据库变更。
- **2026-07-29,Android 人工验收新增只读统一取证**:新增 `capture-android-acceptance.ps1`,只读取指定设备当前包版本、前台 Activity、四项敏感权限、UI 层级、截图和应用退出记录,证据限定写入 Git 已忽略的 `output/`;静态回归拒绝安装、启动、停止、清数据、授权、撤权和输入类命令。脚本已在 `emulator-5554` 实跑,确认 `0.1.10 (110)` / API 35 的原生隐私标题与拒绝/同意按钮可见、手机号登录不可见、四项权限均未授权、退出记录无 Crash/ANR。本项只记录用户选择前状态,未代替用户点击隐私选项。
- **2026-07-29,Android 隐私拒绝取证补齐二次确认与退出态**:只读取证脚本现在按实际原生模板区分首次选择 `first-choice`、二次“确认提示/退出应用” `exit-confirmation` 和弹窗不可见 `not-visible`,并记录 App 进程是否存在、是否前台及当前 UI 是否属于 App。`pidof` 在用户退出后返回非零不再让取证失败,因此可分别留存“暂不同意后的二次确认”和“退出应用后的 Launcher/退出记录”证据;脚本仍不发送点击、启动/停止或权限命令。
- **2026-07-29,定向后端发布/回滚工具与只读计划,未发布**:新增固定 `YCWY:/opt/wygj/app/ruoyi-admin.jar` 和 `wygj-aihr.service` 的 `release-backend.sh`;`plan`/`rollback-plan` 默认只读,`deploy`/`rollback` 必须使用完整 SHA-256 授权串且 Git 工作区干净。执行链包含旧包与清单备份、同目录候选校验、原子切换、systemd 重启、后端 + schema 发布后预检、失败自动恢复、回滚前安全备份和恢复前目标哈希复核;发现并发改包时拒绝自动覆盖,所有备份均保留。离线回归覆盖授权前失败关闭、六段远端 Bash 语法、无删除操作,并在临时目录实跑备份→切换→恢复→并发拒绝→回滚安全备份链。冻结候选实跑只读计划确认候选 JAR `8c676f2f…`、现网 JAR `46c99cff…`、目标/服务/空间、三个公开入口、64/64 schema 和生产禁 DDL 均符合要求;只输出授权串,没有创建远端备份、上传、切换、重启或改库。
- **2026-07-29,8 月 1 日生产 API 无登录探针固化**:新增 GET-only 脚本覆盖 APK 依赖的 20 个入口;实跑得到公开移动首页 `1×200`、鉴权 GET `6×401`、仅 POST 入口 `13×405`。`/api/knowledge/answer-feedback` 因同一路径另有运营 GET,按真实控制器归入鉴权组。回归禁止请求体、表单、授权头、手机号和短信验证码入口;本次未申请验证码、未登录、未上传、未发送业务 POST 或写入数据。该结果证明路由与失败关闭契约,不替代认证态业务闭环。
- **2026-07-29,8 月 1 日双提交交付包取代首个最小包**:新增可复现打包器,分别冻结运行时提交 `dc20b920` 与 operations commit `71f005c2`,重新校验 APK/JAR/内容哈希和提交祖先关系,并将发布、回滚、预检、GET-only API 探针、可识别隐私二次确认/退出态的 Android 只读取证和 Go/No-Go 审计快照纳入 ZIP。当前包 `bangdao-aug1-0.1.10-110-dc20b920-ops71f005c2.zip` 为 `192,926,422` 字节,SHA-256 `4391895420B50EBBD8CB87EA20AF71A70D5DABAD5003F5361A8B034CF7525BCA`;14 个条目及 `SHA256SUMS.txt` 中 13 个载荷逐条通过。旧无 operations 后缀包及中间 `ops861fa0ea`、`ops414af66e` 包仅保留追溯,不再作为当前交付包;运行时 APK/JAR 未重编。
- **2026-07-29,8 月 1 日 APK 生产接口兼容性只读核验,未发布**:线上与候选 `ruoyi-aihr` 均含 819 个非目录/非 Manifest 条目,0 个增删、775 个逐字节相同、44 个不同;短信登录、移动首页、查/练/问、直通车和 ASR/TTS 对应的 9 个关键控制器 class 哈希逐一相同。最新统一无登录 GET 探针得到公开首页业务码 `1×200`、鉴权入口 `6×401`、仅 POST 入口 `13×405`,没有触发短信、登录、业务 POST 或数据写入。44 个差异仅来自 `AihrModelSeedService`、`AihrPracticeSeedService`、`AihrSopSeedService` 及内部类,内容是禁止兜底文案冒充已创建/派发工单、阻止含占位内容或不完整五维评分的场景发布;因此现网接口壳可承接 APK,但候选业务语义红线仍需授权后定向发布后端。管理端/H5 与 schema 不属于该定向后端发布;本次没有执行生产同步、重启或数据库变更。
- **2026-07-26,阿里云百炼 ASR 生产热修复**:`POST /api/ai/asr` 新增 `dashscope/qianwen + qwen3-asr-flash` 的 `/compatible-mode/v1/chat/completions` + Base64 `input_audio` 分支,原 SiliconFlow `/audio/transcriptions` multipart 路径继续兼容,ASR 超时放宽至 30 秒。定向 Maven 测试 10 项通过;后端 JAR(SHA-256 `46c99cff75d21f8536a71c3c058b6437e99dbf9ff4bae3542b44471f3f34ad84`)已发布,生产 ASR 已切换至 `dashscope/qwen3-asr-flash`,旧 `siliconflow/TeleAI/TeleSpeechASR` 已停用。生产接口获得正确转写与受控 `ossId`,Android HBuilderX 标准基座“按住说话”请求成功,线上日志无 403/ASR 异常。回滚目录为 `/opt/wygj/backups/asr-hotfix-20260726210122`;本次未发布静态资源、未变更 schema,也不代表完整包一致性或原生 App 全项验收。
- **2026-07-26,移动端编译链升级与 uni-ui 解析修复,未发布**:本机 HBuilderX GUI 已升级为 `5.22.2026071707`,CLI 为 `5.22.2026072503-alpha`;`mobile-uni` 的 App、App-Plus、H5 与 Vite 编译包统一到对应的 `3.0.0-alpha-5020220260725001` 批次,消除 5.15/5.21 混用产生的两套 `uni-cli-shared` 状态隔离,使登录页 `<uni-forms>`、`<uni-easyinput>` 等组件重新由 `pages.json` easycom 规则正常解析。H5 与 App 均以 `Compiler version: 5.22(vue3)` 构建通过;浏览器和 vivo V2443A(Android 15)真机均确认手机号、验证码标签及输入框正常。HBuilder 5.22 标准基座 `versionName=15.22` 已自动更新并成功运行,测试手机号配合固定验证码登录成功,可进入员工首页并切换“问”页,未出现编译器/SDK 版本不匹配弹窗或组件解析告警。升级后仍须重建并安装 5.22 自定义运行基座完成原生权限全清单;`verify:app-release` 当前因缺少含正式法务 HTTPS 链接的 `androidPrivacy.json` 按预期阻断。本项未发布生产 H5,也未云打包 APK/IPA,手机上的 `com.yincheng.wygj` 正式包未被覆盖。
- **2026-07-26,全网 AI 本地库修复,未发布**:补齐 `reset-dev-db.sh` 遗漏的全网 AI 基表、数据库密钥和千问字段三项正式迁移,并增加迁移顺序及幂等回归,避免重置本地库后再次缺失 `aihr_web_search_provider`;当前本地库为 137 张表,管理端代理下的提供方列表接口验证通过。
- **2026-07-26,本地开发工具链,未发布**:补齐 `reset-dev-db.sh` 的 learning-closure 前置迁移,确保 `content_hash` 在训练成长迁移建索引前存在,并增加顺序回归检查;修复管理端 portless 包装在 Windows/Git Bash 下丢失 Vite 参数的问题。Windows 运行手册改为三个应用进程显式启动,两个 Vite 代理从 `portless list` 读取后端动态端口并直连回环地址,以规避 WSL `bash`、portless `0.15.4` 根目录批量启动差异及代理/TUN 对 Node.js `.localhost` DNS 的干扰。已在本地重建 `ry-vue` 为 130 张表,MySQL/Redis/MinIO/Qdrant、三个 portless 路由和管理端/移动端关键公开接口验证通过;未执行生产发布。
- 2026-07-25 23:56–2026-07-26 02:40 的 App-Plus 批次已提交但**尚未发布**:未构建云打包 App、未发布 H5、未发布后端 JAR、未重启服务。见下两节。
## 2026-07-26 16:41–16:57|播报音色扩充、时长恢复与 HBuilderX 5.15 对齐
### 功能与修复
- 问模块快捷问题改为完整问句,减少短关键词被 Agent 当成不完整表达后再次澄清。
- “我”模块的 AI 播报音色在原有 4 个基础音色上新增 8 个 Qwen TTS 音色;服务端白名单同步放行,非法音色仍回落默认值。方言继续复用既有 21 项选择,并按租户与账号隔离保存。
- App-Plus 逻辑层没有浏览器 `Audio` 构造器;语音条时长改为直接解析 TTS `data:` URI 内的 MPEG Layer III 帧,支持 ID3v2、MPEG1/2/2.5、VBR 和 padding,远端 URL 仍使用宿主音频 API 兜底。
- App 编译链从 5.21 系列回退到本机 HBuilderX `5.15.2026070915` 内置版本:`@dcloudio/uni-app`、`@dcloudio/uni-app-plus`、`@dcloudio/vite-plugin-uni` 固定为 `3.0.0-alpha-5010220260604001`。`@dcloudio/uni-h5` 保留 5.21 系列,因为 5.15 H5 包缺少项目使用的 `Audio` 导出。
### 发布与验证
- **2026-07-26 16:41**:基于生产后端基线隔离构建并原子发布语音白名单 JAR,发布提交为 `bd196de6`,备份目录为 `/opt/wygj/backups/tts-voices-20260726164118-bd196de6`。服务恢复 `active`,健康检查 `200`,错误级别日志为空;生产 schema 仍为 `64/64`。本次只发布后端,没有覆盖更新中的生产 H5。
- **2026-07-26 16:46**:Android 真机发起新的“催费话术怎么说”请求,后端日志确认实际收到 `qwen-audio-3.0-tts-flash-longluxiaohui`、`dialect=shanghai`,3.503 秒生成 14 秒语音;这证明新音色参数已通过客户端、服务端白名单和模型链路,主观音色是否符合预期仍以人工试听为准。
- **2026-07-26 16:45–16:57**:真机实际复现“编译版本 5.21、手机端 SDK 5.15”弹窗。依赖与 HBuilderX 5.15 标准基座对齐后,App 与 H5 构建均通过,重新下发到同一 Android 设备后弹窗消失。该版本号是 uni-app 编译链/调试基座版本,不是 Android `minSdkVersion`。
- 本节完成层级为:音色后端已部署并完成生产请求链路验证;App 依赖对齐、时长解析和快捷问句已实现并完成本地构建/标准基座真机验证。**未重新云打包签名 APK/IPA,未发布 H5,未完成 Android/iOS 自定义基座全清单或人工音色验收。**
## 2026-07-26 02:35–02:40|恢复 App 端回复语音优先
### 功能与修复
- **2026-07-26 02:38**(`d84ad87c`):恢复 App 端回复的语音优先形态。`73712994` 用 `!isNativeAppRuntime()` 关掉原生端 TTS 预生成后,App 上每条回复都退化成纯文字气泡加 `播报` 按钮;语音条、`转文字`、`收起全文` 的模板与样式一直在包内但无法到达。现预生成在所有平台生效,消息以 `transcriptOpen: true` 建立,合成期间文字即可读,不必等一次 TTS 往返。
### 取舍与偏离
- **2026-07-26 02:38**:收起文字的触发点定为**开始播放**,不是合成完成。真机实测本地合成 2–6 秒即就绪,若按合成完成收起,文字会在读到一半时被抽走、只闪约 3 秒,与「不必等」的意图相反。新增 `transcriptPinned` 记录手动 `转文字`/`收起`/`收起全文`,自动收起不覆盖读者选择;不播放则文字一直可读。
- **2026-07-26 02:38**:`preparing` 语音条加 20 秒上限(对齐后端 DashScope 上游超时),超时按 `unavailable` 退化成纯文字加 `播报`,避免永久停在占位时长。该上限只结束界面等待态,**不中止**已发出的合成请求。
- **2026-07-26 02:38**:语音条显示 `语音` 而非微信式 `12"`。`measureAudioDuration` 依赖全局 `Audio`,App-Plus 逻辑层无该对象直接返回 `null`。属该形态既有缺口,非本次引入;修法需改走 `uni.createInnerAudioContext` 的 `duration`,因该函数被对练与摘要播报共用,**未改**。
- **2026-07-26 02:38**:`tests/agent.test.mjs` 中原断言以 `!isNativeAppRuntime()` 等源码字符串锁住旧行为,属同义反复,已换为行为断言:语音优先不依赖平台、合成完成不得收起文字、播放才收起、超时有兜底。
### 验证与边界
- **2026-07-26 02:40**:`vue-tsc --noEmit` 通过;前端单测 `168/168` 通过。`build:app` 按产物核验含 `app-service.js`、`app-renderjs.js`、`manifest.json`,不以 `DONE Build complete.` 为准。
- **2026-07-26 02:40**:真机取样(包推 `__UNI__B36D8BE` 后重启基座):3 秒为 `…` 合成中加红点、文字可读、`收起全文 ▲`;12 秒语音就绪而文字仍在;点播放后文字收起、红点清除;26 秒回到空闲,未复现挂死。
- **2026-07-26 02:40**:**未验证**音频是否真实出声——状态机走完整链路,但设备音频输出无法取证,需人工试听。
- **2026-07-26 02:40**:本节完成层级为「已实现、已本地验证、已提交」。**未构建云打包 App、未发布 H5、未发布后端 JAR、未重启服务**。
- **2026-07-26 02:40**:排障口径修正。`adb exec-out screencap -p` 的 PNG 直接读取会静默返回空内容,若据此描述界面会得出凭空结论;本批已改为先 `sips` 转换/裁剪再读。据此撤回两条当时证据不支持的口头结论:「App 端 TTS 挂死」(实测本次 2–6 秒合成成功)与「该次失败点击由 SDK 弹窗吞掉」(该轮取证画面未显示弹窗,点击落空系启动时序)。16:45 的后续冷启动已独立复现版本弹窗并完成修复,见上文。
## 2026-07-25 23:56–2026-07-26 00:02|App-Plus 实时对练与构建链修复
### 构建链修复(本批最重要)
- **2026-07-25 23:56**(`a3a5cf94`):修复 `npm --prefix mobile-uni run build:app` 长期**假绿**。`@dcloudio/uni-app-plus` 从未被声明为依赖,缺少该编译器时 `uni build -p app` 不报错、退出码 `0`、照样打印 `DONE Build complete.`,但产物只有 `index.html`(仍带 H5 的 `/h5/assets/...` 基路径)、字体和一个 `704` 字节 preload 片段,没有 `app-service.js`、`app-renderjs.js`、`manifest.json`。
- **2026-07-25 23:56**:因 `docs/MOBILE_APP_PACKAGING.md` 把该命令列为本地验证步骤,本批 renderjs 实时对练代码在装上编译器之前**从未经过 App 编译器**,却曾被当作已验证。本次已按同版本 `3.0.0-alpha-5020120260710001` 声明编译器,在 `tests/app-packaging.test.mjs` 加版本对齐闸门,并在打包文档写明:判定 `build:app` 成功只看产物是否含 `app-service.js`、`app-renderjs.js`、`manifest.json`,不看 `DONE Build complete.`。
### 功能与修复
- **2026-07-25 23:58**(`5cf7ce58`):实时对练支持 App-Plus。媒体与 WebRTC 引擎移入 `realtime-browser-engine.js`,由 `components/practice/RealtimePracticeAppBridge.vue` 的 renderjs 脚本在系统 WebView 内执行;认证的 SDP 交换与 `search_knowledge` 工具调用仍留在逻辑层代理,access token 不下放视图层。H5 路径行为不变。
- **2026-07-25 23:56**(`27f4cdac`):部分 uni-app 平台忽略 `uni.request` 的 `timeout`,导致 Promise 永挂、页面无错误出口。改为本地驱动超时,单次 `finish` 守卫保证只 settle 一次,超时先 `task.abort()` 再 reject。
- **2026-07-25 23:57**(`3055d2be`):替换 App-Plus 不支持的两个 API。`URLSearchParams` 在 App-Plus JS core 缺失,`toLocaleDateString('sv-SE', { timeZone: 'Asia/Shanghai' })` 依赖 App 运行时未附带的完整 ICU 数据,二者曾让工作成果页拼出错误查询串或取到设备本地日期。改为 `encodeURIComponent`,业务日统一走 `currentShanghaiDate()` 固定 UTC+8 偏移;Asia/Shanghai 无夏令时,固定偏移是精确值而非近似。
- **2026-07-25 23:58**(`73712994`):原生 App 不再预生成答案 TTS。此前消息以 `preparing` 建立,文字被卡在等待一次 TTS 往返之后;改为原生端标记 `unavailable` 让文字与引用立即渲染,语音由既有 `unavailable` 分支的播放按钮按需触发,不是取消语音。H5 仍保留预生成。
- **2026-07-25 23:58**(`7b014765`):Agent 追问不再答成澄清。规划器在无关键词命中且模型规划不可用/不合法时回落 `CLARIFY`,导致「如果我要报销,一般需要查哪几个文件?」这类已有上下文的追问被要求澄清。现非媒体请求带 `conversationId` 且 `contextVersion > 0` 时改走 `KNOWLEDGE_QA` 接地检索。**取舍**:第二轮起对「你看着办」「帮我处理一下」这类刻意模糊表述的主动澄清也一并被抑制,会改为执行知识检索;空输入仍由 `requireQuestion` 提前拒绝。
- **2026-07-25 23:58**(`c9f5271d`):补记 `30ef6a8f` 已发布的 `/api/aihr/org/sync-changes` 增量同步契约到 `AGENTS.md` 与 `docs/API_INTEGRATION.md`(稳定 `employee.id` 主体键、先 `dryRun=true` 后同起点 `dryRun=false`、全量 `/sync` 对脱敏手机号与重复成员关系 fail-closed)。仅文档,无代码变更。
- **2026-07-25 23:59**(`4fc0c1f5`):App 版本升至 `0.1.5`(`versionCode 105`)。原生权限与插件未变,属常规云打包重建。
### 验证与边界
- **2026-07-26 00:01**:`vue-tsc --noEmit` 通过;前端单测 `162/162`、后端 `694/694` 通过。后端须显式加 `-DskipTests=false`——`backend/pom.xml` 第 60 行把 `skipTests` 默认设为 `true`,不带该参数的 `mvn test` 是空跑且照样输出 `BUILD SUCCESS`,与上面 `build:app` 是同类假绿。
- **2026-07-26 00:01**:`build:app` 在补齐编译器后产出真实 App 包,并按产物核实分层:`RTCPeerConnection` 与 `getUserMedia` 只出现在 `app-renderjs.js`,`realtime/sdp` 端点只出现在 `app-service.js`,renderjs 侧 `0` 命中。
- **2026-07-26 00:02**:以上仅证明 App 平台可正确编译且分层正确。麦克风授权、实时转写、远端语音播放、前后台切换、断线降级只能在真机 WebView 验证,**未验证**;口径已写入 `docs/MOBILE_APP_PACKAGING.md` 与 `docs/MOBILE_APP_DEVICE_ACCEPTANCE.md`。
- **2026-07-26 00:02**:本批完成层级为「已实现、已本地验证、已提交」。**未构建云打包 App、未发布 H5、未发布后端 JAR、未重启服务、未执行 schema 迁移**;`7b014765` 的 Agent 追问修复需后端 JAR 发布后才在生产生效。
## 2026-07-25 15:40–16:15|组织姓名与考试发布修复
### 生产数据修复
- **2026-07-25 15:40**:在 `/opt/wygj/backups/org-name-sync-20260725-1540/org-data.sql` 备份生产组织数据;备份大小 `711248` 字节,SHA-256 为 `9e298bf5e6ac88b6d0e105f510cad3fb9838ed1cf0324a23ee15453a54e3c9dd`。
- **2026-07-25 15:40–15:48**:刷新开放组织目录并将租户 `000000` 绑定到集团根节点 `G:1`。仅按稳定 `employee_id` 精确匹配,补齐 `aihr_org_snapshot.person_name` 共 `3417` 行;未改手机号、项目、岗位和在职状态。
- **2026-07-25 15:48**:生产复核为组织快照 `3417` 行、在职 `2938` 人、在职有姓名 `2938` 人、手机号映射 `3392` 个。使用既有生产主管账号调用团队接口返回 `2316` 名成员,姓名完整 `2316` 名、编号兜底 `0` 名;账号、手机号、验证码和 Token 未写入仓库、截图或本记录。
- **2026-07-25 15:48**:未执行全量组织覆盖。只读预检发现上游 `3424` 名员工中 `3398` 个手机号已脱敏、存在 `1` 条重复项目成员关系,并且当前 `employee_number` 仅能匹配生产既有主体 `7/3417`,稳定 `employee_id` 可匹配 `3417/3417`。在身份字段契约和手机号通道修复前,禁止用 `allowPartialReplace=true` 绕过后执行覆盖同步。
### 考试发布修复
- **2026-07-25 15:55**:移除客户端“考试名称至少 4 个字”的无依据限制,改为仅要求名称非空;同时保留及格分 `1–100`、至少一道题、总分 `100`、题干/选项/答案完整和至少选择一名员工的发布校验。备份当时生产 H5 到 `/opt/wygj/backups/h5-exam-title-20260725-1555/` 后完成首次静态发布。
- **2026-07-25 16:09**:复核发现 `16:01` 的后续 H5 发布重新带入旧 `length>=4` 校验;该次覆盖被识别为生产回退,未将 `15:55` 的短暂上线状态作为最终完成。
- **2026-07-25 16:12**:基于当前主线 `75469b85` 重新构建 H5,保留已发布的陪练“建议回复”功能并叠加考试修复;发布前备份到 `/opt/wygj/backups/h5-exam-restore-20260725-1612/`。生产入口更新为 `/h5/assets/index-QQ2kC1xm.js`,考试页资源为 `/h5/assets/pages-supervisor-exams-edit.B-v9k7L-.js`。
### 验证与边界
- **2026-07-25 16:12**:目标回归 `5/5`、`vue-tsc --noEmit` 和 `npm --prefix mobile-uni run build:h5` 通过;生产考试资源包含“请填写考试名称”和“发布前请至少选择 1 名员工”,不再包含旧 `length>=4` 校验。
- **2026-07-25 16:14**:在生产 H5 `390×844` 视口使用隔离浏览器会话和两名模拟员工完成无写入验收;考试名“测试”可通过名称校验,员工姓名正常显示,“发布给 2 人”按钮启用,未调用保存或发布接口。
- **2026-07-25 16:15**:本次结论为:姓名数据修复已生产验证,考试校验已实现、已本地验证、已重新部署并完成生产 H5 浏览器验证;未执行后端 JAR 发布、服务重启、schema 迁移或全量组织覆盖。对应两处考试源码改动仍在工作区,尚未提交。
## 2026-07-25 15:44–16:05|陪练建议回复
### 功能更新
- **2026-07-25 15:44:45**:完成常规陪练“建议回复”(提交 `acd5fd3a`)。“用这句话回复”改为由 LLM 根据当前会话、回合和老师傅提示生成一条员工可直接回复的新话术,不再复制指导语。
- **2026-07-25 15:44:45**:移动端将 LLM 生成结果只填入输入框,由员工修改后主动发送;生成期间禁用重复点击,接口失败时显示明确错误。
- **2026-07-25 15:44:45**:服务端在既有训练会话归属和身份校验内生成建议回复,不推进训练回合、不改写训练证据;普通训练回合继续保留模型失败时的 seed 降级。
- **2026-07-25 15:44:45**:训练 `/turn` 接口新增 `suggestReply` 请求参数和 `suggestedReply` 响应字段,并保留旧请求、旧响应构造方式兼容。
### 生产发布
- **2026-07-25 15:52:03**:备份生产后端 JAR 与完整移动端 H5,备份目录为 `/opt/wygj/backups/practice-reply-20260725155203-acd5fd3a`。
- **2026-07-25 15:52:45**:将提交 `acd5fd3a` 构建的后端 JAR 原子切换到 `/opt/wygj/app/ruoyi-admin.jar`;本次功能不涉及数据库结构变更。
- **2026-07-25 15:53:16**:重启 `wygj-aihr.service`;Spring Boot 于 `15:53:35` 完成启动。
- **2026-07-25 16:01:13**:将隔离工作树构建的移动端 H5 最终同步到 `/opt/wygj/www/h5`,生产入口固定为 `/h5/assets/index-BDNPeJuO.js`。
- **2026-07-25 16:01–16:02**:完整生产预检通过,确认管理端与移动端静态资源匹配、AIHR 后端模块匹配、schema `64/64`、运行时 schema bootstrap 关闭。
### 线上验证
- **2026-07-25 16:02–16:04**:从生产组织快照只读选择手机号与外部 ID 双向唯一的在职保洁员工,先请求短信验证码再登录;账号值未写入终端输出、截图、报告或仓库。
- **2026-07-25 16:04:03**:在 `390×844` 视口走完场景启动、员工回复、老师傅提示和“用这句话回复”主路径;LLM 生成新的员工话术并填入输入框,没有自动发送,也没有复制老师傅提示,输入框和发送按钮显示完整。
- **2026-07-25 16:04**:发布后复核 `wygj-aihr.service` 为 `active`,自 `15:52:00` 起错误级别日志为 `0`,生产 H5 仍返回 `/h5/assets/index-BDNPeJuO.js`。
### 验收边界
- **2026-07-25 16:04**:本次结论为:**已实现、已部署、已完成生产 H5 浏览器验证**。
- **2026-07-25 16:04**:本次验证不替代 Android/iOS 真机验收,也不代表正式试点窗口、业务内容审核或严格试点指标已经通过。
## 2026-07-25 15:18–15:42|公司文件多岗位解读
### 功能更新
- **2026-07-25 15:18:58**:完成公司文件多岗位解读代码收口(提交 `230dfb4d`)。管理端上传文件并完成正文提炼后,异步生成有原文依据的岗位视角;单个视角包含岗位名称、解读内容、行动建议和原文短引用。
- **2026-07-25 15:18:58**:管理端增加解读状态展示,明确区分“正在生成、已完成、部分完成、生成失败”,并展示已经生成的岗位名称。解读失败不阻断文件摘要、原文件下载、消息发布或消息追问。
- **2026-07-25 15:18:58**:员工端消息详情增加“多岗位解读”。系统优先展示与认证员工岗位匹配的视角;员工可切换查看其他已生成视角,并展开对应的原文依据。
- **2026-07-25 15:18:58**:服务端重新校验租户、登录身份、在职身份、消息状态和附件归属。消息撤回后,员工列表、详情、原文件和后续追问均不再允许访问。
### 数据库更新
- **2026-07-25 15:25–15:26**:生产表 `aihr_broadcast_attachment` 新增 `insight_status`、`insights_json`、`insight_version` 三个字段,并新增 `(insight_status, status, update_time)` 异步队列索引。
- **2026-07-25 15:25–15:26**:迁移仅新增多岗位解读字段和队列索引,不回填历史文件、不修改既有文件 `READY` 状态,也不改变历史消息的发布或撤回状态。
### 生产发布
- **2026-07-25 15:24:06**:完成生产数据库、后端 JAR、管理端和移动端 H5 备份,备份目录为 `/opt/wygj/backups/broadcast-insights-20260725152349`。
- **2026-07-25 15:26:32**:部署新后端 JAR、管理端静态资源和移动端 H5。
- **2026-07-25 15:26:33**:`wygj-aihr.service` 重启并恢复为 `active`。
- **2026-07-25 15:27–15:30**:完整发布预检通过。管理端与移动端静态资源、生产后端 JAR 和 `ruoyi-aihr` 模块哈希均与本地构建一致;生产 schema 为 `64/64`,公司文件附件契约为 `15/15`。
### 线上验证
- **2026-07-25 15:31:52**:管理端上传生产验收 TXT 文件,文件提炼状态进入 `READY`。
- **2026-07-25 15:32:15**:多岗位解读生成完成,共生成“生活顾问/客服、人力、审计/风控、管理层”四个视角,结果状态为 `READY`,规则版本为 `role-perspective-v1`。
- **2026-07-25 15:32:34**:发布全员可见的生产验收消息。
- **2026-07-25 15:38–15:39**:使用生产数据库中的在职员工手机号完成员工端登录验证。在 390×844 视口下验证消息列表、消息详情、四视角切换、行动建议和原文依据展开,未发现横向溢出、内容遮挡或核心入口下沉。
- **2026-07-25 15:39:33**:通过员工端受控入口下载原文件,下载文件 SHA-256 与管理端上传文件完全一致。
- **2026-07-25 15:40:04**:验收完成后撤回测试消息并保留审计原因。
- **2026-07-25 15:40:13–15:40:41**:复核员工端列表不再展示该消息,原详情地址返回“消息不存在或已撤回”。
- **2026-07-25 15:42:11**:更新生产事实文档(提交 `9a34a267`),源码与发布记录已同步至远端 `main`。
### 验收边界
- **2026-07-25 15:42:11**:本次结论为:**已实现、已部署、已完成生产 H5 浏览器验证**。
- **2026-07-25 15:42:11**:本次验证不替代 Android/iOS 真机验收,也不代表正式试点窗口、业务内容审核或严格试点指标已经通过。
- **2026-07-25 15:42:11**:生产验收消息已经撤回;仅保留发布、阅读、下载和撤回审计记录。