# 合同起草页面 UI 修复
## 修复内容
### 1. 修复 `json` 弃用警告
**问题**:
```
"json"已弃用。ts(6385)
This utility is deprecated in favor of opting into Single Fetch via future.v3_singleFetch
and returning raw objects. This method will be removed in React Router v7.
```
**解决方案**:
使用 `Response.json()` 替代 Remix 的 `json()` 函数。
**修改的代码**:
```typescript
// ❌ 旧代码(已弃用)
import { json, redirect } from '@remix-run/node';
export async function loader() {
return json({ data });
}
export async function action() {
return json({ success: true }, { status: 200 });
}
```
```typescript
// ✅ 新代码(使用标准 Web API)
import { redirect } from '@remix-run/node';
export async function loader() {
return Response.json({ data });
}
export async function action() {
return Response.json({ success: true }, { status: 200 });
}
```
**优势**:
- 使用标准 Web API,兼容性更好
- 未来 React Router v7 不会移除
- 符合现代 Web 标准
### 2. 修复 FilePreview 高度问题
**问题**:
FilePreview 组件没有占满父级容器的高度,导致页面布局不完整。
**根本原因**:
1. 父容器没有高度限制
2. FilePreview 根元素没有设置 `h-full`
3. 内容区域使用固定的 `maxHeight: calc(100vh - 150px)`,不适用于嵌套布局
**解决方案**:
#### 修改 1:父容器添加高度
`app/routes/contract-draft.$draftId.tsx`:
```typescript
// ❌ 旧代码
```
```typescript
// ✅ 新代码
```
**变化**:
- 添加 `h-full` - 高度占满父容器
- 添加 `overflow-hidden` - 防止内容溢出
#### 修改 2:FilePreview 根元素使用 Flex 布局
`app/components/reviews/FilePreview.tsx`:
```typescript
// ❌ 旧代码
return (
);
```
```typescript
// ✅ 新代码
return (
);
```
**变化**:
- 根元素:添加 `h-full flex flex-col` - 占满高度,使用垂直 Flex 布局
- Header:添加 `flex-shrink-0` - 固定高度,不压缩
- Content:使用 `flex-1 overflow-auto` 替代固定 `maxHeight` - 占据剩余空间,自动滚动
## 布局原理
### Flex 布局结构
```
┌─────────────────────────────────────────┐
│ h-screen flex flex-col │ ← 全屏容器
├─────────────────────────────────────────┤
│ 顶部工具栏 (固定高度) │ ← flex-shrink-0
├─────────────────────────────────────────┤
│ flex-1 flex overflow-hidden │ ← 主内容区(占据剩余空间)
│ ┌─────────────┬─────────────────────┐ │
│ │ w-[60%] │ w-[40%] │ │
│ │ h-full │ h-full │ │
│ │ ┌─────────┐ │ ┌─────────────────┐ │ │
│ │ │FilePreview│ │PlaceholderForm │ │ │
│ │ │h-full │ │ │ │ │
│ │ │flex-col │ │ │ │ │
│ │ │┌────────┐│ │ │ │ │
│ │ ││Header ││ │ │ │ │
│ │ ││(固定) ││ │ │ │ │
│ │ │├────────┤│ │ │ │ │
│ │ ││Content ││ │ │ │ │
│ │ ││flex-1 ││ │ │ │ │
│ │ ││(自适应)││ │ │ │ │
│ │ │└────────┘│ │ │ │ │
│ │ └─────────┘ │ └─────────────────┘ │ │
│ └─────────────┴─────────────────────┘ │
└─────────────────────────────────────────┘
```
### 关键 CSS 类
| 类名 | 作用 | 使用位置 |
|------|------|----------|
| `h-screen` | 高度 100vh | 根容器 |
| `flex flex-col` | 垂直 Flex 布局 | 根容器、FilePreview |
| `flex-1` | 占据剩余空间 | 主内容区、Content |
| `h-full` | 高度 100% | 左右侧容器、FilePreview |
| `overflow-hidden` | 隐藏溢出 | 左右侧容器 |
| `overflow-auto` | 自动滚动 | Content 区域 |
| `flex-shrink-0` | 不压缩 | Header |
## 测试验证
### 1. 启动开发服务器
```bash
npm run dev
```
### 2. 访问草稿页面
```
http://localhost:5173/contract-draft/1
```
### 3. 验证布局
✅ **应该看到**:
- 页面占满整个屏幕(无滚动条)
- 左侧文档预览占 60% 宽度,**高度占满**
- 右侧表单占 40% 宽度,**高度占满**
- FilePreview 内容区域可以独立滚动
- 表单区域可以独立滚动
✅ **不应该看到**:
- FilePreview 底部有空白
- 页面外层有滚动条(应该在内容区域内滚动)
- 布局错乱或内容溢出
### 4. 响应式测试
- 调整浏览器窗口大小
- FilePreview 和 PlaceholderForm 应该始终占满高度
- 内容区域应该自动调整滚动
## 修改的文件
### 1. `app/routes/contract-draft.$draftId.tsx`
**变化**:
- ✅ 移除 `json` 导入
- ✅ 所有 `json()` 替换为 `Response.json()`
- ✅ 左右侧容器添加 `h-full overflow-hidden`
**位置**:
- Line 7: 移除 `json` 导入
- Line 104: `Response.json({ draft, template })`
- Line 117, 123, 138, 141, 144: `Response.json()`
- Line 353, 374: 添加 `h-full overflow-hidden`
### 2. `app/components/reviews/FilePreview.tsx`
**变化**:
- ✅ 根元素添加 `h-full flex flex-col`
- ✅ Header 添加 `flex-shrink-0`
- ✅ Content 改用 `flex-1 overflow-auto`,移除固定 `maxHeight`
**位置**:
- Line 429: ``
- Line 430: Header 添加 `flex-shrink-0`
- Line 525: `
`
## 常见问题
### Q1: FilePreview 仍然没有占满高度
**原因**:浏览器缓存了旧的样式
**解决**:
1. 硬刷新页面(Ctrl+Shift+R 或 Cmd+Shift+R)
2. 清除浏览器缓存
3. 重启开发服务器
### Q2: 内容区域滚动不流畅
**原因**:可能是 `overflow-hidden` 和 `overflow-auto` 冲突
**解决**:
确保父容器使用 `overflow-hidden`,子容器(内容区域)使用 `overflow-auto`
### Q3: 在其他页面 FilePreview 布局变了
**影响范围**:此修改影响所有使用 FilePreview 的页面
**如果出现问题**:
- 检查该页面的父容器是否有足够的高度
- 可能需要给父容器添加 `h-full` 或明确的高度值
- 或者给 FilePreview 添加一个 prop 来控制是否使用 flex 布局
### Q4: 响应式布局问题
**现象**:小屏幕下布局错乱
**解决**:
可以添加响应式类,例���:
```typescript
```
## 后续优化
### 1. 添加 prop 控制布局模式(可选)
```typescript
interface FilePreviewProps {
// ... existing props
layoutMode?: 'flex' | 'fixed'; // 新增:控制布局模式
}
// 在组件中使用
```
### 2. 优化滚动性能
```typescript
```
### 3. 添加加载状态
在文档加载时显示骨架屏或加载动画,占满高度,避免布局跳动。
## 总结
✅ **已修复**:
1. `json` 弃用警告 - 使用 `Response.json()`
2. FilePreview 高度问题 - 使用 Flex 布局占满父容器
✅ **布局改进**:
- 使用现代 Flex 布局替代固定高度
- 更好的响应式支持
- 内容区域独立滚动
✅ **代码质量**:
- 符合 Web 标准
- 更易维护
- 类型检查通过
🎯 **可以开始测试了**!页面布局应该正常了。