remix图标本地化
This commit is contained in:
@@ -0,0 +1,494 @@
|
||||
# 中国烟草AI合同及卷宗审核系统 - 开发规范指南
|
||||
|
||||
## 📋 概述
|
||||
|
||||
本文档定义了「中国烟草AI合同及卷宗审核系统」的开发规范,包括技术架构、设计风格、代码规范、UI组件等各个方面,确保团队开发的一致性和代码质量。
|
||||
|
||||
## 🏗 技术架构规范
|
||||
|
||||
### 核心技术栈
|
||||
- **前端框架**: Remix (React) + TypeScript
|
||||
- **构建工具**: Vite
|
||||
- **样式系统**: Tailwind CSS + 自定义CSS
|
||||
- **图标库**: Remixicon (已本地化)
|
||||
- **文档处理**: react-pdf, mammoth, docx-preview
|
||||
- **代码规范**: ESLint + TypeScript
|
||||
- **状态管理**: React Context + useState/useEffect
|
||||
|
||||
### 项目结构规范
|
||||
```
|
||||
app/
|
||||
├── api/ # API层接口
|
||||
├── components/ # 组件
|
||||
│ ├── ui/ # 通用UI组件
|
||||
│ ├── layout/ # 布局组件
|
||||
│ ├── error/ # 错误处理组件
|
||||
│ └── [feature]/ # 功能特定组件
|
||||
├── routes/ # Remix路由页面
|
||||
├── styles/ # 样式文件
|
||||
│ ├── main.css # 主样式
|
||||
│ └── components/ # 组件样式
|
||||
├── types/ # TypeScript类型定义
|
||||
├── contexts/ # React Context
|
||||
├── models/ # 数据模型
|
||||
└── utils.ts # 工具函数
|
||||
```
|
||||
|
||||
## 🎨 设计系统规范
|
||||
|
||||
### 颜色主题
|
||||
```css
|
||||
/* 主色调 - 中国烟草企业绿 */
|
||||
--color-primary: #00684a; /* 主色 */
|
||||
--color-primary-hover: #005a3f; /* 悬停色 */
|
||||
--color-primary-light: rgba(0, 104, 74, 0.1); /* 浅色背景 */
|
||||
|
||||
/* 状态颜色 */
|
||||
--color-success: #52c41a; /* 成功绿 */
|
||||
--color-warning: #faad14; /* 警告橙 */
|
||||
--color-error: #f5222d; /* 错误红 */
|
||||
|
||||
/* 中性色系 */
|
||||
--color-gray-50: #f8f9fa; /* 最浅灰 */
|
||||
--color-gray-100: #f1f3f5;
|
||||
--color-gray-200: #e9ecef;
|
||||
--color-gray-300: #dee2e6;
|
||||
--color-gray-400: #ced4da;
|
||||
--color-gray-500: #adb5bd; /* 中性灰 */
|
||||
--color-gray-600: #868e96;
|
||||
--color-gray-700: #495057;
|
||||
--color-gray-800: #343a40;
|
||||
--color-gray-900: #212529; /* 最深灰 */
|
||||
```
|
||||
|
||||
### 字体规范
|
||||
```css
|
||||
font-family: [
|
||||
"-apple-system",
|
||||
"BlinkMacSystemFont",
|
||||
"Segoe UI",
|
||||
"Roboto",
|
||||
"Helvetica Neue",
|
||||
"Arial",
|
||||
"Noto Sans SC", /* 中文优先 */
|
||||
"PingFang SC",
|
||||
"Microsoft YaHei UI",
|
||||
"Microsoft YaHei",
|
||||
"sans-serif"
|
||||
];
|
||||
```
|
||||
|
||||
### 间距系统
|
||||
- 使用Tailwind默认间距: 4px基数 (1, 2, 3, 4, 5, 6...)
|
||||
- 页面容器内边距: `p-5` (20px)
|
||||
- 卡片内边距: `p-4` (16px)
|
||||
- 组件间距: `mb-4` `mt-6` (16px, 24px)
|
||||
|
||||
### 圆角规范
|
||||
- 按钮、卡片: `rounded-md` (6px)
|
||||
- 输入框: `rounded-md` (6px)
|
||||
- 头像: `rounded-full`
|
||||
- 标签: `rounded-md`
|
||||
|
||||
### 阴影系统
|
||||
```css
|
||||
/* 卡片阴影 */
|
||||
.card: shadow-sm; /* 默认 */
|
||||
.card:hover: shadow-md; /* 悬停 */
|
||||
.sidebar: shadow-[0_0_15px_rgba(0,0,0,0.05)]; /* 侧边栏 */
|
||||
```
|
||||
|
||||
## 🧩 组件设计规范
|
||||
|
||||
### 按钮组件
|
||||
```tsx
|
||||
// 类型定义
|
||||
type ButtonType = 'primary' | 'default' | 'danger';
|
||||
type ButtonSize = 'small' | 'medium' | 'large';
|
||||
|
||||
// 样式类
|
||||
.ant-btn-primary: bg-[#00684a] text-white hover:bg-[#005a3f]
|
||||
.ant-btn-default: bg-white border border-gray-300 text-gray-800
|
||||
.ant-btn-danger: bg-[#f5222d] text-white hover:bg-[#cf1f29]
|
||||
```
|
||||
|
||||
### 卡片组件
|
||||
```tsx
|
||||
// 基础结构
|
||||
<Card title="标题" icon="ri-icon-name" className="additional-classes">
|
||||
<div className="card-body">内容</div>
|
||||
</Card>
|
||||
|
||||
// 样式规范
|
||||
.card: bg-white rounded-lg shadow overflow-hidden
|
||||
.card-header: px-5 py-4 border-b border-gray-100
|
||||
.card-title: text-base font-medium text-gray-900
|
||||
```
|
||||
|
||||
### 布局组件
|
||||
```tsx
|
||||
// 侧边栏宽度
|
||||
.sidebar: w-[280px] /* 展开状态 */
|
||||
.sidebar.collapsed: w-20 /* 收缩状态 */
|
||||
|
||||
// 主内容区适配
|
||||
.main-content: ml-[280px] /* 对应侧边栏宽度 */
|
||||
.main-content.sidebar-collapsed: ml-20
|
||||
```
|
||||
|
||||
## 📝 代码规范
|
||||
|
||||
### TypeScript规范
|
||||
```typescript
|
||||
// 接口命名使用PascalCase
|
||||
interface DocumentUI {
|
||||
id: string;
|
||||
name: string;
|
||||
status: ProcessingStatus;
|
||||
}
|
||||
|
||||
// 类型联合使用字符串字面量
|
||||
type ProcessingStatus = 'Waiting' | 'Cutting' | 'Extractioning' | 'Evaluationing' | 'Processed';
|
||||
|
||||
// 组件Props接口
|
||||
interface ComponentProps {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
disabled?: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
### React组件规范
|
||||
```tsx
|
||||
// 函数组件使用function声明
|
||||
export function ComponentName({ prop1, prop2 }: ComponentProps) {
|
||||
// useState放在顶部
|
||||
const [state, setState] = useState<Type>(initialValue);
|
||||
|
||||
// useEffect按逻辑分组
|
||||
useEffect(() => {
|
||||
// 副作用逻辑
|
||||
}, [dependencies]);
|
||||
|
||||
// 事件处理函数
|
||||
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
// 处理逻辑
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="component-container">
|
||||
{/* JSX内容 */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 文件命名规范
|
||||
- 组件文件: `PascalCase.tsx` (如: `Button.tsx`)
|
||||
- 路由文件: `kebab-case.tsx` (如: `user-profile.tsx`)
|
||||
- 样式文件: `kebab-case.css` (如: `button.css`)
|
||||
- 工具文件: `camelCase.ts` (如: `utils.ts`)
|
||||
|
||||
### 导入顺序规范
|
||||
```typescript
|
||||
// 1. React相关
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Link, useLoaderData } from '@remix-run/react';
|
||||
|
||||
// 2. 第三方库
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
// 3. 内部组件 (~/ 别名)
|
||||
import { Card } from '~/components/ui/Card';
|
||||
import { Button } from '~/components/ui/Button';
|
||||
|
||||
// 4. 类型定义
|
||||
import type { DocumentUI } from '~/types/document';
|
||||
|
||||
// 5. 样式文件
|
||||
import styles from '~/styles/components/component.css?url';
|
||||
```
|
||||
|
||||
### CSS类命名规范
|
||||
```css
|
||||
/* BEM方法论 + 功能前缀 */
|
||||
.sidebar-menu-item /* 组件-子元素-状态 */
|
||||
.sidebar-menu-item.active /* 状态修饰符 */
|
||||
.ant-btn-primary /* 组件库前缀 */
|
||||
.text-primary /* 工具类 */
|
||||
```
|
||||
|
||||
## 🎯 UI/UX设计规范
|
||||
|
||||
### 交互动效
|
||||
```css
|
||||
/* 统一过渡动效 */
|
||||
.transition-all-ease: transition-all duration-200 ease-in-out;
|
||||
|
||||
/* 悬停效果 */
|
||||
.sidebar-menu-item:hover: bg-[rgba(0,104,74,0.05)];
|
||||
.card:hover: shadow-md;
|
||||
```
|
||||
|
||||
### 状态指示
|
||||
```typescript
|
||||
// 文件处理状态
|
||||
const statusConfig = {
|
||||
"Waiting": { label: "上传中", icon: "ri-loader-line", color: "blue" },
|
||||
"Cutting": { label: "切分中", icon: "ri-loader-line", color: "purple" },
|
||||
"Extractioning": { label: "抽取中", icon: "ri-loader-line", color: "cyan" },
|
||||
"Evaluationing": { label: "评查中", icon: "ri-loader-line", color: "teal" },
|
||||
"Processed": { label: "已完成", icon: "ri-check-line", color: "green" }
|
||||
};
|
||||
```
|
||||
|
||||
### 图标使用规范 (RemixIcon 本地化)
|
||||
```tsx
|
||||
// 基本图标使用
|
||||
<i className="ri-home-line"></i>
|
||||
<i className="ri-file-list-3-line"></i>
|
||||
<i className="ri-user-line"></i>
|
||||
|
||||
// 图标尺寸控制
|
||||
<i className="ri-home-line ri-lg"></i> // 大图标
|
||||
<i className="ri-home-line ri-xl"></i> // 特大图标
|
||||
<i className="ri-home-line ri-2x"></i> // 2倍大小
|
||||
|
||||
// 结合样式使用
|
||||
<i className="ri-error-warning-line text-red-500"></i>
|
||||
<i className="ri-check-line text-green-600"></i>
|
||||
<i className="ri-information-line text-blue-500"></i>
|
||||
|
||||
// 在按钮组件中使用
|
||||
<Button icon="ri-add-line">添加</Button>
|
||||
<Button icon="ri-edit-line">编辑</Button>
|
||||
<Button icon="ri-delete-bin-line">删除</Button>
|
||||
```
|
||||
|
||||
**图标系统特点:**
|
||||
- **本地化部署**: 字体文件已复制到 `public/fonts/` 目录,无外网依赖
|
||||
- **预加载优化**: 通过 `<link rel="preload">` 确保首次访问图标立即显示
|
||||
- **完整支持**: 包含3000+图标,支持所有RemixIcon官方图标
|
||||
- **性能优化**: 启用 `font-display: swap` 提供更好的加载体验
|
||||
- **浏览器兼容**: 支持IE9+到最新浏览器
|
||||
|
||||
**⚠️ 重要注意事项 - 避免样式冲突:**
|
||||
|
||||
在使用CSS样式隔离(如 `all: unset` 或强制 `font-family: inherit`)时,必须为RemixIcon图标添加例外规则:
|
||||
|
||||
```css
|
||||
/* 错误示例 - 会导致图标不显示 */
|
||||
.my-isolated-container * {
|
||||
font-family: inherit !important; /* 这会覆盖图标字体 */
|
||||
}
|
||||
|
||||
/* 正确示例 - 添加图标例外规则 */
|
||||
.my-isolated-container * {
|
||||
font-family: inherit !important;
|
||||
}
|
||||
.my-isolated-container [class^="ri-"],
|
||||
.my-isolated-container [class*=" ri-"],
|
||||
.my-isolated-container i[class^="ri-"],
|
||||
.my-isolated-container i[class*=" ri-"] {
|
||||
font-family: 'remixicon' !important;
|
||||
font-style: normal !important;
|
||||
font-weight: normal !important;
|
||||
font-variant: normal !important;
|
||||
text-transform: none !important;
|
||||
line-height: 1 !important;
|
||||
-webkit-font-smoothing: antialiased !important;
|
||||
-moz-osx-font-smoothing: grayscale !important;
|
||||
speak: none !important;
|
||||
}
|
||||
```
|
||||
|
||||
**常见问题排查:**
|
||||
1. **图标显示为方块或问号**: 检查是否有CSS规则覆盖了 `font-family: 'remixicon'`
|
||||
2. **只在特定页面不显示**: 检查该页面是否使用了样式隔离规则
|
||||
3. **首次加载不显示**: 确认字体预加载配置正确
|
||||
4. **部分图标不显示**: 检查CSS选择器优先级和 `!important` 使用
|
||||
|
||||
### 国际化和本地化
|
||||
- 界面语言: 简体中文为主
|
||||
- 日期格式: `YYYY年MM月DD日`
|
||||
- 时间格式: `HH:mm:ss`
|
||||
- 数字格式: 使用中文习惯 (如: 万、千)
|
||||
|
||||
## 🔧 工具配置规范
|
||||
|
||||
### ESLint配置要点
|
||||
```javascript
|
||||
// 启用的规则
|
||||
- "plugin:react/recommended"
|
||||
- "plugin:react-hooks/recommended"
|
||||
- "plugin:@typescript-eslint/recommended"
|
||||
- "plugin:jsx-a11y/recommended"
|
||||
```
|
||||
|
||||
### Tailwind配置扩展
|
||||
```typescript
|
||||
// tailwind.config.ts
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: {
|
||||
DEFAULT: '#1677ff', // 保持Remix默认,实际使用CSS变量覆盖
|
||||
// ... 其他色阶
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 性能优化规范
|
||||
|
||||
### 组件优化
|
||||
```typescript
|
||||
// 使用React.memo对纯组件优化
|
||||
export const MemoizedComponent = React.memo(Component);
|
||||
|
||||
// 防抖工具函数使用
|
||||
import { debounce } from '~/utils';
|
||||
const debouncedHandler = debounce(handler, 300);
|
||||
```
|
||||
|
||||
### 资源加载
|
||||
```typescript
|
||||
// 样式文件异步加载
|
||||
import styles from '~/styles/component.css?url';
|
||||
|
||||
// 组件懒加载
|
||||
const LazyComponent = lazy(() => import('~/components/LazyComponent'));
|
||||
```
|
||||
|
||||
## 🚨 错误处理规范
|
||||
|
||||
### 错误边界
|
||||
```tsx
|
||||
// 统一错误处理组件
|
||||
<AppErrorBoundary
|
||||
status={500}
|
||||
statusText="服务器错误"
|
||||
message="服务器发生了意外错误,请稍后重试"
|
||||
/>
|
||||
```
|
||||
|
||||
### API错误处理
|
||||
```typescript
|
||||
// 统一的API响应处理
|
||||
if (response.error) {
|
||||
console.error('API错误:', response.error);
|
||||
return Response.json(
|
||||
{ error: response.error },
|
||||
{ status: response.status || 500 }
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## 📱 响应式设计规范
|
||||
|
||||
### 断点使用
|
||||
- `sm`: 640px+ (移动端横屏)
|
||||
- `md`: 768px+ (平板)
|
||||
- `lg`: 1024px+ (桌面)
|
||||
- `xl`: 1280px+ (大屏)
|
||||
|
||||
### 适配策略
|
||||
```css
|
||||
/* 移动端优先 */
|
||||
.content-container: p-5;
|
||||
@screen sm: .content-container: p-6;
|
||||
|
||||
/* 侧边栏响应式 */
|
||||
@screen md: .sidebar-toggle: block;
|
||||
```
|
||||
|
||||
## 🔍 可访问性规范
|
||||
|
||||
### 语义化HTML
|
||||
```tsx
|
||||
// 使用语义化标签
|
||||
<main className="main-content">
|
||||
<nav className="breadcrumb" aria-label="页面导航">
|
||||
<section className="content-section">
|
||||
```
|
||||
|
||||
### 键盘导航
|
||||
```tsx
|
||||
// 确保所有交互元素可键盘访问
|
||||
<button
|
||||
onKeyDown={(e) => e.key === 'Enter' && handleClick()}
|
||||
aria-label="操作按钮"
|
||||
>
|
||||
```
|
||||
|
||||
## 📋 开发流程规范
|
||||
|
||||
### 组件开发流程
|
||||
1. 创建组件TypeScript接口定义
|
||||
2. 实现组件逻辑 (`.tsx`)
|
||||
3. 编写组件样式 (`.css`)
|
||||
4. 在`main.css`中导入样式
|
||||
5. 编写使用示例
|
||||
6. 进行测试验证
|
||||
|
||||
### 页面开发流程
|
||||
1. 在`routes/`下创建路由文件
|
||||
2. 定义`loader`函数处理数据获取
|
||||
3. 实现页面组件
|
||||
4. 配置`meta`和`links`
|
||||
5. 添加错误处理
|
||||
6. 测试页面功能
|
||||
|
||||
## 🚀 部署和构建规范
|
||||
|
||||
### 环境变量
|
||||
```typescript
|
||||
// 生产环境配置
|
||||
NODE_ENV=production
|
||||
DATABASE_URL=...
|
||||
SESSION_SECRET=...
|
||||
```
|
||||
|
||||
### 构建优化
|
||||
```typescript
|
||||
// vite.config.ts优化配置
|
||||
export default defineConfig({
|
||||
plugins: [remix(), tsconfigPaths()],
|
||||
build: {
|
||||
rollupOptions: {
|
||||
// 代码分割优化
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 开发检查清单
|
||||
|
||||
### 新组件开发
|
||||
- [ ] TypeScript接口定义完整
|
||||
- [ ] 样式使用设计系统颜色
|
||||
- [ ] 支持必要的props (className, disabled等)
|
||||
- [ ] 添加适当的过渡动效
|
||||
- [ ] 编写组件文档注释
|
||||
|
||||
### 新页面开发
|
||||
- [ ] loader函数处理数据和错误
|
||||
- [ ] meta信息配置完整
|
||||
- [ ] 响应式设计适配
|
||||
- [ ] 错误边界处理
|
||||
- [ ] 面包屑导航配置
|
||||
|
||||
### 代码提交前
|
||||
- [ ] ESLint检查通过
|
||||
- [ ] TypeScript编译无错误
|
||||
- [ ] 样式符合设计系统
|
||||
- [ ] 组件功能测试完成
|
||||
- [ ] 代码注释清晰完整
|
||||
|
||||
---
|
||||
|
||||
*此规范将根据项目发展持续更新和完善。*
|
||||
|
||||
Reference in New Issue
Block a user