Files
leaudit-platform-frontend/docs/contract-draft-ui-fixes.md
T
2025-12-05 00:09:32 +08:00

8.8 KiB
Raw Blame History

合同起草页面 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() 函数。

修改的代码

// ❌ 旧代码(已弃用)
import { json, redirect } from '@remix-run/node';

export async function loader() {
  return json({ data });
}

export async function action() {
  return json({ success: true }, { status: 200 });
}
// ✅ 新代码(使用标准 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:

// ❌ 旧代码
<div className="w-[60%] border-r border-gray-200 bg-white">
  <FilePreview ... />
</div>

<div className="w-[40%] bg-white">
  <PlaceholderForm ... />
</div>
// ✅ 新代码
<div className="w-[60%] border-r border-gray-200 bg-white h-full overflow-hidden">
  <FilePreview ... />
</div>

<div className="w-[40%] bg-white h-full overflow-hidden">
  <PlaceholderForm ... />
</div>

变化

  • 添加 h-full - 高度占满父容器
  • 添加 overflow-hidden - 防止内容溢出

修改 2FilePreview 根元素使用 Flex 布局

app/components/reviews/FilePreview.tsx:

// ❌ 旧代码
return (
  <div className="file-preview">
    <div className="file-preview-header ...">...</div>
    <div className="file-preview-content" style={{ maxHeight: 'calc(100vh - 150px)' }}>...</div>
  </div>
);
// ✅ 新代码
return (
  <div className="file-preview h-full flex flex-col">
    <div className="file-preview-header ... flex-shrink-0">...</div>
    <div className="file-preview-content flex-1 overflow-auto">...</div>
  </div>
);

变化

  • 根元素:添加 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. 启动开发服务器

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: <div className="file-preview h-full flex flex-col">
  • Line 430: Header 添加 flex-shrink-0
  • Line 525: <div className="file-preview-content flex-1 overflow-auto">

常见问题

Q1: FilePreview 仍然没有占满高度

原因:浏览器缓存了旧的样式

解决

  1. 硬刷新页面(Ctrl+Shift+R 或 Cmd+Shift+R
  2. 清除浏览器缓存
  3. 重启开发服务器

Q2: 内容区域滚动不流畅

原因:可能是 overflow-hiddenoverflow-auto 冲突

解决 确保父容器使用 overflow-hidden,子容器(内容区域)使用 overflow-auto

Q3: 在其他页面 FilePreview 布局变了

影响范围:此修改影响所有使用 FilePreview 的页面

如果出现问题

  • 检查该页面的父容器是否有足够的高度
  • 可能需要给父容器添加 h-full 或明确的高度值
  • 或者给 FilePreview 添加一个 prop 来控制是否使用 flex 布局

Q4: 响应式布局问题

现象:小屏幕下布局错乱

解决 可以添加响应式类,例

<div className="w-full md:w-[60%] h-full overflow-hidden">

后续优化

1. 添加 prop 控制布局模式(可选)

interface FilePreviewProps {
  // ... existing props
  layoutMode?: 'flex' | 'fixed';  // 新增:控制布局模式
}

// 在组件中使用
<div className={`file-preview ${layoutMode === 'flex' ? 'h-full flex flex-col' : ''}`}>

2. 优化滚动性能

<div
  className="file-preview-content flex-1 overflow-auto"
  style={{ scrollBehavior: 'smooth' }}  // 平滑滚动
>

3. 添加加载状态

在文档加载时显示骨架屏或加载动画,占满高度,避免布局跳动。

总结

已修复

  1. json 弃用警告 - 使用 Response.json()
  2. FilePreview 高度问题 - 使用 Flex 布局占满父容器

布局改进

  • 使用现代 Flex 布局替代固定高度
  • 更好的响应式支持
  • 内容区域独立滚动

代码质量

  • 符合 Web 标准
  • 更易维护
  • 类型检查通过

🎯 可以开始测试了!页面布局应该正常了。