生成时间:2026-09-16 · 执行:sonnet 执行层 agent(只读,未修改任何文件)
⚠️ 本次比对对象是 tablet 目录下 frame5-record-entry.tsx,不是 record-canvas.tsx。判定证据:
$ grep -rn "<RecordCanvas" web/app --include=*.tsx
(0 命中)
$ grep -n "RecordCanvas" web/app/h5/tablet/pane/panes/refractive-record/refractive-record-pane.tsx
46: import { RecordCanvas, type DraftState } from "./record-canvas";
817: // (旧三栏组件文件 PatientRail/RecordCanvas/AdvancedVisionSection/RecordSummaryRail
$ grep -n "<Frame5RecordEntry" web/app/h5/tablet/pane/panes/refractive-record/refractive-record-pane.tsx
839: <Frame5RecordEntry
857: <Frame5RecordEntry
875: <Frame5RecordEntry
RecordCanvas 组件本体在全仓 0 处被渲染(<RecordCanvas 0 命中),refractive-record-pane.tsx:817 注释也明确称其为"旧三栏组件",只导入未使用;Frame5RecordEntry 才是真正被渲染 3 次的录入组件(新建/编辑/查看-只读态)。因此:
frame5-record-entry.tsx(+ 整卡复用 advanced-vision-section.tsx 做卡7视功能 + 复用 vision-acuity-picker.tsx 做视力滚轮 + constrained-number-picker.tsx 提供视功能数值弹层)record-canvas.tsx 仅作为字段字面量数据源继续被复用(VA_ROWS/BIO_SPECS/OCULAR_EXAMS/DraftState 类型导出),其组件本体 RecordCanvas() 是死代码,不参与本次比对web/app/h5/store-refractive/[patientId]/record/new/page.tsx(2414 行,新建/编辑共用同一表单,?editRecordId= 走 hydrate 分支);[recordId]/page.tsx 经查文件头注释是"记录查看页"(三 Tab + AI分析 + 门店结论),不是录入页,不在本次比对范围内(该文件当前被另一 agent 编辑中,本次全程未读写)⚠️ 并发提示:record/new/page.tsx 与 [recordId]/page.tsx 当前有另一 agent 正在改动(git status 显示 Modified),本报告是读取时刻的快照,若另一 agent 完工后字段有变化,此表需要重新核对。
| # | 差异 | 平板端 | 手机端 |
|---|---|---|---|
| S1 | 卡片折叠/进度条 | 8 卡固定全展开,无折叠、无进度胶囊、无"已完成/必填"文字徽章(frame5-record-entry.tsx 全文无 doneFlags/FoldHeader/ProgressPills) |
有 doneFlags(new/page.tsx:1009-1029)驱动的 FoldHeader 折叠头 + ProgressPills 横滑进度条(:704-746),每卡显示"必填/已完成/选填"等文字徽章 |
| S2 | AI 识别回填高亮 | 0 命中——grep -c aiFilled frame5-record-entry.tsx = 0,AI 识别结果直接覆盖原值,无"请核对"视觉标记(对照组:aiBusy/aiMsg 在同文件各命中多次,证明查法有效、非漏查) |
有 aiFilledKeys 状态(new/page.tsx:878),AI 回填的字段 NumberCell/VA 按钮变绿底(GREEN_BG),人工手动改动后自动清除该 key(:1001-1006、:2302-2307) |
| S3 | 视功能数值字段手输通道 | 17 个数值字段(DLP/NLP/DVP/NVP 数值、AC/A、远/近ACT数值、PFC/NFC/NPC破裂恢复、NRA/PRA/BCC/AMP)在卡片表面只有按钮,点击后弹出 ConstrainedNumberPicker 弹层,弹层内才有键盘输入框(advanced-vision-section.tsx 全部 17 处 onClick={() => setPicker(...)} 按钮,无一处卡片表面 <input>) |
同 17 个字段卡片表面直接是 NumberCell(可直接手输)+ 额外一个 chevron 按钮打开 VfPickerSheet 档位弹层(如 new/page.tsx:1897-1918 数值输入格 + 选档位按钮并存) |
| S4 | 立体视自定义弧秒入口 | 隐藏在"其他"切换按钮后面,点击才弹出 ConstrainedNumberPicker(advanced-vision-section.tsx:237-246) |
常驻可见的 NumberCell,无需先点按钮(new/page.tsx:1852-1867) |
| S5 | 检查日期年份下限 | VisitDateField 未传 minYear,DateWheel 默认 thisYear-18(date-wheel.tsx:72),可选最早 18 年前 |
显式传 minYear={new Date().getFullYear() - 3}(new/page.tsx:2347),可选最早仅 3 年前 |
| S6 | 卡8 备注长度约束 | <textarea> 无 maxLength、无字数计数器(frame5-record-entry.tsx:743-749),仅服务端 note max_length 兜底 |
maxLength={NOTE_MAX_LEN}(500)+ "剩余 N 字"实时计数器(new/page.tsx:2254、:2259-2261) |
| 字段 | 维度 | 平板端(file:line) | 手机端(file:line) | 差异判定 |
|---|---|---|---|---|
| 检查日期 visit_at | ①手输 | 否,纯弹层滚轮选择,收起态是不可编辑按钮(visit-date-field.tsx:66-74) |
否,同为弹层滚轮(new/page.tsx:1255-1267 触发按钮 + :2343-2350 DateWheel) |
一致(交互形态相同:两端都是"点击→居中弹层→三列滚轮→确定") |
| ②档位/选择器 | 有,DateWheel 三列(年/月/日)(visit-date-field.tsx:94-100) |
有,同款 DateWheel(new/page.tsx:2343-2350) |
一致(同一 DateWheel 组件,仅配色 accent 不同——蓝色 vs 绿色,纯视觉) |
|
| ③枚举/范围 | maxDate=今天,minYear 未传→默认 thisYear-18(visit-date-field.tsx:97、date-wheel.tsx:72) |
maxDate=今天,显式 minYear=thisYear-3(new/page.tsx:2346-2347) |
差异(见结构性差异S5):平板端可选最早18年前,手机端仅3年前 | |
| ④联动 | 无 | 无 | 一致 | |
| ⑤实时校验 | 有:选中日期晚于今天时报错"检查日期不能晚于今天"(frame5-record-entry.tsx:405-408,注释明确说明这是防御性兜底,因 DateWheel 已物理夹住不会真触发) |
无对应前端校验分支(mobile DateWheel 同样传了 maxDate,但页面代码里未见类似 visitDateError 兜底判断与提示文案) |
差异:平板端多一层防御性文案兜底,手机端目前只依赖 DateWheel 的 maxDate 硬夹,无兜底提示 UI(存疑,见第5节) |
|
| ⑥单位 | 无(日期无单位) | 无 | 一致 | |
| ⑦必填标记 | ★(frame5-record-entry.tsx:392,ariaLabel="必填标记") |
*(new/page.tsx:1253,RequiredStar 默认 ariaLabel="必填标记") |
一致(星号符号不同——平板★ vs 手机*,属已知 Card 内 RequiredStar 组件差异,非本字段独有) |
|
| ⑧默认值 | new Date().toISOString()(今天,refractive-record-pane.tsx:81) |
new Date().toISOString()(今天,new/page.tsx:855) |
一致 |
| 字段 | 维度 | 平板端 | 手机端 | 差异判定 |
|---|---|---|---|---|
| 记录法切换(小数制/5分制) | ①手输 | 否,两个 toggle 按钮(frame5-record-entry.tsx:428-445) |
否,同款 toggle(new/page.tsx:1287-1308) |
一致 |
| ②档位 | 无(二选一按钮,非档位) | 无 | 一致 | |
| ③枚举 | decimal/five_point 两选一(同上行号) |
同(new/page.tsx:1289、:1300) |
一致 | |
| ④联动 | 有:切换记法后 VA_ROWS 显示值按记法重新解释(通过 VisionAcuityPicker/VaPickerSheet 内 counterpart() 换算) |
同款联动(new/page.tsx:419-420 DECIMAL_WHEEL/FIVE_WHEEL) |
一致 | |
| ⑤实时校验 | 无 | 无 | 一致 | |
| ⑥单位 | 无 | 无 | 一致 | |
| ⑦必填 | 无(切换开关本身非必填项) | 无 | 一致 | |
| ⑧默认值 | "decimal"(refractive-record-pane.tsx:81 等同源) |
"decimal"(new/page.tsx:856) |
一致 | |
| 裸眼视力(unaided_va_raw) | ①手输 | 否,点开按钮弹 VisionAcuityPicker 滚轮(frame5-record-entry.tsx:460-467),滚轮内不可键盘输入(纯滚动选择,vision-acuity-picker.tsx 全文无 <input>) |
否,同样弹 VaPickerSheet 滚轮(new/page.tsx:1319-1329),滚轮内同样不可键盘输入(VaPickerSheet 组件全文无 <input>) |
一致 |
| ②档位 | 有,DECIMAL_WHEEL/FIVE_WHEEL 固定档位表(lib/va-map.ts,两端共用同一份) |
同(new/page.tsx:45-47 直接 import 平板端同一 lib/va-map.ts) |
一致(手机端直接复用平板端的纯数据模块,非重复造表) | |
| ③枚举 | 同上,档位即枚举 | 同 | 一致 | |
| ④联动 | 有:显示"对应{另一记法}{值}"副文案(vision-acuity-picker.tsx:94、:112) |
有,同款副文案(new/page.tsx:472、:489-491) |
一致 | |
| ⑤实时校验 | 无(滚轮选择不会产生非法值) | 无 | 一致 | |
| ⑥单位 | 无(视力无单位) | 无 | 一致 | |
| ⑦必填 | ★,row.kind === "unaided" 时渲染(frame5-record-entry.tsx:455) |
*,required={row.kind === "unaided"}(new/page.tsx:1314) |
一致(符号不同,已在结构性差异中说明,不重复记差异) | |
| ⑧默认值 | 未记录时按钮显示"未记录"(frame5-record-entry.tsx:248-249 show()),弹层打开默认档位小数制1.0/5分制5.0(vision-acuity-picker.tsx:29) |
同款空值文案"未记录"(new/page.tsx:235-236),弹层默认档位同为1.0/5.0(new/page.tsx:420) |
一致 | |
| 戴镜视力(wearing_va_raw) | ①-⑧ | 同"裸眼视力"整套交互,唯一区别是无 ★ 必填(frame5-record-entry.tsx:450-469 同一 VA_ROWS.map 循环渲染) |
同"裸眼视力"整套交互,同样无 * 必填(new/page.tsx:1313-1332 同一循环) |
一致 |
| 矫正视力(corrected_va_raw) | ①-⑧ | 同上,无必填(同循环) | 同上,无必填(同循环) | 一致 |
| 卡1 AI 回填高亮 | (附加维度) | 无此机制(见结构性差异 S2) | 有:裸眼视力按钮命中 aiFilledKeys 时变绿底(new/page.tsx:1317、:1325) |
差异(见 S2,手机端独有) |
| 字段 | 维度 | 平板端 | 手机端 | 差异判定 |
|---|---|---|---|---|
| 球镜 DS(current_sphere) | ①手输 | 是,NumberCell 直填(frame5-record-entry.tsx:487-492) |
是,同款 NumberCell 直填(new/page.tsx:1352-1362) |
一致 |
| ②档位 | 无(纯数值直填,无弹层) | 无 | 一致 | |
| ③枚举 | 无(自由数值) | 无 | 一致 | |
| ④联动 | 无(自镜度数不联动其他字段) | 无 | 一致 | |
| ⑤实时校验 | 有:失焦超界静默夹紧到 [-20,20],不弹提示(frame5-record-entry.tsx:194-206 NumberCell onBlur) |
有,同款静默夹紧逻辑(new/page.tsx:334-349,逐字节复刻,文件头注释亦声明"逐字节复刻") |
一致 | |
| ⑥单位 | D,标签行内小字(frame5-record-entry.tsx:486) |
D,同款(new/page.tsx EyeRow unit="D" 调用处) |
一致 | |
| ⑦必填 | 无 ★(frame5-record-entry.tsx:486 无 RequiredStar) |
无 *(EyeRow 调用未传 required) |
一致 | |
| ⑧默认值 | 空(null/未记录) |
空(null/未记录) |
一致 | |
| 柱镜 DC(current_cylinder) | ①-⑧ | 同"球镜"整套,范围同为[-20,20]2位小数带符号(frame5-record-entry.tsx:487-492) |
同"球镜"整套(new/page.tsx:1365-1378) |
一致 |
| ④联动(补充) | 有:柱镜清零/清空 → 联动清空同侧轴位(frame5-record-entry.tsx:271-273 commitNumeric) |
有,同款联动(new/page.tsx:993-995) |
一致 | |
| 轴位 AX(current_axis) | ①手输 | 是,NumberCell(frame5-record-entry.tsx:498-503),范围[1,180]整数 |
是,同款(new/page.tsx:1381-1391) |
一致 |
| ④联动 | 有:axisDisabled() 判定柱镜为0/空时禁用本字段(frame5-record-entry.tsx:257-260、:499) |
有,同款判定函数(new/page.tsx:981-984、:1384) |
一致 | |
| ⑤-⑧ | 同柱镜套路,无单独必填星标 | 同 | 一致 |
| 字段 | 维度 | 平板端 | 手机端 | 差异判定 |
|---|---|---|---|---|
| 验光方式(refraction_method) | ①手输 | 否,三个单选按钮:小瞳综合/散瞳/散开雾视(frame5-record-entry.tsx:522-535) |
否,同三个单选按钮(new/page.tsx:1420-1436) |
一致 |
| ②档位 | 无(枚举单选,非档位) | 无 | 一致 | |
| ③枚举 | small_pupil/cycloplegic/store_fogging 三选一(同上) |
同三值(new/page.tsx:1421) |
一致 | |
| ④联动 | 有:未选中时,本卡 AI识别按钮 + 3个数值字段全部禁用 + 顶部橙色提示条(frame5-record-entry.tsx:513-517、:540、:573、:584) |
有,同款联动禁用+提示条(new/page.tsx:1408-1416、:1448、:1457、:1478、:1494、:1510) |
一致 | |
| ⑤实时校验 | 有:未选验光方式时橙提示"请先选择验光方式…"(frame5-record-entry.tsx:514-517) |
有,一字不差同文案(new/page.tsx:1409-1415) |
一致 | |
| ⑥单位 | 无 | 无 | 一致 | |
| ⑦必填 | 无独立星标(但门槛联动等效必填) | 无独立星标 | 一致 | |
| ⑧默认值 | null(未选) |
null(未选) |
一致 | |
| AI识别(验光单上传) | ①手输 | 否,按钮触发隐藏 <input type=file>(frame5-record-entry.tsx:540-551) |
否,同款隐藏 file input(new/page.tsx:1442-1464) |
一致 |
| ②档位 | 不适用 | 不适用 | 一致 | |
| ③枚举 | accept="image/*"(frame5-record-entry.tsx:546) |
同(new/page.tsx:1455) |
一致 | |
| ④联动 | 有:disabled={aiBusy!==null \|\| !draft.refraction_method}(frame5-record-entry.tsx:540) |
有,同款联动条件(new/page.tsx:1448、:1457) |
一致 | |
| ⑤实时校验/反馈 | 有:识别中/已回填N项/识别失败三态文案(frame5-record-entry.tsx:544、:553-556) |
有,同三态文案(new/page.tsx:1451、:1466-1470),外加回填字段变绿底(见 S2) |
差异:反馈文案一致,但手机端多一层视觉高亮(见 S2,已计入结构性差异,不在此重复计"差异"权重) | |
| ⑥单位 | 不适用 | 不适用 | 一致 | |
| ⑦必填 | 不适用(可选操作) | 不适用 | 一致 | |
| ⑧默认值 | 不适用 | 不适用 | 一致 | |
| 主觉球镜 DS(subjective_sphere) | ①手输 | 是,NumberCell(frame5-record-entry.tsx:572-576) |
是,NumberCell(new/page.tsx:1475-1486) |
一致 |
| ②档位 | 无 | 无 | 一致 | |
| ③枚举 | 无(自由数值[-20,20]2位小数带符号) | 无,同范围 | 一致 | |
| ④联动 | 无独立联动(受验光方式门槛联动,已在上面记) | 同 | 一致 | |
| ⑤实时校验 | 有,同款静默夹紧 | 有,同款 | 一致 | |
| ⑥单位 | D(frame5-record-entry.tsx:569) |
D | 一致 | |
| ⑦必填 | ★(frame5-record-entry.tsx:569 <RequiredStar />) |
*(new/page.tsx:1473 EyeRow required) |
一致(符号差异已在S部分说明) | |
| ⑧默认值 | 空 | 空 | 一致 | |
| 主觉柱镜 DC(subjective_cylinder) | ①-⑧ | 同球镜整套 + ★必填(frame5-record-entry.tsx:562-576) |
同球镜整套 + *必填(new/page.tsx:1489-1503) |
一致 |
| ④联动(补充) | 有:清零/清空联动清空主觉轴位(frame5-record-entry.tsx:274-276) |
有,同款(new/page.tsx:996-998) |
一致 | |
| 主觉轴位 AX(subjective_axis) | ①手输 | 是,NumberCell,范围[1,180]整数(frame5-record-entry.tsx:582-587) |
是,同(new/page.tsx:1505-1517) |
一致 |
| ④联动 | 有:axisDisabled(eye,"subjective") + 验光方式双重门槛(frame5-record-entry.tsx:584) |
有,同双重门槛(new/page.tsx:1510) |
一致 | |
| ⑦必填 | 无独立星标 | 无独立星标 | 一致 |
| 字段 | 维度 | 平板端 | 手机端 | 差异判定 |
|---|---|---|---|---|
| 眼压 IOP(iop) | ①手输 | 是,NumberCell,范围[5,60]整数(frame5-record-entry.tsx:601-604,iopSpec 取自 BIO_SPECS) |
是,同(new/page.tsx:1538-1552,BASIC_SPECS 常量 1:1 抄自平板端) |
一致 |
| ②档位 | 无 | 无 | 一致 | |
| ③枚举 | 无(自由数值) | 无 | 一致 | |
| ④联动 | 无 | 无 | 一致 | |
| ⑤实时校验 | 有,静默夹紧 | 有,同 | 一致 | |
| ⑥单位 | mmHg(iopSpec.unit,来自 record-canvas.tsx:46) |
mmHg(BASIC_SPECS 同值,new/page.tsx:106) |
一致 | |
| ⑦必填 | 无 ★ | 无 * | 一致 | |
| ⑧默认值 | 空 | 空 | 一致 | |
| 单眼瞳距 PD(monocular_pd) | ①-⑧ | 同IOP套路,范围[15,45]整数,单位mm(frame5-record-entry.tsx:608-614) |
同(new/page.tsx:107、:1538-1552) |
一致 |
| 单眼瞳高 PH(monocular_ph) | ①-⑧ | 同套路,范围[10,40]整数,单位mm(frame5-record-entry.tsx:617-623) |
同(new/page.tsx:108) |
一致 |
| 字段 | 维度 | 平板端 | 手机端 | 差异判定 |
|---|---|---|---|---|
| AI识别(眼轴曲率单上传) | ①-⑧ | 同卡3 AI识别交互形态,唯一区别:无验光方式门槛,仅 disabled={aiBusy!==null}(frame5-record-entry.tsx:635) |
同,同样只受 aiBusy 门槛(new/page.tsx:1577、:1585) |
一致 |
| 本次眼轴 AL(axial_length) | ①手输 | 是,NumberCell,范围[14,38]2位小数(frame5-record-entry.tsx:662-667,bioSpecs 过滤自 BIO_SPECS) |
是,同(new/page.tsx:1601-1616,BIO_SPECS 常量) |
一致 |
| ②档位 | 无 | 无 | 一致 | |
| ③枚举 | 无 | 无 | 一致 | |
| ④联动 | 无 | 无 | 一致 | |
| ⑤实时校验 | 有,静默夹紧 | 有,同 | 一致 | |
| ⑥单位 | mm(record-canvas.tsx:43) |
mm(new/page.tsx:111) |
一致 | |
| ⑦必填 | ★(frame5-record-entry.tsx:659 spec.key === "axial_length" && <RequiredStar />) |
*(new/page.tsx:1602 required={spec.key === "axial_length"}) |
一致 | |
| ⑧默认值 | 空 | 空 | 一致 | |
| 角膜曲率 K1(keratometry_k1) | ①-⑧ | 同套路,范围[30,60]2位小数,无必填星标(frame5-record-entry.tsx:44-45定义,:655-668渲染) |
同(new/page.tsx:112) |
一致 |
| 角膜曲率 K2(keratometry_k2) | ①-⑧ | 同套路,同范围,无必填星标 | 同(new/page.tsx:113) |
一致 |
| 卡5 AI 回填高亮 | (附加维度) | 无(见S2) | 有,aiFilledKeys 命中变绿底(new/page.tsx:1611) |
差异(计入S2,手机端独有) |
| 字段 | 维度 | 平板端 | 手机端 | 差异判定 |
|---|---|---|---|---|
| 眼前节状态(anterior_segment_status) | ①手输 | 否,两个枚举按钮:未见明显异常/异常(frame5-record-entry.tsx:688-698) |
否,同两个按钮(new/page.tsx:1648-1662) |
一致 |
| ②档位 | 无(枚举,非档位) | 无 | 一致 | |
| ③枚举 | normal/abnormal,再点同一项取消回未检查(pickOcular,frame5-record-entry.tsx:280-287) |
同(pickOcular,new/page.tsx:961-968,1:1抄自平板端) |
一致 | |
| ④联动 | 有:选normal或取消时清空该项备注(frame5-record-entry.tsx:285) |
有,同款联动(new/page.tsx:966) |
一致 | |
| ⑤实时校验 | 无(未检查时仅小字提示"未检查 → 都不选",frame5-record-entry.tsx:700-702) |
无,同款提示文案(new/page.tsx:1663-1665) |
一致 | |
| ⑥单位 | 无 | 无 | 一致 | |
| ⑦必填 | 无星标(整卡无必填要求) | 无星标 | 一致 | |
| ⑧默认值 | null(未检查) |
null(未检查) |
一致 | |
| 眼前节异常备注(anterior_segment_note) | ①手输 | 是,abnormal 时才显示的文本输入框(frame5-record-entry.tsx:704-716),无 placeholder(B3整改令删除) |
是,同款条件显示(new/page.tsx:1667-1681),同样无 placeholder |
一致 |
| ②-⑧ | 无档位/枚举/联动(纯自由文本);无单位;无必填;默认空字符串/null | 同 | 一致 | |
| 眼底状态/备注(fundus_status/note) | 全部维度 | 同"眼前节"整套(frame5-record-entry.tsx:677-721 同一 OCULAR_EXAMS.map 循环渲染) |
同"眼前节"整套(new/page.tsx:1634-1687 同一循环) |
一致 |
| OCT状态/备注(oct_status/note) | 全部维度 | 同上,同循环 | 同上,同循环 | 一致 |
平板端整卡由
AdvancedVisionSection渲染,手机端对应逻辑在new/page.tsx卡7区块(:1691-2237)内联实现。所有数值字段范围/step 1:1 抄自平板端(文件头注释多处"1:1 抄自"标注,已逐一 grep 核对)。
| 字段 | 维度 | 平板端 | 手机端 | 差异判定 |
|---|---|---|---|---|
| 本次视功能检查(visual_function_done) | ①手输 | 否,两按钮"本次已做/本次未做"(advanced-vision-section.tsx:121-132) |
否,同两按钮(new/page.tsx:1705-1724) |
一致 |
| ②档位 | 无 | 无 | 一致 | |
| ③枚举 | true/false/null(再点取消回null,onDoneChange(done===v?null:v)) |
同(new/page.tsx:1713) |
一致 | |
| ④联动 | 有:选"本次未做"时,整卡后续分组(双眼视觉起)靠外层调用方判断——查证:AdvancedVisionSection 本身不根据 done 隐藏子分组(组件内没有 done===false 分支跳过渲染,advanced-vision-section.tsx:113-506 通篇无此判断),即平板端选"未做"后其余分组仍然全部照常展开可填 |
有明确联动:draft.visual_function_done === false 时直接跳过渲染所有分组,只显示提示"本次未做视功能检查,已跳过以下分组"(new/page.tsx:1728-1732) |
确认差异:手机端"未做"会隐藏全部视功能子分组,平板端"未做"后子分组仍然全部展开、字段照常可填/可能被误填 | |
| ⑤实时校验 | 无 | 有:未做时的提示文案(见上) | 一致(此维度本身无冲突,差异已计入④) | |
| ⑥单位 | 无 | 无 | 一致 | |
| ⑦必填 | 无 | 无 | 一致 | |
| ⑧默认值 | null |
null |
一致 | |
| Worth远(worth_far_result) | ①手输 | 是(仅"其他"态):点"其他"后出现自由输入框(advanced-vision-section.tsx:186-195) |
是,同款"其他"态自由输入(new/page.tsx:1785-1794) |
一致 |
| ②档位 | 无(固定枚举+自由文本,非数值档位) | 无 | 一致 | |
| ③枚举 | WORTH_OPTIONS=["4点·融合","5点·复视","2点·左眼抑制","3点·右眼抑制"] + "其他"(advanced-vision-section.tsx:34、:160-184) |
同4值+"其他"(new/page.tsx:125、:1754-1783) |
一致 | |
| ④联动 | 有:选中已有非枚举值时自动判定isOther展开自由框(advanced-vision-section.tsx:152-153) |
有,同款判定(new/page.tsx:1746-1747) |
一致 | |
| ⑤实时校验 | 无 | 无 | 一致 | |
| ⑥单位 | 无 | 无 | 一致 | |
| ⑦必填 | 无 | 无 | 一致 | |
| ⑧默认值 | null |
null |
一致 | |
| Worth近(worth_near_result) | 全部维度 | 同"Worth远"整套,同一 .map 循环(advanced-vision-section.tsx:148-198) |
同"Worth远"整套,同一循环(new/page.tsx:1742-1797) |
一致 |
| 立体视有/无(stereopsis_present) | ①手输 | 否,两按钮"有/无"(advanced-vision-section.tsx:203-219) |
否,同两按钮(new/page.tsx:1807-1827) |
一致 |
| ②-③ | 无档位;枚举true/false |
同 | 一致 | |
| ④联动 | 有:选"无"时联动清空 stereopsis_arcsec(advanced-vision-section.tsx:207-209) |
有,同款联动(new/page.tsx:1814-1816) |
一致 | |
| ⑤-⑧ | 无校验/单位/必填;默认null |
同 | 一致 | |
| 立体视弧秒档位(stereopsis_arcsec · 15档) | ①手输 | 否,15个固定档位 chip 按钮(STEREO_LEVELS,advanced-vision-section.tsx:40、:222-236) |
否,同15档位 chip(new/page.tsx:126、:1831-1850) |
一致 |
| ②档位 | 有,15档(同上) | 有,同15档 | 一致 | |
| ③枚举 | [3000,800,480,400,240,200,140,120,100,80,60,50,40,30,15] |
同一数组(new/page.tsx:126) |
一致 | |
| ④联动 | 有:stereopsis_present===false 时禁用(advanced-vision-section.tsx:225) |
有,同禁用条件(new/page.tsx:1836) |
一致 | |
| ⑤-⑧ | 无校验;单位″;无必填;默认null | 同 | 一致 | |
| 立体视弧秒-自定义值(同字段,非档位输入) | ①手输 | 是,但需先点"其他"按钮才弹出 ConstrainedNumberPicker,弹层内含键盘输入框(advanced-vision-section.tsx:237-246) |
是,常驻 NumberCell 直接可输,无需先点按钮(new/page.tsx:1852-1867) |
确认差异(结构性 S4):入口可见性不同——平板端隐藏在"其他"按钮后,手机端始终可见 |
| ②档位 | 有(打开后仍是同一 ConstrainedNumberPicker,但 mode:"free" 无 step,故弹层内无离散档位,只有键盘输入,advanced-vision-section.tsx:240) |
无对应弹层(直接 NumberCell 手输,无二次弹层) |
确认差异:平板端此值走"二次确认"弹层,手机端是即时提交(失焦即 commitVf) |
|
| ③枚举 | 范围10,3000 | 范围[10,3000]同(new/page.tsx:1861-1862) |
一致(数值域一致,交互形态见上两条差异) | |
| ④联动 | 同"有/无"禁用联动 | 同 | 一致 | |
| ⑤-⑧ | 无校验;单位″;无必填;默认按当前值判断 | 同 | 一致 | |
| DLP远距水平-数值(dlp_amount) | ①手输 | 否,按钮显示值+点击开 ConstrainedNumberPicker 弹层(弹层内可键盘输入)(advanced-vision-section.tsx:273-281) |
是,NumberCell 卡面直接手输 + chevron按钮开 VfPickerSheet 弹层(双通道)(new/page.tsx:1895-1919) |
确认差异(S3):平板端单通道(弹层内输入),手机端双通道(卡面直填+弹层选档位) |
| ②档位 | 有:弹层内本身无离散chip(mode:"free" 无 step,同stereopsis自定义值同理——查证:setPicker 传的 spec 均无 step 字段,advanced-vision-section.tsx:274-277),故平板端此处弹层其实也无档位chip,纯键盘输入 |
有,VfPickerSheet 弹层内按 step=1 生成离散档位列表(new/page.tsx:1912、buildVfSteps函数:534-544) |
确认差异:手机端此处比平板端多了"离散档位可点选"的能力(平板端该字段弹层实测无档位,仅键盘输入) | |
| ③枚举 | 范围[0,50]整数(advanced-vision-section.tsx:275) |
范围[0,50]step=1(new/page.tsx:1912) |
一致(数值域一致) | |
| ④联动 | 有:数值填了但方向未选 → groupBroken 提示"请选方向"(advanced-vision-section.tsx:269、:298-302) |
有,同款判据+文案(new/page.tsx:1889、:1942-1946) |
一致 | |
| ⑤实时校验 | 有(同④联动提示) | 有,同 | 一致 | |
| ⑥单位 | Δ(advanced-vision-section.tsx:275) |
Δ(new/page.tsx:1912) |
一致 | |
| ⑦必填 | 无独立星标(仅联动提示"方向必选"徽标,挂在分组标题,非本字段) | 无独立星标(同款分组级"方向必选"note,new/page.tsx:1878) |
一致 | |
| ⑧默认值 | 空 | 空 | 一致 | |
| DLP远距水平-方向(dlp_direction) | ①手输 | 否,3个方向chip(Exo/Ortho/Eso,H_DIRS,advanced-vision-section.tsx:283-296) |
否,同3个chip(new/page.tsx:1920-1941) |
一致 |
| ②-③ | 无档位;枚举exo/ortho/eso,每项带≈BI/≈BO副标注 |
同(H_DIRS常量1:1抄,new/page.tsx:128-132) |
一致 | |
| ④联动 | 有(同上数值×方向成组校验) | 有,同 | 一致 | |
| ⑤-⑧ | 同上组;无单位;无独立必填;默认null | 同 | 一致 | |
| NLP近距水平-数值(nlp_amount) | 全部维度 | 同"DLP数值"整套,同PHORIAS.map循环(advanced-vision-section.tsx:266-315) |
同"DLP数值"整套,同PHORIAS.map循环(new/page.tsx:1883-1949) |
一致(与DLP相比:S3/离散档位两条差异同样成立,不重复计) |
| NLP近距水平-方向(nlp_direction) | 全部维度 | 同"DLP方向"整套 | 同"DLP方向"整套 | 一致 |
| DVP远距垂直-数值(dvp_amount) | 全部维度 | 同"DLP数值"整套,方向用V_DIRS(右高/Ortho/左高) |
同,方向用V_DIRS同款(new/page.tsx:133-137) |
一致(S3差异同样成立) |
| DVP远距垂直-方向(dvp_direction) | 全部维度 | 同,V_DIRS3项 |
同 | 一致 |
| NVP近距垂直-数值(nvp_amount) | 全部维度 | 同"DLP数值"整套 | 同 | 一致(S3差异同样成立) |
| NVP近距垂直-方向(nvp_direction) | 全部维度 | 同,V_DIRS3项 |
同 | 一致 |
| AC/A梯度法(aca_ratio) | ①手输 | 否,按钮显示值+点击开弹层(advanced-vision-section.tsx:307-313,SINGLES[0]) |
是,NumberCell卡面直填(decimals=1格式化)+chevron开VfPickerSheet(new/page.tsx:1954-1975) |
确认差异(S3):同DLP数值字段的双通道vs单通道差异 |
| ②档位 | step=0.5(advanced-vision-section.tsx:87),弹层内buildSteps会生成离散档位(此字段ConstrainedNumberPicker确实带step,与stereopsis/DLP等"无step纯键盘"字段不同——需注意本字段平板端确实有弹层档位,不属于上面"无档位"的特例) |
step=0.5,VfPickerSheet同款离散档位(new/page.tsx:1968) |
一致(档位值域一致,交互通道数量差异已计入①) | |
| ③枚举 | 范围0,20 | 范围0,20 | 一致 | |
| ④联动 | 无(AC/A不参与方向成组校验) | 无 | 一致 | |
| ⑤-⑧ | 无校验;单位Δ/D;无必填;默认空 | 同 | 一致 | |
| 远UCT性质(far_uct_type) | ①手输 | 否,隐斜/显斜2个chip(COVERS.map,advanced-vision-section.tsx:349-360) |
否,同2个chip(new/page.tsx:2003-2017) |
一致 |
| ②-③ | 无档位;枚举phoria/tropia |
同 | 一致 | |
| ④联动 | 无(UCT性质本身不参与成组校验,ACT数值×方向才成组) | 无 | 一致 | |
| ⑤-⑧ | 无校验/单位;无必填;默认null | 同 | 一致 | |
| 远ACT数值(far_act_amount) | ①手输 | 否,按钮+弹层(advanced-vision-section.tsx:362-370) |
是,NumberCell+chevron双通道(new/page.tsx:2021-2043) |
确认差异(S3) |
| ②档位 | step=1(advanced-vision-section.tsx:364),弹层内有离散档位 |
step=1,VfPickerSheet同离散档位(new/page.tsx:2037) |
一致(值域一致) | |
| ③枚举 | 范围[0,60] | 范围[0,60] | 一致 | |
| ④联动 | 有:数值×方向成组,groupBroken(advanced-vision-section.tsx:335-336) |
有,同款(new/page.tsx:1995-1996) |
一致 | |
| ⑤实时校验 | 有(同④) | 有,同 | 一致 | |
| ⑥单位 | Δ | Δ | 一致 | |
| ⑦必填 | 无独立星标(分组级"ACT方向必选"徽标) | 无独立星标,同款分组级note | 一致 | |
| ⑧默认值 | 空 | 空 | 一致 | |
| 远ACT方向(far_act_direction) | ①手输 | 否,5个方向chip:Exo/Eso/右高/左高/Ortho(ACT_DIRS,advanced-vision-section.tsx:63-69、:376-390) |
否,同5个chip(new/page.tsx:144-150、:2046-2062) |
一致 |
| ②-⑧ | 无档位;枚举5值;联动成组校验;无单位;无必填;默认null | 同 | 一致 | |
| 近UCT性质(near_uct_type) | 全部维度 | 同"远UCT性质"整套,同COVERS.map循环 |
同,同循环 | 一致 |
| 近ACT数值(near_act_amount) | 全部维度 | 同"远ACT数值"整套(S3差异同样成立) | 同 | 一致(差异已在"远ACT数值"记录,不重复) |
| 近ACT方向(near_act_direction) | 全部维度 | 同"远ACT方向"整套 | 同 | 一致 |
| PFC远融像性集合-破裂(pfc_break) | ①手输 | 否,按钮+弹层(PAIRS.map,advanced-vision-section.tsx:421-429) |
是,NumberCell+chevron(new/page.tsx:2100-2123) |
确认差异(S3) |
| ②档位 | step=1,范围0,60 |
step=1,范围0,60 |
一致 | |
| ③枚举 | 同上 | 同上 | 一致 | |
| ④联动 | 有:恢复值不能孤立于破裂值(orphanRecovery,advanced-vision-section.tsx:415-418) |
有,同款判据+文案"破裂/恢复成对·需先录破裂"(new/page.tsx:2088-2090、:2150-2154) |
一致 | |
| ⑤-⑧ | 有校验(同④);单位Δ;无必填;默认空 | 同 | 一致 | |
| PFC远融像性集合-恢复(pfc_recovery) | 全部维度 | 同"破裂"整套(S3差异同样成立) | 同 | 一致(差异已记在"破裂") |
| NFC远融像性散开-破裂(nfc_break) | 全部维度 | 同PFC破裂整套,step=1范围[0,60] |
同 | 一致(S3差异同样成立) |
| NFC远融像性散开-恢复(nfc_recovery) | 全部维度 | 同 | 同 | 一致 |
| NPC集合近点-破裂(npc_break) | ①-⑧ | 同PFC破裂,但step=0.5,范围[1,40],单位cm(advanced-vision-section.tsx:83) |
同,step=0.5范围[1,40]单位cm(new/page.tsx:162) |
一致(S3差异同样成立) |
| NPC集合近点-恢复(npc_recovery) | 全部维度 | 同上 | 同 | 一致 |
| NRA负相对调节(nra) | ①手输 | 否,方块按钮显示值+点击开弹层(SINGLES.slice(1),advanced-vision-section.tsx:454-466) |
是,NumberCell+chevron(new/page.tsx:2180-2204) |
确认差异(S3) |
| ②档位 | step=0.25,范围0,6 |
step=0.25,范围0,6 |
一致 | |
| ③-⑧ | 单位D;无联动;无校验;无必填;默认空 | 同 | 一致 | |
| PRA正相对调节(pra) | 全部维度 | 同NRA整套,step=0.25范围-10,0 |
同,范围-10,0 | 一致(S3差异同样成立) |
| BCC双眼交叉柱镜(bcc) | 全部维度 | 同,step=0.25范围-3,3 |
同,范围-3,3 | 一致 |
| AMP调节幅度(amp) | 全部维度 | 同,step=0.25范围0,25 |
同,范围0,25 | 一致 |
| 评估(assessment · 6选多选) | ①手输 | 否,6个多选chip(ASSESSMENTS,advanced-vision-section.tsx:23-30、:474-486) |
否,同6个chip(new/page.tsx:176-183、:2213-2231) |
一致 |
| ②档位 | 无(多选枚举,非档位) | 无 | 一致 | |
| ③枚举 | 调节不足/调节过度/集合不足/集合过度/散开不足/散开过度(6值,同上) | 同6值(1:1抄) | 一致 | |
| ④联动 | 有:取消到空集合时回写null而非空数组(DB约束,advanced-vision-section.tsx:103-106) |
有,同款回写逻辑(new/page.tsx:2221-2224) |
一致 | |
| ⑤-⑧ | 无校验;无单位;无必填;默认null |
同 | 一致 |
| 字段 | 维度 | 平板端 | 手机端 | 差异判定 |
|---|---|---|---|---|
| 备注(note) | ①手输 | 是,<textarea>(frame5-record-entry.tsx:743-749),无 placeholder(B3整改令删除) |
是,<textarea>(new/page.tsx:2251-2258),同样无 placeholder |
一致 |
| ②档位 | 无 | 无 | 一致 | |
| ③枚举 | 无(自由文本) | 无 | 一致 | |
| ④联动 | 无 | 无 | 一致 | |
| ⑤实时校验 | 无:<textarea> 无 maxLength 属性,无长度限制/计数器(frame5-record-entry.tsx:743-749 全属性列表中确认无 maxLength) |
有:maxLength={NOTE_MAX_LEN}(500)+"剩余 N 字"实时计数器(new/page.tsx:2254、:2259-2261) |
确认差异(结构性S6):平板端可无限输入(仅服务端note max_length兜底拒绝,用户体验是提交才知道超长),手机端前端硬限制+实时倒数提示 |
|
| ⑥单位 | 无 | 无 | 一致 | |
| ⑦必填 | 无(选填) | 无(选填) | 一致 | |
| ⑧默认值 | null |
null |
一致 |
frame5-record-entry.tsx:743-749 <textarea> 无 maxLength、无计数器;手机端有 500 字硬限制+实时倒数(new/page.tsx:2254、:2259-2261)。平板端用户可能录入超长文本,提交时才被服务端 note max_length 拒绝,体验劣于手机端,且是数据完整性/用户体验层面的真实缺口,不是纯视觉差异。new/page.tsx:1728-1732);平板端 AdvancedVisionSection 组件内没有根据 done 隐藏子分组的判断(通篇 grep 确认),即平板端标记"未做"后,门店仍可能继续在展开的分组里录入数据,造成"标记未做但数据非空"的语义矛盾,属两端行为真实不一致,非纯视觉差异。NumberCell 直填 + chevron 档位弹层双通道)比平板端(仅按钮开弹层单通道)多一种直接手输入口。字段清单:DLP/NLP/DVP/NVP 数值(4)、AC/A(1)、远/近 ACT 数值(2)、PFC/NFC/NPC 破裂+恢复(6)、NRA/PRA/BCC/AMP(4)——共 17 个,与此前一轮排查记录的"17个字段"一致,本次确认该差异仍然存在,只是方向已反转:此前是"平板端有档位、手机端只能手输",现在是"手机端双通道更全、平板端单通道"。仍需长官确认这个"多通道"是否是刻意保留的产品设计,还是需要平板端也补齐直填能力以对齐手机端体验。advanced-vision-section.tsx:237-246);手机端该输入框常驻可见(new/page.tsx:1852-1867)。aiFilledKeys 状态给 AI 回填字段加绿底"待核对"提示(涉及卡1裸眼视力、卡3主觉球镜/柱镜/轴位、卡5眼轴/K1/K2,共 7 个字段位点);平板端 frame5-record-entry.tsx 全文 aiFilled 0 命中,AI 识别结果直接覆盖显示,无任何"这是刚识别出来还没人工核对过"的视觉区分。这是手机端更优的方向,但仍是两端能力不对等,建议记录以便决定是否要反向补给平板端。VisitDateField未传minYear,继承DateWheel默认thisYear-18);手机端只能选最早3年前(new/page.tsx:2347显式minYear=thisYear-3)。对于需要补录历史就诊记录的场景,手机端范围明显更窄。doneFlags+FoldHeader+ProgressPills 折叠与进度提示体系,平板端8卡固定全展开、无该体系。这是产品形态差异(平板屏幕大适合全展开,手机屏幕小适合折叠),很可能是刻意设计,但仍按"不许把能力差异当一致"原则记录在案。#b8641f),手机端用"*"(同色值#b8641f)。纯符号差异,含义/位置/触发条件完全一致,严重度最低,仅作记录。frame5-record-entry.tsx:405-408 有一段"防御性兜底"代码:即便 DateWheel 已经把 maxDate 卡死,仍在 onChange 回调里二次判断"选中日期>今天"并弹错误文案。我在 new/page.tsx 里搜索了 visitDateError/不能晚于今天 等关键词,没有找到对应实现(mobile 的 DateWheel onChange 直接 setDraft,确认弹层时才 combineDateKeepTime 写入,中间无越界判断分支)。但由于两端 DateWheel 都已经用 maxDate 硬夹选项,这段兜底代码在正常操作路径下本就不会被触发(平板端注释自己也这么说),所以我无法排除"两端其实都无法真正触发这个错误提示、这段差异没有实际影响"的可能性。没有把握之处:没有做真机/模拟器操作去尝试绕过 DateWheel 的 maxDate 限制(比如系统时间校准问题、时区边界等罕见场景下是否会绕过硬夹),因此不确定这条差异是否有实际后果,列为存疑而非确认差异。advanced-vision-section.tsx 里 setPicker({spec:{...}}) 传参是否带 step 字段。多数字段(DLP/ACT/PFC等)在 setPicker 调用处显式带了 step(如 line 275 step:1、line 364 step:1),但 stereopsis 自定义值(line 240)和 AC/A(line 309 引用 SINGLES[0],该常量本身带 step:0.5,见 line 87)传参路径不同。我按"最终传给 ConstrainedNumberPicker 的 spec.step 是否为 undefined"这个唯一判据来判断"弹层内有没有离散档位列表"(constrained-number-picker.tsx:59-64 buildSteps 逻辑印证:只有 step!==undefined 时才生成档位)。我认为这个判据是可靠的(有源码逻辑支撑,非猜测),但没有做真机截图验证弹层实际渲染效果,如果 ConstrainedNumberPicker 还有别的隐藏分支我没读到,结论可能有偏差,故仍标注"存疑"以防万一,建议后续如需高精度验收再补一次真机截图核对。[recordId]/page.tsx(记录查看页)与本录入页字段是否完全对齐 —— 该文件不在本次比对范围(它是查看页非录入页),且当前正被另一 agent 编辑,我全程未读取其内容,故无法判断查看页展示的字段集合是否与本报告覆盖的录入字段集合一致。如后续需要"录入-查看"两页字段一致性核对,需另开任务且需等该 agent 完工后再读。计数口径说明:本表按"交互控件"粒度计数字段(如"裸眼视力"算1个字段,不因OD/OS两栏拆成2个);"确认差异"既给出"差异类型数"(8类,见清单)也给出"受影响字段位点数"(约26个),两个数字口径不同但均已在正文逐条列出,供长官按需引用,不存在互相矛盾。