save code

This commit is contained in:
xsl
2026-01-25 00:02:54 +08:00
commit f33a902c95
4 changed files with 2561 additions and 0 deletions
@@ -0,0 +1,748 @@
# 项目信息管理系统 - 设计文档
## 1. 项目概述
### 1.1 项目背景
开发一个基于BS架构的项目信息管理系统,用于管理项目的合同、编号、名称、预算、付款等信息。系统支持多部门协作,市场部用户可以新建项目,其他部门用户可以填写和更新项目信息。
### 1.2 技术选型
| 层级 | 技术 | 说明 |
|------|------|------|
| 前端 | React + React Router | 前后端分离架构 |
| UI组件库 | Ant Design | 企业级UI组件 |
| HTTP客户端 | Axios | API请求 |
| 状态管理 | Context API | 简单状态管理 |
| 后端 | Python Flask | 轻量级Web框架 |
| ORM | SQLAlchemy | 数据库ORM |
| 数据库 | MySQL | 关系型数据库 |
| 认证 | JWT Token | 无状态认证 |
| 开发工具 | Create React App, pipenv | 前后端开发环境 |
### 1.3 系统特点
- 轻量级架构,适合小并发场景
- 无需Redis缓存,降低部署复杂度
- 基于角色的权限控制(RBAC
- 前后端分离,易于维护和扩展
## 2. 功能需求
### 2.1 用户管理
#### 2.1.1 登录功能
- 用户名/密码登录
- JWT Token认证
- 自动登录(Token存储在LocalStorage
#### 2.1.2 用户管理(管理员)
- 创建用户:设置用户名、密码、部门、角色
- 编辑用户信息
- 删除用户
- 重置用户密码
- 查看用户列表
#### 2.1.3 权限控制
- **管理员**:所有权限
- **市场部用户**:创建项目、查看项目、编辑自己的项目
- **其他部门用户**:查看项目、编辑项目信息(如付款、状态等)
### 2.2 项目管理
#### 2.2.1 市场部权限
- **创建项目**:填写项目基本信息
- **查看项目**:浏览所有项目列表和详情
- **编辑项目**:修改自己创建的项目
#### 2.2.2 其他部门权限
- **查看项目**:浏览所有项目列表和详情
- **更新项目**:填写和更新项目信息(预算、付款、状态等)
#### 2.2.3 项目信息字段
| 字段名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| project_no | String | 是 | 项目编号(唯一) |
| contract_no | String | 是 | 合同编号 |
| name | String | 是 | 项目名称 |
| budget | Decimal | 是 | 项目预算 |
| payment_amount | Decimal | 否 | 已付款金额 |
| status | String | 是 | 项目状态(灵活状态) |
| start_date | Date | 否 | 开始日期 |
| end_date | Date | 否 | 结束日期 |
| created_by | Integer | 是 | 创建人ID(外键) |
| department | String | 是 | 所属部门 |
| description | Text | 否 | 项目描述 |
| created_at | DateTime | 是 | 创建时间 |
| updated_at | DateTime | 是 | 更新时间 |
#### 2.2.4 项目状态示例
- 新建
- 进行中
- 已完成
- 已暂停
- 已取消
(支持灵活状态,可由用户自定义)
## 3. 系统架构
### 3.1 架构图
```
┌─────────────────────────────────────────────────┐
│ 浏览器 │
│ (React + Ant Design + React Router + Axios) │
└─────────────────────────────────────────────────┘
│ HTTP/HTTPS
│ JWT Token
┌─────────────────────────────────────────────────┐
│ Flask 后端服务 │
│ ┌─────────────────────────────────────────┐ │
│ │ API Layer (Flask Routes) │ │
│ ├─────────────────────────────────────────┤ │
│ │ Business Logic (Services) │ │
│ ├─────────────────────────────────────────┤ │
│ │ Data Access (SQLAlchemy ORM) │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
│ SQL
┌─────────────────────────────────────────────────┐
│ MySQL 数据库 │
│ ┌─────────────────────────────────────────┐ │
│ │ users │ │
│ │ projects │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
```
### 3.2 项目目录结构
```
ocean_project_manager/
├── backend/ # 后端代码
│ ├── app/
│ │ ├── __init__.py # Flask应用初始化
│ │ ├── config.py # 配置文件
│ │ ├── models/ # 数据库模型
│ │ │ ├── __init__.py
│ │ │ ├── user.py
│ │ │ └── project.py
│ │ ├── routes/ # API路由
│ │ │ ├── __init__.py
│ │ │ ├── auth.py # 认证相关
│ │ │ ├── users.py # 用户管理
│ │ │ └── projects.py # 项目管理
│ │ ├── services/ # 业务逻辑
│ │ │ ├── __init__.py
│ │ │ ├── auth_service.py
│ │ │ ├── user_service.py
│ │ │ └── project_service.py
│ │ └── utils/ # 工具函数
│ │ ├── __init__.py
│ │ ├── jwt_utils.py
│ │ └── decorators.py
│ ├── requirements.txt # Python依赖
│ ├── run.py # 启动文件
│ └── .env # 环境变量
├── frontend/ # 前端代码
│ ├── public/
│ │ └── index.html
│ ├── src/
│ │ ├── components/ # 公共组件
│ │ │ ├── Layout.js
│ │ │ ├── Header.js
│ │ │ └── Sidebar.js
│ │ ├── pages/ # 页面组件
│ │ │ ├── Login.js
│ │ │ ├── Dashboard.js
│ │ │ ├── UserList.js
│ │ │ ├── UserForm.js
│ │ │ ├── ProjectList.js
│ │ │ ├── ProjectForm.js
│ │ │ └── ProjectDetail.js
│ │ ├── services/ # API服务
│ │ │ ├── api.js # Axios配置
│ │ │ ├── auth.js
│ │ │ ├── user.js
│ │ │ └── project.js
│ │ ├── contexts/ # Context
│ │ │ └── AuthContext.js
│ │ ├── utils/ # 工具函数
│ │ │ └── auth.js
│ │ ├── App.js # 根组件
│ │ ├── index.js # 入口文件
│ │ └── App.css
│ ├── package.json
│ └── .env # 环境变量
├── docs/ # 文档
│ ├── plans/ # 设计文档
│ │ └── 2026-01-24-project-management-system-design.md
│ └── api/ # API文档
└── README.md
```
## 4. 数据库设计
### 4.1 数据库表结构
#### 4.1.1 用户表 (users)
| 字段名 | 类型 | 约束 | 说明 |
|--------|------|------|------|
| id | INT | PRIMARY KEY, AUTO_INCREMENT | 用户ID |
| username | VARCHAR(50) | UNIQUE, NOT NULL | 用户名 |
| password_hash | VARCHAR(255) | NOT NULL | 密码哈希 |
| real_name | VARCHAR(100) | NOT NULL | 真实姓名 |
| department | VARCHAR(50) | NOT NULL | 部门(市场部/技术部/财务部等) |
| role | ENUM | NOT NULL | 角色(admin/market/other |
| email | VARCHAR(100) | UNIQUE | 邮箱 |
| phone | VARCHAR(20) | | 电话 |
| is_active | BOOLEAN | DEFAULT TRUE | 是否激活 |
| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | 创建时间 |
| updated_at | DATETIME | DEFAULT CURRENT_TIMESTAMP ON UPDATE | 更新时间 |
```sql
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
real_name VARCHAR(100) NOT NULL,
department VARCHAR(50) NOT NULL,
role ENUM('admin', 'market', 'other') NOT NULL,
email VARCHAR(100) UNIQUE,
phone VARCHAR(20),
is_active BOOLEAN DEFAULT TRUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- 索引
CREATE INDEX idx_users_username ON users(username);
CREATE INDEX idx_users_department ON users(department);
CREATE INDEX idx_users_role ON users(role);
```
#### 4.1.2 项目表 (projects)
| 字段名 | 类型 | 约束 | 说明 |
|--------|------|------|------|
| id | INT | PRIMARY KEY, AUTO_INCREMENT | 项目ID |
| project_no | VARCHAR(50) | UNIQUE, NOT NULL | 项目编号 |
| contract_no | VARCHAR(50) | NOT NULL | 合同编号 |
| name | VARCHAR(200) | NOT NULL | 项目名称 |
| budget | DECIMAL(15,2) | NOT NULL | 项目预算 |
| payment_amount | DECIMAL(15,2) | DEFAULT 0 | 已付款金额 |
| status | VARCHAR(50) | NOT NULL | 项目状态 |
| start_date | DATE | | 开始日期 |
| end_date | DATE | | 结束日期 |
| created_by | INT | NOT NULL, FOREIGN KEY | 创建人ID |
| department | VARCHAR(50) | NOT NULL | 所属部门 |
| description | TEXT | | 项目描述 |
| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | 创建时间 |
| updated_at | DATETIME | DEFAULT CURRENT_TIMESTAMP ON UPDATE | 更新时间 |
```sql
CREATE TABLE projects (
id INT PRIMARY KEY AUTO_INCREMENT,
project_no VARCHAR(50) UNIQUE NOT NULL,
contract_no VARCHAR(50) NOT NULL,
name VARCHAR(200) NOT NULL,
budget DECIMAL(15,2) NOT NULL,
payment_amount DECIMAL(15,2) DEFAULT 0,
status VARCHAR(50) NOT NULL,
start_date DATE,
end_date DATE,
created_by INT NOT NULL,
department VARCHAR(50) NOT NULL,
description TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE RESTRICT
);
-- 索引
CREATE INDEX idx_projects_project_no ON projects(project_no);
CREATE INDEX idx_projects_contract_no ON projects(contract_no);
CREATE INDEX idx_projects_status ON projects(status);
CREATE INDEX idx_projects_department ON projects(department);
CREATE INDEX idx_projects_created_by ON projects(created_by);
```
### 4.2 角色权限矩阵
| 功能 | admin | market | other |
|------|-------|--------|-------|
| 登录 | ✓ | ✓ | ✓ |
| 创建用户 | ✓ | ✗ | ✗ |
| 编辑用户 | ✓ | ✗ | ✗ |
| 删除用户 | ✓ | ✗ | ✗ |
| 查看用户列表 | ✓ | ✗ | ✗ |
| 创建项目 | ✓ | ✓ | ✗ |
| 编辑项目信息 | ✓ | ✓ | ✓ |
| 删除项目 | ✓ | ✓ | ✗ |
| 查看所有项目 | ✓ | ✓ | ✓ |
| 查看项目详情 | ✓ | ✓ | ✓ |
## 5. API设计
### 5.1 API规范
- **Base URL**: `/api/v1`
- **Content-Type**: `application/json`
- **认证方式**: JWT Token(在Header中传递:`Authorization: Bearer <token>`
- **响应格式**:
```json
{
"success": true,
"message": "操作成功",
"data": {}
}
```
### 5.2 认证相关API
#### 5.2.1 用户登录
- **URL**: `POST /api/v1/auth/login`
- **请求体**:
```json
{
"username": "admin",
"password": "password123"
}
```
- **响应**:
```json
{
"success": true,
"message": "登录成功",
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": 1,
"username": "admin",
"real_name": "管理员",
"department": "管理部",
"role": "admin"
}
}
}
```
#### 5.2.2 获取当前用户信息
- **URL**: `GET /api/v1/auth/me`
- **Header**: `Authorization: Bearer <token>`
- **响应**:
```json
{
"success": true,
"data": {
"id": 1,
"username": "admin",
"real_name": "管理员",
"department": "管理部",
"role": "admin"
}
}
```
#### 5.2.3 登出
- **URL**: `POST /api/v1/auth/logout`
- **Header**: `Authorization: Bearer <token>`
- **响应**:
```json
{
"success": true,
"message": "登出成功"
}
```
### 5.3 用户管理API
#### 5.3.1 获取用户列表
- **URL**: `GET /api/v1/users`
- **Header**: `Authorization: Bearer <token>`
- **权限**: admin
- **查询参数**:
- `page`: 页码(默认1
- `page_size`: 每页数量(默认10
- `department`: 部门筛选
- `role`: 角色筛选
- **响应**:
```json
{
"success": true,
"data": {
"items": [
{
"id": 1,
"username": "admin",
"real_name": "管理员",
"department": "管理部",
"role": "admin",
"email": "admin@example.com",
"is_active": true,
"created_at": "2026-01-24T10:00:00"
}
],
"total": 1,
"page": 1,
"page_size": 10
}
}
```
#### 5.3.2 创建用户
- **URL**: `POST /api/v1/users`
- **Header**: `Authorization: Bearer <token>`
- **权限**: admin
- **请求体**:
```json
{
"username": "zhangsan",
"password": "password123",
"real_name": "张三",
"department": "市场部",
"role": "market",
"email": "zhangsan@example.com",
"phone": "13800138000"
}
```
- **响应**:
```json
{
"success": true,
"message": "用户创建成功",
"data": {
"id": 2,
"username": "zhangsan",
"real_name": "张三",
"department": "市场部",
"role": "market"
}
}
```
#### 5.3.3 更新用户
- **URL**: `PUT /api/v1/users/{id}`
- **Header**: `Authorization: Bearer <token>`
- **权限**: admin
- **请求体**:
```json
{
"real_name": "张三",
"email": "zhangsan2@example.com",
"phone": "13900139000"
}
```
#### 5.3.4 删除用户
- **URL**: `DELETE /api/v1/users/{id}`
- **Header**: `Authorization: Bearer <token>`
- **权限**: admin
#### 5.3.5 重置用户密码
- **URL**: `POST /api/v1/users/{id}/reset-password`
- **Header**: `Authorization: Bearer <token>`
- **权限**: admin
- **请求体**:
```json
{
"new_password": "newpassword123"
}
```
### 5.4 项目管理API
#### 5.4.1 获取项目列表
- **URL**: `GET /api/v1/projects`
- **Header**: `Authorization: Bearer <token>`
- **权限**: 所有用户
- **查询参数**:
- `page`: 页码(默认1
- `page_size`: 每页数量(默认10
- `status`: 状态筛选
- `department`: 部门筛选
- **响应**:
```json
{
"success": true,
"data": {
"items": [
{
"id": 1,
"project_no": "PRJ2026001",
"contract_no": "CT2026001",
"name": "某公司官网开发",
"budget": 50000.00,
"payment_amount": 25000.00,
"status": "进行中",
"start_date": "2026-01-01",
"end_date": "2026-03-31",
"department": "市场部",
"created_by": {
"id": 2,
"real_name": "张三"
},
"created_at": "2026-01-24T10:00:00"
}
],
"total": 1,
"page": 1,
"page_size": 10
}
}
```
#### 5.4.2 获取项目详情
- **URL**: `GET /api/v1/projects/{id}`
- **Header**: `Authorization: Bearer <token>`
- **权限**: 所有用户
#### 5.4.3 创建项目
- **URL**: `POST /api/v1/projects`
- **Header**: `Authorization: Bearer <token>`
- **权限**: admin, market
- **请求体**:
```json
{
"project_no": "PRJ2026002",
"contract_no": "CT2026002",
"name": "电商平台开发",
"budget": 100000.00,
"status": "新建",
"start_date": "2026-02-01",
"end_date": "2026-06-30",
"department": "市场部",
"description": "电商平台开发项目"
}
```
#### 5.4.4 更新项目
- **URL**: `PUT /api/v1/projects/{id}`
- **Header**: `Authorization: Bearer <token>`
- **权限**: 所有用户
- **请求体**:
```json
{
"payment_amount": 50000.00,
"status": "进行中",
"description": "项目更新描述"
}
```
#### 5.4.5 删除项目
- **URL**: `DELETE /api/v1/projects/{id}`
- **Header**: `Authorization: Bearer <token>`
- **权限**: admin, market(只能删除自己创建的)
## 6. 前端设计
### 6.1 页面结构
```
登录页 (Login)
└─ 登录表单
主布局 (Layout)
├─ 顶部导航栏 (Header)
│ ├─ Logo
│ ├─ 用户信息
│ └─ 登出按钮
└─ 侧边栏 (Sidebar)
└─ 菜单
├─ 仪表盘 (Dashboard)
├─ 用户管理 (UserList) - 仅管理员
└─ 项目管理 (ProjectList)
├─ 项目列表
├─ 创建项目
└─ 项目详情
```
### 6.2 核心组件
#### 6.2.1 AuthContext
全局认证状态管理:
```javascript
const AuthContext = createContext({
user: null,
token: null,
login: () => {},
logout: () => {},
isAuthenticated: false
});
```
#### 6.2.2 ProtectedRoute
路由守卫组件,保护需要登录的页面。
#### 6.2.3 API Service
统一的API调用封装:
- 统一的错误处理
- 自动添加Token
- 请求拦截器
- 响应拦截器
### 6.3 页面设计
#### 6.3.1 登录页
- 简洁的登录表单
- 用户名/密码输入
- 记住我选项
- 错误提示
#### 6.3.2 仪表盘
- 项目统计卡片(总项目数、进行中、已完成等)
- 最近项目列表
- 快速操作入口
#### 6.3.3 用户管理页
- 用户列表表格
- 搜索和筛选功能
- 创建/编辑/删除/重置密码操作
- 分页功能
#### 6.3.4 项目列表页
- 项目列表表格
- 搜索和筛选(状态、部门)
- 创建项目按钮
- 分页功能
#### 6.3.5 项目表单
- 项目信息表单
- 表单验证
- 保存/取消按钮
#### 6.3.6 项目详情页
- 项目详细信息展示
- 编辑功能
- 操作日志(可选)
### 6.4 UI风格
- 使用Ant Design默认主题
- 响应式布局
- 简洁、专业的企业级UI
## 7. 安全设计
### 7.1 认证安全
- 密码使用bcrypt加密存储
- JWT Token有效期设置(如24小时)
- Token过期自动刷新机制
### 7.2 权限控制
- 后端基于装饰器的权限验证
- 前端路由级别的权限控制
- 前端组件级别的权限控制
### 7.3 数据安全
- SQL注入防护(使用SQLAlchemy ORM
- XSS防护(React自动转义)
- 输入验证(前后端双重验证)
## 8. 部署方案
### 8.1 开发环境
**后端**
```bash
cd backend
pipenv install
pipenv shell
python run.py
# 服务运行在 http://localhost:5000
```
**前端**
```bash
cd frontend
npm install
npm start
# 服务运行在 http://localhost:3000
```
**数据库**
- 本地MySQL数据库
- 数据库名:`project_manager`
- 配置文件:`.env`
### 8.2 生产环境(推荐方案)
**使用Docker Compose**
```yaml
version: '3.8'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: project_manager
volumes:
- mysql_data:/var/lib/mysql
ports:
- "3306:3306"
backend:
build: ./backend
ports:
- "5000:5000"
depends_on:
- mysql
environment:
DATABASE_URL: mysql+pymysql://root:rootpassword@mysql/project_manager
SECRET_KEY: your-secret-key
frontend:
build: ./frontend
ports:
- "80:80"
depends_on:
- backend
volumes:
mysql_data:
```
## 9. 后续优化建议
### 9.1 功能扩展
- 项目附件上传
- 操作日志记录
- 数据导出功能
- 报表统计功能
### 9.2 性能优化
- 数据库索引优化
- API响应缓存(如需要)
- 前端代码分割
### 9.3 用户体验
- 表单自动保存
- 批量操作功能
- 消息通知功能
## 10. 开发计划
### 10.1 第一阶段(MVP
- 用户登录/登出
- 项目CRUD基础功能
- 简单的用户管理(仅管理员)
### 10.2 第二阶段
- 权限控制完善
- 项目列表筛选和搜索
- 表单验证优化
### 10.3 第三阶段(可选)
- 高级功能扩展
- 性能优化
- 用户体验优化
+758
View File
@@ -0,0 +1,758 @@
# UI设计规范文档
## 1. 设计系统概述
本系统采用Ant Design风格,简洁专业,适合企业级应用。
## 2. 颜色系统
### 2.1 主色调
```css
/* 主品牌色 - 蓝色 */
--primary-color: #1890ff;
/* 功能色 */
--success-color: #52c41a; /* 成功/进行中 */
--warning-color: #fa8c16; /* 警告/暂停 */
--error-color: #ff4d4f; /* 错误/删除 */
--info-color: #1890ff; /* 信息/新建 */
```
### 2.2 中性色
```css
--text-primary: #333333; /* 主要文字 */
--text-secondary: #666666; /* 次要文字 */
--text-disabled: #999999; /* 禁用文字 */
--border-color: #e8e8e8; /* 边框颜色 */
--divider-color: #f0f0f0; /* 分割线颜色 */
```
### 2.3 背景色
```css
--layout-header-bg: #001529; /* 顶部导航背景 */
--layout-sidebar-bg: #ffffff; /* 侧边栏背景 */
--layout-content-bg: #f0f2f5; /* 内容区背景 */
--component-bg: #ffffff; /* 组件背景 */
```
## 3. 状态标签颜色
| 状态 | 背景色 | 文字颜色 | 适用场景 |
|------|--------|----------|----------|
| 新建 | #e6f7ff | #1890ff | 项目初始状态 |
| 进行中 | #f6ffed | #52c41a | 项目执行中 |
| 已完成 | #f5f5f5 | #999999 | 项目完成 |
| 已暂停 | #fff7e6 | #fa8c16 | 项目暂停 |
| 已取消 | #fff1f0 | #f5222d | 项目取消 |
| 正常 | #f6ffed | #52c41a | 用户状态正常 |
| 禁用 | #f5f5f5 | #999999 | 用户状态禁用 |
| 管理员 | #fff1f0 | #f5222d | 管理员角色 |
| 市场部 | #e6f7ff | #1890ff | 市场部角色 |
| 其他部门 | #e6f7ff | #1890ff | 其他部门角色 |
## 4. 字体系统
```css
/* 字体家族 */
--font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
/* 字体大小 */
--font-size-base: 14px;
--font-size-lg: 16px;
--font-size-sm: 12px;
--font-size-title: 18px;
--font-size-heading: 24px;
/* 字重 */
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
```
## 5. 间距系统
```css
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 12px;
--spacing-lg: 16px;
--spacing-xl: 24px;
--spacing-xxl: 32px;
```
## 6. 组件样式
### 6.1 按钮
```css
/* 主按钮 */
.btn-primary {
background-color: #1890ff;
color: #ffffff;
border: none;
padding: 6px 16px;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s;
}
.btn-primary:hover {
background-color: #40a9ff;
}
/* 默认按钮 */
.btn-default {
background-color: #ffffff;
color: #666666;
border: 1px solid #d9d9d9;
padding: 6px 16px;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s;
}
.btn-default:hover {
border-color: #1890ff;
color: #1890ff;
}
/* 链接按钮 */
.btn-link {
background: none;
color: #1890ff;
border: none;
padding: 0 8px;
cursor: pointer;
transition: all 0.3s;
}
.btn-link:hover {
color: #40a9ff;
}
/* 危险按钮 */
.btn-danger {
background: none;
color: #ff4d4f;
border: none;
padding: 0 8px;
cursor: pointer;
transition: all 0.3s;
}
.btn-danger:hover {
color: #ff7875;
}
```
### 6.2 输入框
```css
.form-input {
width: 100%;
padding: 8px 12px;
border: 1px solid #d9d9d9;
border-radius: 4px;
font-size: 14px;
color: #333333;
transition: all 0.3s;
}
.form-input:focus {
border-color: #1890ff;
outline: none;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
.form-input::placeholder {
color: #cccccc;
}
```
### 6.3 选择框
```css
.form-select {
width: 100%;
padding: 8px 12px;
border: 1px solid #d9d9d9;
border-radius: 4px;
font-size: 14px;
color: #333333;
background-color: #ffffff;
cursor: pointer;
transition: all 0.3s;
}
.form-select:focus {
border-color: #1890ff;
outline: none;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
```
### 6.4 卡片
```css
.card {
background: #ffffff;
border-radius: 8px;
padding: 24px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
margin-bottom: 24px;
}
.card-title {
font-size: 16px;
font-weight: 600;
color: #333333;
margin-bottom: 20px;
border-bottom: 1px solid #e8e8e8;
padding-bottom: 12px;
}
```
### 6.5 表格
```css
.table {
width: 100%;
border-collapse: collapse;
}
.table thead th {
background: #fafafa;
padding: 12px 16px;
text-align: left;
font-weight: 600;
color: #333333;
border-bottom: 1px solid #e8e8e8;
font-size: 14px;
}
.table tbody td {
padding: 12px 16px;
border-bottom: 1px solid #e8e8e8;
color: #666666;
font-size: 14px;
}
.table tbody tr:hover {
background: #fafafa;
}
```
### 6.6 标签
```css
.tag {
display: inline-block;
padding: 2px 8px;
border-radius: 2px;
font-size: 12px;
line-height: 1.5;
}
.tag-blue {
background: #e6f7ff;
border: 1px solid #91d5ff;
color: #1890ff;
}
.tag-green {
background: #f6ffed;
border: 1px solid #b7eb8f;
color: #52c41a;
}
.tag-orange {
background: #fff7e6;
border: 1px solid #ffd591;
color: #fa8c16;
}
.tag-red {
background: #fff1f0;
border: 1px solid #ffa39e;
color: #f5222d;
}
.tag-gray {
background: #f5f5f5;
border: 1px solid #d9d9d9;
color: #999999;
}
```
### 6.7 头像
```css
.avatar {
width: 32px;
height: 32px;
background: #1890ff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
color: #ffffff;
font-weight: 500;
}
.avatar-lg {
width: 64px;
height: 64px;
font-size: 24px;
}
```
## 7. 布局系统
### 7.1 整体布局
```
┌─────────────────────────────────────────┐
│ Header (顶部导航) │
│ #001529 │
├──────────┬──────────────────────────────┤
│ │ │
│ Sidebar │ Content │
│ (侧边栏) │ (内容区) │
│ #ffffff │ #f0f2f5 │
│ 256px │ │
│ │ │
└──────────┴──────────────────────────────┘
```
### 7.2 顶部导航栏
```css
.layout-header {
height: 64px;
background: #001529;
padding: 0 24px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
}
```
### 7.3 侧边栏
```css
.layout-sider {
width: 256px;
background: #ffffff;
border-right: 1px solid #e8e8e8;
position: fixed;
left: 64px;
top: 64px;
bottom: 0;
overflow-y: auto;
}
/* 菜单项 */
.menu-item {
padding: 12px 24px;
display: flex;
align-items: center;
gap: 10px;
color: #666666;
cursor: pointer;
border-left: 3px solid transparent;
transition: all 0.3s;
}
.menu-item:hover {
background: #e6f7ff;
color: #1890ff;
}
.menu-item.active {
background: #e6f7ff;
color: #1890ff;
border-left-color: #1890ff;
}
```
### 7.4 内容区
```css
.layout-content {
margin-left: 256px;
margin-top: 64px;
padding: 24px;
background: #f0f2f5;
min-height: calc(100vh - 64px);
}
```
## 8. 统计卡片
```css
.stat-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 24px;
margin-bottom: 24px;
}
.stat-card {
background: #ffffff;
padding: 24px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.stat-label {
font-size: 14px;
color: #666666;
margin-bottom: 8px;
}
.stat-value {
font-size: 32px;
font-weight: 600;
color: #1890ff;
}
.stat-icon {
float: right;
font-size: 24px;
color: #1890ff;
opacity: 0.3;
}
```
## 9. 表单系统
### 9.1 表单组
```css
.form-group {
margin-bottom: 20px;
}
.form-label {
display: block;
margin-bottom: 8px;
color: #333333;
font-weight: 500;
font-size: 14px;
}
.form-label.required::after {
content: ' *';
color: #ff4d4f;
}
```
### 9.2 表单行(两列布局)
```css
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.form-row-3 {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
```
## 10. 工具栏
```css
.toolbar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.toolbar-left {
display: flex;
gap: 12px;
align-items: center;
}
```
## 11. Modal 弹窗
```css
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.45);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.modal {
background: #ffffff;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
width: 600px;
max-width: 90vw;
max-height: 90vh;
overflow-y: auto;
}
.modal-header {
padding: 16px 24px;
border-bottom: 1px solid #e8e8e8;
font-size: 16px;
font-weight: 600;
color: #333333;
}
.modal-body {
padding: 24px;
}
.modal-footer {
padding: 16px 24px;
border-top: 1px solid #e8e8e8;
display: flex;
justify-content: flex-end;
gap: 12px;
}
```
## 12. 响应式设计
```css
/* 平板 */
@media (max-width: 1024px) {
.stat-grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* 移动端 */
@media (max-width: 768px) {
.layout-sider {
width: 200px;
}
.layout-content {
margin-left: 200px;
}
.stat-grid {
grid-template-columns: 1fr;
}
.form-row {
grid-template-columns: 1fr;
}
.table {
font-size: 12px;
}
.toolbar {
flex-direction: column;
gap: 12px;
align-items: stretch;
}
}
```
## 13. 动画效果
```css
/* 过渡动画 */
.transition-all {
transition: all 0.3s ease;
}
/* 悬停效果 */
.hover-scale:hover {
transform: scale(1.02);
}
.hover-shadow:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
/* 淡入淡出 */
.fade-in {
animation: fadeIn 0.3s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
```
## 14. React 组件实现参考
### 14.1 颜色配置 (config/colors.js)
```javascript
export const colors = {
primary: '#1890ff',
success: '#52c41a',
warning: '#fa8c16',
error: '#ff4d4f',
info: '#1890ff',
text: {
primary: '#333333',
secondary: '#666666',
disabled: '#999999',
},
border: {
base: '#e8e8e8',
light: '#f0f0f0',
},
bg: {
header: '#001529',
sidebar: '#ffffff',
content: '#f0f2f5',
component: '#ffffff',
},
};
```
### 14.2 状态标签组件 (components/Tag.jsx)
```jsx
import React from 'react';
import { colors } from '../config/colors';
const tagStyles = {
new: { bg: '#e6f7ff', color: '#1890ff', border: '#91d5ff' },
inProgress: { bg: '#f6ffed', color: '#52c41a', border: '#b7eb8f' },
completed: { bg: '#f5f5f5', color: '#999999', border: '#d9d9d9' },
paused: { bg: '#fff7e6', color: '#fa8c16', border: '#ffd591' },
cancelled: { bg: '#fff1f0', color: '#f5222d', border: '#ffa39e' },
};
export const Tag = ({ children, type = 'default' }) => {
const style = tagStyles[type] || { bg: '#f5f5f5', color: '#999999', border: '#d9d9d9' };
return (
<span style={{
display: 'inline-block',
padding: '2px 8px',
borderRadius: '2px',
fontSize: '12px',
lineHeight: 1.5,
background: style.bg,
color: style.color,
border: `1px solid ${style.border}`,
}}>
{children}
</span>
);
};
```
### 14.3 卡片组件 (components/Card.jsx)
```jsx
import React from 'react';
export const Card = ({ title, children, extra }) => (
<div style={{
background: '#ffffff',
borderRadius: '8px',
padding: '24px',
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)',
marginBottom: '24px',
}}>
{title && (
<div style={{
fontSize: '16px',
fontWeight: 600,
color: '#333333',
marginBottom: '20px',
borderBottom: '1px solid #e8e8e8',
paddingBottom: '12px',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
}}>
{title}
{extra}
</div>
)}
{children}
</div>
);
```
## 15. 图标使用
推荐使用以下图标库:
- **Ant Design Icons**`@ant-design/icons`
- **React Icons**`react-icons`
常用图标:
- Dashboard: `DashboardOutlined`
- Project: `FileTextOutlined`
- User: `UserOutlined`
- Settings: `SettingOutlined`
- Add: `PlusOutlined`
- Edit: `EditOutlined`
- Delete: `DeleteOutlined`
- View: `EyeOutlined`
- Logout: `LogoutOutlined`
## 16. 页面布局模板
```jsx
import React from 'react';
const PageLayout = ({ children, title }) => (
<div style={{
marginLeft: '256px',
marginTop: '64px',
padding: '24px',
background: '#f0f2f5',
minHeight: 'calc(100vh - 64px)',
}}>
{title && (
<h1 style={{
fontSize: '24px',
fontWeight: 600,
color: '#333333',
marginBottom: '24px',
}}>
{title}
</h1>
)}
{children}
</div>
);
```
## 17. 注意事项
1. **颜色使用**:统一使用预定义的颜色变量,不要使用硬编码的颜色值
2. **间距统一**:使用间距系统保持一致性
3. **响应式**:移动端、平板、桌面端都要适配
4. **可访问性**:确保对比度符合WCAG标准,最小对比度4.5:1
5. **性能**:避免过度使用动画,保持流畅的用户体验
6. **浏览器兼容**:确保在主流浏览器中正常显示