Files
Mdeical_Sur_Report/工程分析/实现方案-2026-04-17-23-12-52.md

112 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 实现方案 — 2026-04-17-23-12-52
## 根因分析
### 问题1格式选项缺失与旧值残留
- `types.ts``DEFAULT_FORM_FIELDS` 中,`startTime``endTime``timeFormat` 仍被硬编码为 `'24h'`(历史遗留)。
- `TemplateManage.tsx` 中的 `defaultFormats` 虽然已包含 `HH:mm``hh:mm A`,但 `customTimeFormats` 的 datalist 未按字段类型过滤,导致 date/time 格式混在一起显示,用户体验混乱。
- 用户的 `localStorage``customTimeFormats` 可能还残留旧值 `'24h'``'12h'`
### 问题2报告编辑器显示 "24h"
- `formatTimeDisplay('14:30', '24h')` 中,格式字符串 `'24h'` 不包含 `HH`/`hh`/`mm`/`A` 等任何替换 token函数直接原样返回 `'24h'`
- 这是 F1 根因的直接后果:`formFieldsConfig` 中的 `timeFormat = '24h'` 被传入格式化函数。
### 问题3输入框点击失效
- `TemplateManage.tsx` 字段管理列表位于一个 `overflow-y-auto` 的滚动容器中。
- 点击字段卡片后,卡片内部展开编辑表单,高度瞬间增加。如果卡片原本位于可视区域底部,展开后的输入框可能刚好处于容器边缘之外。
- 浏览器的 hit-testing 在布局突变时可能无法正确将点击事件路由到新出现的输入框上,导致需要手动滚动后才能点击。
## 修改文件清单
| 文件 | 修改内容 |
|------|---------|
| `src/types.ts` | `DEFAULT_FORM_FIELDS``startTime`/`endTime``timeFormat``'24h'` 改为 `'HH:mm'` |
| `src/pages/ReportEditor.tsx` | `formatTimeDisplay` 开头增加 `if (fmt === '24h') fmt = 'HH:mm';` 兼容兜底 |
| `src/pages/TemplateManage.tsx` | ① `defaultFormats` 初始化时过滤掉旧脏数据 `'24h'`/`'12h'`;② datalist 渲染时按字段类型date/time过滤选项③ 字段编辑卡片 `onClick` 中增加 `scrollIntoView` |
## 具体代码变更
### 1. types.ts
```ts
// 修改前
{ key: 'startTime', label: '手术开始时间', category: '时间', type: 'time', visibleInForm: true, isSystemLocked: true, timeFormat: '24h', timeDefault: 'specific' },
{ key: 'endTime', label: '手术终止时间', category: '时间', type: 'time', visibleInForm: true, isSystemLocked: true, timeFormat: '24h', timeDefault: 'specific' },
// 修改后
{ key: 'startTime', label: '手术开始时间', category: '时间', type: 'time', visibleInForm: true, isSystemLocked: true, timeFormat: 'HH:mm', timeDefault: 'specific' },
{ key: 'endTime', label: '手术终止时间', category: '时间', type: 'time', visibleInForm: true, isSystemLocked: true, timeFormat: 'HH:mm', timeDefault: 'specific' },
```
### 2. ReportEditor.tsx
```ts
// 在 formatTimeDisplay 函数开头增加一行兼容兜底
const formatTimeDisplay = (timeStr: string, fmt?: string): string => {
if (!timeStr || !fmt) return timeStr || '';
if (fmt === '24h') fmt = 'HH:mm'; // 兼容旧脏数据
// ... 后续代码不变
};
```
### 3. TemplateManage.tsx
**3.1 清理旧脏数据(初始化时)**
```ts
// 修改前
const savedFormats = storage.get<string[]>('customTimeFormats', []);
const defaultFormats = ['YYYY-MM-DD', 'YYYY年MM月DD日', 'MM-DD', 'MM月DD日', 'HH:mm', 'hh:mm A'];
setCustomTimeFormats(Array.from(new Set([...defaultFormats, ...savedFormats])));
// 修改后
const savedFormats = storage.get<string[]>('customTimeFormats', []);
const defaultFormats = ['YYYY-MM-DD', 'YYYY年MM月DD日', 'MM-DD', 'MM月DD日', 'HH:mm', 'hh:mm A'];
// 过滤掉历史遗留的无效旧格式
const cleanedSaved = savedFormats.filter(f => f !== '24h' && f !== '12h');
setCustomTimeFormats(Array.from(new Set([...defaultFormats, ...cleanedSaved])));
```
**3.2 按字段类型过滤 datalist**
在编辑字段和新增字段的 format `<datalist>` 渲染处,增加按 `field.type` / `newFieldForm.type` 过滤:
```tsx
<datalist id={`edit-format-list-${field.key}`}>
{customTimeFormats
.filter(fmt => {
const isDateFormat = /YYYY|MM|DD/.test(fmt);
const isTimeFormat = /HH|hh|mm|A/.test(fmt);
if (field.type === 'date') return isDateFormat;
if (field.type === 'time') return isTimeFormat;
return true;
})
.map(fmt => <option key={fmt} value={fmt} />)}
</datalist>
```
新增字段的 datalist 同理。
**3.3 编辑卡片点击后自动滚动对齐**
```tsx
onClick={(e) => {
setEditingFieldKey(field.key);
// ... 其他 setState
const target = e.currentTarget;
setTimeout(() => {
target.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}, 50);
}}
```
## 风险点与应对措施
| 风险 | 应对措施 |
|------|---------|
| 清理 `customTimeFormats` 中的 `'24h'`/`'12h'` 可能误删用户真正想保留的自定义格式 | 仅过滤精确匹配 `'24h'``'12h'` 两个字符串,不影响其他自定义格式 |
| 按类型过滤 datalist 可能误过滤 | 使用正则 `/YYYY|MM|DD/` 识别日期格式,`/HH|hh|mm|A/` 识别时间格式;若格式同时满足两者(理论上不应发生)则同时显示 |
| `scrollIntoView` 在极端短容器中频繁触发 | 使用 `block: 'nearest'` 而非 `'start'`减少不必要的滚动50ms 延迟确保 DOM 已撑开 |
## 回滚策略
- `types.ts` 的修改可直接回退两个字段的 `timeFormat` 字符串。
- `ReportEditor.tsx` 的修改仅增加一行,删除即可。
- `TemplateManage.tsx` 的修改均为增量逻辑,回滚时移除条件块即可。