dev2 · 2026-08-21 · 阶段 1 需求明确
【实证】= 我 grep 过 origin/test 代码;其余是设计描述
以「子席位」为载体把智脑开放给家长:门店开通、平台管控与对账、C 端三功能+孩子档案。
一期目标:基础功能、业务能跑。
页面从上到下三段:
1. 筛选条:时间快捷档(今天/本周/本月/自定义)+ 机构名称 + 账号 + 状态 + 开通来源
2. 快速统计卡(随筛选联动·全局合计):期间开通总数 · 生效中总数 · 已到期总数
→ 选「今天」不选机构 = 今天所有机构一共开了多少,一眼出数
3. 机构聚合列表:一行一机构(期间开通/累计/生效中/已到期)+ 行尾「明细」按钮
→ 点开大弹框(宽弹窗·非抽屉,长官定):该机构席位流水
(账号·微信昵称/头像(未绑定则显示"未绑定")·手机号·开通日·时长·到期日·状态)
+ 行内管控(停用/启用/换绑/重置密码)+ 分页
【实证】正式席位页已有微信昵称/头像/未绑定这套列(seats/page.tsx 命中 5/4/4 处),照搬
- 按月导出对账单按钮(按当前筛选导 CSV)
- 机构详情页:一行「子席位 N 个 → 查看」跳转(带机构预筛),不做整套 tab
OrgBrainConfig(app/models/database.py:61),不在 organizations 表subseat/sub_seat/parent_seat/child_seat/子席位 在 app/ 下 0 命中;enable_refractive_record 命中 7 文件 ⇒ 查法有效)⇒ 必须新加一列 enable_parent_subseat,enable_refractive_record(Phase 63 · opt-in · server_default false)写web/app/h5/settings/components/SeatStoreCard.tsx 渲染(不是 settings/page.tsx)SeatStoreCard.tsx:316 = {data.enable_tablet_home_branding && (<section…>)}/api/h5/store-card:app/api/h5_store_card.py:145 已在select(OrgBrainConfig.enable_tablet_home_branding)、:193 放进返回体 ⇒ 多选一列 + 多一个 keyorg-features:设置页目录内 0 命中;全前端只有 web/app/h5/chat/lib/auth.ts 拉它admin/orgs/page.tsx 的 show_expiry_countdown(:292)/enable_refractive_record(:297)加一行;app/services/org_service.pydatabase.py + migration / h5_store_card.py /SeatStoreCard.tsx / admin/orgs/page.tsx / org_service.pyweb/app/h5/settings/page.tsx):只有两个分支 —— :176 {isSeat && <SeatStoreCard/>}、:178 {!isSeat && …家长资料…}role='org_seat' ⇒ isSeat=true ⇒ 家长会看到门店那四区块!isSeat 支里(:288 / :306)seat_type='parent' 渲染家长版设置页,四组:POST /api/seat/change-password)③关于(AboutSheet + 隐私政策)④账号(退出登录)role 分不出门店和家长,必须有 seat_typemenu-sidebar.tsx 抽屉平板 / 手机原样复用,唯一改动是底部「设置」指向家长版tablet/page.tsx:76 那个 profile 热区坐标已弃用,是残留);web/app/h5/chat/components/seat-login-sheet.tsx →POST /api/seat/login,平板 / 手机共用;家长输 subXXXX + 密码,与门店席位完全同一条链路users 表 role='org_seat'(seat_auth.py:3 / :199 / :510)setSeatToken + onSuccess(org_features) 关弹窗,不做任何跳转SeatLoginResponse(seat_auth.py:79)现在只有access_token / refresh_token / org_features / must_change_password;seat_type / visible_features / account_type 三个词在 seat_auth.py 0 命中org_features 命中 8 ⇒ 查法有效)⇒ 前端拿不到"门店账号还是家长账号"users 表加一档标识(如 seat_type:store/parent),门店开通子席位时写 parentSeatLoginResponse 加 seat_type + visible_featuresGET /api/seat/org-features 同步补(刷新页面时也要能拿到)TABLET_FEATURES(menu-sidebar.tsx:41-50)+ filter(:72)过滤,enable_refractive_record 的 fail-closed 双门:flag 真且有 token 才渲染,h5/chat/page.tsx:544,前端结构零改,其余入口自然消失)c-end-reuse-assessment-20260821.md 物理 grep 评估):patients(姓名/出生/性别/家长手机号/家族史/戴镜史/既往防控/监护人同意)refractive_records + refractive_record_eyes(裸眼·戴镜·矫正视力/自镜与主觉球柱轴/GET /patients/{id}/records 时间线c-end-vendorB-reference-20260821.md)——🔴 影像上传:就近上传 + 就地回填(长官 8-21 定 · 不照厂家 B 堆在表单末尾)
| 表单段 | 段内数值 | 段下方挂的图 | 上传后 |
|---|---|---|---|
| 验光(方式:无/小瞳/快散/中散/慢散) | 球镜/柱镜/轴位/矫正视力 | 电脑验光单 | 自动回填球镜·柱镜·裸眼视力 → 家长核对(方式选「电脑」) |
| 眼轴检查 | 眼轴/眼压/K1/K2 | 眼轴曲率报告单 | 自动回填眼轴·K1·K2·眼压 → 家长核对 |
| OCT 结论 | normal/abnormal + 备注 | OCT 图 | 只存不识别 |
| 眼底结论 | normal/abnormal + 备注 | 眼底照相 | 只存不识别 |
| 其它 | — | 视功能/眼压等杂项图 | 只存不识别 |
每块已上传的图要能展示出来(缩略图 + 可点开大图)。
- 🔴 录入主路径 = 拍照上传 → 系统识别自动填 → 家长核对 → 提交;手工填只作兜底
【实证】秒读 OCR 已提取 裸眼视力 · 眼压 · 眼轴 · K1/K2 · 球镜/柱镜
(four_l_report.py:232-250)—— 恰好覆盖厂家 B 的全部必填项(眼轴 K1 *K2)。
厂家 B 是"只存不分析",我们是"存了还能自动填",这是比两家参照品都强的地方
- 「读取上次」必做:家长约 3 个月来一次,验光地点/戴镜情况/身高体重/防控措施几乎不变,
不给一键带出就得重填几十项
- 分享:一期加(复用现有分享链路,成本低)· 导出文件:二期做(长官 8-21 定)(真实场景是
带去医院给医生看,非高频;要做 PDF 排版,工作量不小)
- 防控措施:沿用现有档案级 prevention_history(长官 8-21 定),不做记录级
- 🔴 归属标记改为"可见 + 可辨识"(2026-08-21 口径变更):家长建的档案仍打
owner_type=parent 标记,但门店端可以查看(入口在平板「视力屈光记录」),
列表与详情显示「家长自建」来源标签,与门店自建区分;
仍新增家长身份鉴权(复用子席位登录态,共用 service 只换 scope)
- 数据来源:秒读解析自动写入 + 手动录入
【实证】秒读 OCR 已提取裸眼视力/眼轴/曲率K1/K2/球柱镜(four_l_report.py:232-246)
- 登录方式已被现网约束证实:enable_user_registration 与 enable_password_login
互斥,签约门店标准套餐写死 password_login=True / user_registration=False
⇒ 「账号密码交付」是唯一不顶掉门店现有登录的方案;
另:enable_refractive_record 在签约套餐里本来就是 True,门店已具备该能力
- 到期自动停用;C 端显示到期日
线下按月对账,系统只记数量,不设开通上限,不碰支付/结算链路。
| 事项 | 一期留的口 |
|---|---|
| 续期(门店办 + 后台也能办) | 到期即停用;时长/到期字段已设计好 |
| 按次购买秒读次数(微信支付+价格管理) | 配额表预留「购买次数」字段 |
| 到期前提醒(家长/门店) | 一期仅 C 端显示到期日 |
| 问答额度精细化(若有滥用) | 沿用现有机构级日计量,先观察 |
| 眼轴预测 / 百分位定位(参照品有) | 算法跟对方要、不确定拿得到;一期只做实测曲线 |
| 合并展示门店档案(参照品有) | 一期不做门店档案打通 |
| 导出文件(参照品 B 有 · 带去医院给医生看) | 一期先给分享,导出 PDF 二期做 |
| # | 问题 | 结论 |
|---|---|---|
| Q1 | 开通交付方式 | 开完给账号密码,家长自己登录绑手机号(不定向录手机号)。理由:支持批量开、与正式席位同模式复用最彻底;定向开唯一好处"开出来就带手机号"不值得牺牲批量 |
| Q2 | 孩子档案/报告门店可见性 | ~~一期门店不可看~~ → 🔴 2026-08-21 变更:外部回复到,门店端查看孩子档案与报告提到一期,入口放平板端「视力屈光记录」,家长建的档案带「家长自建」来源标识 |
| Q3 | 问答限次 | 不限次(沿用现有机构级日计量) |
| Q4 | 正式席位手机号再开子席位 | 允许(B 端 C 端互不影响;唯一性只约束"一个手机号一个子席位") |
| Q5 | 防控措施枚举里的品牌词(憩尔目/压轴/紫金龙等) | 照抄不改(长官 8-21 定) |
| Q6 | 档案身份证号字段 | 保留,选填不砍(长官 8-21 定) |
vision_exams长官定「必须整到一个表,不能识别去 A、手填去 B」。选 vision_exams 的物理依据:
four_l_orchestrator.py:665 / ocr_persistence_service.py:96 /md_parser_service.py:381 / bulk_importer.py:189 四处 VisionExam(chief_complaint · 既往史 medical_history ·height · 体重 weight · 戴镜 current_lens_status · 验光方式 refraction_method ·ref_*(球镜/柱镜/轴位/矫正视力)· 戴镜处方组 rx_* · 眼轴 axial_length_* ·iop_* · K1/K2 · 角膜散光 ast_* · 角膜中央厚度 cct_* ·worth_4dot · 交替遮盖 alternate_cover · 眼位 eye_position ·prevention_history · 检查日期 visit_date · 来源 data_source(系统/手动录入)refraction_method 的语义正是长官指出的那个结构(现值 小瞳/散瞳/电脑)——一期在 vision_exams 上补:验光地点 · 防控笔记(或复用 remarks/user_supplement_info)
· refraction_method 枚举扩为 无 / 小瞳 / 快散 / 中散 / 慢散(照参照品 B)
⚠️
refractive_records(Phase 63 平板端那套)本期不动、不迁移、不双写;
它继续服务门店平板端。C 端档案只读写vision_exams。
visible_features: ["chat","report","myopia_world","child_profile"])TABLET_FEATURES 的注册表写法(menu-sidebar.tsx:41-50 + filter :72)enable_refractive_record 那条 fail-closed 双门(开关 true 且有 token 才显示)不另开设置页,也不塞进机构编辑弹窗 —— 就在「子席位管理」页里配"家长端显示哪些模块"。
h5/chat 药丸与样式,入口改注册表渲染h5/tablet/pane 那套壳(左菜单 + 右面板),菜单项换成家长四项长官定「档案里不计入,只有报告秒读上传才吃 6 次」。
⇒ 实现上两条链路分开计量:档案内的识别回填不计数;「报告秒读」功能才扣次。
不另做识别引擎。上传的图按现有秒读方式识别 → 回填到 vision_exams 对应字段 → 家长核对。
识别不出来的照旧手填;图片本身一律存档(现成受管表 report_image 的 kind 枚举
refraction/axial/oct/fundus 与四类图一一对应)。
c-end-plan-selfaudit-20260821.md)| # | 自检发现 | 长官处置 | 一期要做什么 |
|---|---|---|---|
| 1 | 家长行为/报告图按 org 落表(seat_activity_log/report_image),会混进门店机构线 |
修 | _ACTOR_TYPES 新增子席位一档;反向清查所有按 org_id 聚合的读接口,逐个排除子席位 |
| 2 | 秒读配额是新机制(现表是"机构+按天+消息/图片数",秒读还没接配额) | 修 | 新建按账号+365天+秒读次数的配额模型 + 在秒读入口做扣减(解析成功才扣,失败可回滚)。工作量单独算,不是"加个字段" |
| 3 | B 端设置页门店进不进得去存疑 | 门店可进设置页(长官确认) | 「子席位开通管理」就放该页,一期范围不变 |
| 4 | 到期停用没定执行者 | 到期即自动停用;C 端本来就要登录 | 登录时校验到期(惰性),不新增定时任务;后台列表"已到期"用 SQL 条件算 |
| 5 | 家长 AI 用量成本记谁头上 | 不专门做成本核算 | 用量大头自然归机构(现状即如此);明细可按家长查是免费副产品 —— seat_activity_log 本来就带 org_id + actor_id + event_type,不新建账、不加工作量。真要算钱二期再说 |
activated_seat_count、结算侧一切按席位算的数字,都不受子席位影响 —— 两套账彻底分开云机环境 · 非验收证据。