commit f33a902c95be0c9cea26a87888967f1d721503e2 Author: xsl Date: Sun Jan 25 00:02:54 2026 +0800 save code diff --git a/docs/plans/2026-01-24-project-management-system-design.md b/docs/plans/2026-01-24-project-management-system-design.md new file mode 100644 index 00000000..5f2cc54b --- /dev/null +++ b/docs/plans/2026-01-24-project-management-system-design.md @@ -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 `) +- **响应格式**: +```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 ` +- **响应**: +```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 ` +- **响应**: +```json +{ + "success": true, + "message": "登出成功" +} +``` + +### 5.3 用户管理API + +#### 5.3.1 获取用户列表 +- **URL**: `GET /api/v1/users` +- **Header**: `Authorization: Bearer ` +- **权限**: 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 ` +- **权限**: 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 ` +- **权限**: admin +- **请求体**: +```json +{ + "real_name": "张三", + "email": "zhangsan2@example.com", + "phone": "13900139000" +} +``` + +#### 5.3.4 删除用户 +- **URL**: `DELETE /api/v1/users/{id}` +- **Header**: `Authorization: Bearer ` +- **权限**: admin + +#### 5.3.5 重置用户密码 +- **URL**: `POST /api/v1/users/{id}/reset-password` +- **Header**: `Authorization: Bearer ` +- **权限**: admin +- **请求体**: +```json +{ + "new_password": "newpassword123" +} +``` + +### 5.4 项目管理API + +#### 5.4.1 获取项目列表 +- **URL**: `GET /api/v1/projects` +- **Header**: `Authorization: Bearer ` +- **权限**: 所有用户 +- **查询参数**: + - `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 ` +- **权限**: 所有用户 + +#### 5.4.3 创建项目 +- **URL**: `POST /api/v1/projects` +- **Header**: `Authorization: Bearer ` +- **权限**: 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 ` +- **权限**: 所有用户 +- **请求体**: +```json +{ + "payment_amount": 50000.00, + "status": "进行中", + "description": "项目更新描述" +} +``` + +#### 5.4.5 删除项目 +- **URL**: `DELETE /api/v1/projects/{id}` +- **Header**: `Authorization: Bearer ` +- **权限**: 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 第三阶段(可选) +- 高级功能扩展 +- 性能优化 +- 用户体验优化 diff --git a/docs/ui-design-spec.md b/docs/ui-design-spec.md new file mode 100644 index 00000000..dd4bda9a --- /dev/null +++ b/docs/ui-design-spec.md @@ -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 ( + + {children} + + ); +}; +``` + +### 14.3 卡片组件 (components/Card.jsx) + +```jsx +import React from 'react'; + +export const Card = ({ title, children, extra }) => ( +
+ {title && ( +
+ {title} + {extra} +
+ )} + {children} +
+); +``` + +## 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 }) => ( +
+ {title && ( +

+ {title} +

+ )} + {children} +
+); +``` + +## 17. 注意事项 + +1. **颜色使用**:统一使用预定义的颜色变量,不要使用硬编码的颜色值 +2. **间距统一**:使用间距系统保持一致性 +3. **响应式**:移动端、平板、桌面端都要适配 +4. **可访问性**:确保对比度符合WCAG标准,最小对比度4.5:1 +5. **性能**:避免过度使用动画,保持流畅的用户体验 +6. **浏览器兼容**:确保在主流浏览器中正常显示 diff --git a/frontend-preview.html b/frontend-preview.html new file mode 100644 index 00000000..19d37da4 --- /dev/null +++ b/frontend-preview.html @@ -0,0 +1,293 @@ + + + + + + 项目信息管理系统 - UI预览 + + + + + + + + + + +
+ + + + diff --git a/ui-design.html b/ui-design.html new file mode 100644 index 00000000..0525d229 --- /dev/null +++ b/ui-design.html @@ -0,0 +1,762 @@ + + + + + + 项目信息管理系统 - UI设计图 + + + +
+

📐 项目信息管理系统 - UI设计图

+ + +

1. 登录页面

+
+ +
+ + +

2. 仪表盘页面

+
+
+ +
+ 管理员 +
+ +
+
+
+ +
+
+
+
📊
+
总项目数
+
15
+
+
+
🔄
+
进行中
+
8
+
+
+
+
已完成
+
5
+
+
+
💰
+
本月预算
+
¥50万
+
+
+ +
+
最近项目
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
项目编号项目名称预算状态创建人
PRJ2026001某公司官网开发¥50,000进行中张三
PRJ2026002电商平台开发¥100,000新建李四
PRJ2026003移动APP开发¥150,000已完成王五
+
+
+
+
+ + +

3. 项目管理页面

+
+
+ +
+ 管理员 +
+ +
+
+
+ +
+
+
项目管理
+
+
+ + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
项目编号合同编号项目名称预算已付款状态部门创建人操作
PRJ2026001CT2026001某公司官网开发¥50,000¥25,000进行中市场部张三 + + + +
PRJ2026002CT2026002电商平台开发¥100,000¥50,000新建市场部李四 + + + +
PRJ2026003CT2026003移动APP开发¥150,000¥150,000已完成技术部王五 + + + +
PRJ2026004CT2026004数据分析系统¥80,000¥30,000进行中市场部张三 + + + +
PRJ2026005CT2026005企业OA系统¥200,000¥0已暂停技术部赵六 + + + +
+
+
+
+
+ + +

4. 用户管理页面(仅管理员可见)

+
+
+ +
+ 管理员 +
+ +
+
+
+ +
+
+
用户管理
+
+
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
用户名真实姓名部门角色邮箱状态创建时间操作
admin管理员管理部管理员admin@example.com正常2026-01-10 + + + +
zhangsan张三市场部市场部zhangsan@example.com正常2026-01-15 + + + +
lisi李四市场部市场部lisi@example.com正常2026-01-16 + + + +
wangwu王五技术部其他部门wangwu@example.com正常2026-01-17 + + + +
zhaoliu赵六技术部其他部门zhaoliu@example.com禁用2026-01-18 + + + +
+
+
+
+
+ + +

5. 新建/编辑项目表单

+
+
+
+
新建项目
+
+
+ + +
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+
+
+ +
+ 💡 设计说明: +
    +
  • 整体采用Ant Design风格,简洁专业
  • +
  • 深色顶部导航栏(#001529),浅色侧边栏(白色),内容区使用浅灰背景(#f0f2f5)
  • +
  • 状态标签使用不同颜色区分:新建-蓝色、进行中-绿色、已完成-灰色、已暂停-橙色、已取消-红色
  • +
  • 按钮样式:主操作用蓝色(#1890ff),删除操作用红色
  • +
  • 表格支持搜索和筛选功能
  • +
  • 所有页面共用相同的布局结构(Header + Sidebar + Content)
  • +
+
+
+ +