# 合同起草页面 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 标准 - 更易维护 - 类型检查通过 🎯 **可以开始测试了**!页面布局应该正常了。