release(android): close 0.1.17 device candidate

This commit is contained in:
key
2026-07-30 21:02:56 +08:00
parent c16a3e83d7
commit adedcb4200
14 changed files with 149 additions and 52 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
## Unreleased ## Unreleased
- **2026-07-30,五通道处理人配置与 Android 权限 Activity 生命周期收口,已本地验证、尚未发布**:管理端“直通反馈”新增五通道处理人就绪概览和 `superadmin` 专用配置入口;服务端候选人只返回当前租户已启用的后台用户,排除 APP 用户、超级管理员和已绑定用户,写入时复核 `expectedTenantId`,页面按服务端 `minimumHandlers=2` 提示主处理人/替补缺口,并在移除会破坏就绪状态前明确告警。生产只读检查仍为五个角色各 `0` 人,且新接口当前返回 404;本轮没有擅自绑定人员或写生产数据库。Android 麦克风授权现在与系统文件选择器共用原生 Activity 活动标记,权限回调后等待应用窗口重新获得焦点,六个相关页面在授权框/选择器暂时离开 App 时不再把待完成录音或上传任务误判为取消。`ruoyi-aihr` 全量 708 项、管理端定向 28 项、移动端 208 项、移动端类型检查、管理端生产构建、App-Plus 构建及发布资源门禁均通过;管理端本地真实浏览器确认五张通道卡、`0/5` 就绪状态和候选人对话框正常。已生成的 `0.1.16 (116)` DCloud 测试签名 APK(SHA-256 `183E67137CE9B73FC6D41A728779D40EB0122F8F62E1951B65DDC356203937F5`)通过包名、API 35、明文流量和签名深检,但其内嵌 `app-service.js` 不等于当前构建且不含本轮窗口焦点/权限 Activity 修复,不能作为当前源码候选;后续须使用新版本号重新签名出包并在同一包上真机回归。本项尚未发布后端、管理端、H5、原生 App 或 schema。 - **2026-07-30,`0.1.17 (117)` Android 技术候选与五通道处理人配置完成收口,正式发布仍为 No-Go**:管理端“直通反馈”五通道处理人配置已在线可用,生产按有效后台用户规则只读复核后,`direct_president`、`direct_finance`、`direct_hr`、`direct_audit`、`direct_operations` 均为 `2/2`;Android 权限 Activity 生命周期修复已进入新的 DCloud 测试签名 APK `mobile-uni/dist/debug/bangdao-0.1.17-dcloud-test.apk`,包体 SHA-256 为 `0A8581D70A5988E4BDCF4BB3F0C88B4608FA8C6785FDCF1569DD56CE88E27F60`,包名 `com.yincheng.wygj`、版本 `0.1.17 (117)`、target SDK 35、禁止明文流量和签名深检均通过。vivo V2443A(Android 15/API 35)已在同一签名包上完成覆盖安装、正式账号登录、员工首页、学习中心、麦克风允许/拒绝/最终恢复、系统音频选择器、App 媒体选择器、生产 ASR、成果投稿确认和五通道入口回归;测试成果形成 `#7 / PENDING` 待审核记录,测试音频与会话已清理,最终无 Crash/ANR。移动端 209 项、后端定向 46 项、管理端定向 4 项、类型检查、App-Plus 构建、发布资源门禁和生产认证态冒烟均通过;认证态 UI 审计改为只从调用参数或环境变量接收手机号/验证码,报告、控制台和默认截图路由不再持久化认证凭据。该 APK 仅安装到已连接真机,未进行受控分发,也未在本项重发 H5、管理端、后端或 schema。严格门禁仍为正式场景 `0/5`、题库证据 `0/30`、通道验收 `0/5`、负责人签认 `0/5`、受控分发 `PENDING`,且同包离线、WebRTC、图片/视频/文档上传、受控下载和主管/候选人角色尚未验收,因此只能作为继续受控验收的技术候选,不能签署 8 月 1 日正式 Go。
- **2026-07-30,学习中心错题列表异常已修复、发布并完成真机验证**:vivo V2443A(Android 15)的线上会话进入“学习”页后显示“发生未知异常”,同页任务、知识引用等请求正常,生产日志将故障收敛到 `GET /api/aihr/mobile/practice/mistakes`;其 SQL 文本中的 JSON `LIKE '%"redFlag":true%'` 被 `String.formatted()` 误当成格式指令,触发 `UnknownFormatConversionException: Conversion = '"'`。当前改为只替换身份 `IN` 参数的专用占位符,保留两个 `LIKE` 通配符原样,并增加 SQL 生成回归测试;`AihrPracticeSeedServiceTest` 103 项、`ruoyi-aihr` 全量 707 项测试和 `ruoyi-admin` 生产包构建均通过。提交 `edb8c825` 的后端 JAR `346687564b38adbba643fc7d94d2faedbb51449198b4eef6c3fa90fb99646c83` 已通过定向发布脚本备份、原子切换、重启和发布后预检,旧包备份在 `/opt/wygj/backups/backend-20260730005606-be16c229cfc2`;远近端整包及内嵌 `ruoyi-aihr-5.6.2.jar` 哈希一致,服务、公开接口、64/64 schema 和生产禁运行时 DDL 均通过。同一真机从“今日”重新进入“学习中心”后不再显示异常,错题、分数和“去再练”入口正常;对应错题接口在 `22ms` 内结束,重启后日志未再出现 `UnknownFormatConversionException`。本次只发布后端,未发布移动 H5、原生 App、管理端或 schema 迁移。 - **2026-07-30,学习中心错题列表异常已修复、发布并完成真机验证**:vivo V2443A(Android 15)的线上会话进入“学习”页后显示“发生未知异常”,同页任务、知识引用等请求正常,生产日志将故障收敛到 `GET /api/aihr/mobile/practice/mistakes`;其 SQL 文本中的 JSON `LIKE '%"redFlag":true%'` 被 `String.formatted()` 误当成格式指令,触发 `UnknownFormatConversionException: Conversion = '"'`。当前改为只替换身份 `IN` 参数的专用占位符,保留两个 `LIKE` 通配符原样,并增加 SQL 生成回归测试;`AihrPracticeSeedServiceTest` 103 项、`ruoyi-aihr` 全量 707 项测试和 `ruoyi-admin` 生产包构建均通过。提交 `edb8c825` 的后端 JAR `346687564b38adbba643fc7d94d2faedbb51449198b4eef6c3fa90fb99646c83` 已通过定向发布脚本备份、原子切换、重启和发布后预检,旧包备份在 `/opt/wygj/backups/backend-20260730005606-be16c229cfc2`;远近端整包及内嵌 `ruoyi-aihr-5.6.2.jar` 哈希一致,服务、公开接口、64/64 schema 和生产禁运行时 DDL 均通过。同一真机从“今日”重新进入“学习中心”后不再显示异常,错题、分数和“去再练”入口正常;对应错题接口在 `22ms` 内结束,重启后日志未再出现 `UnknownFormatConversionException`。本次只发布后端,未发布移动 H5、原生 App、管理端或 schema 迁移。
- **2026-07-29,Android 文件选择、麦克风拒绝降级与上传路径修复,源码候选升级为 `0.1.16 (116)`,尚无签名 APK**:真机确认 `0.1.13` 在允许麦克风时可完成原生录音和生产 ASR,但拒绝后的降级误用 App 不支持的 `uni.chooseFile`。Android 非媒体文件现改用系统 `ACTION_OPEN_DOCUMENT`,通过 `ParcelFileDescriptor + FileChannel.transferFrom` 复制到应用专属外部缓存,避免 Native.js `byte[]` 参数兼容问题;图片/视频改走 App `uni.chooseMedia`,页面生命周期会保留系统选择器中的待完成任务,录音前统一检查麦克风权限。vivo Android 15 真机在 HBuilderX 5.22 标准调试基座完成取消、重复打开、`100,542` 字节 WAV 精确复制、multipart 上传和生产 ASR。首次成果投稿验证实际只进入追问态,当时并未出现“确认投稿”,此前“未点击确认投稿”的表述已纠正;继续补充时线上整理请求耗时 `94,965ms`,超过客户端 `45,000ms` 门限。当前源码改为仅首轮调用 AI,后续原话并入当前草稿后交由既有服务端本地复核,真机复验后续整理耗时 `1ms`,确认卡及“确认投稿”按钮均已显示但未点击,未形成正式投稿。移动端 206 项测试、类型检查、App 发布资源预检和 App-Plus 构建通过;调查用 `0.1.14/0.1.15` APK 已删除。DCloud 当日云打包额度耗尽,最终 `0.1.16` 签名 APK、深检和同包真机复验仍未完成,因此当前仍为 No-Go,未发布移动 H5、原生 App、后端、管理端或数据库。 - **2026-07-29,Android 文件选择、麦克风拒绝降级与上传路径修复,源码候选升级为 `0.1.16 (116)`,尚无签名 APK**:真机确认 `0.1.13` 在允许麦克风时可完成原生录音和生产 ASR,但拒绝后的降级误用 App 不支持的 `uni.chooseFile`。Android 非媒体文件现改用系统 `ACTION_OPEN_DOCUMENT`,通过 `ParcelFileDescriptor + FileChannel.transferFrom` 复制到应用专属外部缓存,避免 Native.js `byte[]` 参数兼容问题;图片/视频改走 App `uni.chooseMedia`,页面生命周期会保留系统选择器中的待完成任务,录音前统一检查麦克风权限。vivo Android 15 真机在 HBuilderX 5.22 标准调试基座完成取消、重复打开、`100,542` 字节 WAV 精确复制、multipart 上传和生产 ASR。首次成果投稿验证实际只进入追问态,当时并未出现“确认投稿”,此前“未点击确认投稿”的表述已纠正;继续补充时线上整理请求耗时 `94,965ms`,超过客户端 `45,000ms` 门限。当前源码改为仅首轮调用 AI,后续原话并入当前草稿后交由既有服务端本地复核,真机复验后续整理耗时 `1ms`,确认卡及“确认投稿”按钮均已显示但未点击,未形成正式投稿。移动端 206 项测试、类型检查、App 发布资源预检和 App-Plus 构建通过;调查用 `0.1.14/0.1.15` APK 已删除。DCloud 当日云打包额度耗尽,最终 `0.1.16` 签名 APK、深检和同包真机复验仍未完成,因此当前仍为 No-Go,未发布移动 H5、原生 App、后端、管理端或数据库。
- **2026-07-29,资料处理中心普通文档/图片单文件 500MB 已发布并完成生产验证**:管理端批量导入、后端异步队列、ZIP 子文件和 Tika 输入流统一允许受支持文件 `≤500MiB`,沿用生产 Spring/Undertow `500MB/520MB` 传输层配置;仍保留 ZIP 最多 1000 个子文件、解压总量 ≤2GB、禁止嵌套 ZIP 等安全边界,同步 SOP 上传和公司文件继续保持 100MB。生产实测发现首个候选虽已放宽页面和队列校验,但 Tika 内仍残留独立 `100MiB` 输入流上限,导致首批队列 `1194/1195` 上传成功后加工失败;补齐解析器上限及回归断言后,11 项定向后端测试和后端生产打包通过。管理端发布前备份整站到 `/opt/wygj/backups/www-20260729213203`,线上 `processing-BjvQ3qpr.js` 与本地产物 SHA-256 均为 `6ace59477519d6c53cbfe207a229518a7e2f7568e05961cfea28d669e1eeb305`,移动 H5 树哈希保持 `ba4aa656d64fc301141280357c204a67141d1e6b2e2a26a0be21c0dd48a25712` 未变。最终后端 JAR SHA-256 为 `be16c229cfc255e4cdf5ec32df047994b54d7d2c31b6c729dde6d949e191e53d`,旧包备份在 `/opt/wygj/backups/backend-20260729214901-5ef5dd484b5d`;整包及内嵌 `ruoyi-aihr-5.6.2.jar` 远近端哈希一致,服务、公开接口、64/64 schema 和生产禁运行时 DDL 预检均通过。已登录生产 Chrome 验收批次 `b-c2560e95-0cf7-46e0-9bdc-7690ea86ffd7` 中,`4、巡检表(事业部颗粒归仓专用).xlsx`(101.6MB,队列 `1196`、附件 `2036`)完成 5 个片段和 5 个向量,`新员工培训-社区发展中心-社区资源.pptx`(147.9MB,队列 `1197`、附件 `2037`)完成 7 个片段和 7 个向量;两项均显示“已完成/已入库”,数据库片段均含 embedding。资料总数从 1032 增至 1034,目标空间从 22 增至 24 个文件,处理中和需处理均为 0。本次只定向发布后端与管理端,未重发移动 H5、未执行 schema 迁移,不代表当前工作树与线上完整包全部匹配。 - **2026-07-29,资料处理中心普通文档/图片单文件 500MB 已发布并完成生产验证**:管理端批量导入、后端异步队列、ZIP 子文件和 Tika 输入流统一允许受支持文件 `≤500MiB`,沿用生产 Spring/Undertow `500MB/520MB` 传输层配置;仍保留 ZIP 最多 1000 个子文件、解压总量 ≤2GB、禁止嵌套 ZIP 等安全边界,同步 SOP 上传和公司文件继续保持 100MB。生产实测发现首个候选虽已放宽页面和队列校验,但 Tika 内仍残留独立 `100MiB` 输入流上限,导致首批队列 `1194/1195` 上传成功后加工失败;补齐解析器上限及回归断言后,11 项定向后端测试和后端生产打包通过。管理端发布前备份整站到 `/opt/wygj/backups/www-20260729213203`,线上 `processing-BjvQ3qpr.js` 与本地产物 SHA-256 均为 `6ace59477519d6c53cbfe207a229518a7e2f7568e05961cfea28d669e1eeb305`,移动 H5 树哈希保持 `ba4aa656d64fc301141280357c204a67141d1e6b2e2a26a0be21c0dd48a25712` 未变。最终后端 JAR SHA-256 为 `be16c229cfc255e4cdf5ec32df047994b54d7d2c31b6c729dde6d949e191e53d`,旧包备份在 `/opt/wygj/backups/backend-20260729214901-5ef5dd484b5d`;整包及内嵌 `ruoyi-aihr-5.6.2.jar` 远近端哈希一致,服务、公开接口、64/64 schema 和生产禁运行时 DDL 预检均通过。已登录生产 Chrome 验收批次 `b-c2560e95-0cf7-46e0-9bdc-7690ea86ffd7` 中,`4、巡检表(事业部颗粒归仓专用).xlsx`(101.6MB,队列 `1196`、附件 `2036`)完成 5 个片段和 5 个向量,`新员工培训-社区发展中心-社区资源.pptx`(147.9MB,队列 `1197`、附件 `2037`)完成 7 个片段和 7 个向量;两项均显示“已完成/已入库”,数据库片段均含 embedding。资料总数从 1032 增至 1034,目标空间从 22 增至 24 个文件,处理中和需处理均为 0。本次只定向发布后端与管理端,未重发移动 H5、未执行 schema 迁移,不代表当前工作树与线上完整包全部匹配。
+3 -3
View File
@@ -11,9 +11,9 @@
- 品牌:管理端与员工端统一显示“帮道”,继续使用现有红色品牌图标。 - 品牌:管理端与员工端统一显示“帮道”,继续使用现有红色品牌图标。
- 基础链路:租户列表、验证码、`000000 / admin / admin123` 加密登录已验证。 - 基础链路:租户列表、验证码、`000000 / admin / admin123` 加密登录已验证。
- 管理端:除 AI 面试、训练、案例、SOP 和资料处理外,已包含大喇叭发布、单文件提炼与多岗位解读、五渠道直通反馈收件箱、内容/任务运营、问题榜运营、知识空间、全网 AI 配置和组织权限;员工个人训练、主管复盘、团队难题、成长证据与训练录音仅在认证 APP 按项目范围访问。 - 管理端:除 AI 面试、训练、案例、SOP 和资料处理外,已包含大喇叭发布、单文件提炼与多岗位解读、五渠道直通反馈收件箱、内容/任务运营、问题榜运营、知识空间、全网 AI 配置和组织权限;员工个人训练、主管复盘、团队难题、成长证据与训练录音仅在认证 APP 按项目范围访问。
- 用户侧:`mobile-uni/` 承载员工、候选人和主管三端;“问”已改为数字师傅 Agent,文字、ASR 转写和图片/视频统一先做意图规划,再按服务端权限调用知识、训练、待办、记忆、媒体或全网工具,寒暄和不完整表达不再机械落入 RAG。现有能力还包括手机号登录、30 分钟短期多轮、原文件/视频受控交付、大喇叭公司文件摘要/下载/多岗位解读/追问、五渠道直通反馈、“记一下”确认卡、三级字号、训练/题目反馈、问题榜与积分、岗位考试、案例、候选面试/资料、主管复盘/派发及学员模式。Agent 代码已随 2026-07-25 完整包部署;2026-07-29 当前 DCloud 云端证书内测 APK 为 `0.1.13 (113)`,SHA-256 `FA2D2A6DC84AE759714E6D16D146C1E1552A0F3F53C046069422012361D1D0C0`,启动阶段不展示 DCloud 原生隐私确认,法务同意统一由登录页承担。该版进一步让认证身份、角色和组织岗位异常失败关闭,不再回退为普通员工或公开首页;移动端 199 项、`ruoyi-aihr` 700 项、类型检查、App-Plus 资源和 APK 深检已通过。干净提交 `af8af2f6` 的统一 RC 已达到 `releaseEligible=true`,证据在 `output/aug1-rc/0.1.13-113-af8af2f6-frozen/`;冻结候选后端 JAR SHA-256 为 `93AD272118F6A28F88C2BFA305F5C450E163CBE22577FF5BE3E85B3BD3958DAD`,其语义已包含在 2026-07-29 后续定向发布的生产 JAR `5376B67B…` 中。当前双提交交付包为 `output/aug1-release/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 只作历史追溯。生产现有在职 APP 账号的固定码链路已经完整通过首次获取/登录、认证只读主路径、退出、旧令牌失效、等待防刷窗口后的再次获取和重新登录,应用日志确认两次均未真实发送短信;固定码、登录和重新登录不再列为功能缺口。当前 x86_64 AVD 对仅含 ARM ABI 的 DCloud Weex 运行时出现 IPC 超时;浏览器截图只作布局和交互补充证据,不替代 App 运行、认证业务或设备能力验收,也不因此修改发布 ABI、增加降级路径或启用兜底内容。机器签认当前准确显示正式场景 `0/5`、有据问题 `0/30`、通道验收 `0/5`、负责人签认 `0/5`、受控分发 `PENDING`,五个处理角色有效绑定均为 `0`;生产后端定向发布已经完成,但业务签认、受控分发和真机门禁仍未闭环,当前 Go/No-Go 仍为 No-Go。旧 `mobile/` 只用于历史回溯。 - 用户侧:`mobile-uni/` 承载员工、候选人和主管三端;“问”统一由服务端 Agent 规划知识、训练、待办、记忆、媒体或全网工具。现有能力还包括手机号登录、短期多轮、受控原文件/视频、大喇叭、五通道直通车、确认式记忆、训练与考试、成果投稿、候选面试/资料及主管复盘/派发。旧 `mobile/` 只用于历史回溯。
- 2026-07-30 增量状态:五通道处理人自助配置和 Android 权限 Activity 生命周期修复已实现并完成本地自动化/浏览器/App-Plus 构建验证,但尚未发布;生产新配置接口仍为 404,五个角色各为 `0` 人。最新生成的签名 `0.1.16 (116)` APK 不包含最终窗口焦点修复且包内业务资源与当前构建不一致,不能作为当前源码候选,后续必须用新版本号重新签名并做同包真机回归。详见 [Changelog](CHANGELOG.md) 与 [Go/No-Go](docs/帮道8月1日Android内测Go-No-Go-20260728.md)。 - 2026-07-30 增量状态:五通道处理人配置和 Android 权限 Activity 生命周期修复已部署;生产五个处理角色按有效后台用户口径均为 `2/2`。签名 `0.1.17 (117)` 已通过 API 35、网络安全、法务、签名和包内业务资源深检,并在 vivo Android 15 真机完成正式账号登录、学习中心、麦克风允许/拒绝/恢复、系统选择器取消、音频选择/ASR、成果投稿确认保存及五通道入口回归。移动端 209 项、后端定向 46 项、管理端直通车 4 项和类型检查均通过。详见 [Go/No-Go](docs/帮道8月1日Android内测Go-No-Go-20260728.md)。
- Android 当前边界:最后一个签名内测包仍是 `0.1.13 (113)`;它已在 vivo Android 15 真机完成真实页面登录、麦克风允许和生产 ASR,但麦克风拒绝后的文件降级存在缺陷。当前源码为 `0.1.16 (116)`,已改用 Android 系统文档选择器、SAF `FileChannel` 复制、应用专属外部缓存和 App 媒体选择器;206 项移动端测试、类型检查、App 发布资源预检、App-Plus 构建及标准调试基座的真实 WAV 选择/上传/生产 ASR 已通过。DCloud 当日云打包额度耗尽,尚无 `0.1.16` 签名 APK,调试基座不能替代最终签名包验收。 - Android 当前边界:`0.1.17` 已是当前技术候选,但仍使用 DCloud 测试签名;真实断网、WebRTC、实际图片/视频/文档上传、受控下载及主管/候选人同包回归未完成。严格签认仍为场景 `0/5`、题目 `0/30`、通道验收 `0/5`、负责人 `0/5`、受控分发 `PENDING`,因此正式 8 月 1 日发布结论仍为 No-Go。
- 英雄路径:AI 面试(真模型出题/评分)、三角色对练(真 LLM 客户回复+评分,ASR/TTS 配置后支持语音)、案例沉淀(真实语音上传+ASR 转写+模型整理)均为真模型优先、未配置或失败回退本地兜底;生产短音频 ASR 当前为阿里云百炼 `qwen3-asr-flash`,SiliconFlow audio 接口保留兼容。SOP 知识库已接中文关键词 + MySQL Fulltext + Qdrant 混合召回 + rerank 重排,支持 txt/md/PDF/Word/Excel/PPT/图片/视频上传解析入库(图片走 vision OCR,视频走 ffmpeg 抽音轨转写+关键帧描述),资料处理中心支持 ZIP 异步展开后逐文件入队;模型配置页可查看向量库维度/点数并一键重建。 - 英雄路径:AI 面试(真模型出题/评分)、三角色对练(真 LLM 客户回复+评分,ASR/TTS 配置后支持语音)、案例沉淀(真实语音上传+ASR 转写+模型整理)均为真模型优先、未配置或失败回退本地兜底;生产短音频 ASR 当前为阿里云百炼 `qwen3-asr-flash`,SiliconFlow audio 接口保留兼容。SOP 知识库已接中文关键词 + MySQL Fulltext + Qdrant 混合召回 + rerank 重排,支持 txt/md/PDF/Word/Excel/PPT/图片/视频上传解析入库(图片走 vision OCR,视频走 ffmpeg 抽音轨转写+关键帧描述),资料处理中心支持 ZIP 异步展开后逐文件入队;模型配置页可查看向量库维度/点数并一键重建。
- 资料处理:已新增解析任务状态页,按 `aihr_knowledge_attach` 和 `aihr_knowledge_fragment` 展示待重试、解析中、已完成、失败、片段数和向量化状态;任务列表按当前筛选结果前端分页(10/20/50 条,筛选或刷新回到第一页)。页面只保留“批量导入”,通过异步队列处理多文件或 ZIP,不提供浏览器目录选择和服务端目录导入入口。历史图片/视频若无片段会保持可重试失败,可直接从原 OSS 文件重新入队;2026-07-29 生产已用该链路恢复原卡住的 4 项资料,全部生成片段并入库。后端目录导入接口仅保留为运维/调试能力。 - 资料处理:已新增解析任务状态页,按 `aihr_knowledge_attach` 和 `aihr_knowledge_fragment` 展示待重试、解析中、已完成、失败、片段数和向量化状态;任务列表按当前筛选结果前端分页(10/20/50 条,筛选或刷新回到第一页)。页面只保留“批量导入”,通过异步队列处理多文件或 ZIP,不提供浏览器目录选择和服务端目录导入入口。历史图片/视频若无片段会保持可重试失败,可直接从原 OSS 文件重新入队;2026-07-29 生产已用该链路恢复原卡住的 4 项资料,全部生成片段并入库。后端目录导入接口仅保留为运维/调试能力。
- 组织人员:`aihr_org_snapshot` 本地 reset 保留演示 seed;生产通过 `POST /api/aihr/org/sync` 同步外部组织。2026-07-25 记录的生产快照为 3417 人、2938 人在职且均有姓名、3392 个手机号映射、175 名在职主管和 20 名项目经理;姓名通过稳定 `employee_id` 定向补齐,未执行全量覆盖。当前上游 `employee_number` 与既有主体不一致且手机号大量脱敏,修复契约前禁止强制全量同步;人数属于时点事实,发布或验收前应重新查询。 - 组织人员:`aihr_org_snapshot` 本地 reset 保留演示 seed;生产通过 `POST /api/aihr/org/sync` 同步外部组织。2026-07-25 记录的生产快照为 3417 人、2938 人在职且均有姓名、3392 个手机号映射、175 名在职主管和 20 名项目经理;姓名通过稳定 `employee_id` 定向补齐,未执行全量覆盖。当前上游 `employee_number` 与既有主体不一致且手机号大量脱敏,修复契约前禁止强制全量同步;人数属于时点事实,发布或验收前应重新查询。
+3 -3
View File
@@ -295,7 +295,7 @@
- 生产服务保持 `AIHR_PRACTICE_RUNTIME_SCHEMA_BOOTSTRAP` 关闭,远端只读 schema 预检为 `64/64`,后端 JAR 与 AIHR 模块哈希和发布源一致;请求仍只能校验结构,不能执行 DDL。 - 生产服务保持 `AIHR_PRACTICE_RUNTIME_SCHEMA_BOOTSTRAP` 关闭,远端只读 schema 预检为 `64/64`,后端 JAR 与 AIHR 模块哈希和发布源一致;请求仍只能校验结构,不能执行 DDL。
- 2026-07-25 15:44:45,源码提交 `acd5fd3a` 增加常规陪练“建议回复”:服务端根据当前回合与教练提示生成可编辑但不自动发送的员工回复,失败时不复制提示。该提交已推送、尚未部署或生产验证。 - 2026-07-25 15:44:45,源码提交 `acd5fd3a` 增加常规陪练“建议回复”:服务端根据当前回合与教练提示生成可编辑但不自动发送的员工回复,失败时不复制提示。该提交已推送、尚未部署或生产验证。
- 2026-07-29,8 月 1 日 `0.1.13 (113)` 候选已在干净提交 `af8af2f6` 完成统一 RC,`releaseEligible=true`;199 项移动端测试、类型检查、H5/App、管理端构建、`ruoyi-aihr` 700 项测试、后端打包和 APK 深检通过,证据在 `output/aug1-rc/0.1.13-113-af8af2f6-frozen/`。生产固定码完成首次获取/登录、退出、旧令牌失效、等待防刷窗口后的再次获取和重新登录,两次均确认未真实发送短信;该项不再列为缺口。候选后端 JAR SHA-256 为 `93AD272118F6A28F88C2BFA305F5C450E163CBE22577FF5BE3E85B3BD3958DAD`,生产只读发布计划通过但未获部署授权、未发布。当前双提交交付包 `output/aug1-release/bangdao-aug1-0.1.13-113-af8af2f6-ops46f4616b.zip` 大小 `192,948,093` 字节,SHA-256 为 `F6DF4AB2660A4D3523C7E9785C1F8B572770F1F795A841E2D95C88936A8AE9C0`,20 个条目和内部哈希已复核;严格门禁覆盖正式场景、问题证据、五类负责人、五通道授权/越权/单次正式回复和受控分发/法务/签名决策,包内 Go/No-Go 已指向当前双提交包,旧 `ops9c53668c` ZIP 只作历史追溯。当前机器签认仍为正式场景 `0/5`、问题证据 `0/30`、通道验收 `0/5`、负责人签认 `0/5`、受控分发 `PENDING`。 - 2026-07-29,8 月 1 日 `0.1.13 (113)` 候选已在干净提交 `af8af2f6` 完成统一 RC,`releaseEligible=true`;199 项移动端测试、类型检查、H5/App、管理端构建、`ruoyi-aihr` 700 项测试、后端打包和 APK 深检通过,证据在 `output/aug1-rc/0.1.13-113-af8af2f6-frozen/`。生产固定码完成首次获取/登录、退出、旧令牌失效、等待防刷窗口后的再次获取和重新登录,两次均确认未真实发送短信;该项不再列为缺口。候选后端 JAR SHA-256 为 `93AD272118F6A28F88C2BFA305F5C450E163CBE22577FF5BE3E85B3BD3958DAD`,生产只读发布计划通过但未获部署授权、未发布。当前双提交交付包 `output/aug1-release/bangdao-aug1-0.1.13-113-af8af2f6-ops46f4616b.zip` 大小 `192,948,093` 字节,SHA-256 为 `F6DF4AB2660A4D3523C7E9785C1F8B572770F1F795A841E2D95C88936A8AE9C0`,20 个条目和内部哈希已复核;严格门禁覆盖正式场景、问题证据、五类负责人、五通道授权/越权/单次正式回复和受控分发/法务/签名决策,包内 Go/No-Go 已指向当前双提交包,旧 `ops9c53668c` ZIP 只作历史追溯。当前机器签认仍为正式场景 `0/5`、问题证据 `0/30`、通道验收 `0/5`、负责人签认 `0/5`、受控分发 `PENDING`。
- 2026-07-29 后续获得独立授权并通过 `release-backend.sh` 完成生产后端定向发布;当前 JAR SHA-256 为 `5376b67b33b171b5c85e22cd6a2f20bbb0bc527fc50a223603d0aec3f6587bac`,服务、三个公开入口和后端 + schema 发布后预检通过,冻结候选所含的内容语义与移动身份失败关闭不再是生产阻断项。同批还发布资料处理媒体重试 schema 和管理端,移动 H5 未重发;正式内容、五通道处理人、受控分发和 Android 真机门禁仍保持 No-Go。 - 2026-07-29 后续获得独立授权并通过 `release-backend.sh` 完成生产后端定向发布;当时 JAR SHA-256 为 `5376b67b33b171b5c85e22cd6a2f20bbb0bc527fc50a223603d0aec3f6587bac`,服务、三个公开入口和后端 + schema 发布后预检通过,冻结候选所含的内容语义与移动身份失败关闭不再是生产阻断项。同批还发布资料处理媒体重试 schema 和管理端,移动 H5 未重发。
- 2026-07-29 真机完成签名 `0.1.13` 的真实页面登录、麦克风允许和生产 ASR,同时发现拒绝后的文件降级误用 App 不支持的 `uni.chooseFile`。当前源码 `0.1.16 (116)` 已改用 Android 系统文档选择器、SAF `FileChannel` 复制、应用专属外部缓存和 App 媒体选择器;206 项移动端测试、类型检查、App 发布资源预检、App-Plus 构建,以及 vivo 标准调试基座的取消、重复打开、真实 WAV 选择/上传/生产 ASR 已通过。DCloud 当日云打包额度耗尽,尚无 `0.1.16` 签名 APK,调试基座不能替代最终候选验收。 - 2026-07-30 当前签名候选已升级为 `0.1.17 (117)`。APK 深检通过包名/版本、API 35、禁止明文流量、DCloud 测试签名、登录法务和包内业务资源一致性;vivo Android 15 真机完成正式账号登录、学习中心、麦克风允许/拒绝/恢复、系统文件/媒体选择器取消、合成中文 WAV 选择/生产 ASR、成果投稿确认保存和五通道入口。移动端 209 项、后端定向 46 项、管理端直通车 4 项及类型检查通过;生产五个直通角色按有效后台用户口径均为 `2/2`。
当前只能确认 `0.1.13` 自动化候选已冻结、生产后端定向发布成功且 schema 为 64/64,以及 `0.1.16` 源码的 Android 音频链路在标准调试基座通过;不能把这些结果外推为 `0.1.16` 已出包或当前完整包已与线上匹配。正式内容与五通道处理人签认、主管真实复盘、最终签名包真机媒体和严格试点仍未完成,不能称“陪练模块完整交付完成”。 当前可以确认 `0.1.17` 技术候选已出包、深检并完成员工端真机主链路,但不能外推为当前完整包已与线上匹配或严格试点已通过。正式场景/题目、五通道业务验收、五类负责人、受控分发/签名/法务、主管真实复盘、真实断网、WebRTC、实际图片/视频/文档、受控下载和严格试点仍未完成,不能称“陪练模块完整交付完成”。
+1 -1
View File
@@ -12,7 +12,7 @@
> >
> 2026-07-25 直通车员工提交页新增语音转文字输入与渠道图标:语音复用既有 `/api/ai/asr` 链路,录音或权限失败仅提示改文字输入(表单页文字为主路径,不做选文件降级);本地自动化(150/150)与 mock API 浏览器验证通过,已推送 `origin/main`,未发布生产、未做真机验收。 > 2026-07-25 直通车员工提交页新增语音转文字输入与渠道图标:语音复用既有 `/api/ai/asr` 链路,录音或权限失败仅提示改文字输入(表单页文字为主路径,不做选文件降级);本地自动化(150/150)与 mock API 浏览器验证通过,已推送 `origin/main`,未发布生产、未做真机验收。
> >
> 2026-07-30 本地增量新增五通道处理人配置:只有 `superadmin` 可查看当前租户处理人、检索合格候选并增删角色绑定;服务端排除 APP 用户、超级管理员、停用/删除和跨租户账号,写请求复核 `expectedTenantId`,管理端按每通道至少 2 人展示就绪状态并在移除后不足时告警。全量后端 708 项、管理端定向 28 项和本地真实浏览器通过;生产新接口当前仍为 404、五个角色有效绑定仍均为 0,本项尚未发布且未写生产数据。 > 2026-07-30 增量新增并发布五通道处理人配置:只有 `superadmin` 可查看当前租户处理人、检索合格候选并增删角色绑定;服务端排除 APP 用户、超级管理员、停用/删除和跨租户账号,写请求复核 `expectedTenantId`,管理端按每通道至少 2 人展示就绪状态并在移除后不足时告警。生产只读查询按同一资格规则确认五个角色均为 `2/2`;人数门槛已满足,但通道负责人正例、越权反例和一次正式回复签认仍未完成。
> >
> 本文只维护当前结论、证据层级和剩余门槛。逐提交发布流水已从当前真相文档移除,需要追溯时使用 Git 历史;不得再用 2026-07-14/15 的“尚未发布”记录判断现网。 > 本文只维护当前结论、证据层级和剩余门槛。逐提交发布流水已从当前真相文档移除,需要追溯时使用 Git 历史;不得再用 2026-07-14/15 的“尚未发布”记录判断现网。
+7 -7
View File
@@ -54,11 +54,11 @@ Android 每个人工步骤完成后,可在不改变设备状态的前提下保
同一真机随后使用生产现有在职 APP 主体和固定码完成页面登录;账号、固定码和令牌未进入日志、截图或仓库。`0.1.13` 允许麦克风后,原生按住录音、上传和生产 ASR 已跑通,识别结果进入真实“问”主路径。拒绝麦克风后的文件降级同时暴露两个 App-Plus 缺陷:`uni.chooseFile` 在 App 不受支持,且 Native.js 无法可靠构造并传递 Java `byte[]`。调查包 `0.1.14/0.1.15` 仅用于定位,生成的 APK 已删除,不得分发。 同一真机随后使用生产现有在职 APP 主体和固定码完成页面登录;账号、固定码和令牌未进入日志、截图或仓库。`0.1.13` 允许麦克风后,原生按住录音、上传和生产 ASR 已跑通,识别结果进入真实“问”主路径。拒绝麦克风后的文件降级同时暴露两个 App-Plus 缺陷:`uni.chooseFile` 在 App 不受支持,且 Native.js 无法可靠构造并传递 Java `byte[]`。调查包 `0.1.14/0.1.15` 仅用于定位,生成的 APK 已删除,不得分发。
当前源码候选已升级为 `0.1.16 (116)`:Android 非媒体文件通过系统 `ACTION_OPEN_DOCUMENT` 选择,以 `ParcelFileDescriptor + FileChannel.transferFrom` 复制到应用专属外部缓存;页面生命周期会区分系统选择器暂时离开和真实离页,图片/视频改走 App 支持的 `uni.chooseMedia`,麦克风拒绝在启动录音前统一进入降级。vivo 真机使用 HBuilderX 5.22 标准调试基座完成选择器打开、取消、重复打开及选择 `100,542` 字节 WAV;复制后字节数一致,并继续完成 multipart 上传和生产 ASR。首次成果投稿验证只生成追问草稿,实际尚未显示“确认投稿”,不是已经出现按钮但未点击。复查又确认每轮补充重新调用模型会继续生成追问,且一次线上整理耗时 `94,965ms`,超过客户端 `45,000ms` 超时门限。当前源码改为首轮 AI 整理、后续原话并入当前草稿后交由既有服务端本地复核;同一真机复验后续整理耗时 `1ms`,已显示成果投稿确认卡和“确认投稿”按钮,但没有点击、没有形成正式投稿。当前 206/206 项移动端测试、类型检查、App 发布资源预检和 App-Plus 构建通过。 `0.1.16 (116)` 源码阶段完成了 Android 系统 `ACTION_OPEN_DOCUMENT`、`ParcelFileDescriptor + FileChannel.transferFrom`、应用专属外部缓存、App 媒体选择器和权限 Activity/页面生命周期修复,并在 HBuilderX 5.22 标准调试基座完成取消、重复打开和真实 WAV 上传/ASR。成果投稿阶段先后定位并修复了追问反复调用模型和 `45,000ms` 超时问题,确认卡已经能出现。上述调查只保留为历史过程。
2026-07-30,同一 vivo 真机的已登录线上会话进入“学习”中心时显示“发生未知异常”,但任务统计和知识引用仍能加载。生产只读日志确认只有 `GET /api/aihr/mobile/practice/mistakes` 失败:错题 SQL 使用 `String.formatted()` 填充身份参数时,把 JSON `LIKE '%"redFlag":true%'` 中的百分号误解析为格式指令,抛出 `UnknownFormatConversionException`。提交 `edb8c825` 的本地源码改为专用占位符替换并增加回归测试;后端 JAR `346687564b38adbba643fc7d94d2faedbb51449198b4eef6c3fa90fb99646c83` 已通过定向发布脚本完成生产备份、原子切换、重启及整包/内嵌模块、公开接口、64/64 schema 和生产禁运行时 DDL 预检。同一真机从“今日”重新进入后,顶部异常消失,错题本显示真实错题、分数和“去再练”入口;服务端对应请求在 `22ms` 内正常结束,重启后未再出现 `UnknownFormatConversionException`。证据位于 Git 已忽略的 `output/aug1-rc/android-acceptance/20260730-learning-after-backend-deploy/`。本项只验证该后端修复,不替代签名 `0.1.16` APK 或其余 Android/iOS 验收门禁。 2026-07-30,同一 vivo 真机的已登录线上会话进入“学习”中心时曾显示“发生未知异常”。生产只读日志确认 `GET /api/aihr/mobile/practice/mistakes` 的 JSON `LIKE` 百分号被 `String.formatted()` 误解析;提交 `edb8c825` 改为专用占位符并随后端 JAR `346687564b38adbba643fc7d94d2faedbb51449198b4eef6c3fa90fb99646c83` 定向发布。签名 `0.1.17` 真机复验已加载真实今日任务、岗位 SOP 和错题本,未再出现系统错误;证据位于 `output/aug1-rc/android-acceptance/20260730-123522-aug1-0.1.17-learning-center/`。
由于 DCloud 当日免费云打包次数已用尽,`0.1.16` 的最终签名 APK 尚未生成,标准调试基座证据不能冒充签名包验收。最后一个可重复校验的签名包仍是 `0.1.13 (113)`,但它不包含上述系统选择器修复;额度恢复或购买次数后必须重新云打包、深检并在同一真机复跑麦克风拒绝、选择器取消/选择和 ASR。当前结论因此仍为 No-Go。 当前 DCloud 测试签名候选已升级为 `0.1.17 (117)`:大小 `33,922,976` 字节,APK SHA-256 `0A8581D70A5988E4BDCF4BB3F0C88B4608FA8C6785FDCF1569DD56CE88E27F60`。拆包门禁确认包内业务资源与当前 App-Plus 构建一致;同一 APK 已在 vivo Android 15 真机完成登录、麦克风允许/拒绝/恢复、权限 Activity 返回、系统文件/媒体选择器取消、`191,352` 字节合成中文 WAV 选择和生产 ASR、成果投稿确认保存。正式结论仍为 No-Go 的原因已转为业务内容/通道/负责人签认、受控分发与企业签名决策,以及真实断网、WebRTC、实际图片/视频/文档、受控下载和其余角色门禁。
随后根据企业内部应用的体验决策,`0.1.12 (112)` 取消 DCloud 启动原生确认,法务同意统一放到登录页。新 APK 大小 `33,921,458` 字节,SHA-256 为 `DD24E5F20BC7C064F5059E538A1FAB7518DF46CBAB502F59A3629F0B1B1F5EBB`;包体门禁确认 `prompt=none`、登录页两个 HTTPS 链接和未勾选拦截均已内置。在同一 Android 15/API 35 虚拟机卸载旧包后全新安装,取证结果为原生隐私层 `not-visible`、四项敏感权限未授权、进程与前台 Activity 正常且无 Crash/ANR,证据位于 `output/aug1-rc/android-acceptance/20260729-021418-no-native-privacy-fresh-install-retry/`。当前 AVD 是 `x86_64`,而 APK 只含 `arm64-v8a/armeabi-v7a`;DCloud Weex 跨架构转译实际报 `spinWaitPeer timeout`、`sender is null` 和 IPC timeout,所以原生外壳可见但页面主体空白。该现象不证明产品页面失败,也不能作为页面通过证据;不得为此修改正式 ABI、回退 H5 壳或增加业务兜底。 随后根据企业内部应用的体验决策,`0.1.12 (112)` 取消 DCloud 启动原生确认,法务同意统一放到登录页。新 APK 大小 `33,921,458` 字节,SHA-256 为 `DD24E5F20BC7C064F5059E538A1FAB7518DF46CBAB502F59A3629F0B1B1F5EBB`;包体门禁确认 `prompt=none`、登录页两个 HTTPS 链接和未勾选拦截均已内置。在同一 Android 15/API 35 虚拟机卸载旧包后全新安装,取证结果为原生隐私层 `not-visible`、四项敏感权限未授权、进程与前台 Activity 正常且无 Crash/ANR,证据位于 `output/aug1-rc/android-acceptance/20260729-021418-no-native-privacy-fresh-install-retry/`。当前 AVD 是 `x86_64`,而 APK 只含 `arm64-v8a/armeabi-v7a`;DCloud Weex 跨架构转译实际报 `spinWaitPeer timeout`、`sender is null` 和 IPC timeout,所以原生外壳可见但页面主体空白。该现象不证明产品页面失败,也不能作为页面通过证据;不得为此修改正式 ABI、回退 H5 壳或增加业务兜底。
@@ -77,18 +77,18 @@ Android 每个人工步骤完成后,可在不改变设备状态的前提下保
- [x] `0.1.8 (108)` 在同一虚拟机完成保留数据覆盖安装、标准 Launcher 启动和首次隐私弹窗前的后台/前台恢复,未见 FATAL 或 ANR。 - [x] `0.1.8 (108)` 在同一虚拟机完成保留数据覆盖安装、标准 Launcher 启动和首次隐私弹窗前的后台/前台恢复,未见 FATAL 或 ANR。
- [x] `0.1.10 (110)` 从 `0.1.9` 保留数据覆盖安装并冷启动成功,最新原生隐私弹窗、未授权权限基线和无 FATAL/ANR 状态保持。 - [x] `0.1.10 (110)` 从 `0.1.9` 保留数据覆盖安装并冷启动成功,最新原生隐私弹窗、未授权权限基线和无 FATAL/ANR 状态保持。
- [x] 只读统一取证脚本已通过状态变更命令回归并在虚拟机实跑,可重复保存当前版本、Activity、隐私控件、权限、UI、截图和退出记录。 - [x] 只读统一取证脚本已通过状态变更命令回归并在虚拟机实跑,可重复保存当前版本、Activity、隐私控件、权限、UI、截图和退出记录。
- [x] 媒体选择取消/真实失败、Android 系统选择器生命周期、直通车首次弱网恢复和登录法务门禁状态机已由当前 206/206 个移动端测试覆盖;真实断网恢复仍列为下方人工门禁。 - [x] 媒体选择取消/真实失败、Android 系统选择器生命周期、直通车首次弱网恢复和登录法务门禁状态机已由当前 209/209 个移动端测试覆盖;真实断网恢复仍列为下方人工门禁。
- [x] `0.1.12 (112)` 全新安装后不显示原生隐私确认,四项敏感权限保持未授权且无 Crash/ANR;包内登录协议门禁与统一 RC 自动校验通过。 - [x] `0.1.12 (112)` 全新安装后不显示原生隐私确认,四项敏感权限保持未授权且无 Crash/ANR;包内登录协议门禁与统一 RC 自动校验通过。
- [x] `0.1.13 (113)` 在 vivo Android 15 真机完成保留数据升级、同版本覆盖安装、冷启动、登录法务门禁、两个线上法务正文和前后台热恢复;四项敏感权限保持未授权且未见 Crash/ANR。 - [x] `0.1.13 (113)` 在 vivo Android 15 真机完成保留数据升级、同版本覆盖安装、冷启动、登录法务门禁、两个线上法务正文和前后台热恢复;四项敏感权限保持未授权且未见 Crash/ANR。
- [x] 同一真机在签名 `0.1.13` 完成真实页面登录和麦克风允许后的原生录音/生产 ASR;当前 `0.1.16` 源码又在 HBuilderX 标准调试基座完成 Android 系统选择器取消、重复打开、真实 WAV 选择、精确复制、上传、生产 ASR 和无提交草稿整理。 - [x] 同一真机在签名 `0.1.17` 完成真实页面登录、麦克风允许/拒绝/恢复、原生录音取消、系统文件/媒体选择器取消、真实 WAV 选择/生产 ASR 和成果投稿确认保存。
## Android(最低 Android 10 + 一台当前主流机型) ## Android(最低 Android 10 + 一台当前主流机型)
- [x] 登录页协议默认未勾选;两个法务链接能打开正确正文;未勾选时验证码和登录均不发请求,勾选后才允许继续。 - [x] 登录页协议默认未勾选;两个法务链接能打开正确正文;未勾选时验证码和登录均不发请求,勾选后才允许继续。
- [x] 在 Android 设备选择数据库现有有效手机号,点击获取验证码后使用生产固定码登录;未开启真实短信,且未保存手机号、固定码或令牌。 - [x] 在 Android 设备选择数据库现有有效手机号,点击获取验证码后使用生产固定码登录;未开启真实短信,且未保存手机号、固定码或令牌。
- [ ] 首次录音允许麦克风后,可完成转写;拒绝麦克风后不循环申请,能选择本地音频继续。允许分支已在签名 `0.1.13` 通过;拒绝、取消、重复选择和本地音频 ASR 已在 `0.1.16` 标准调试基座通过,仍须等待 `0.1.16` 签名 APK 后复跑。 - [x] 首次录音允许麦克风后可完成转写;拒绝麦克风后系统“禁止”生效、不循环申请,并能进入本地音频选择继续 ASR。签名 `0.1.17` 已完成允许、拒绝、选择器取消、WAV 选择、生产 ASR和权限恢复。
- [ ] 原生实时对练可完成麦克风授权、实时转写与远端语音播放;WebRTC/WebView 不可用或断线时明确提示并保留录音对练。 - [ ] 原生实时对练可完成麦克风授权、实时转写与远端语音播放;WebRTC/WebView 不可用或断线时明确提示并保留录音对练。
- [ ] 图片、视频、文档和音频可选择并上传;受控附件下载后可打开,不泄露 OSS 地址。当前仅完成 `0.1.16` 调试基座的 Android 音频选择/上传/ASR,图片、视频、文档、受控下载和最终签名包仍待验收。 - [ ] 图片、视频、文档和音频可选择并上传;受控附件下载后可打开,不泄露 OSS 地址。签名 `0.1.17` 已完成音频选择/上传/ASR及图片/视频选择器取消;实际图片、视频、文档和受控下载仍待验收。
- [ ] 前后台切换、网络断开/恢复、窄屏和底部手势区无白屏、遮挡或重复提交。 - [ ] 前后台切换、网络断开/恢复、窄屏和底部手势区无白屏、遮挡或重复提交。
- [ ] 再次安装同版本后,桌面图标、启动图和 Android 导航栏不闪白。 - [ ] 再次安装同版本后,桌面图标、启动图和 Android 导航栏不闪白。
+2 -2
View File
@@ -74,7 +74,7 @@ APK 门禁还会比较包内与当前 `dist/build/app/app-service.js` 的 SHA-25
```powershell ```powershell
.\scripts\prepare-aug1-rc.ps1 ` .\scripts\prepare-aug1-rc.ps1 `
-ApkPath '.\mobile-uni\dist\debug\bangdao-0.1.13-dcloud-test.apk' ` -ApkPath '.\mobile-uni\dist\debug\bangdao-0.1.17-dcloud-test.apk' `
-BuildKind dcloud-test -BuildKind dcloud-test
``` ```
@@ -82,7 +82,7 @@ APK 门禁还会比较包内与当前 `dist/build/app/app-service.js` 的 SHA-25
2026-07-28 最终自定义基座大小为 `21,158,193` 字节,SHA-256 为 `82D3352FF96A86F5DB4AC0C71DCB0ED6CEC98F2A785F6EAED2FE8D4FC0C5F704`。2026-07-29 最后一个已生成并可重复校验的独立内测包为 `bangdao-0.1.13-dcloud-test.apk`:包名 `com.yincheng.wygj`、版本 `0.1.13 (113)`、`targetSdkVersion=35`,大小 `33,921,543` 字节,SHA-256 为 `FA2D2A6DC84AE759714E6D16D146C1E1552A0F3F53C046069422012361D1D0C0`,签名证书 SHA-256 为 `AB06ECC0DE544DE73C385F3F0690B22966EBC12887FB8BEE1830CDBEFDEBEF5D`。APK 反编译门禁确认包内业务资源等于冻结时的 App-Plus 编译产物、启动原生隐私提示已关闭、登录页法务链接与未勾选拦截及身份加载失败关闭已进入包体,并通过敏感值、`usesCleartextTraffic=false`、`networkSecurityConfig` 和系统证书信任检查。干净提交 `af8af2f6dd169e4616a4ca0ca724e8b809502ab3` 的统一 RC 已完成,`releaseEligible=true`,证据在 `output/aug1-rc/0.1.13-113-af8af2f6-frozen/`;候选后端 JAR SHA-256 为 `93AD272118F6A28F88C2BFA305F5C450E163CBE22577FF5BE3E85B3BD3958DAD`。当前双提交交付包为 `output/aug1-release/bangdao-aug1-0.1.13-113-af8af2f6-ops46f4616b.zip`,大小 `192,948,093` 字节、SHA-256 为 `F6DF4AB2660A4D3523C7E9785C1F8B572770F1F795A841E2D95C88936A8AE9C0`,20 个条目和内部哈希已复核;严格门禁覆盖正式场景、问题证据、五类负责人、五通道授权/越权/单次正式回复和受控分发/法务/签名决策,包内 Go/No-Go 已指向当前双提交包,`ops9c53668c`、`0.1.12` 及更早 RC/交付 ZIP 只保留为历史基线。当前 AVD 为 `x86_64`,APK 原生库仅含 `arm64-v8a/armeabi-v7a`;安装和原生外壳可由系统转译运行,但 DCloud Weex JS 进程实际出现 `spinWaitPeer`/IPC 超时,页面主体空白不能用于判断产品页面。浏览器验证只作补充,不替代 App 运行;不会为了模拟器改变正式 ABI、回退为 H5 壳或增加业务兜底。该包仍使用 DCloud 云端测试证书,只能作为 8 月 1 日受控内测包;受控分发、法务例外和测试签名接受当前均待业务签认,企业正式 release 还必须使用签认后的企业证书摘要。 2026-07-28 最终自定义基座大小为 `21,158,193` 字节,SHA-256 为 `82D3352FF96A86F5DB4AC0C71DCB0ED6CEC98F2A785F6EAED2FE8D4FC0C5F704`。2026-07-29 最后一个已生成并可重复校验的独立内测包为 `bangdao-0.1.13-dcloud-test.apk`:包名 `com.yincheng.wygj`、版本 `0.1.13 (113)`、`targetSdkVersion=35`,大小 `33,921,543` 字节,SHA-256 为 `FA2D2A6DC84AE759714E6D16D146C1E1552A0F3F53C046069422012361D1D0C0`,签名证书 SHA-256 为 `AB06ECC0DE544DE73C385F3F0690B22966EBC12887FB8BEE1830CDBEFDEBEF5D`。APK 反编译门禁确认包内业务资源等于冻结时的 App-Plus 编译产物、启动原生隐私提示已关闭、登录页法务链接与未勾选拦截及身份加载失败关闭已进入包体,并通过敏感值、`usesCleartextTraffic=false`、`networkSecurityConfig` 和系统证书信任检查。干净提交 `af8af2f6dd169e4616a4ca0ca724e8b809502ab3` 的统一 RC 已完成,`releaseEligible=true`,证据在 `output/aug1-rc/0.1.13-113-af8af2f6-frozen/`;候选后端 JAR SHA-256 为 `93AD272118F6A28F88C2BFA305F5C450E163CBE22577FF5BE3E85B3BD3958DAD`。当前双提交交付包为 `output/aug1-release/bangdao-aug1-0.1.13-113-af8af2f6-ops46f4616b.zip`,大小 `192,948,093` 字节、SHA-256 为 `F6DF4AB2660A4D3523C7E9785C1F8B572770F1F795A841E2D95C88936A8AE9C0`,20 个条目和内部哈希已复核;严格门禁覆盖正式场景、问题证据、五类负责人、五通道授权/越权/单次正式回复和受控分发/法务/签名决策,包内 Go/No-Go 已指向当前双提交包,`ops9c53668c`、`0.1.12` 及更早 RC/交付 ZIP 只保留为历史基线。当前 AVD 为 `x86_64`,APK 原生库仅含 `arm64-v8a/armeabi-v7a`;安装和原生外壳可由系统转译运行,但 DCloud Weex JS 进程实际出现 `spinWaitPeer`/IPC 超时,页面主体空白不能用于判断产品页面。浏览器验证只作补充,不替代 App 运行;不会为了模拟器改变正式 ABI、回退为 H5 壳或增加业务兜底。该包仍使用 DCloud 云端测试证书,只能作为 8 月 1 日受控内测包;受控分发、法务例外和测试签名接受当前均待业务签认,企业正式 release 还必须使用签认后的企业证书摘要。
当前源码版本为 `0.1.16 (116)`,已修复 Android 麦克风拒绝后的系统文件选择、SAF 复制、上传路径和页面生命周期;标准调试基座已在 vivo Android 15 真机完成真实 WAV 选择、上传和生产 ASR。`npm run verify:app-release` 与 `npm run build:app` 只证明出包输入资源可用。DCloud 当日云打包额度耗尽,尚未生成 `0.1.16` 签名 APK;`0.1.14/0.1.15` 调查 APK 已删除。不得把 `dist/build/app`、标准调试基座或旧 `0.1.13` 的哈希标为当前源码的签名候选。 当前源码和 DCloud 测试签名候选均为 `0.1.17 (117)`。APK 大小 `33,922,976` 字节,SHA-256 为 `0A8581D70A5988E4BDCF4BB3F0C88B4608FA8C6785FDCF1569DD56CE88E27F60`,签名证书 SHA-256 为 `AB06ECC0DE544DE73C385F3F0690B22966EBC12887FB8BEE1830CDBEFDEBEF5D`;拆包门禁已确认 API 35、禁止明文流量、登录法务和包内业务资源与当前 App-Plus 构建一致。同一 APK 已在 vivo Android 15 真机完成登录、麦克风允许/拒绝/恢复、系统选择器取消、音频选择/生产 ASR 和成果投稿确认。它仍是 DCloud 测试签名,不等于企业正式 release;受控分发、法务/签名接受和剩余设备门禁见 Go/No-Go。
企业正式签名 APK 还必须用发布负责人保管的证书摘要执行 release 模式核验;该模式会额外拒绝 `debuggable=true`、明文 HTTP 和签名摘要不一致: 企业正式签名 APK 还必须用发布负责人保管的证书摘要执行 release 模式核验;该模式会额外拒绝 `debuggable=true`、明文 HTTP 和签名摘要不一致:
@@ -8,29 +8,31 @@
## 结论 ## 结论
**当前为 No-Go,暂不能把现有 APK 标记为 8 月 1 日可分发版本。** **当前技术候选已可用于继续受控验收,但正式 8 月 1 日发布仍为 No-Go。**
`0.1.13` DCloud 云端证书 APK 已生成并通过深检,且在 vivo Android 15 真机完成真实页面登录、麦克风允许和生产 ASR;干净提交 `af8af2f6` 的统一 RC 曾达到 `releaseEligible=true`。随后生成的签名 `0.1.16 (116)` APK 也通过包名、API 35、明文流量和签名深检,但其内嵌 `app-service.js` 早于 2026-07-30 最终麦克风权限 Activity/窗口焦点修复,与当前 App-Plus 构建不一致,不能作为当前源码候选。当前源码已完成 Android 系统选择器、SAF 复制、上传路径和授权/选择器生命周期收口,并通过本地自动化与 App-Plus 构建;生产后端不再阻断,当前阻断点是用新版本号生成最终签名候选并同包复验、发布五通道配置能力后绑定经业务批准的处理人、正式业务内容与企业发布签认,以及真实断网、WebRTC、图片/视频/文档和受控下载等剩余真机门禁。 签名 `0.1.17 (117)` 已生成并通过包名、版本、API 35、禁止明文流量、DCloud 测试签名、登录法务与包内业务资源一致性深检;同一 APK 已覆盖安装到 vivo Android 15 真机,完成正式账号登录、学习中心、麦克风允许/拒绝/恢复、系统文件与媒体选择器取消、WAV 选择与生产 ASR、成果投稿确认保存,以及大喇叭到五通道直通车只读回归。生产五通道也已按服务端资格规则各配置 2 名有效后台处理人。当前阻断已从“没有当前签名包/没有处理人”收窄为正式内容、通道与负责人签认,受控分发/法务/签名决策,以及真实断网、WebRTC、实际图片/视频/文档和受控下载等剩余同包真机门禁。
## 已通过 ## 已通过
| 检查项 | 当前结果 | | 检查项 | 当前结果 |
|---|---| |---|---|
| 当前运行时冻结 | 干净提交 `af8af2f6dd169e4616a4ca0ca724e8b809502ab3` 的 `0.1.13 (113)` 统一 RC 已完成,`releaseEligible=true`;证据目录为 `output/aug1-rc/0.1.13-113-af8af2f6-frozen/`,候选后端 JAR SHA-256 为 `93AD272118F6A28F88C2BFA305F5C450E163CBE22577FF5BE3E85B3BD3958DAD` | | 当前运行时冻结 | 干净提交 `af8af2f6dd169e4616a4ca0ca724e8b809502ab3` 的 `0.1.13 (113)` 统一 RC 已完成,`releaseEligible=true`;证据目录为 `output/aug1-rc/0.1.13-113-af8af2f6-frozen/`,候选后端 JAR SHA-256 为 `93AD272118F6A28F88C2BFA305F5C450E163CBE22577FF5BE3E85B3BD3958DAD` |
| 移动端自动化 | 当前 208 项单元测试通过;TypeScript 类型检查通过;新增 Android SAF、FileChannel、应用专属外部缓存、麦克风预检、权限 Activity 焦点恢复和系统选择器生命周期回归,相关页面继续覆盖取消/平台失败分流 | | 移动端自动化 | 当前 209 项单元测试通过;TypeScript 类型检查通过;新增 Android SAF、FileChannel、应用专属外部缓存、麦克风预检、权限 Activity 焦点恢复、系统选择器生命周期,以及认证态 UI 审计不持久化手机号/验证码回归 |
| 构建 | 当前 App 发布资源预检与 App-Plus 构建通过;管理端生产构建与 28 项定向测试通过。已生成的签名 `0.1.16` APK 早于最终麦克风生命周期修复,包内业务资源与当前构建不一致,不能把它当成当前源码出包 | | 构建 | 当前 App 发布资源预检、App-Plus 构建和 `0.1.17` APK 深检通过;本轮另复跑后端学习/成果投稿/直通车/语音定向测试 46 项及管理端直通车测试 4 项,均通过 |
| P0 后端语义 | `ruoyi-aihr` 708 项全量测试通过,0 失败、0 错误;本轮新增五通道处理人配置的超级管理员、租户和候选人资格契约覆盖 | | P0 后端语义 | `ruoyi-aihr` 708 项全量测试通过,0 失败、0 错误;本轮新增五通道处理人配置的超级管理员、租户和候选人资格契约覆盖 |
| 内容候选门禁 | 已生成 5 个禁用场景候选和 30 道待审政策题,机器校验通过;正式可发布场景 `0`、正式有据标准答案 `0`,不得导入或启用 | | 内容候选门禁 | 已生成 5 个禁用场景候选和 30 道待审政策题,机器校验通过;正式可发布场景 `0`、正式有据标准答案 `0`,不得导入或启用 |
| 最终业务就绪门禁 | `verify-aug1-formal-content.mjs --strict` 和 `verify-aug1-release-readiness.sh --execute` 已落地并覆盖正反例;当前机器签认准确返回场景 `0/5`、问题证据 `0/30`、通道验收 `0/5`、负责人签认 `0/5`、受控分发 `PENDING` 并失败关闭。签认完成后还会只读核对生产固定码模式、五角色各至少两名有效处理人和五个已发布场景的版本/哈希/审核链/SOP 引用;不请求验证码、不登录、不发短信、不写数据库 | | 最终业务就绪门禁 | `verify-aug1-formal-content.mjs --strict` 和 `verify-aug1-release-readiness.sh --execute` 已落地并覆盖正反例;当前机器签认准确返回场景 `0/5`、问题证据 `0/30`、通道验收 `0/5`、负责人签认 `0/5`、受控分发 `PENDING` 并失败关闭。签认完成后还会只读核对生产固定码模式、五角色各至少两名有效处理人和五个已发布场景的版本/哈希/审核链/SOP 引用;不请求验证码、不登录、不发短信、不写数据库 |
| App 资源门禁 | 正式法务 URL、登录页同意门禁、原生 `prompt=none`、API 35、图标和启动图检查通过 | | App 资源门禁 | 正式法务 URL、登录页同意门禁、原生 `prompt=none`、API 35、图标和启动图检查通过 |
| 独立 APK | 最新生成文件为 `com.yincheng.wygj 0.1.16 (116)`,大小 `33,922,835` 字节,SHA-256 `183E67137CE9B73FC6D41A728779D40EB0122F8F62E1951B65DDC356203937F5`,`targetSdkVersion=35`、v2 DCloud 测试签名、明文 HTTP 关闭;但该包不含当前最终麦克风生命周期修复,不能作为当前候选。`0.1.13` 仍只保留为历史统一 RC | | 独立 APK | 当前候选为 `com.yincheng.wygj 0.1.17 (117)`,文件 `mobile-uni/dist/debug/bangdao-0.1.17-dcloud-test.apk`,大小 `33,922,976` 字节,SHA-256 `0A8581D70A5988E4BDCF4BB3F0C88B4608FA8C6785FDCF1569DD56CE88E27F60`,`targetSdkVersion=35`、DCloud 测试签名、明文 HTTP 关闭;签名证书 SHA-256 为 `AB06ECC0DE544DE73C385F3F0690B22966EBC12887FB8BEE1830CDBEFDEBEF5D` |
| 双提交交付包 | `output/aug1-release/bangdao-aug1-0.1.13-113-af8af2f6-ops46f4616b.zip`;运行时 `af8af2f6`、operations `46f4616b`,大小 `192,948,093` 字节,SHA-256 `F6DF4AB2660A4D3523C7E9785C1F8B572770F1F795A841E2D95C88936A8AE9C0`,20 个条目和内部哈希复核通过;严格门禁覆盖正式场景、问题证据、五类负责人、五通道授权/越权/单次正式回复和受控分发/法务/签名决策,包内 Go/No-Go 已指向当前双提交包,旧 `ops9c53668c` ZIP 只作历史追溯 | | 双提交交付包 | `output/aug1-release/bangdao-aug1-0.1.13-113-af8af2f6-ops46f4616b.zip`;运行时 `af8af2f6`、operations `46f4616b`,大小 `192,948,093` 字节,SHA-256 `F6DF4AB2660A4D3523C7E9785C1F8B572770F1F795A841E2D95C88936A8AE9C0`,20 个条目和内部哈希复核通过;严格门禁覆盖正式场景、问题证据、五类负责人、五通道授权/越权/单次正式回复和受控分发/法务/签名决策,包内 Go/No-Go 已指向当前双提交包,旧 `ops9c53668c` ZIP 只作历史追溯 |
| APK 内容门禁 | `0.1.16` 的原生提示、登录法务、未勾选拦截、身份失败关闭、敏感值和网络安全扫描通过;但包内 `app-service.js` SHA-256 为 `24BC971FE8A13DDCF6C4C2640A8F6C2241299A8C5B24A6452DE4D58CCF33CFAC`,当前构建为 `1A13F998BB43F3298CD40FE28FC85EEDBE0A9E9EDF5F0C6B7AD1FD7519C20C5B`,资源一致性门禁失败 | | APK 内容门禁 | `0.1.17` 的包名/版本、原生提示、登录法务、未勾选拦截、身份失败关闭、敏感值、网络安全、签名和包内业务资源与当前 App-Plus 构建一致性均通过 |
| 真机安装启动 | vivo V2443A(Android 15/API 35)完成当前 `0.1.13` 从 `0.1.6` 保留数据升级、同版本再次覆盖安装和 Launcher 冷启动;四项敏感权限保持未授权,未见 Crash/ANR | | 真机安装启动 | vivo V2443A(Android 15/API 35)已从签名 `0.1.16` 保留数据覆盖升级到签名 `0.1.17`,Launcher 启动、前台 Activity 和页面渲染正常,未见 Crash/ANR;录音权限在负向测试后已恢复为授权,图片/视频权限继续保持未授权 |
| 虚拟机安装与生命周期 | 本机 `Medium_Phone` Android 15/API 35 已全新安装 `0.1.12`;启动原生隐私层不可见、四项敏感权限为 `false`、未见 Crash/ANR。AVD 为 `x86_64`、APK 仅含 ARM ABI,Weex 跨架构转译实际报 `spinWaitPeer`/IPC timeout;原生外壳证据有效,页面主体既不判失败也不判通过,不向发布包增加 x86 ABI或 H5 兜底 | | 虚拟机安装与生命周期 | 本机 `Medium_Phone` Android 15/API 35 已全新安装 `0.1.12`;启动原生隐私层不可见、四项敏感权限为 `false`、未见 Crash/ANR。AVD 为 `x86_64`、APK 仅含 ARM ABI,Weex 跨架构转译实际报 `spinWaitPeer`/IPC timeout;原生外壳证据有效,页面主体既不判失败也不判通过,不向发布包增加 x86 ABI或 H5 兜底 |
| Android 统一取证 | 当前 `0.1.13 (113)` 进程和前台 Activity 正常、原生隐私层 `not-visible`、四项敏感权限为 `false`、退出记录无 Crash/ANR;Home 后进程保持,热恢复约 `0.2s`。证据在 `output/aug1-rc/android-acceptance/20260729-140453-upgrade-0.1.13-cold-launch/` | | Android 统一取证 | 当前 `0.1.17 (117)` 进程和前台 Activity 正常、原生隐私层 `not-visible`、未见历史 Crash/ANR;脱敏证据包括 `output/aug1-rc/android-acceptance/20260730-123230-aug1-0.1.17-authenticated-home/` 与 `20260730-123522-aug1-0.1.17-learning-center/` |
| 登录页法务策略 | 启动不再弹原生确认,包体门禁通过;vivo 真机实测协议默认未勾选、验证码/登录请求前失败关闭、勾选后进入验证码校验,两个链接分别打开线上服务协议和 2026-07-28 版隐私正文;脱敏截图不含手机号、验证码或令牌 | | 登录页法务策略 | 启动不再弹原生确认,包体门禁通过;vivo 真机实测协议默认未勾选、验证码/登录请求前失败关闭、勾选后进入验证码校验,两个链接分别打开线上服务协议和 2026-07-28 版隐私正文;脱敏截图不含手机号、验证码或令牌 |
| 真机登录与音频 | vivo 真机使用生产现有在职 APP 主体和固定码完成页面登录,签名 `0.1.13` 完成麦克风允许、原生录音和生产 ASR;当前 `0.1.16` 资源在 HBuilderX 5.22 标准调试基座完成系统选择器取消、重复打开、`100,542` 字节 WAV 精确复制、multipart 上传、生产 ASR 和成果草稿整理,未点击确认投稿。账号、固定码、令牌和业务正文未入库为证据 | | 真机登录与音频 | vivo 真机使用生产现有在职 APP 主体和固定码完成 `0.1.17` 页面登录;麦克风已覆盖允许、长按录音上滑取消、系统“禁止”、拒绝后的文件降级和权限恢复。系统文件/媒体选择器取消均正常回到 App;另选择 `191,352` 字节合成中文 WAV,生产 ASR 返回有效文本并进入问师傅,测试文件随后从手机和电脑删除 |
| 真机核心业务 | 学习中心加载真实今日任务、岗位 SOP 和错题本,无系统错误;成果投稿完成两条补充追问、确认卡和正式确认,返回投稿编号 `#7`、`PENDING/待审核`;大喇叭与直通车显示总裁、财务、人力、审计、运营五通道。测试投稿明确标记为 8 月 1 日真机验收记录 |
| 五通道处理人 | 生产只读查询按服务端同一资格规则排除 APP 用户、停用用户和超级管理员后,`direct_president/direct_finance/direct_hr/direct_audit/direct_operations` 均为 `2/2`,达到主处理人和备份门槛;人员身份不进入证据 |
| 生产固定码认证 | 运行时确认固定码和生产显式开关同时启用;生产应用日志确认首次和重新登录前的两次验证码请求均命中“未真实发送短信”分支。只选择已存在 `app_user` 的双向唯一在职主体,不触发自动注册,不输出手机号、固定码或令牌 | | 生产固定码认证 | 运行时确认固定码和生产显式开关同时启用;生产应用日志确认首次和重新登录前的两次验证码请求均命中“未真实发送短信”分支。只选择已存在 `app_user` 的双向唯一在职主体,不触发自动注册,不输出手机号、固定码或令牌 |
| 认证后非真机主路径 | `scripts/verify-aug1-authenticated-production.sh --execute` 通过身份/非空项目范围、认证首页、训练历史/画像、五通道、我的反馈、大喇叭、考试、案例/全网能力只读入口、退出、旧令牌业务码 401、防刷窗口后的再次获取、重新登录、重新读取身份和再次退出;五通道返回数为 5。未提交业务写入、附件、ASR/TTS 或 Agent 请求 | | 认证后非真机主路径 | `scripts/verify-aug1-authenticated-production.sh --execute` 通过身份/非空项目范围、认证首页、训练历史/画像、五通道、我的反馈、大喇叭、考试、案例/全网能力只读入口、退出、旧令牌业务码 401、防刷窗口后的再次获取、重新登录、重新读取身份和再次退出;五通道返回数为 5。未提交业务写入、附件、ASR/TTS 或 Agent 请求 |
| 法务静态页 | `https://peilian.njzhmj.top/legal/terms.html` 与 `https://peilian.njzhmj.top/legal/privacy.html` 已部署并可访问;发布前站点备份为 `/opt/wygj/backups/www-20260728224710` | | 法务静态页 | `https://peilian.njzhmj.top/legal/terms.html` 与 `https://peilian.njzhmj.top/legal/privacy.html` 已部署并可访问;发布前站点备份为 `/opt/wygj/backups/www-20260728224710` |
@@ -40,10 +42,10 @@
## No-Go 阻断项 ## No-Go 阻断项
1. **当前源码对应的最终签名候选包尚不存在。** `0.1.13` 的真实登录、麦克风允许和 ASR 已通过,但拒绝后的文件降级存在缺陷;`0.1.14/0.1.15` 仅为调查包且 APK 已删除。已生成的 `0.1.16` 签名包早于最终权限 Activity/窗口焦点修复,包内业务资源与当前构建不一致。必须使用新版本号生成、深检并真机复跑同一签名 APK,调试基座和旧 `0.1.16` 均不能替代该门禁。 1. **正式内容与负责人签认仍为空。** 严格门禁当前仍准确失败:`releaseStatus`、正式内容版本和来源未批准,5 个场景、30 道题、5 个通道、5 类负责人签认均未完成,正式可发布场景仍为 `0/5`,有据标准答案仍为 `0/30`。已上传资料和测试投稿不能自动替代业务审核。
2. **核心业务的非写入认证入口已通过,正式业务闭环仍受内容和处理人阻断。** 认证账号下身份、项目范围、首页、训练历史/画像、五通道列表、我的反馈、大喇叭、考试、案例和全网能力只读入口均已通过;五通道处理人配置已在本地实现并验证,但生产新接口仍为 404、五个角色有效绑定仍均为 0。正式“练”仍没有可发布的 5 个场景,图片/视频/文档、受控下载、WebRTC 和真实断网恢复仍待最终签名包真机验收。不得通过创建测试内容或绑定任意用户制造假闭环。 2. **剩余同包真机门禁尚未完成。** `0.1.17` 已覆盖登录、学习、麦克风正反例、文件/媒体选择器取消、音频选择和 ASR,但真实断网恢复、WebRTC、实际图片/视频/文档选择与上传、受控下载、主管/候选人角色同包回归仍需完成。
3. **内容与业务验收不足。** 当前仅收到 1/24 份生活顾问访谈。技术侧已把调研整理为 30 道政策题候选和 5 个场景候选,并提供统一签认单,但全部保持待审/禁用,正式可发布场景仍为 0/5,正式有据标准答案仍为 0/30。生产只读审计确认 `direct_president/direct_finance/direct_hr/direct_audit/direct_operations` 五个角色的有效用户绑定数均为 0,必须由业务负责人指定主处理人和替补后再验收。 3. **通道业务验收尚未签字。** 五通道各 2 名有效处理人已配置,员工端入口已通过;仍需获批处理人分别完成正例、跨通道越权反例和一次正式回复,并由通道负责人记录批准,不能仅用数据库人数代替业务验收。
4. **APK 分发与企业发布尚未签认。** 后端发布授权、备份、原子切换、发布后验证和回滚点已经闭环;最后一个签名 APK `0.1.13` 已关闭明文流量但不含当前选择器修复,`0.1.16` 尚未云打包。受控分发批准、测试签名接受、企业签名和公司法务正式签认仍是对应发布层级的门槛。 4. **APK 分发与企业发布尚未签认。** `0.1.17` 当前使用 DCloud 测试签名;受控分发批准、测试签名接受、企业签名/公司法务决策、分发证据哈希和发布负责人签字仍为 `PENDING`,因此不能称为 8 月 1 日正式可分发版本。
## 转为 Go 的最短路径 ## 转为 Go 的最短路径
@@ -53,9 +55,11 @@
| 已完成 | 在干净提交上冻结 `0.1.13` APK 与候选后端 JAR,并执行生产只读发布计划 | `releaseEligible=true`,冻结目录 `output/aug1-rc/0.1.13-113-af8af2f6-frozen/`;候选 JAR `93AD2721…` 和当时现网 `46C99CFF…` 只保留为冻结/发布前基线 | | 已完成 | 在干净提交上冻结 `0.1.13` APK 与候选后端 JAR,并执行生产只读发布计划 | `releaseEligible=true`,冻结目录 `output/aug1-rc/0.1.13-113-af8af2f6-frozen/`;候选 JAR `93AD2721…` 和当时现网 `46C99CFF…` 只保留为冻结/发布前基线 |
| 已完成 | 获得明确授权后使用 `release-backend.sh deploy` 发布内容语义、移动身份失败关闭和后续资料处理恢复;保留回滚点并完成发布后验证 | 生产 JAR `5376B67B…`、服务 active、三个公开入口 HTTP 200、媒体重试 schema 契约通过;管理端同步发布,移动 H5 未重发 | | 已完成 | 获得明确授权后使用 `release-backend.sh deploy` 发布内容语义、移动身份失败关闭和后续资料处理恢复;保留回滚点并完成发布后验证 | 生产 JAR `5376B67B…`、服务 active、三个公开入口 HTTP 200、媒体重试 schema 契约通过;管理端同步发布,移动 H5 未重发 |
| 已完成 | 使用生产现有在职 APP 主体和固定码完成非真机认证、退出、重新获取、重新登录及认证后只读主路径;固定码请求不真实发送短信 | `scripts/verify-aug1-authenticated-production.sh --execute` 全部通过,五通道数为 5,旧令牌按业务码 401 拒绝,两次验证码请求均有“未真实发送”日志;执行过程不输出手机号、固定码或令牌 | | 已完成 | 使用生产现有在职 APP 主体和固定码完成非真机认证、退出、重新获取、重新登录及认证后只读主路径;固定码请求不真实发送短信 | `scripts/verify-aug1-authenticated-production.sh --execute` 全部通过,五通道数为 5,旧令牌按业务码 401 拒绝,两次验证码请求均有“未真实发送”日志;执行过程不输出手机号、固定码或令牌 |
| 1 | 业务方按统一签认单审核 30 道题和 5 个场景候选,补齐正式来源;同时指定五渠道主处理人和替补 | [业务内容与五通道签认单](帮道8月1日业务内容与五通道签认单-20260729.md)、正式内容版本、授权矩阵;正式可发布场景从 0/5 提升到 5/5、有据标准答案从 0/30 提升到 30/30,五个角色有效绑定均不少于 2 | | 已完成 | 生成、深检并在 Android 15 真机安装当前 `0.1.17 (117)` 签名候选,复跑登录、学习中心、麦克风正反例、选择器取消、音频 ASR、成果投稿确认和五通道入口 | APK SHA-256 `0A8581D7…`、签名 `AB06ECC0…`、API 35、业务资源一致;录音权限测试后已恢复,测试音频已清理 |
| 2 | 绑定获批处理人后完成五通道正例、跨通道反例和一次正式回复;用正式内容完成“查/练/问”业务写入闭环 | 每条用例的时间、角色、结果和脱敏证据;不记录手机号、验证码或反馈正文 | | 已完成 | 为五个直通车角色配置符合资格的主处理人和备份 | 生产只读计数五个角色均为 `2/2`,不输出人员身份 |
| 3 | 使用新版本号(建议 `0.1.17 (117)`)生成并深检当前源码签名 APK,在 Android 真机复跑麦克风允许/拒绝、权限 Activity 返回、系统选择器取消/选择、音频 ASR,并继续完成真实断网、WebRTC、图片/视频/文档和受控下载 | 新 APK 版本、哈希、签名、包内业务资源与冻结构建一致,以及同一包对应的设备证据;当前标准调试基座和旧 `0.1.16` 均不得替代签名包验收 | | 1 | 业务方按统一签认单审核 30 道题和 5 个场景候选,补齐正式来源、五通道业务验收和五类负责人签字 | [业务内容与五通道签认单](帮道8月1日业务内容与五通道签认单-20260729.md)、正式内容版本、来源哈希、授权矩阵;场景 `5/5`、题目 `30/30`、通道 `5/5`、负责人 `5/5` |
| 4 | 7 月 31 日复跑安装、升级、回滚和完整 Go/No-Go | RC APK 哈希、签认人、回滚点、最终结论 | | 2 | 在同一 `0.1.17` 包继续完成真实断网、WebRTC、实际图片/视频/文档、受控下载及主管/候选人角色,并完成五通道正例/越权反例/一次正式回复 | 每条用例的时间、角色、结果和脱敏证据;不记录手机号、验证码、令牌或反馈正文 |
| 3 | 完成受控分发、测试签名接受或企业签名、公司法务和发布负责人决策 | `distributionApproval=APPROVED`、分发证据引用与 SHA-256、签名决定和签认时间 |
| 4 | 在干净提交上冻结 `0.1.17` APK 和交付包,7 月 31 日复跑安装、升级、回滚及完整 Go/No-Go | RC 提交、APK/交付包哈希、回滚点、签认人和最终结论 |
公司法务签认与企业签名可在负责人明确接受“仅限小范围受控内部测试”的前提下不阻断技术验收,但不能省略登录页协议门禁、权限反例、版本冻结、生产依赖匹配和核心业务闭环。 公司法务签认与企业签名可在负责人明确接受“仅限小范围受控内部测试”的前提下不阻断技术验收,但不能省略登录页协议门禁、权限反例、版本冻结、生产依赖匹配和核心业务闭环。
@@ -62,7 +62,7 @@
- 直通车已经支持五通道、业务匿名、按角色收件和一次正式回复。 - 直通车已经支持五通道、业务匿名、按角色收件和一次正式回复。
- 生产短音频 ASR 已切换到阿里云百炼 `qwen3-asr-flash`,并在一台 Android 标准基座完成过“按住说话→转写→提交”验证。 - 生产短音频 ASR 已切换到阿里云百炼 `qwen3-asr-flash`,并在一台 Android 标准基座完成过“按住说话→转写→提交”验证。
当前短板主要是:正式内容、五通道真实处理人、`0.1.16` 最终签名 APK、企业签名/法务签认,以及真实断网、WebRTC、图片/视频/文档和受控下载等剩余真机反例。生产后端定向发布与发布后预检已经完成;最后一个签名内测包仍是 `0.1.13`,当前 `0.1.16` 只有源码构建和标准调试基座证据,不能替代最终签名包或正式试点。 当前短板主要是:正式内容与五通道业务签认、受控分发/企业签名/法务决策,以及真实断网、WebRTC、实际图片/视频/文档、受控下载和主管/候选人角色等剩余真机门禁。生产后端与五通道处理人配置已经完成;当前 DCloud 测试签名候选为 `0.1.17 (117)`,已完成深检和员工端真机主链路,但不能替代上述业务与发布签认。
### 3.1 生产只读基线(2026-07-27) ### 3.1 生产只读基线(2026-07-27)
@@ -90,7 +90,7 @@
| 门禁 | 结果 | 说明 | | 门禁 | 结果 | 说明 |
|---|---|---| |---|---|---|
| `mobile-uni` 单元测试 | 通过 | 当前 206/206;新增 Android SAF、FileChannel、应用专属外部缓存、麦克风预检和系统选择器生命周期回归,既有身份/岗位失败关闭、取消/失败分流、九个消费页面、直通车弱网恢复及版本一致性继续通过 | | `mobile-uni` 单元测试 | 通过 | 当前 209/209;新增 Android SAF、FileChannel、应用专属外部缓存、麦克风预检、系统选择器生命周期和认证 UI 审计凭据不落盘回归,既有身份/岗位失败关闭、取消/失败分流、九个消费页面、直通车弱网恢复及版本一致性继续通过 |
| `mobile-uni` TypeScript 检查 | 通过 | `npm --prefix mobile-uni run typecheck` | | `mobile-uni` TypeScript 检查 | 通过 | `npm --prefix mobile-uni run typecheck` |
| H5 资源构建 | 通过 | 仅证明 H5 资源可编译 | | H5 资源构建 | 通过 | 仅证明 H5 资源可编译 |
| App-Plus 资源构建 | 通过 | 仅生成 HBuilderX 出包资源,不等同于 APK | | App-Plus 资源构建 | 通过 | 仅生成 HBuilderX 出包资源,不等同于 APK |
@@ -103,7 +103,7 @@
| `ruoyi-aihr` 后端全量测试 | 通过 | 700 个测试,0 失败、0 错误;包含正式场景占位来源/回合/Rubric 禁止发布和移动身份空结果失败关闭回归;Windows CRLF 引发的 7 个源码契约误判已通过读取时统一 LF 修复并全量复跑 | | `ruoyi-aihr` 后端全量测试 | 通过 | 700 个测试,0 失败、0 错误;包含正式场景占位来源/回合/Rubric 禁止发布和移动身份空结果失败关闭回归;Windows CRLF 引发的 7 个源码契约误判已通过读取时统一 LF 修复并全量复跑 |
| 法务配置技术链路 | 通过 | 登录协议默认不勾选;协议未配置时禁止验证码与登录;配置生成器和发布联网校验已接入,发布包拒绝开发验证码提示 | | 法务配置技术链路 | 通过 | 登录协议默认不勾选;协议未配置时禁止验证码与登录;配置生成器和发布联网校验已接入,发布包拒绝开发验证码提示 |
| 正式 App 发布配置校验 | **技术通过,法务签认阻断** | 受控内测版协议正文已通过 Caddy 公网 HTTPS 发布;启动原生提示关闭,登录页协议默认未勾选且验证码/登录失败关闭,包体与联网门禁使用同一组地址。公司法务尚未正式签认正文,不能视为正式发布通过 | | 正式 App 发布配置校验 | **技术通过,法务签认阻断** | 受控内测版协议正文已通过 Caddy 公网 HTTPS 发布;启动原生提示关闭,登录页协议默认未勾选且验证码/登录失败关闭,包体与联网门禁使用同一组地址。公司法务尚未正式签认正文,不能视为正式发布通过 |
| Android 设备、调试基座、测试签名和设备门禁 | **部分通过,仍阻断** | vivo Android 15 真机已在签名 `0.1.13` 完成真实页面登录、麦克风允许和生产 ASR;当前 `0.1.16` 源码又在 HBuilderX 5.22 标准调试基座完成系统选择器取消、重复打开、真实 WAV 选择、精确复制、multipart 上传和生产 ASR。DCloud 当日云打包额度耗尽,尚无包含修复的 `0.1.16` 签名 APK;真实断网、WebRTC、图片/视频/文档和受控下载仍待同一最终签名包验收 | | Android 设备、调试基座、测试签名和设备门禁 | **部分通过,仍阻断** | 签名 `0.1.17` 已在 vivo Android 15 真机完成正式账号登录、学习中心、麦克风允许/拒绝/恢复、权限 Activity 返回、系统文件/媒体选择器取消、真实 WAV 选择/生产 ASR、成果投稿确认保存和五通道入口;真实断网、WebRTC、实际图片/视频/文档、受控下载和其余角色仍待同包验收 |
统一 RC 脚本已在干净运行时提交 `dc20b92061f10a356ed73eb105ef7b00c8b8a617` 上完整复跑,证据目录为 `output/aug1-rc/0.1.10-110-dc20b920-frozen/`,结果为 `releaseEligible=true`。发布/回滚、API 探针和可识别隐私二次确认/退出态的 Android 取证工具另冻结在 operations commit `71f005c22981989c5f2b24fa31c385a1b82657b7`。当前双提交交付包为 `output/aug1-release/bangdao-aug1-0.1.10-110-dc20b920-ops71f005c2.zip`,大小 `192,926,422` 字节,SHA-256 为 `4391895420B50EBBD8CB87EA20AF71A70D5DABAD5003F5361A8B034CF7525BCA`;已完成 14 个 ZIP 条目和 13 个 `SHA256SUMS.txt` 载荷的逐条复验。旧无 operations 后缀包、`ops861fa0ea` 与 `ops414af66e` 包保留作追溯但均已被替代。上述本地自动化冻结不替代生产后端发布授权和人工验收。 统一 RC 脚本已在干净运行时提交 `dc20b92061f10a356ed73eb105ef7b00c8b8a617` 上完整复跑,证据目录为 `output/aug1-rc/0.1.10-110-dc20b920-frozen/`,结果为 `releaseEligible=true`。发布/回滚、API 探针和可识别隐私二次确认/退出态的 Android 取证工具另冻结在 operations commit `71f005c22981989c5f2b24fa31c385a1b82657b7`。当前双提交交付包为 `output/aug1-release/bangdao-aug1-0.1.10-110-dc20b920-ops71f005c2.zip`,大小 `192,926,422` 字节,SHA-256 为 `4391895420B50EBBD8CB87EA20AF71A70D5DABAD5003F5361A8B034CF7525BCA`;已完成 14 个 ZIP 条目和 13 个 `SHA256SUMS.txt` 载荷的逐条复验。旧无 operations 后缀包、`ops861fa0ea` 与 `ops414af66e` 包保留作追溯但均已被替代。上述本地自动化冻结不替代生产后端发布授权和人工验收。
@@ -113,11 +113,11 @@
同日后续已获得独立授权并通过 `release-backend.sh` 完成生产后端定向发布;生产 JAR SHA-256 为 `5376b67b33b171b5c85e22cd6a2f20bbb0bc527fc50a223603d0aec3f6587bac`,服务、三个公开入口和后端 + schema 发布后预检通过,后端发布不再是 8 月 1 日 APK 的阻断项。同批发布资料处理媒体恢复 schema 和管理端,移动 H5 未重发;这不改变正式场景/题目、五通道处理人、受控分发与真机设备门禁的 No-Go 状态。 同日后续已获得独立授权并通过 `release-backend.sh` 完成生产后端定向发布;生产 JAR SHA-256 为 `5376b67b33b171b5c85e22cd6a2f20bbb0bc527fc50a223603d0aec3f6587bac`,服务、三个公开入口和后端 + schema 发布后预检通过,后端发布不再是 8 月 1 日 APK 的阻断项。同批发布资料处理媒体恢复 schema 和管理端,移动 H5 未重发;这不改变正式场景/题目、五通道处理人、受控分发与真机设备门禁的 No-Go 状态。
同日真机继续确认 `0.1.13` 的麦克风允许和生产 ASR 可用,但拒绝后的降级误用 App 不支持的 `uni.chooseFile`。当前源码已升级为 `0.1.16 (116)`,改用 Android 系统文档选择器、`ParcelFileDescriptor + FileChannel.transferFrom`、应用专属外部缓存和 App 媒体选择器,并保留系统选择器暂时离开时的待完成任务。vivo 真机标准调试基座完成取消、重复打开、`100,542` 字节 WAV 选择/复制/上传和生产 ASR。首次成果投稿验证只到追问态,没有出现“确认投稿”;继续补充又暴露整理请求 `94,965ms`、超过客户端 `45,000ms` 的问题。当前源码已改为仅首轮调用 AI,后续补充走服务端本地合并复核,同机复验耗时 `1ms` 并显示确认卡和“确认投稿”按钮,但未点击、未形成正式投稿。206 项测试、类型检查、App 发布资源预检和 App-Plus 构建通过。调查用 `0.1.14/0.1.15` APK 已删除,DCloud 当日云打包额度耗尽,`0.1.16` 签名 APK 尚不存在,不能进入分发。 同日真机继续确认 `0.1.13` 的麦克风允许和生产 ASR 可用,并在 `0.1.16` 源码阶段修复拒绝后的系统文档选择、SAF `FileChannel` 复制、应用专属外部缓存、App 媒体选择器和权限 Activity 生命周期。随后生成的签名 `0.1.17 (117)` 已通过包内资源一致性深检,并在 vivo Android 15 真机完成允许/拒绝/恢复、选择器取消、合成中文 WAV 选择/生产 ASR;成果投稿实际点击“确认投稿”并返回 `#7 PENDING/待审核`。当前 209 项移动端测试、类型检查、App 发布资源预检和 App-Plus 构建通过。
生活顾问调研已转成 `docs/content-candidates/aug1-life-advisor-content-candidates-v0.1.json`:包含 5 个禁用场景候选和 30 道待审政策题,内容候选校验脚本通过。由于当前只收到 1/24 份访谈,且正式来源、业务审核和 Rubric 签认尚未完成,正式可发布场景与正式有据标准答案均为 `0`;交付包中的候选文件只供审核,不得直接导入或启用。 生活顾问调研已转成 `docs/content-candidates/aug1-life-advisor-content-candidates-v0.1.json`:包含 5 个禁用场景候选和 30 道待审政策题,内容候选校验脚本通过。由于当前只收到 1/24 份访谈,且正式来源、业务审核和 Rubric 签认尚未完成,正式可发布场景与正式有据标准答案均为 `0`;交付包中的候选文件只供审核,不得直接导入或启用。
业务回填入口已统一为 `docs/帮道8月1日业务内容与五通道签认单-20260729.md`。2026-07-29 生产只读审计确认五个直通角色均存在,但有效用户绑定数分别为 0;系统功能可用不等于真实收件人已配置,技术侧不得擅自绑定人员。 业务回填入口已统一为 `docs/帮道8月1日业务内容与五通道签认单-20260729.md`。2026-07-30 生产只读审计按服务端资格规则确认五个直通角色各有 2 名有效后台处理人;人数门槛已满足,但仍须通道负责人完成授权、越权和一次正式回复验收并签字,系统配置不能替代业务批准。
### 3.3 Android 真机预检快照(2026-07-28) ### 3.3 Android 真机预检快照(2026-07-28)
@@ -138,9 +138,9 @@
- 本机 Android Studio `Medium_Phone` 虚拟机已启动为 Android 15/API 35(`1080×2400`、密度 `420`)。在此前未安装本应用的虚拟机上,`0.1.6 (106)` 首次安装和 Launcher 冷启动成功,最新包真实显示原生隐私弹窗,四项相机、录音、图片和视频权限均未授予,crash 缓冲区为空。虚拟机只补充干净安装和 API 35 权限基线,不替代真机媒体、WebRTC、弱网与系统浏览器验收;拒绝/同意仍由用户亲自执行。 - 本机 Android Studio `Medium_Phone` 虚拟机已启动为 Android 15/API 35(`1080×2400`、密度 `420`)。在此前未安装本应用的虚拟机上,`0.1.6 (106)` 首次安装和 Launcher 冷启动成功,最新包真实显示原生隐私弹窗,四项相机、录音、图片和视频权限均未授予,crash 缓冲区为空。虚拟机只补充干净安装和 API 35 权限基线,不替代真机媒体、WebRTC、弱网与系统浏览器验收;拒绝/同意仍由用户亲自执行。
- `0.1.8 (108)` 进一步把 Android 原生清单和 `network_security_config.xml` 纳入 App 构建链及 APK 反编译门禁。独立内测 APK 大小 `33,921,705` 字节,SHA-256 为 `E252140645F3AAD14B3594FD78E76BDF1A2122F7DC70EBD21CC5DF53223C7878`;APK 反编译确认 `usesCleartextTraffic=false`、`networkSecurityConfig` 引用和系统证书信任配置均已进入安装包,本机虚拟机卸载旧实例后全新安装并在 `2.904s` 内冷启动,最新隐私弹窗真实显示,四项敏感权限未授予且 crash 缓冲区为空。 - `0.1.8 (108)` 进一步把 Android 原生清单和 `network_security_config.xml` 纳入 App 构建链及 APK 反编译门禁。独立内测 APK 大小 `33,921,705` 字节,SHA-256 为 `E252140645F3AAD14B3594FD78E76BDF1A2122F7DC70EBD21CC5DF53223C7878`;APK 反编译确认 `usesCleartextTraffic=false`、`networkSecurityConfig` 引用和系统证书信任配置均已进入安装包,本机虚拟机卸载旧实例后全新安装并在 `2.904s` 内冷启动,最新隐私弹窗真实显示,四项敏感权限未授予且 crash 缓冲区为空。
- 同一 `0.1.8` APK 随后在虚拟机完成保留数据的覆盖安装:覆盖后冷启动 `3.092s`、标准 Launcher Intent 暖启动 `0.538s`、切到系统桌面再恢复热启动 `0.120s`;三次均回到 `PandoraEntryActivity`,隐私弹窗保持可见,四项权限仍为 `granted=false`,未发现 FATAL 或 ANR。该证据只完成安装与首次弹窗前的生命周期基线,未代替用户选择隐私选项。 - 同一 `0.1.8` APK 随后在虚拟机完成保留数据的覆盖安装:覆盖后冷启动 `3.092s`、标准 Launcher Intent 暖启动 `0.538s`、切到系统桌面再恢复热启动 `0.120s`;三次均回到 `PandoraEntryActivity`,隐私弹窗保持可见,四项权限仍为 `granted=false`,未发现 FATAL 或 ANR。该证据只完成安装与首次弹窗前的生命周期基线,未代替用户选择隐私选项。
- 针对 Android 系统文件选择器“用户取消”被误判为上传或转写失败的问题,五个选择服务已统一结构化取消信号,九个页面在取消时恢复空闲态并清理残留“转写中”;当前 `0.1.16` 源码已在 vivo 标准调试基座完成真实取消、重复打开和音频选择/上传/ASR。最终签名 `0.1.16` 仍须复跑同一组门禁。 - 针对 Android 系统文件选择器“用户取消”被误判为上传或转写失败的问题,五个选择服务已统一结构化取消信号,九个页面在取消时恢复空闲态并清理残留“转写中”;签名 `0.1.17` 已在 vivo 真机完成系统文件/媒体选择器取消和音频选择/生产 ASR。
- `0.1.10 (110)` DCloud 独立内测 APK 大小 `33,922,134` 字节,SHA-256 为 `20CB16B4E9D024DBF5EEEF577BFBA3B4DF5E5E78B597BABB99CB7450C7AE5034`。同一虚拟机从 `0.1.9` 保留数据覆盖安装成功,Launcher 冷启动约 `1.271s`,最新原生隐私弹窗可见,四项权限仍为 `granted=false`,未发现 FATAL 或 ANR。 - `0.1.10 (110)` DCloud 独立内测 APK 大小 `33,922,134` 字节,SHA-256 为 `20CB16B4E9D024DBF5EEEF577BFBA3B4DF5E5E78B597BABB99CB7450C7AE5034`。同一虚拟机从 `0.1.9` 保留数据覆盖安装成功,Launcher 冷启动约 `1.271s`,最新原生隐私弹窗可见,四项权限仍为 `granted=false`,未发现 FATAL 或 ANR。
- 自定义基座和独立内测 APK 均使用 DCloud 云端测试证书,不是企业正式签名 APK;最后一个签名包 `0.1.13` 已关闭明文流量、内置网络安全配置并取消启动原生隐私确认,但不包含当前系统选择器修复。`0.1.16` 云打包、公司法务签认、企业签名和最终签名包权限反例仍是正式发布阻断。 - 自定义基座和独立内测 APK 均使用 DCloud 云端测试证书,不是企业正式签名 APK;当前签名 `0.1.17` 已关闭明文流量、内置网络安全配置、取消启动原生隐私确认并包含系统选择器/权限修复。受控分发批准、测试签名接受或企业签名、公司法务签认和剩余设备门禁仍是正式发布阻断。
## 4. P0 工作分解 ## 4. P0 工作分解
@@ -10,7 +10,7 @@
## 1. 当前结论 ## 1. 当前结论
技术侧已经把生活顾问调研转成可逐项审核的 5 个场景候选和 30 道问题候选,并完成五通道接口、固定码登录和认证后只读主路径验证。2026-07-30 又在本地完成 `superadmin` 五通道处理人配置入口和租户/用户资格保护,但该增量尚未发布,生产五个角色的有效绑定仍均为 0。业务方尚未提供正式制度来源、内容审核结论和五通道处理人,因此当前不能启用候选内容,也不能把“通道可选”解释成“有人收件”。 技术侧已经把生活顾问调研转成可逐项审核的 5 个场景候选和 30 道问题候选,并完成五通道接口、固定码登录和认证后只读主路径验证。2026-07-30 又发布 `superadmin` 五通道处理人配置入口和租户/用户资格保护;生产五个角色按有效后台用户口径均为 `2/2`。业务方仍未提供正式制度来源、内容审核结论、五通道业务验收和负责人签字,因此当前不能启用候选内容,也不能把“已配置处理人”解释成“通道已正式验收”。
截至 2026-07-29 的签认基线: 截至 2026-07-29 的签认基线:
@@ -68,7 +68,7 @@
## 4. 五通道处理人和权限签认 ## 4. 五通道处理人和权限签认
生产只读审计确认五个角色均已存在,但当前每个角色的有效用户绑定数都是 0。处理人身份由业务负责人指定,技术侧不得擅自把任意后台用户绑定为真实收件人。 生产只读审计确认五个角色均已存在,且当前每个角色都有 2 名符合服务端资格规则的有效后台处理人。仍须由通道负责人核对这些绑定并完成正例、跨通道越权反例和一次正式回复签认;技术人数检查不能代替业务批准。
| 通道 | 角色代码 | 主处理人 | 替补处理人 | 本通道列表/详情正例 | 其他四通道越权反例 | 一次正式回复 | 业务签认 | | 通道 | 角色代码 | 主处理人 | 替补处理人 | 本通道列表/详情正例 | 其他四通道越权反例 | 一次正式回复 | 业务签认 |
|---|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|---|
@@ -98,7 +98,7 @@
- 首次退出成功,旧令牌再次访问时按业务码 401 拒绝;第二次固定码登录、身份读取和退出再次通过; - 首次退出成功,旧令牌再次访问时按业务码 401 拒绝;第二次固定码登录、身份读取和退出再次通过;
- 脚本只选择已存在 `app_user`,不会触发手机号自动注册,不提交反馈、训练、附件、ASR/TTS 或 Agent 业务请求。 - 脚本只选择已存在 `app_user`,不会触发手机号自动注册,不提交反馈、训练、附件、ASR/TTS 或 Agent 业务请求。
这组证据完成登录与认证只读链路;后续 vivo 真机又完成签名 `0.1.13` 的麦克风允许/生产 ASR,以及当前 `0.1.16` 源码标准调试基座的系统选择器取消、真实音频选择/上传/ASR。上述结果仍不替代 `0.1.16` 最终签名 APK、真实断网、WebRTC、图片/视频/文档、受控下载,也不替代本单的内容与处理人签认。 这组证据完成登录与认证只读链路;后续 vivo 真机又在签名 `0.1.17` 完成学习中心、麦克风允许/拒绝/恢复、系统选择器取消、真实音频选择/生产 ASR、成果投稿确认保存和五通道入口。生产只读查询按服务端资格规则确认五个直通角色各有 2 名有效后台处理人。上述结果仍不替代真实断网、WebRTC、实际图片/视频/文档、受控下载,也不替代本单的正式内容、通道业务验收和负责人签认。
## 6. 最终签认 ## 6. 最终签认
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "aihr-mobile-uni", "name": "aihr-mobile-uni",
"version": "0.1.16", "version": "0.1.17",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "aihr-mobile-uni", "name": "aihr-mobile-uni",
"version": "0.1.16", "version": "0.1.17",
"dependencies": { "dependencies": {
"@dcloudio/uni-app": "3.0.0-alpha-5020220260725001", "@dcloudio/uni-app": "3.0.0-alpha-5020220260725001",
"@dcloudio/uni-app-plus": "3.0.0-alpha-5020220260725001", "@dcloudio/uni-app-plus": "3.0.0-alpha-5020220260725001",
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"$schema": "https://json.schemastore.org/package", "$schema": "https://json.schemastore.org/package",
"name": "aihr-mobile-uni", "name": "aihr-mobile-uni",
"version": "0.1.16", "version": "0.1.17",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
+78 -3
View File
@@ -53,9 +53,48 @@ const DEFAULT_ROUTES = [
'pages/candidate/index/index', 'pages/candidate/index/index',
'pages/supervisor/index/index', 'pages/supervisor/index/index',
]; ];
const routes = (argValue('--routes') || DEFAULT_ROUTES.join(',')).split(',').map((s) => s.trim()).filter(Boolean); const AUTH_DEFAULT_ROUTES = [
'pages/user/today/index',
'pages/user/sop/index',
'pages/user/practice/index',
'pages/user/direct/index',
'pages/user/work-results/index',
'pages/candidate/index/index',
'pages/supervisor/index/index',
];
const apiBase = (argValue('--api') || 'http://127.0.0.1:8081').replace(/\/$/, '');
const loginPhone = argValue('--phone') || process.env.AIHR_UI_AUDIT_PHONE || '';
const loginCode = argValue('--code') || process.env.AIHR_UI_AUDIT_CODE || '';
if (loginPhone && !loginCode) {
throw new Error('认证态审计需要通过 --code 或 AIHR_UI_AUDIT_CODE 显式提供验证码');
}
const routes = (argValue('--routes') || (loginPhone ? AUTH_DEFAULT_ROUTES : DEFAULT_ROUTES).join(','))
.split(',').map((s) => s.trim()).filter(Boolean);
// ---------- H5 静态服务(SPA 回退) ---------- // ---------- 登录态(凭据只留在进程内,不写入日志、截图或报告) ----------
async function loginForToken() {
const smsResp = await fetch(`${apiBase}/resource/sms/code?phonenumber=${encodeURIComponent(loginPhone)}`);
const smsPayload = await smsResp.json().catch(() => ({}));
if (!smsResp.ok || (smsPayload.code !== undefined && smsPayload.code !== 200)) {
// 验证码按手机号粒度限频;已下发且在有效期内的固定码仍可登录,输错不作废
console.log(`[auth] 验证码请求被限频,沿用已下发验证码重试登录(${smsPayload.msg || smsResp.status})`);
}
const loginResp = await fetch(`${apiBase}/auth/mobile/sms-login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ phonenumber: loginPhone, smsCode: loginCode }),
});
const loginPayload = await loginResp.json().catch(() => ({}));
const token = loginPayload?.data?.access_token;
const clientId = loginPayload?.data?.client_id;
if (!loginResp.ok || !token || !clientId) {
throw new Error(`登录失败:HTTP ${loginResp.status} ${loginPayload.msg || ''}`);
}
console.log('[auth] 已完成认证(手机号、验证码、token 与 clientId 均不写入报告)');
return { token, clientId };
}
// ---------- H5 静态服务(SPA 回退 + /dev-api 代理) ----------
const MIME = { const MIME = {
'.html': 'text/html; charset=utf-8', '.js': 'text/javascript', '.css': 'text/css', '.html': 'text/html; charset=utf-8', '.js': 'text/javascript', '.css': 'text/css',
'.json': 'application/json', '.png': 'image/png', '.jpg': 'image/jpeg', '.webp': 'image/webp', '.json': 'application/json', '.png': 'image/png', '.jpg': 'image/jpeg', '.webp': 'image/webp',
@@ -67,8 +106,31 @@ function serveH5() {
if (!existsSync(path.join(h5Dir, 'index.html'))) { if (!existsSync(path.join(h5Dir, 'index.html'))) {
throw new Error(`未找到 H5 构建产物 ${h5Dir},请先 npm run build:h5,或用 --url 指向已有服务`); throw new Error(`未找到 H5 构建产物 ${h5Dir},请先 npm run build:h5,或用 --url 指向已有服务`);
} }
const server = http.createServer((req, res) => { const server = http.createServer(async (req, res) => {
let p = decodeURIComponent(new URL(req.url, 'http://x').pathname); let p = decodeURIComponent(new URL(req.url, 'http://x').pathname);
// 与 vite dev 一致的代理行为:/dev-api/* → apiBase/*(去前缀)
if (p.startsWith('/dev-api/')) {
try {
const body = ['GET', 'HEAD'].includes(req.method) ? undefined : await new Promise((resolve) => {
const chunks = [];
req.on('data', (c) => chunks.push(c));
req.on('end', () => resolve(Buffer.concat(chunks)));
});
const headers = {};
for (const h of ['content-type', 'authorization', 'clientid', 'content-language']) {
if (req.headers[h]) headers[h] = req.headers[h];
}
const upstream = await fetch(`${apiBase}${p.slice(8)}${new URL(req.url, 'http://x').search}`, {
method: req.method, headers, body,
});
res.writeHead(upstream.status, { 'Content-Type': upstream.headers.get('content-type') || 'application/json' });
res.end(Buffer.from(await upstream.arrayBuffer()));
} catch (error) {
res.writeHead(502, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ code: 502, msg: `dev-api 代理失败:${error.message}` }));
}
return;
}
if (p.startsWith('/h5/')) p = p.slice(3); if (p.startsWith('/h5/')) p = p.slice(3);
if (p === '/' || p === '') p = '/index.html'; if (p === '/' || p === '') p = '/index.html';
let file = path.join(h5Dir, p); let file = path.join(h5Dir, p);
@@ -193,6 +255,7 @@ const COLLECTOR = `(() => {
})()`; })()`;
// ---------- 主流程 ---------- // ---------- 主流程 ----------
const session = loginPhone ? await loginForToken() : null;
const served = argValue('--url') ? null : await serveH5(); const served = argValue('--url') ? null : await serveH5();
const baseUrl = argValue('--url') || served.url; const baseUrl = argValue('--url') || served.url;
console.log(`[setup] baseUrl=${baseUrl}`); console.log(`[setup] baseUrl=${baseUrl}`);
@@ -208,6 +271,17 @@ const pages = [];
try { try {
await page.send('Page.enable'); await page.send('Page.enable');
await page.send('Runtime.enable'); await page.send('Runtime.enable');
if (session) {
// 与应用 saveAuth 相同的 storage 键,注入已登录会话(不经过 UI,不触发额外短信)
await page.send('Page.addScriptToEvaluateOnNewDocument', {
source: [
`localStorage.setItem('aihr_mobile_access_token', ${JSON.stringify(session.token)});`,
`localStorage.setItem('aihr_mobile_client_id', ${JSON.stringify(session.clientId)});`,
`localStorage.setItem('aihr_mobile_phone', ${JSON.stringify(loginPhone)});`,
`localStorage.setItem('aihr_mobile_tenant_id', '000000');`,
].join('\n'),
});
}
await page.send('Emulation.setDeviceMetricsOverride', { await page.send('Emulation.setDeviceMetricsOverride', {
width: VIEW_W, height: VIEW_H, deviceScaleFactor: 2, mobile: true, width: VIEW_W, height: VIEW_H, deviceScaleFactor: 2, mobile: true,
}); });
@@ -334,6 +408,7 @@ lines.push('# mobile-uni 渲染态 UI 审计');
lines.push(''); lines.push('');
lines.push(`- 生成时间:${new Date().toISOString()}`); lines.push(`- 生成时间:${new Date().toISOString()}`);
lines.push(`- 入口:${baseUrl}(${argValue('--url') ? '外部服务' : '本地静态服务 dist/build/h5'}),视口 ${VIEW_W}×${VIEW_H} @2x`); lines.push(`- 入口:${baseUrl}(${argValue('--url') ? '外部服务' : '本地静态服务 dist/build/h5'}),视口 ${VIEW_W}×${VIEW_H} @2x`);
lines.push(`- 会话:${session ? `已认证(凭据不入报告),API 代理 ${apiBase}` : '未登录(页面呈现登录门禁/空态/错误态)'}`);
lines.push(`- Chrome:${chrome.chromeBin}`); lines.push(`- Chrome:${chrome.chromeBin}`);
lines.push(`- palette:${palette.size} 色;字阶:${[...fontScale].sort((a, b) => a - b).join('/')}px;半径 token:${[...radiusTokens].sort((a, b) => a - b).join('/')}px`); lines.push(`- palette:${palette.size} 色;字阶:${[...fontScale].sort((a, b) => a - b).join('/')}px;半径 token:${[...radiusTokens].sort((a, b) => a - b).join('/')}px`);
lines.push(`- 口径:按可见元素的 getComputedStyle 计次(一个元素一次),非源码声明次数;默认未登录态渲染,异步接口失败的页面呈现错误/空态`); lines.push(`- 口径:按可见元素的 getComputedStyle 计次(一个元素一次),非源码声明次数;默认未登录态渲染,异步接口失败的页面呈现错误/空态`);
+2 -2
View File
@@ -3,8 +3,8 @@
"appid" : "__UNI__B36D8BE", "appid" : "__UNI__B36D8BE",
"description" : "帮道员工端", "description" : "帮道员工端",
"vueVersion" : "3", "vueVersion" : "3",
"versionName" : "0.1.16", "versionName" : "0.1.17",
"versionCode" : "116", "versionCode" : "117",
"uniStatistics" : { "uniStatistics" : {
"enable" : false "enable" : false
}, },
+18
View File
@@ -241,3 +241,21 @@ test('8 月 1 日 RC 脚本默认拒绝脏工作区且记录完整构建证据',
assert.match(script, /releaseEligible = \$releaseEligible/); assert.match(script, /releaseEligible = \$releaseEligible/);
assert.match(script, /APK metadata, login legal links, no native privacy prompt, signature, content match and sensitive-value scan/); assert.match(script, /APK metadata, login legal links, no native privacy prompt, signature, content match and sensitive-value scan/);
}); });
test('认证态 UI 审计不持久化手机号或验证码', async () => {
const script = await readFile(
new URL('../scripts/ui-rendered-audit.mjs', import.meta.url),
'utf8'
);
const authRoutesStart = script.indexOf('const AUTH_DEFAULT_ROUTES');
const authRoutesEnd = script.indexOf('];', authRoutesStart);
const authRoutes = script.slice(authRoutesStart, authRoutesEnd);
assert.ok(authRoutesStart >= 0 && authRoutesEnd > authRoutesStart);
assert.match(script, /AIHR_UI_AUDIT_PHONE/);
assert.match(script, /AIHR_UI_AUDIT_CODE/);
assert.doesNotMatch(script, /argValue\('--code'\)\s*\|\|\s*['"]\d+/);
assert.doesNotMatch(script, /session\.masked|loginPhone\.slice/);
assert.doesNotMatch(authRoutes, /pages\/user\/profile\/index/);
assert.match(script, /已认证(凭据不入报告)/);
});