Files
zkxw/docs/superpowers/specs/2026-10-10-market-miniapp-role-features-implementation-summary.md
T
2026-10-13 15:18:01 +08:00

7.8 KiB
Raw Blame History

存储业务移动端功能实施总结

1. 实施结果

本次已完成市场专员、地区经理在小程序中的存储业务入口,以及由 mobile-oa-h5 承载的六类业务功能:预签约订单、协议单、催缴、缴费、样本和运费。小程序只负责受控入口和 WebView 宿主,业务列表、详情、表单与有限动作均在 H5 中实现。

业务链路为:

mobile-h5 首页菜单
  -> /pages/market/webview/index?entry=<固定入口>
  -> mobile-oa-h5 固定角色路由
  -> /api/mini/market/{specialist|manager}/...

客户端不能传入任意 H5 URL、租户、现场 scope 或销售/经理身份来扩大权限。

2. 菜单与入口

菜单迁移为每个移动端虚拟根创建两个目录和十二个叶子,不自动写入角色菜单关系:

角色组 六个固定入口
市场专员 specialist-presign、specialist-protocol、specialist-payment-chase、specialist-payment、specialist-sample、specialist-freight
地区经理 manager-presign、manager-protocol、manager-payment-chase、manager-payment、manager-sample、manager-freight

首页接口返回 groupTitle 区分角色组。目录本身没有可进入 path;入口 icon 按设计保持空置。未知 entry、原型链键和任意 URL 均被白名单拒绝。

3. 权限与数据范围

所有移动市场接口同时应用:

  1. 当前租户与软删除过滤;
  2. 当前租户有效直接角色与启用职位继承角色的 data scope 并集;
  3. 当前固定路由的现场范围。

现场范围为:

  • 市场专员:单据采集信息 sales_user_id = 当前用户;
  • 地区经理:当前用户负责地区(is_leader=1)或单据 region_manager_user_id = 当前用户;
  • 兼岗用户进入哪套固定路由,就使用哪套现场范围,不做页面内并集。

详情和所有写操作均重新校验范围。涉及并发写入的样本办理、运费关联和批次头修改使用 MySQL current read、稳定锁顺序与锁后权限复核,避免 REPEATABLE READ 旧快照授权。

4. 六模块开放能力

模块 实际开放动作 明确不开放
预签约订单 列表、详情、新建、编辑、原子转正式 删除、财务确认;终态继续编辑/转换
协议单 细胞/科研双来源列表、详情、新建、编辑 审核、作废、退款、财务动作、转换
催缴 逾期未清与未来 30 天未清查询,跳转登记缴费 催缴编辑实体、发送/标记催缴
缴费 v2 样本缴费查看、登记/编辑草稿、提交财务确认、确认中撤回 财务确认/拒绝、删除、退款、开票、修改应缴计划
样本 双来源进度查看;细胞储存证/保险轻量办理 科研样本写入、接收/质检/生产/入库状态、实验室码
运费 scope 内批次查看、新建、样本关联/解绑;own-only 批次头编辑 修改含范围外明细的共享批次头、查看隐藏明细/数量

后端返回 allowedActions,H5 再与模块静态白名单取交集。按钮隐藏不是授权手段,直达写接口重复执行状态和范围校验。

5. 运费脱敏

  • 批次只要存在至少一条当前 scope 可见明细即可见;
  • 列表、关键词、来源筛选、total 和详情明细只基于可见行;
  • 响应只返回 visibleItemCount,不返回总关联数、隐藏数、共享标志或他人明细;
  • 创建、关联、解绑先完整校验全部样本,任一越权则整单回滚;
  • 样本已属于其他批次时返回冲突,不静默迁移;
  • 只有全部有效明细都在当前 scope 时才允许修改批次头;
  • 生成列与唯一索引保证同一样本最多存在一条有效运费关联。

6. 表单支撑与附件安全

移动表单 options 使用固定资源接口,不提供任意字典或全租户用户搜索。地区、医院和人员均按当前角色与业务单范围收敛;样本办理人员限定为该样本当前父单地区内的启用人员。

附件上传规则:

  • 固定服务端目录,不接受客户端 folder;
  • 单文件非空且不超过 10 MiB;
  • 仅允许约定的图片、PDF 和 Office 类型,并校验扩展名、MIME 与文件结构;
  • HEIC/HEIF 严格校验 ISO-BMFF ftyp box 和品牌;
  • 暂存附件必须匹配当前租户、上传人、角色入口和模块;
  • 业务保存时批量锁定并在同一事务内绑定到唯一业务 ID;
  • 单字段最多 20 个引用、总长度不超过 4000;
  • 历史业务中已保存的 URL 可原样保留,但不能借此引入新外链;
  • 数据库提交前失败会回滚并清理对象存储文件。

本期未增加不安全的移动端附件下载接口。

7. 数据库迁移与部署顺序

建议按以下顺序执行:

  1. docs/sql/migrations/2026-10-10-market-field-scope-indexes.sql
  2. docs/sql/migrations/2026-10-10-presign-convert-unique.sql
  3. docs/sql/migrations/2026-10-11-market-payment-indexes.sql
  4. docs/sql/migrations/2026-10-11-market-sample-indexes.sql
  5. docs/sql/migrations/2026-10-11-market-freight-indexes.sql
  6. docs/sql/migrations/2026-10-10-market-mobile-menus.sql

迁移前应先备份相关表,并处理脚本报告的历史重复预签转换、重复运费批次号或重复有效样本关联。菜单迁移后由管理员将十二个叶子权限分配给对应角色。

回滚采用数据库备份恢复或经审核的反向 DDL;不建议在未核对线上索引依赖时直接删除索引/生成列。菜单回滚应按迁移自然键删除新增叶子与空目录,不处理既有角色授权以外的数据。

8. 自动验证结果

2026-10-11 最终验证:

  • 后端市场定向:215 passed;
  • 市场 SQL 静态测试:11 passed;
  • 后端全量:最初为 912 passed, 4 failed;后续已修复 CBC 测试契约和 3 项协议排序问题,复验为 916 passed, 0 failed;
  • Python compileall:通过;
  • 字段一致性:0 errors, 5 warnings,5 项为脚本既有实体告警;该脚本未注册本次 market DTO,本次字段白名单由 test_market_* 覆盖;
  • mobile-h5:5/5 passed;
  • mobile-oa-h5:62/62 passed;
  • mobile-oa-h5 Vite 构建:通过,保留既有大 chunk 警告;
  • git diff --check:通过;
  • 后端知识图谱:6122 nodes / 33427 edges / 40 communities。

MySQL 验证使用隔离启动的 MySQL 5.7.24 临时实例,六份迁移连续执行两轮均成功。两个测试租户各得到 2 个目录和 12 个叶子,sys_role_menu 未增加;索引、生成列和重复数据预检符合预期。临时数据库验证后已删除。

9. 手工验收状态

自动化测试和构建已完成。以下环境相关项目尚未在本任务中执行,因此不声明通过:

  • 375px、390px、430px 真实浏览器视口的逐页视觉检查;
  • 微信开发者工具中的 WebView、返回宿主、安全区和键盘体验;
  • 使用真实专员、经理、兼岗账号进行端到端菜单授权与操作验收;
  • 真实 MinIO、生产同构域名和登录 token 失效联调。

部署到测试环境后应按实施计划 Task 11 Step 4 的七项矩阵完成并留存截图/录屏。

10. 已知限制与后续事项

  • 市场菜单正式 icon 尚未提供,当前按设计空置;
  • 缴费移动端明确支持 v2 样本缴费模型,v1 历史记录返回兼容提示;
  • 科研样本本期只读,因为现有模型没有不影响质检/入库状态的市场轻量办理实体;
  • 移动端附件下载未开放,避免复用旧后台的模糊 URL 查询;
  • Vite 主 chunk 仍有超过 500 kB 的既有警告,可后续单独做代码分包;
  • mobile-h5 Node 测试有未声明 type: module 的重解析警告,不影响当前运行结果;
  • 字段一致性 5 个既有 warning 应另立任务处理;后端 4 个既有基线测试失败已于 2026-10-11 修复。