save code
This commit is contained in:
@@ -0,0 +1,81 @@
|
|||||||
|
# 海洋项目管理系统 - 权限控制
|
||||||
|
|
||||||
|
## 目录权限说明
|
||||||
|
|
||||||
|
本项目采用严格的工作目录分离策略,各角色只能在指定目录中工作。
|
||||||
|
|
||||||
|
## 权限配置
|
||||||
|
|
||||||
|
### 后端程序员
|
||||||
|
✅ **允许访问:**
|
||||||
|
- backend/
|
||||||
|
|
||||||
|
❌ **禁止访问:**
|
||||||
|
- frontend/
|
||||||
|
- testing/
|
||||||
|
|
||||||
|
### 前端程序员
|
||||||
|
✅ **允许访问:**
|
||||||
|
- frontend/
|
||||||
|
|
||||||
|
❌ **禁止访问:**
|
||||||
|
- backend/
|
||||||
|
- testing/
|
||||||
|
|
||||||
|
### 测试工程师
|
||||||
|
✅ **允许访问:**
|
||||||
|
- testing/
|
||||||
|
|
||||||
|
❌ **禁止访问:**
|
||||||
|
- backend/
|
||||||
|
- frontend/
|
||||||
|
|
||||||
|
## 实施方法
|
||||||
|
|
||||||
|
### Git Hooks (建议)
|
||||||
|
使用pre-commit hook检查跨目录提交:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# .git/hooks/pre-commit
|
||||||
|
|
||||||
|
USER_ROLE=${USER_ROLE:-unknown}
|
||||||
|
|
||||||
|
if [ "$USER_ROLE" = "backend" ]; then
|
||||||
|
if git diff --cached --name-only | grep -E "^frontend/|^testing/"; then
|
||||||
|
echo "❌ 错误: 后端程序员不能提交frontend/或testing/目录的文件"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$USER_ROLE" = "frontend" ]; then
|
||||||
|
if git diff --cached --name-only | grep -E "^backend/|^testing/"; then
|
||||||
|
echo "❌ 错误: 前端程序员不能提交backend/或testing/目录的文件"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$USER_ROLE" = "testing" ]; then
|
||||||
|
if git diff --cached --name-only | grep -E "^backend/|^frontend/"; then
|
||||||
|
echo "❌ 错误: 测试工程师不能提交backend/或frontend/目录的文件"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
### 使用方法
|
||||||
|
```bash
|
||||||
|
export USER_ROLE=backend # 设置你的角色
|
||||||
|
git commit -m "提交信息"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 违规处理
|
||||||
|
|
||||||
|
如发现跨目录提交:
|
||||||
|
1. 技术总监将拒绝合并
|
||||||
|
2. 要求重新在正确目录中工作
|
||||||
|
3. 记录违规情况
|
||||||
|
|
||||||
|
## 例外情况
|
||||||
|
|
||||||
|
只有在获得技术总监明确批准的情况下,才可以跨目录工作。
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
# 海洋项目管理系统
|
||||||
|
|
||||||
|
## 项目概述
|
||||||
|
|
||||||
|
海洋项目管理系统是一个全栈项目管理系统,采用前后端分离架构。
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
ocean_project_manager/
|
||||||
|
├── backend/ # 后端开发(后端程序员工作区)
|
||||||
|
├── frontend/ # 前端开发(前端程序员工作区)
|
||||||
|
├── testing/ # 测试工作(测试工程师工作区)
|
||||||
|
└── docs/ # 项目文档
|
||||||
|
```
|
||||||
|
|
||||||
|
## 团队角色
|
||||||
|
|
||||||
|
### 技术总监
|
||||||
|
- 审查设计和代码
|
||||||
|
- 协调团队协作
|
||||||
|
- 批准重大变更
|
||||||
|
|
||||||
|
### 后端程序员
|
||||||
|
- 工作目录: `backend/`
|
||||||
|
- 负责API开发和维护
|
||||||
|
- 编写API文档
|
||||||
|
- 编写单元测试
|
||||||
|
|
||||||
|
### 前端程序员
|
||||||
|
- 工作目录: `frontend/`
|
||||||
|
- 负责UI开发和维护
|
||||||
|
- 编写组件文档
|
||||||
|
- 集成后端API
|
||||||
|
|
||||||
|
### 测试工程师
|
||||||
|
- 工作目录: `testing/`
|
||||||
|
- 编写测试计划和用例
|
||||||
|
- 执行功能测试和自动化测试
|
||||||
|
- 生成测试报告
|
||||||
|
|
||||||
|
## 工作规范
|
||||||
|
|
||||||
|
各角色的详细工作规范请查看:
|
||||||
|
|
||||||
|
- [后端程序员工作规范](backend/WORKSTANDARDS.md)
|
||||||
|
- [前端程序员工作规范](frontend/WORKSTANDARDS.md)
|
||||||
|
- [测试工程师工作规范](testing/WORKSTANDARDS.md)
|
||||||
|
- [团队协作规范](docs/TEAM-COLLABORATION.md)
|
||||||
|
|
||||||
|
## 工作流程
|
||||||
|
|
||||||
|
1. **需求分析**: 技术总监编写设计方案
|
||||||
|
2. **开发**: 后端和前端程序员在各自目录中开发
|
||||||
|
3. **测试**: 测试工程师执行测试并生成报告
|
||||||
|
4. **审查**: 技术总监审查代码和文档
|
||||||
|
5. **发布**: 合并代码并部署
|
||||||
|
|
||||||
|
## 重要提醒
|
||||||
|
|
||||||
|
⚠️ **各角色只能在各自的工作目录中工作**
|
||||||
|
|
||||||
|
- 后端程序员只能在 `backend/` 目录中工作
|
||||||
|
- 前端程序员只能在 `frontend/` 目录中工作
|
||||||
|
- 测试工程师只能在 `testing/` 目录中工作
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
### 后端程序员
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
# 查看工作规范
|
||||||
|
cat WORKSTANDARDS.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### 前端程序员
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
# 查看工作规范
|
||||||
|
cat WORKSTANDARDS.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### 测试工程师
|
||||||
|
```bash
|
||||||
|
cd testing
|
||||||
|
# 查看工作规范
|
||||||
|
cat WORKSTANDARDS.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## 文档资源
|
||||||
|
|
||||||
|
- [UI设计规范](docs/ui-design-spec.md)
|
||||||
|
- [设计方案](docs/plans/)
|
||||||
|
- [团队协作规范](docs/TEAM-COLLABORATION.md)
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# 后端开发目录
|
||||||
|
|
||||||
|
## 目录说明
|
||||||
|
|
||||||
|
### src/
|
||||||
|
源代码目录,包含所有后端业务逻辑代码。
|
||||||
|
|
||||||
|
#### controllers/
|
||||||
|
控制器层,处理HTTP请求和响应。
|
||||||
|
|
||||||
|
#### services/
|
||||||
|
服务层,实现业务逻辑。
|
||||||
|
|
||||||
|
#### models/
|
||||||
|
数据模型,定义数据库表结构。
|
||||||
|
|
||||||
|
#### routes/
|
||||||
|
路由定义,配置API端点。
|
||||||
|
|
||||||
|
#### middleware/
|
||||||
|
中间件,处理认证、日志等横切关注点。
|
||||||
|
|
||||||
|
#### utils/
|
||||||
|
工具函数,提供通用功能。
|
||||||
|
|
||||||
|
### tests/
|
||||||
|
测试目录,包含单元测试和集成测试。
|
||||||
|
|
||||||
|
### docs/
|
||||||
|
文档目录,包含API文档和技术文档。
|
||||||
|
|
||||||
|
### config/
|
||||||
|
配置目录,包含数据库配置、环境变量等。
|
||||||
|
|
||||||
|
## 工作规范
|
||||||
|
|
||||||
|
详见 [WORKSTANDARDS.md](WORKSTANDARDS.md)
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
# 后端程序员工作规范
|
||||||
|
|
||||||
|
## 工作目录
|
||||||
|
- **主目录**: `backend/`
|
||||||
|
- **代码目录**: `backend/src/`
|
||||||
|
- **测试目录**: `backend/tests/`
|
||||||
|
- **文档目录**: `backend/docs/`
|
||||||
|
- **配置目录**: `backend/config/`
|
||||||
|
|
||||||
|
## 开发规范
|
||||||
|
|
||||||
|
### 代码结构
|
||||||
|
```
|
||||||
|
backend/
|
||||||
|
├── src/ # 源代码
|
||||||
|
│ ├── controllers/ # 控制器
|
||||||
|
│ ├── services/ # 业务逻辑
|
||||||
|
│ ├── models/ # 数据模型
|
||||||
|
│ ├── routes/ # 路由定义
|
||||||
|
│ ├── middleware/ # 中间件
|
||||||
|
│ └── utils/ # 工具函数
|
||||||
|
├── tests/ # 单元测试和集成测试
|
||||||
|
├── docs/ # API文档和技术文档
|
||||||
|
├── config/ # 配置文件
|
||||||
|
└── requirements.txt # Python依赖(如使用Python)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 开发流程
|
||||||
|
1. 在 `backend/src/` 中编写业务代码
|
||||||
|
2. 在 `backend/tests/` 中编写单元测试
|
||||||
|
3. 在 `backend/docs/` 中编写API文档
|
||||||
|
4. 提交前必须运行测试
|
||||||
|
|
||||||
|
### 代码提交规范
|
||||||
|
- 提交信息格式: `[backend] <类型>: <描述>`
|
||||||
|
- 类型: feat, fix, docs, style, refactor, test, chore
|
||||||
|
- 示例: `[backend] feat: 添加用户认证API`
|
||||||
|
|
||||||
|
### 禁止事项
|
||||||
|
- ❌ 不得在 `frontend/` 或 `testing/` 目录中工作
|
||||||
|
- ❌ 不得修改公共配置文件(需提交技术总监审批)
|
||||||
|
- ❌ 不得提交包含敏感信息的代码
|
||||||
|
|
||||||
|
## API文档要求
|
||||||
|
- 所有API必须在 `backend/docs/api.md` 中文档化
|
||||||
|
- 文档包含: 接口路径、请求方法、参数、返回值、错误码
|
||||||
|
- 使用OpenAPI/Swagger格式
|
||||||
|
|
||||||
|
## 测试要求
|
||||||
|
- 单元测试覆盖率 > 80%
|
||||||
|
- 所有新增功能必须有对应测试
|
||||||
|
- 测试文件命名: `test_<模块名>.py` 或 `<模块名>.test.js`
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
- 语言: Python/Node.js/Go
|
||||||
|
- 框架: 根据项目需求选择
|
||||||
|
- 数据库: PostgreSQL/MySQL/MongoDB
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
# 海洋项目管理系统 - 团队协作规范
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
ocean_project_manager/
|
||||||
|
├── backend/ # 后端程序员工作区
|
||||||
|
│ ├── src/ # 后端源代码
|
||||||
|
│ ├── tests/ # 后端测试
|
||||||
|
│ ├── docs/ # API文档
|
||||||
|
│ └── WORKSTANDARDS.md
|
||||||
|
├── frontend/ # 前端程序员工作区
|
||||||
|
│ ├── src/ # 前端源代码
|
||||||
|
│ ├── tests/ # 前端测试
|
||||||
|
│ ├── docs/ # 组件文档
|
||||||
|
│ └── WORKSTANDARDS.md
|
||||||
|
├── testing/ # 测试工程师工作区
|
||||||
|
│ ├── testcases/ # 测试用例
|
||||||
|
│ ├── reports/ # 测试报告
|
||||||
|
│ ├── scripts/ # 自动化测试脚本
|
||||||
|
│ └── WORKSTANDARDS.md
|
||||||
|
└── docs/ # 项目文档
|
||||||
|
├── plans/ # 设计方案
|
||||||
|
└── ui-design-spec.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## 角色职责
|
||||||
|
|
||||||
|
### 技术总监
|
||||||
|
- 审查设计和文档
|
||||||
|
- Review代码质量
|
||||||
|
- 协调团队协作
|
||||||
|
- 批准重大变更
|
||||||
|
|
||||||
|
### 后端程序员
|
||||||
|
- 负责后端API开发和维护
|
||||||
|
- 编写API文档
|
||||||
|
- 确保代码质量和测试覆盖率
|
||||||
|
- 工作目录: `backend/`
|
||||||
|
|
||||||
|
### 前端程序员
|
||||||
|
- 负责前端UI开发和维护
|
||||||
|
- 编写组件文档
|
||||||
|
- 集成后端API
|
||||||
|
- 工作目录: `frontend/`
|
||||||
|
|
||||||
|
### 测试工程师
|
||||||
|
- 编写测试计划和测试用例
|
||||||
|
- 执行功能测试、UI测试、自动化测试
|
||||||
|
- 生成测试报告和Bug报告
|
||||||
|
- 工作目录: `testing/`
|
||||||
|
|
||||||
|
## 协作流程
|
||||||
|
|
||||||
|
### 1. 需求分析阶段
|
||||||
|
- 技术总监编写设计方案
|
||||||
|
- 后端程序员和前端程序员查看设计方案
|
||||||
|
- 测试工程师编写测试计划
|
||||||
|
|
||||||
|
### 2. 开发阶段
|
||||||
|
**后端开发流程:**
|
||||||
|
1. 后端程序员开发API
|
||||||
|
2. 编写单元测试
|
||||||
|
3. 更新API文档 (`backend/docs/api.md`)
|
||||||
|
4. 提交代码审查
|
||||||
|
|
||||||
|
**前端开发流程:**
|
||||||
|
1. 前端程序员查看API文档
|
||||||
|
2. 开发UI组件
|
||||||
|
3. 集成API
|
||||||
|
4. 编写组件测试
|
||||||
|
5. 提交代码审查
|
||||||
|
|
||||||
|
### 3. 测试阶段
|
||||||
|
1. 测试工程师执行测试用例
|
||||||
|
2. 记录Bug和问题
|
||||||
|
3. 生成测试报告
|
||||||
|
4. 后端程序员和前端程序员修复Bug
|
||||||
|
|
||||||
|
### 4. 发布阶段
|
||||||
|
1. 技术总监审查代码和测试报告
|
||||||
|
2. 合并代码到主分支
|
||||||
|
3. 部署上线
|
||||||
|
|
||||||
|
## 代码审查流程
|
||||||
|
|
||||||
|
### 提交PR要求
|
||||||
|
1. 代码必须通过所有测试
|
||||||
|
2. 必须有对应文档更新
|
||||||
|
3. 提交信息符合规范
|
||||||
|
4. Pull Request描述清晰
|
||||||
|
|
||||||
|
### 审查检查项
|
||||||
|
- [ ] 代码符合规范
|
||||||
|
- [ ] 测试覆盖率达标
|
||||||
|
- [ ] 文档完整
|
||||||
|
- [ ] 无安全漏洞
|
||||||
|
- [ ] 性能可接受
|
||||||
|
|
||||||
|
## 文档要求
|
||||||
|
|
||||||
|
### 设计文档
|
||||||
|
- 存储位置: `docs/plans/`
|
||||||
|
- 包含: 需求分析、架构设计、数据库设计
|
||||||
|
|
||||||
|
### API文档
|
||||||
|
- 存储位置: `backend/docs/api.md`
|
||||||
|
- 使用OpenAPI/Swagger格式
|
||||||
|
|
||||||
|
### 测试文档
|
||||||
|
- 存储位置: `testing/docs/`
|
||||||
|
- 包含: 测试计划、测试用例、Bug报告
|
||||||
|
|
||||||
|
## 沟通机制
|
||||||
|
|
||||||
|
### 每日站会
|
||||||
|
- 各角色汇报工作进展
|
||||||
|
- 讨论遇到的问题
|
||||||
|
|
||||||
|
### 周会
|
||||||
|
- 代码审查
|
||||||
|
- 设计方案讨论
|
||||||
|
- 进度同步
|
||||||
|
|
||||||
|
### 紧急沟通
|
||||||
|
- 重大Bug立即通知技术总监
|
||||||
|
- 设计变更需要技术总监批准
|
||||||
|
|
||||||
|
## 版本管理
|
||||||
|
|
||||||
|
### 分支策略
|
||||||
|
- `main`: 生产环境
|
||||||
|
- `develop`: 开发环境
|
||||||
|
- `feature/<功能名>`: 功能分支
|
||||||
|
- `bugfix/<bug编号>`: Bug修复分支
|
||||||
|
|
||||||
|
### 提交规范
|
||||||
|
- 后端: `[backend] <类型>: <描述>`
|
||||||
|
- 前端: `[frontend] <类型>: <描述>`
|
||||||
|
- 测试: `[testing] <类型>: <描述>`
|
||||||
|
|
||||||
|
## 质量保证
|
||||||
|
|
||||||
|
### 代码质量
|
||||||
|
- 后端测试覆盖率 > 80%
|
||||||
|
- 前端关键组件必须有测试
|
||||||
|
- 代码必须通过Linter检查
|
||||||
|
|
||||||
|
### 测试质量
|
||||||
|
- 功能测试覆盖率 100%
|
||||||
|
- 关键流程必须有自动化测试
|
||||||
|
- Bug修复必须经过验证
|
||||||
|
|
||||||
|
### 文档质量
|
||||||
|
- API文档与代码同步
|
||||||
|
- 组件文档包含使用示例
|
||||||
|
- 测试用例清晰可执行
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
# docs/pid.md 文档更新说明
|
||||||
|
|
||||||
|
## 更新时间
|
||||||
|
2026-01-25
|
||||||
|
|
||||||
|
## 更新内容
|
||||||
|
|
||||||
|
### 1. 更新了第3.2节 - 项目目录结构
|
||||||
|
|
||||||
|
**更新前**: 使用传统的Flask项目结构(app目录)
|
||||||
|
**更新后**: 采用新的团队协作目录结构
|
||||||
|
|
||||||
|
**变更说明**:
|
||||||
|
- 后端结构从 `backend/app/` 更新为 `backend/src/`,包含更清晰的分层架构(controllers, services, models, routes, middleware, utils)
|
||||||
|
- 前端结构从基本的React项目结构更新为包含types、hooks、styles等子目录的现代React项目结构
|
||||||
|
- 新增了 `testing/` 目录,包含testcases、reports、data、scripts、docs等子目录
|
||||||
|
- 为每个工作区添加了WORKSTANDARDS.md和README.md
|
||||||
|
|
||||||
|
### 2. 新增第3.3节 - 工作目录说明
|
||||||
|
|
||||||
|
**新增内容**:
|
||||||
|
- 后端程序员工作区职责和主要工作
|
||||||
|
- 前端程序员工作区职责和主要工作
|
||||||
|
- 测试工程师工作区职责和主要工作
|
||||||
|
|
||||||
|
### 3. 新增第3.4节 - 权限限制
|
||||||
|
|
||||||
|
**新增内容**:
|
||||||
|
- 明确规定各角色只能在指定目录中工作
|
||||||
|
- 添加权限控制文档链接
|
||||||
|
- 强调跨目录工作需要技术总监批准
|
||||||
|
|
||||||
|
### 4. 新增第4章 - 团队协作
|
||||||
|
|
||||||
|
**新增内容**:
|
||||||
|
- 4.1 角色职责: 详细说明各角色的工作职责
|
||||||
|
- 4.2 工作流程: 包含需求分析、后端开发、前端开发、测试、代码审查五个阶段的详细流程
|
||||||
|
- 4.3 代码提交规范: 明确各角色的提交信息格式和类型说明
|
||||||
|
- 4.4 文档规范: 说明后端、前端、测试的文档规范
|
||||||
|
- 4.5 沟通机制: 说明日常沟通、文档沟通、技术总监审查的方式
|
||||||
|
|
||||||
|
### 5. 更新章节编号
|
||||||
|
|
||||||
|
由于新增了第4章"团队协作",后续章节编号全部+1:
|
||||||
|
- 原第4章"数据库设计" → 现第5章
|
||||||
|
- 原第5章"API设计" → 现第6章
|
||||||
|
- 原第6章"前端设计" → 现第7章
|
||||||
|
- 原第7章"安全设计" → 现第8章
|
||||||
|
- 原第8章"部署方案" → 现第9章
|
||||||
|
- 原第9章"后续优化建议" → 现第10章
|
||||||
|
- 原第10章"开发计划" → 现第11章
|
||||||
|
|
||||||
|
### 6. 新增第12章 - 相关文档
|
||||||
|
|
||||||
|
**新增内容**:
|
||||||
|
- 12.1 团队协作文档链接
|
||||||
|
- 12.2 角色工作规范链接
|
||||||
|
- 12.3 技术文档链接
|
||||||
|
- 12.4 项目文档链接
|
||||||
|
|
||||||
|
### 7. 更新所有子章节编号
|
||||||
|
|
||||||
|
所有子章节编号根据父章节编号进行了相应更新:
|
||||||
|
- 数据库设计: 4.1-4.2 → 5.1-5.2
|
||||||
|
- API设计: 5.1-5.4 → 6.1-6.4
|
||||||
|
- 前端设计: 6.1-6.4 → 7.1-7.4
|
||||||
|
- 安全设计: 7.1-7.3 → 8.1-8.3
|
||||||
|
- 部署方案: 8.1-8.2 → 9.1-9.2
|
||||||
|
- 后续优化建议: 9.1-9.3 → 10.1-10.3
|
||||||
|
- 开发计划: 10.1-10.3 → 11.1-11.3
|
||||||
|
|
||||||
|
## 影响范围
|
||||||
|
|
||||||
|
1. **文档结构**: 文档从10章扩展到12章,新增了团队协作和相关文档两章
|
||||||
|
2. **项目架构**: 完全按照当前的项目目录结构更新,与实际的backend/、frontend/、testing/目录保持一致
|
||||||
|
3. **角色分工**: 明确了后端程序员、前端程序员、测试工程师的具体职责和工作范围
|
||||||
|
4. **协作流程**: 提供了详细的团队协作流程,从前端到后端再到测试的完整工作链
|
||||||
|
|
||||||
|
## 后续维护
|
||||||
|
|
||||||
|
- 后端程序员需要在 `backend/docs/api.md` 中维护API文档
|
||||||
|
- 前端程序员需要在 `frontend/docs/components.md` 中维护组件文档
|
||||||
|
- 测试工程师需要在 `testing/docs/` 中维护测试文档
|
||||||
|
- 技术总监负责维护本设计文档 (`docs/pid.md`)
|
||||||
|
|
||||||
|
## 文档状态
|
||||||
|
|
||||||
|
✅ 已完成更新,文档与当前项目架构保持一致
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**更新人**: 技术总监
|
||||||
|
**审核**: 待审核
|
||||||
@@ -123,74 +123,264 @@
|
|||||||
|
|
||||||
```
|
```
|
||||||
ocean_project_manager/
|
ocean_project_manager/
|
||||||
├── backend/ # 后端代码
|
├── backend/ # 后端程序员工作区
|
||||||
│ ├── app/
|
│ ├── src/ # 源代码
|
||||||
│ │ ├── __init__.py # Flask应用初始化
|
│ │ ├── controllers/ # 控制器层
|
||||||
│ │ ├── config.py # 配置文件
|
|
||||||
│ │ ├── models/ # 数据库模型
|
|
||||||
│ │ │ ├── __init__.py
|
|
||||||
│ │ │ ├── user.py
|
|
||||||
│ │ │ └── project.py
|
|
||||||
│ │ ├── routes/ # API路由
|
|
||||||
│ │ │ ├── __init__.py
|
|
||||||
│ │ │ ├── auth.py # 认证相关
|
│ │ │ ├── auth.py # 认证相关
|
||||||
│ │ │ ├── users.py # 用户管理
|
│ │ │ ├── users.py # 用户管理
|
||||||
│ │ │ └── projects.py # 项目管理
|
│ │ │ └── projects.py # 项目管理
|
||||||
│ │ ├── services/ # 业务逻辑
|
│ │ ├── services/ # 业务逻辑层
|
||||||
│ │ │ ├── __init__.py
|
|
||||||
│ │ │ ├── auth_service.py
|
│ │ │ ├── auth_service.py
|
||||||
│ │ │ ├── user_service.py
|
│ │ │ ├── user_service.py
|
||||||
│ │ │ └── project_service.py
|
│ │ │ └── project_service.py
|
||||||
|
│ │ ├── models/ # 数据模型层
|
||||||
|
│ │ │ ├── user.py
|
||||||
|
│ │ │ └── project.py
|
||||||
|
│ │ ├── routes/ # 路由定义
|
||||||
|
│ │ │ ├── auth.py
|
||||||
|
│ │ │ ├── users.py
|
||||||
|
│ │ │ └── projects.py
|
||||||
|
│ │ ├── middleware/ # 中间件
|
||||||
|
│ │ │ ├── jwt_middleware.py
|
||||||
|
│ │ │ └── auth_middleware.py
|
||||||
│ │ └── utils/ # 工具函数
|
│ │ └── utils/ # 工具函数
|
||||||
│ │ ├── __init__.py
|
|
||||||
│ │ ├── jwt_utils.py
|
│ │ ├── jwt_utils.py
|
||||||
│ │ └── decorators.py
|
│ │ └── password_utils.py
|
||||||
|
│ ├── tests/ # 单元测试和集成测试
|
||||||
|
│ ├── docs/ # API文档和技术文档
|
||||||
|
│ │ └── api.md # API文档
|
||||||
|
│ ├── config/ # 配置文件
|
||||||
│ ├── requirements.txt # Python依赖
|
│ ├── requirements.txt # Python依赖
|
||||||
│ ├── run.py # 启动文件
|
│ ├── run.py # 启动文件
|
||||||
│ └── .env # 环境变量
|
│ ├── WORKSTANDARDS.md # 后端程序员工作规范
|
||||||
|
│ └── README.md # 后端开发说明
|
||||||
│
|
│
|
||||||
├── frontend/ # 前端代码
|
├── frontend/ # 前端程序员工作区
|
||||||
│ ├── public/
|
│ ├── src/ # 源代码
|
||||||
│ │ └── index.html
|
│ │ ├── components/ # 可复用组件
|
||||||
│ ├── src/
|
│ │ │ ├── Layout.jsx
|
||||||
│ │ ├── components/ # 公共组件
|
│ │ │ ├── Header.jsx
|
||||||
│ │ │ ├── Layout.js
|
│ │ │ └── Sidebar.jsx
|
||||||
│ │ │ ├── Header.js
|
|
||||||
│ │ │ └── Sidebar.js
|
|
||||||
│ │ ├── pages/ # 页面组件
|
│ │ ├── pages/ # 页面组件
|
||||||
│ │ │ ├── Login.js
|
│ │ │ ├── Login.jsx
|
||||||
│ │ │ ├── Dashboard.js
|
│ │ │ ├── Dashboard.jsx
|
||||||
│ │ │ ├── UserList.js
|
│ │ │ ├── UserList.jsx
|
||||||
│ │ │ ├── UserForm.js
|
│ │ │ ├── UserForm.jsx
|
||||||
│ │ │ ├── ProjectList.js
|
│ │ │ ├── ProjectList.jsx
|
||||||
│ │ │ ├── ProjectForm.js
|
│ │ │ ├── ProjectForm.jsx
|
||||||
│ │ │ └── ProjectDetail.js
|
│ │ │ └── ProjectDetail.jsx
|
||||||
|
│ │ ├── hooks/ # 自定义Hooks
|
||||||
|
│ │ │ └── useAuth.js
|
||||||
│ │ ├── services/ # API服务
|
│ │ ├── services/ # API服务
|
||||||
│ │ │ ├── api.js # Axios配置
|
│ │ │ ├── api.js # Axios配置
|
||||||
│ │ │ ├── auth.js
|
│ │ │ ├── auth.js
|
||||||
│ │ │ ├── user.js
|
│ │ │ ├── user.js
|
||||||
│ │ │ └── project.js
|
│ │ │ └── project.js
|
||||||
│ │ ├── contexts/ # Context
|
|
||||||
│ │ │ └── AuthContext.js
|
|
||||||
│ │ ├── utils/ # 工具函数
|
│ │ ├── utils/ # 工具函数
|
||||||
│ │ │ └── auth.js
|
│ │ │ └── auth.js
|
||||||
│ │ ├── App.js # 根组件
|
│ │ ├── styles/ # 样式文件
|
||||||
│ │ ├── index.js # 入口文件
|
│ │ │ └── global.css
|
||||||
│ │ └── App.css
|
│ │ ├── types/ # TypeScript类型定义
|
||||||
|
│ │ │ ├── user.ts
|
||||||
|
│ │ │ └── project.ts
|
||||||
|
│ │ ├── App.jsx # 根组件
|
||||||
|
│ │ └── index.js # 入口文件
|
||||||
|
│ ├── tests/ # 组件测试
|
||||||
|
│ ├── docs/ # 组件文档和开发文档
|
||||||
|
│ │ └── components.md # 组件文档
|
||||||
│ ├── package.json
|
│ ├── package.json
|
||||||
│ └── .env # 环境变量
|
│ ├── WORKSTANDARDS.md # 前端程序员工作规范
|
||||||
|
│ └── README.md # 前端开发说明
|
||||||
│
|
│
|
||||||
├── docs/ # 文档
|
├── testing/ # 测试工程师工作区
|
||||||
|
│ ├── testcases/ # 测试用例
|
||||||
|
│ │ ├── api/ # API测试用例
|
||||||
|
│ │ │ ├── auth_test.json
|
||||||
|
│ │ │ ├── user_test.json
|
||||||
|
│ │ │ └── project_test.json
|
||||||
|
│ │ ├── ui/ # UI测试用例
|
||||||
|
│ │ │ ├── login_test.json
|
||||||
|
│ │ │ ├── user_list_test.json
|
||||||
|
│ │ │ └── project_list_test.json
|
||||||
|
│ │ └── integration/ # 集成测试用例
|
||||||
|
│ │ └── workflow_test.json
|
||||||
|
│ ├── reports/ # 测试报告
|
||||||
|
│ ├── data/ # 测试数据
|
||||||
|
│ ├── scripts/ # 自动化测试脚本
|
||||||
|
│ │ ├── api_test.py # API自动化测试
|
||||||
|
│ │ └── ui_test.js # UI自动化测试
|
||||||
|
│ ├── docs/ # 测试文档
|
||||||
|
│ │ ├── test_plan.md # 测试计划
|
||||||
|
│ │ └── test_strategy.md # 测试策略
|
||||||
|
│ ├── WORKSTANDARDS.md # 测试工程师工作规范
|
||||||
|
│ └── README.md # 测试工作说明
|
||||||
|
│
|
||||||
|
├── docs/ # 项目文档
|
||||||
│ ├── plans/ # 设计文档
|
│ ├── plans/ # 设计文档
|
||||||
│ │ └── 2026-01-24-project-management-system-design.md
|
│ │ └── 2026-01-24-project-management-system-design.md
|
||||||
│ └── api/ # API文档
|
│ ├── ui-design-spec.md # UI设计规范
|
||||||
|
│ ├── pid.md # 项目信息文档(本文档)
|
||||||
|
│ └── TEAM-COLLABORATION.md # 团队协作规范
|
||||||
│
|
│
|
||||||
└── README.md
|
├── ACCESS-CONTROL.md # 权限控制文档
|
||||||
|
├── README.md # 项目说明
|
||||||
|
└── .git/ # Git仓库
|
||||||
```
|
```
|
||||||
|
|
||||||
## 4. 数据库设计
|
### 3.3 工作目录说明
|
||||||
|
|
||||||
### 4.1 数据库表结构
|
#### 后端程序员工作区 (`backend/`)
|
||||||
|
- **负责**: 后端API开发、数据库设计、单元测试编写
|
||||||
|
- **主要工作**: 在 `backend/src/` 中编写业务代码
|
||||||
|
- **输出文档**: `backend/docs/api.md` - API文档
|
||||||
|
- **测试**: `backend/tests/` - 单元测试和集成测试
|
||||||
|
|
||||||
|
#### 前端程序员工作区 (`frontend/`)
|
||||||
|
- **负责**: 前端UI开发、组件封装、API集成
|
||||||
|
- **主要工作**: 在 `frontend/src/` 中编写UI组件
|
||||||
|
- **输出文档**: `frontend/docs/components.md` - 组件文档
|
||||||
|
- **测试**: `frontend/tests/` - 组件测试
|
||||||
|
|
||||||
|
#### 测试工程师工作区 (`testing/`)
|
||||||
|
- **负责**: 测试计划编写、测试用例设计、自动化测试
|
||||||
|
- **主要工作**: 在 `testing/testcases/` 中编写测试用例
|
||||||
|
- **输出文档**: `testing/reports/` - 测试报告
|
||||||
|
- **自动化**: `testing/scripts/` - 自动化测试脚本
|
||||||
|
|
||||||
|
### 3.4 权限限制
|
||||||
|
|
||||||
|
⚠️ **严格遵守工作目录限制**
|
||||||
|
|
||||||
|
- 后端程序员只能在 `backend/` 目录中工作
|
||||||
|
- 前端程序员只能在 `frontend/` 目录中工作
|
||||||
|
- 测试工程师只能在 `testing/` 目录中工作
|
||||||
|
|
||||||
|
跨目录工作需要技术总监批准,详见 [ACCESS-CONTROL.md](../ACCESS-CONTROL.md)
|
||||||
|
|
||||||
|
## 4. 团队协作
|
||||||
|
|
||||||
|
### 4.1 角色职责
|
||||||
|
|
||||||
|
#### 技术总监
|
||||||
|
- 审查设计方案和技术文档
|
||||||
|
- Review代码质量和架构设计
|
||||||
|
- 协调团队协作,解决技术分歧
|
||||||
|
- 批准重大变更和跨目录访问请求
|
||||||
|
|
||||||
|
#### 后端程序员
|
||||||
|
- **工作目录**: `backend/`
|
||||||
|
- **主要职责**:
|
||||||
|
- 设计和实现后端API接口
|
||||||
|
- 编写API文档 (`backend/docs/api.md`)
|
||||||
|
- 编写单元测试,确保测试覆盖率 > 80%
|
||||||
|
- 参与技术方案讨论和代码审查
|
||||||
|
|
||||||
|
#### 前端程序员
|
||||||
|
- **工作目录**: `frontend/`
|
||||||
|
- **主要职责**:
|
||||||
|
- 实现前端UI组件和页面
|
||||||
|
- 编写组件文档 (`frontend/docs/components.md`)
|
||||||
|
- 集成后端API,确保前后端对接
|
||||||
|
- 遵循UI设计规范 (`docs/ui-design-spec.md`)
|
||||||
|
|
||||||
|
#### 测试工程师
|
||||||
|
- **工作目录**: `testing/`
|
||||||
|
- **主要职责**:
|
||||||
|
- 编写测试计划和测试用例
|
||||||
|
- 执行功能测试、UI测试、自动化测试
|
||||||
|
- 生成测试报告和Bug报告
|
||||||
|
- 验证Bug修复效果
|
||||||
|
|
||||||
|
### 4.2 工作流程
|
||||||
|
|
||||||
|
#### 4.2.1 需求分析阶段
|
||||||
|
1. 技术总监编写设计方案 (`docs/plans/`)
|
||||||
|
2. 后端程序员和前端程序员查看设计方案
|
||||||
|
3. 测试工程师编写测试计划 (`testing/docs/`)
|
||||||
|
|
||||||
|
#### 4.2.2 后端开发流程
|
||||||
|
1. 后端程序员在 `backend/src/` 中开发API
|
||||||
|
2. 编写单元测试 (`backend/tests/`)
|
||||||
|
3. 更新API文档 (`backend/docs/api.md`)
|
||||||
|
4. 提交代码进行审查
|
||||||
|
|
||||||
|
#### 4.2.3 前端开发流程
|
||||||
|
1. 前端程序员查看API文档 (`backend/docs/api.md`)
|
||||||
|
2. 在 `frontend/src/` 中开发UI组件
|
||||||
|
3. 集成后端API
|
||||||
|
4. 编写组件测试 (`frontend/tests/`)
|
||||||
|
5. 提交代码进行审查
|
||||||
|
|
||||||
|
#### 4.2.4 测试流程
|
||||||
|
1. 测试工程师执行测试用例 (`testing/testcases/`)
|
||||||
|
2. 记录Bug和问题
|
||||||
|
3. 生成测试报告 (`testing/reports/`)
|
||||||
|
4. 后端程序员和前端程序员根据Bug报告修复问题
|
||||||
|
5. 测试工程师验证修复效果
|
||||||
|
|
||||||
|
#### 4.2.5 代码审查流程
|
||||||
|
1. 开发人员提交Pull Request
|
||||||
|
2. 技术总监审查代码质量、文档完整性、测试覆盖率
|
||||||
|
3. 如有问题,退回修改;如通过,合并到主分支
|
||||||
|
|
||||||
|
### 4.3 代码提交规范
|
||||||
|
|
||||||
|
#### 提交信息格式
|
||||||
|
- 后端程序员: `[backend] <类型>: <描述>`
|
||||||
|
- 前端程序员: `[frontend] <类型>: <描述>`
|
||||||
|
- 测试工程师: `[testing] <类型>: <描述>`
|
||||||
|
|
||||||
|
#### 类型说明
|
||||||
|
- `feat`: 新功能
|
||||||
|
- `fix`: Bug修复
|
||||||
|
- `docs`: 文档更新
|
||||||
|
- `style`: 代码格式调整
|
||||||
|
- `refactor`: 代码重构
|
||||||
|
- `test`: 测试相关
|
||||||
|
- `chore`: 构建或工具相关
|
||||||
|
|
||||||
|
#### 示例
|
||||||
|
```
|
||||||
|
[backend] feat: 添加用户认证API
|
||||||
|
[frontend] fix: 修复项目列表分页问题
|
||||||
|
[testing] test: 添加用户登录API测试用例
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.4 文档规范
|
||||||
|
|
||||||
|
#### 后端文档
|
||||||
|
- **API文档**: `backend/docs/api.md`
|
||||||
|
- 使用OpenAPI/Swagger格式
|
||||||
|
- 包含: 接口路径、请求方法、参数、返回值、错误码
|
||||||
|
|
||||||
|
#### 前端文档
|
||||||
|
- **组件文档**: `frontend/docs/components.md`
|
||||||
|
- 包含: 组件名称、Props、使用示例、截图
|
||||||
|
|
||||||
|
#### 测试文档
|
||||||
|
- **测试计划**: `testing/docs/test_plan.md`
|
||||||
|
- **测试报告**: `testing/reports/` 目录
|
||||||
|
- **Bug报告**: 包含标题、重现步骤、预期结果、实际结果、截图/日志
|
||||||
|
|
||||||
|
### 4.5 沟通机制
|
||||||
|
|
||||||
|
#### 日常沟通
|
||||||
|
- 各角色在各自目录中独立工作
|
||||||
|
- 需要协作时通过技术总监协调
|
||||||
|
|
||||||
|
#### 文档沟通
|
||||||
|
- 后端API文档作为前后端对接的桥梁
|
||||||
|
- 测试报告作为Bug修复的依据
|
||||||
|
- 所有重要决策记录在项目文档中
|
||||||
|
|
||||||
|
#### 技术总监审查
|
||||||
|
- 所有设计方案需要技术总监批准
|
||||||
|
- 所有代码合并需要技术总监审查
|
||||||
|
- 重大变更需要技术总监批准
|
||||||
|
|
||||||
|
## 5. 数据库设计
|
||||||
|
|
||||||
|
### 5.1 数据库表结构
|
||||||
|
|
||||||
#### 4.1.1 用户表 (users)
|
#### 4.1.1 用户表 (users)
|
||||||
|
|
||||||
@@ -275,7 +465,7 @@ CREATE INDEX idx_projects_department ON projects(department);
|
|||||||
CREATE INDEX idx_projects_created_by ON projects(created_by);
|
CREATE INDEX idx_projects_created_by ON projects(created_by);
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.2 角色权限矩阵
|
### 5.2 角色权限矩阵
|
||||||
|
|
||||||
| 功能 | admin | market | other |
|
| 功能 | admin | market | other |
|
||||||
|------|-------|--------|-------|
|
|------|-------|--------|-------|
|
||||||
@@ -290,9 +480,9 @@ CREATE INDEX idx_projects_created_by ON projects(created_by);
|
|||||||
| 查看所有项目 | ✓ | ✓ | ✓ |
|
| 查看所有项目 | ✓ | ✓ | ✓ |
|
||||||
| 查看项目详情 | ✓ | ✓ | ✓ |
|
| 查看项目详情 | ✓ | ✓ | ✓ |
|
||||||
|
|
||||||
## 5. API设计
|
## 6. API设计
|
||||||
|
|
||||||
### 5.1 API规范
|
### 6.1 API规范
|
||||||
|
|
||||||
- **Base URL**: `/api/v1`
|
- **Base URL**: `/api/v1`
|
||||||
- **Content-Type**: `application/json`
|
- **Content-Type**: `application/json`
|
||||||
@@ -306,7 +496,7 @@ CREATE INDEX idx_projects_created_by ON projects(created_by);
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5.2 认证相关API
|
### 6.2 认证相关API
|
||||||
|
|
||||||
#### 5.2.1 用户登录
|
#### 5.2.1 用户登录
|
||||||
- **URL**: `POST /api/v1/auth/login`
|
- **URL**: `POST /api/v1/auth/login`
|
||||||
@@ -363,7 +553,7 @@ CREATE INDEX idx_projects_created_by ON projects(created_by);
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5.3 用户管理API
|
### 6.3 用户管理API
|
||||||
|
|
||||||
#### 5.3.1 获取用户列表
|
#### 5.3.1 获取用户列表
|
||||||
- **URL**: `GET /api/v1/users`
|
- **URL**: `GET /api/v1/users`
|
||||||
@@ -458,7 +648,7 @@ CREATE INDEX idx_projects_created_by ON projects(created_by);
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5.4 项目管理API
|
### 6.4 项目管理API
|
||||||
|
|
||||||
#### 5.4.1 获取项目列表
|
#### 5.4.1 获取项目列表
|
||||||
- **URL**: `GET /api/v1/projects`
|
- **URL**: `GET /api/v1/projects`
|
||||||
@@ -542,9 +732,9 @@ CREATE INDEX idx_projects_created_by ON projects(created_by);
|
|||||||
- **Header**: `Authorization: Bearer <token>`
|
- **Header**: `Authorization: Bearer <token>`
|
||||||
- **权限**: admin, market(只能删除自己创建的)
|
- **权限**: admin, market(只能删除自己创建的)
|
||||||
|
|
||||||
## 6. 前端设计
|
## 7. 前端设计
|
||||||
|
|
||||||
### 6.1 页面结构
|
### 7.1 页面结构
|
||||||
|
|
||||||
```
|
```
|
||||||
登录页 (Login)
|
登录页 (Login)
|
||||||
@@ -566,7 +756,7 @@ CREATE INDEX idx_projects_created_by ON projects(created_by);
|
|||||||
└─ 项目详情
|
└─ 项目详情
|
||||||
```
|
```
|
||||||
|
|
||||||
### 6.2 核心组件
|
### 7.2 核心组件
|
||||||
|
|
||||||
#### 6.2.1 AuthContext
|
#### 6.2.1 AuthContext
|
||||||
全局认证状态管理:
|
全局认证状态管理:
|
||||||
@@ -590,7 +780,7 @@ const AuthContext = createContext({
|
|||||||
- 请求拦截器
|
- 请求拦截器
|
||||||
- 响应拦截器
|
- 响应拦截器
|
||||||
|
|
||||||
### 6.3 页面设计
|
### 7.3 页面设计
|
||||||
|
|
||||||
#### 6.3.1 登录页
|
#### 6.3.1 登录页
|
||||||
- 简洁的登录表单
|
- 简洁的登录表单
|
||||||
@@ -625,31 +815,31 @@ const AuthContext = createContext({
|
|||||||
- 编辑功能
|
- 编辑功能
|
||||||
- 操作日志(可选)
|
- 操作日志(可选)
|
||||||
|
|
||||||
### 6.4 UI风格
|
### 7.4 UI风格
|
||||||
- 使用Ant Design默认主题
|
- 使用Ant Design默认主题
|
||||||
- 响应式布局
|
- 响应式布局
|
||||||
- 简洁、专业的企业级UI
|
- 简洁、专业的企业级UI
|
||||||
|
|
||||||
## 7. 安全设计
|
## 8. 安全设计
|
||||||
|
|
||||||
### 7.1 认证安全
|
### 8.1 认证安全
|
||||||
- 密码使用bcrypt加密存储
|
- 密码使用bcrypt加密存储
|
||||||
- JWT Token有效期设置(如24小时)
|
- JWT Token有效期设置(如24小时)
|
||||||
- Token过期自动刷新机制
|
- Token过期自动刷新机制
|
||||||
|
|
||||||
### 7.2 权限控制
|
### 8.2 权限控制
|
||||||
- 后端基于装饰器的权限验证
|
- 后端基于装饰器的权限验证
|
||||||
- 前端路由级别的权限控制
|
- 前端路由级别的权限控制
|
||||||
- 前端组件级别的权限控制
|
- 前端组件级别的权限控制
|
||||||
|
|
||||||
### 7.3 数据安全
|
### 8.3 数据安全
|
||||||
- SQL注入防护(使用SQLAlchemy ORM)
|
- SQL注入防护(使用SQLAlchemy ORM)
|
||||||
- XSS防护(React自动转义)
|
- XSS防护(React自动转义)
|
||||||
- 输入验证(前后端双重验证)
|
- 输入验证(前后端双重验证)
|
||||||
|
|
||||||
## 8. 部署方案
|
## 9. 部署方案
|
||||||
|
|
||||||
### 8.1 开发环境
|
### 9.1 开发环境
|
||||||
|
|
||||||
**后端**:
|
**后端**:
|
||||||
```bash
|
```bash
|
||||||
@@ -673,7 +863,7 @@ npm start
|
|||||||
- 数据库名:`project_manager`
|
- 数据库名:`project_manager`
|
||||||
- 配置文件:`.env`
|
- 配置文件:`.env`
|
||||||
|
|
||||||
### 8.2 生产环境(推荐方案)
|
### 9.2 生产环境(推荐方案)
|
||||||
|
|
||||||
**使用Docker Compose**:
|
**使用Docker Compose**:
|
||||||
|
|
||||||
@@ -712,37 +902,62 @@ volumes:
|
|||||||
mysql_data:
|
mysql_data:
|
||||||
```
|
```
|
||||||
|
|
||||||
## 9. 后续优化建议
|
## 10. 后续优化建议
|
||||||
|
|
||||||
### 9.1 功能扩展
|
### 10.1 功能扩展
|
||||||
- 项目附件上传
|
- 项目附件上传
|
||||||
- 操作日志记录
|
- 操作日志记录
|
||||||
- 数据导出功能
|
- 数据导出功能
|
||||||
- 报表统计功能
|
- 报表统计功能
|
||||||
|
|
||||||
### 9.2 性能优化
|
### 10.2 性能优化
|
||||||
- 数据库索引优化
|
- 数据库索引优化
|
||||||
- API响应缓存(如需要)
|
- API响应缓存(如需要)
|
||||||
- 前端代码分割
|
- 前端代码分割
|
||||||
|
|
||||||
### 9.3 用户体验
|
### 10.3 用户体验
|
||||||
- 表单自动保存
|
- 表单自动保存
|
||||||
- 批量操作功能
|
- 批量操作功能
|
||||||
- 消息通知功能
|
- 消息通知功能
|
||||||
|
|
||||||
## 10. 开发计划
|
## 11. 开发计划
|
||||||
|
|
||||||
### 10.1 第一阶段(MVP)
|
### 11.1 第一阶段(MVP)
|
||||||
- 用户登录/登出
|
- 用户登录/登出
|
||||||
- 项目CRUD基础功能
|
- 项目CRUD基础功能
|
||||||
- 简单的用户管理(仅管理员)
|
- 简单的用户管理(仅管理员)
|
||||||
|
|
||||||
### 10.2 第二阶段
|
### 11.2 第二阶段
|
||||||
- 权限控制完善
|
- 权限控制完善
|
||||||
- 项目列表筛选和搜索
|
- 项目列表筛选和搜索
|
||||||
- 表单验证优化
|
- 表单验证优化
|
||||||
|
|
||||||
### 10.3 第三阶段(可选)
|
### 11.3 第三阶段(可选)
|
||||||
- 高级功能扩展
|
- 高级功能扩展
|
||||||
- 性能优化
|
- 性能优化
|
||||||
- 用户体验优化
|
- 用户体验优化
|
||||||
|
|
||||||
|
## 12. 相关文档
|
||||||
|
|
||||||
|
### 12.1 团队协作文档
|
||||||
|
- [团队协作规范](../TEAM-COLLABORATION.md) - 详细的团队协作流程和规范
|
||||||
|
- [权限控制文档](../ACCESS-CONTROL.md) - 各角色访问权限说明
|
||||||
|
|
||||||
|
### 12.2 角色工作规范
|
||||||
|
- [后端程序员工作规范](../backend/WORKSTANDARDS.md) - 后端开发详细规范
|
||||||
|
- [前端程序员工作规范](../frontend/WORKSTANDARDS.md) - 前端开发详细规范
|
||||||
|
- [测试工程师工作规范](../testing/WORKSTANDARDS.md) - 测试工作详细规范
|
||||||
|
|
||||||
|
### 12.3 技术文档
|
||||||
|
- [UI设计规范](../docs/ui-design-spec.md) - 前端UI设计规范
|
||||||
|
- [后端API文档](../backend/docs/api.md) - API接口文档(由后端程序员维护)
|
||||||
|
- [前端组件文档](../frontend/docs/components.md) - 前端组件文档(由前端程序员维护)
|
||||||
|
- [测试文档](../testing/docs/) - 测试计划和测试策略(由测试工程师维护)
|
||||||
|
|
||||||
|
### 12.4 项目文档
|
||||||
|
- [README.md](../README.md) - 项目说明文档
|
||||||
|
- [设计方案](../docs/plans/) - 项目设计方案和技术设计文档
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**文档维护**: 本文档由技术总监维护,如有疑问请联系技术总监。
|
||||||
@@ -1,293 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>项目信息管理系统 - UI预览</title>
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/antd/5.12.2/reset.min.css">
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.10/dayjs.min.js"></script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.10/locale/zh-cn.js"></script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/antd/5.12.2/antd.min.js"></script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/@ant-design/icons/5.2.6/index.min.js"></script>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
||||||
background: #f0f2f5;
|
|
||||||
}
|
|
||||||
#root {
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
.ant-layout {
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
.ant-layout-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 0 24px;
|
|
||||||
background: #001529;
|
|
||||||
}
|
|
||||||
.ant-layout-sider {
|
|
||||||
box-shadow: 2px 0 8px rgba(0,0,0,0.15);
|
|
||||||
}
|
|
||||||
.ant-layout-content {
|
|
||||||
margin: 24px 16px;
|
|
||||||
padding: 24px;
|
|
||||||
min-height: 280px;
|
|
||||||
}
|
|
||||||
.logo {
|
|
||||||
color: white;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 600;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
.user-info {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
.dashboard-cards {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
|
||||||
gap: 24px;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
|
||||||
.dashboard-card {
|
|
||||||
background: white;
|
|
||||||
padding: 24px;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
.dashboard-card h3 {
|
|
||||||
margin: 0 0 8px 0;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
.dashboard-card .number {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 32px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #1890ff;
|
|
||||||
}
|
|
||||||
.preview-section {
|
|
||||||
margin-bottom: 48px;
|
|
||||||
}
|
|
||||||
.preview-section h2 {
|
|
||||||
border-bottom: 2px solid #1890ff;
|
|
||||||
padding-bottom: 12px;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
|
||||||
.mockup {
|
|
||||||
background: white;
|
|
||||||
padding: 24px;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="root"></div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
const { useState } = React;
|
|
||||||
const { Layout, Menu, Card, Table, Button, Form, Input, Select, DatePicker, Space, Dropdown, Avatar, Tag, Modal, message, Statistic } = antd;
|
|
||||||
const { Header, Sider, Content } = Layout;
|
|
||||||
const { ProjectOutlined, UserOutlined, DashboardOutlined, LogoutOutlined, SettingOutlined, FileTextOutlined, TeamOutlined, PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined } = icons;
|
|
||||||
dayjs.locale('zh-cn');
|
|
||||||
|
|
||||||
const { Option } = Select;
|
|
||||||
const { RangePicker } = DatePicker;
|
|
||||||
|
|
||||||
const menuItems = [
|
|
||||||
{ key: 'dashboard', icon: React.createElement(DashboardOutlined), label: '仪表盘' },
|
|
||||||
{ key: 'projects', icon: React.createElement(FileTextOutlined), label: '项目管理' },
|
|
||||||
{ key: 'users', icon: React.createElement(TeamOutlined), label: '用户管理' },
|
|
||||||
];
|
|
||||||
|
|
||||||
const projectColumns = [
|
|
||||||
{ title: '项目编号', dataIndex: 'project_no', key: 'project_no' },
|
|
||||||
{ title: '合同编号', dataIndex: 'contract_no', key: 'contract_no' },
|
|
||||||
{ title: '项目名称', dataIndex: 'name', key: 'name' },
|
|
||||||
{ title: '预算', dataIndex: 'budget', key: 'budget', render: (val) => `¥${val.toLocaleString()}` },
|
|
||||||
{ title: '已付款', dataIndex: 'payment_amount', key: 'payment_amount', render: (val) => `¥${val.toLocaleString()}` },
|
|
||||||
{ title: '状态', dataIndex: 'status', key: 'status', render: (status) => {
|
|
||||||
const colorMap = { '新建': 'blue', '进行中': 'green', '已完成': 'default', '已暂停': 'orange', '已取消': 'red' };
|
|
||||||
return React.createElement(Tag, { color: colorMap[status] || 'default' }, status);
|
|
||||||
}},
|
|
||||||
{ title: '所属部门', dataIndex: 'department', key: 'department' },
|
|
||||||
{ title: '创建人', dataIndex: 'created_by_name', key: 'created_by_name' },
|
|
||||||
{ title: '创建时间', dataIndex: 'created_at', key: 'created_at', render: (val) => dayjs(val).format('YYYY-MM-DD') },
|
|
||||||
{
|
|
||||||
title: '操作',
|
|
||||||
key: 'action',
|
|
||||||
render: () => React.createElement(Space, null,
|
|
||||||
React.createElement(Button, { type: 'link', size: 'small', icon: React.createElement(EyeOutlined) }, '查看'),
|
|
||||||
React.createElement(Button, { type: 'link', size: 'small', icon: React.createElement(EditOutlined) }, '编辑'),
|
|
||||||
React.createElement(Button, { type: 'link', size: 'small', danger: true, icon: React.createElement(DeleteOutlined) }, '删除')
|
|
||||||
)
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const userColumns = [
|
|
||||||
{ title: '用户名', dataIndex: 'username', key: 'username' },
|
|
||||||
{ title: '真实姓名', dataIndex: 'real_name', key: 'real_name' },
|
|
||||||
{ title: '部门', dataIndex: 'department', key: 'department' },
|
|
||||||
{ title: '角色', dataIndex: 'role', key: 'role', render: (role) => {
|
|
||||||
const roleMap = { 'admin': '管理员', 'market': '市场部', 'other': '其他部门' };
|
|
||||||
return React.createElement(Tag, { color: role === 'admin' ? 'red' : 'blue' }, roleMap[role] || role);
|
|
||||||
}},
|
|
||||||
{ title: '邮箱', dataIndex: 'email', key: 'email' },
|
|
||||||
{ title: '状态', dataIndex: 'is_active', key: 'is_active', render: (active) => React.createElement(Tag, { color: active ? 'green' : 'default' }, active ? '正常' : '禁用') },
|
|
||||||
{ title: '创建时间', dataIndex: 'created_at', key: 'created_at', render: (val) => dayjs(val).format('YYYY-MM-DD') },
|
|
||||||
{
|
|
||||||
title: '操作',
|
|
||||||
key: 'action',
|
|
||||||
render: () => React.createElement(Space, null,
|
|
||||||
React.createElement(Button, { type: 'link', size: 'small', icon: React.createElement(EditOutlined) }, '编辑'),
|
|
||||||
React.createElement(Button, { type: 'link', size: 'small', icon: React.createElement(SettingOutlined) }, '重置密码'),
|
|
||||||
React.createElement(Button, { type: 'link', size: 'small', danger: true, icon: React.createElement(DeleteOutlined) }, '删除')
|
|
||||||
)
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const projectData = [
|
|
||||||
{ key: 1, project_no: 'PRJ2026001', contract_no: 'CT2026001', name: '某公司官网开发', budget: 50000, payment_amount: 25000, status: '进行中', department: '市场部', created_by_name: '张三', created_at: '2026-01-24' },
|
|
||||||
{ key: 2, project_no: 'PRJ2026002', contract_no: 'CT2026002', name: '电商平台开发', budget: 100000, payment_amount: 50000, status: '新建', department: '市场部', created_by_name: '李四', created_at: '2026-01-23' },
|
|
||||||
{ key: 3, project_no: 'PRJ2026003', contract_no: 'CT2026003', name: '移动APP开发', budget: 150000, payment_amount: 150000, status: '已完成', department: '技术部', created_by_name: '王五', created_at: '2026-01-20' },
|
|
||||||
{ key: 4, project_no: 'PRJ2026004', contract_no: 'CT2026004', name: '数据分析系统', budget: 80000, payment_amount: 30000, status: '进行中', department: '市场部', created_by_name: '张三', created_at: '2026-01-18' },
|
|
||||||
{ key: 5, project_no: 'PRJ2026005', contract_no: 'CT2026005', name: '企业OA系统', budget: 200000, payment_amount: 0, status: '已暂停', department: '技术部', created_by_name: '赵六', created_at: '2026-01-15' },
|
|
||||||
];
|
|
||||||
|
|
||||||
const userData = [
|
|
||||||
{ key: 1, username: 'admin', real_name: '管理员', department: '管理部', role: 'admin', email: 'admin@example.com', is_active: true, created_at: '2026-01-10' },
|
|
||||||
{ key: 2, username: 'zhangsan', real_name: '张三', department: '市场部', role: 'market', email: 'zhangsan@example.com', is_active: true, created_at: '2026-01-15' },
|
|
||||||
{ key: 3, username: 'lisi', real_name: '李四', department: '市场部', role: 'market', email: 'lisi@example.com', is_active: true, created_at: '2026-01-16' },
|
|
||||||
{ key: 4, username: 'wangwu', real_name: '王五', department: '技术部', role: 'other', email: 'wangwu@example.com', is_active: true, created_at: '2026-01-17' },
|
|
||||||
{ key: 5, username: 'zhaoliu', real_name: '赵六', department: '技术部', role: 'other', email: 'zhaoliu@example.com', is_active: false, created_at: '2026-01-18' },
|
|
||||||
];
|
|
||||||
|
|
||||||
function App() {
|
|
||||||
const [currentView, setCurrentView] = useState('dashboard');
|
|
||||||
const [selectedMenu, setSelectedMenu] = useState('dashboard');
|
|
||||||
const [userModalVisible, setUserModalVisible] = useState(false);
|
|
||||||
const [projectModalVisible, setProjectModalVisible] = useState(false);
|
|
||||||
|
|
||||||
const handleMenuClick = ({ key }) => {
|
|
||||||
setSelectedMenu(key);
|
|
||||||
setCurrentView(key);
|
|
||||||
};
|
|
||||||
|
|
||||||
const Dashboard = () => React.createElement('div', null,
|
|
||||||
React.createElement('div', { className: 'dashboard-cards' },
|
|
||||||
React.createElement(Card, null,
|
|
||||||
React.createElement(Statistic, { title: '总项目数', value: 15, prefix: React.createElement(ProjectOutlined) })
|
|
||||||
),
|
|
||||||
React.createElement(Card, null,
|
|
||||||
React.createElement(Statistic, { title: '进行中', value: 8, valueStyle: { color: '#3f8600' }, prefix: React.createElement(FileTextOutlined) })
|
|
||||||
),
|
|
||||||
React.createElement(Card, null,
|
|
||||||
React.createElement(Statistic, { title: '已完成', value: 5, prefix: React.createElement(FileTextOutlined) })
|
|
||||||
),
|
|
||||||
React.createElement(Card, null,
|
|
||||||
React.createElement(Statistic, { title: '本月预算', value: 500000, prefix: '¥' })
|
|
||||||
)
|
|
||||||
),
|
|
||||||
React.createElement(Card, { title: '最近项目' },
|
|
||||||
React.createElement(Table, {
|
|
||||||
columns: projectColumns,
|
|
||||||
dataSource: projectData.slice(0, 3),
|
|
||||||
pagination: false
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const ProjectList = () => React.createElement('div', null,
|
|
||||||
React.createElement('div', { style: { marginBottom: 16, display: 'flex', justifyContent: 'space-between' } },
|
|
||||||
React.createElement(Space, null,
|
|
||||||
React.createElement(Input, { placeholder: '搜索项目...', style: { width: 200 } }),
|
|
||||||
React.createElement(Select, { placeholder: '状态', style: { width: 120 } },
|
|
||||||
React.createElement(Option, { value: '新建' }, '新建'),
|
|
||||||
React.createElement(Option, { value: '进行中' }, '进行中'),
|
|
||||||
React.createElement(Option, { value: '已完成' }, '已完成')
|
|
||||||
),
|
|
||||||
React.createElement(Select, { placeholder: '部门', style: { width: 120 } },
|
|
||||||
React.createElement(Option, { value: '市场部' }, '市场部'),
|
|
||||||
React.createElement(Option, { value: '技术部' }, '技术部')
|
|
||||||
)
|
|
||||||
),
|
|
||||||
React.createElement(Button, { type: 'primary', icon: React.createElement(PlusOutlined) }, '新建项目')
|
|
||||||
),
|
|
||||||
React.createElement(Card, null,
|
|
||||||
React.createElement(Table, {
|
|
||||||
columns: projectColumns,
|
|
||||||
dataSource: projectData,
|
|
||||||
pagination: { pageSize: 10 }
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const UserList = () => React.createElement('div', null,
|
|
||||||
React.createElement('div', { style: { marginBottom: 16, display: 'flex', justifyContent: 'space-between' } },
|
|
||||||
React.createElement(Space, null,
|
|
||||||
React.createElement(Input, { placeholder: '搜索用户...', style: { width: 200 } }),
|
|
||||||
React.createElement(Select, { placeholder: '角色', style: { width: 120 } },
|
|
||||||
React.createElement(Option, { value: 'admin' }, '管理员'),
|
|
||||||
React.createElement(Option, { value: 'market' }, '市场部'),
|
|
||||||
React.createElement(Option, { value: 'other' }, '其他部门')
|
|
||||||
)
|
|
||||||
),
|
|
||||||
React.createElement(Button, { type: 'primary', icon: React.createElement(PlusOutlined) }, '新建用户')
|
|
||||||
),
|
|
||||||
React.createElement(Card, null,
|
|
||||||
React.createElement(Table, {
|
|
||||||
columns: userColumns,
|
|
||||||
dataSource: userData,
|
|
||||||
pagination: { pageSize: 10 }
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const content = {
|
|
||||||
dashboard: Dashboard,
|
|
||||||
projects: ProjectList,
|
|
||||||
users: UserList
|
|
||||||
}[currentView] || Dashboard;
|
|
||||||
|
|
||||||
return React.createElement(Layout, null,
|
|
||||||
React.createElement(Header, null,
|
|
||||||
React.createElement('div', { className: 'logo' },
|
|
||||||
React.createElement(ProjectOutlined),
|
|
||||||
' 项目信息管理系统'
|
|
||||||
),
|
|
||||||
React.createElement('div', { className: 'user-info' },
|
|
||||||
React.createElement(Avatar, { icon: React.createElement(UserOutlined) }),
|
|
||||||
React.createElement('span', { style: { color: 'white' } }, '管理员'),
|
|
||||||
React.createElement(Button, { type: 'text', icon: React.createElement(LogoutOutlined), style: { color: 'white' } }, '退出')
|
|
||||||
)
|
|
||||||
),
|
|
||||||
React.createElement(Layout, null,
|
|
||||||
React.createElement(Sider, { width: 256, style: { background: '#fff' } },
|
|
||||||
React.createElement(Menu, {
|
|
||||||
mode: 'inline',
|
|
||||||
selectedKeys: [selectedMenu],
|
|
||||||
items: menuItems,
|
|
||||||
onClick: handleMenuClick
|
|
||||||
})
|
|
||||||
),
|
|
||||||
React.createElement(Content, { style: { background: '#fff' } }, content())
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
|
||||||
root.render(React.createElement(App));
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
# 前端开发目录
|
||||||
|
|
||||||
|
## 目录说明
|
||||||
|
|
||||||
|
### src/
|
||||||
|
源代码目录,包含所有前端UI代码。
|
||||||
|
|
||||||
|
#### components/
|
||||||
|
可复用组件,如按钮、表单、卡片等。
|
||||||
|
|
||||||
|
#### pages/
|
||||||
|
页面组件,如登录页、首页、设置页等。
|
||||||
|
|
||||||
|
#### hooks/
|
||||||
|
自定义React Hooks,封装可复用的状态逻辑。
|
||||||
|
|
||||||
|
#### services/
|
||||||
|
API服务,封装与后端的HTTP请求。
|
||||||
|
|
||||||
|
#### utils/
|
||||||
|
工具函数,提供通用功能。
|
||||||
|
|
||||||
|
#### styles/
|
||||||
|
样式文件,包含全局样式和主题。
|
||||||
|
|
||||||
|
#### types/
|
||||||
|
TypeScript类型定义。
|
||||||
|
|
||||||
|
### tests/
|
||||||
|
测试目录,包含组件测试和集成测试。
|
||||||
|
|
||||||
|
### docs/
|
||||||
|
文档目录,包含组件文档和开发文档。
|
||||||
|
|
||||||
|
## 工作规范
|
||||||
|
|
||||||
|
详见 [WORKSTANDARDS.md](WORKSTANDARDS.md)
|
||||||
|
|
||||||
|
## UI设计规范
|
||||||
|
|
||||||
|
详见 [../docs/ui-design-spec.md](../docs/ui-design-spec.md)
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
# 前端程序员工作规范
|
||||||
|
|
||||||
|
## 工作目录
|
||||||
|
- **主目录**: `frontend/`
|
||||||
|
- **源代码目录**: `frontend/src/`
|
||||||
|
- **组件目录**: `frontend/src/components/`
|
||||||
|
- **页面目录**: `frontend/src/pages/`
|
||||||
|
- **样式目录**: `frontend/src/styles/`
|
||||||
|
- **测试目录**: `frontend/tests/`
|
||||||
|
- **文档目录**: `frontend/docs/`
|
||||||
|
|
||||||
|
## 开发规范
|
||||||
|
|
||||||
|
### 代码结构
|
||||||
|
```
|
||||||
|
frontend/
|
||||||
|
├── src/ # 源代码
|
||||||
|
│ ├── components/ # 可复用组件
|
||||||
|
│ ├── pages/ # 页面组件
|
||||||
|
│ ├── hooks/ # 自定义Hooks
|
||||||
|
│ ├── services/ # API服务
|
||||||
|
│ ├── utils/ # 工具函数
|
||||||
|
│ ├── styles/ # 样式文件
|
||||||
|
│ └── types/ # TypeScript类型定义
|
||||||
|
├── tests/ # 组件测试
|
||||||
|
├── docs/ # 组件文档和开发文档
|
||||||
|
└── package.json # 依赖管理
|
||||||
|
```
|
||||||
|
|
||||||
|
### 开发流程
|
||||||
|
1. 在 `frontend/src/` 中编写UI组件和页面
|
||||||
|
2. 在 `frontend/tests/` 中编写组件测试
|
||||||
|
3. 在 `frontend/docs/` 中编写组件文档
|
||||||
|
4. 开发前需在 `docs/ui-design-spec.md` 中查看UI设计规范
|
||||||
|
|
||||||
|
### 代码提交规范
|
||||||
|
- 提交信息格式: `[frontend] <类型>: <描述>`
|
||||||
|
- 类型: feat, fix, style, refactor, test, chore
|
||||||
|
- 示例: `[frontend] feat: 添加项目列表组件`
|
||||||
|
|
||||||
|
### 禁止事项
|
||||||
|
- ❌ 不得在 `backend/` 或 `testing/` 目录中工作
|
||||||
|
- ❌ 不得修改后端API(需协调后端程序员)
|
||||||
|
- ❌ 不得提交未经过测试的代码
|
||||||
|
|
||||||
|
## UI组件要求
|
||||||
|
- 所有组件必须在 `frontend/docs/components.md` 中文档化
|
||||||
|
- 文档包含: 组件名称、Props、使用示例、截图
|
||||||
|
- 遵循设计规范 `docs/ui-design-spec.md`
|
||||||
|
|
||||||
|
## 测试要求
|
||||||
|
- 关键组件必须有单元测试
|
||||||
|
- 测试文件命名: `<组件名>.test.tsx` 或 `<组件名>.spec.tsx`
|
||||||
|
- 使用Jest或Vitest测试框架
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
- 框架: React/Vue/Angular
|
||||||
|
- 状态管理: Redux/Vuex/Zustand
|
||||||
|
- 样式: Tailwind CSS/CSS Modules
|
||||||
|
- 构建工具: Vite/Webpack
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# 测试工作目录
|
||||||
|
|
||||||
|
## 目录说明
|
||||||
|
|
||||||
|
### testcases/
|
||||||
|
测试用例目录。
|
||||||
|
|
||||||
|
#### api/
|
||||||
|
API测试用例,测试后端接口功能。
|
||||||
|
|
||||||
|
#### ui/
|
||||||
|
UI测试用例,测试前端用户界面。
|
||||||
|
|
||||||
|
#### integration/
|
||||||
|
集成测试用例,测试系统整体功能。
|
||||||
|
|
||||||
|
### reports/
|
||||||
|
测试报告目录,存储每次测试的结果报告。
|
||||||
|
|
||||||
|
### data/
|
||||||
|
测试数据目录,存储测试用的数据。
|
||||||
|
|
||||||
|
### scripts/
|
||||||
|
自动化测试脚本目录,存储自动化测试代码。
|
||||||
|
|
||||||
|
### docs/
|
||||||
|
测试文档目录,包含测试计划、测试策略等。
|
||||||
|
|
||||||
|
## 工作规范
|
||||||
|
|
||||||
|
详见 [WORKSTANDARDS.md](WORKSTANDARDS.md)
|
||||||
|
|
||||||
|
## 测试流程
|
||||||
|
|
||||||
|
1. 编写测试计划
|
||||||
|
2. 编写测试用例
|
||||||
|
3. 执行测试
|
||||||
|
4. 记录Bug
|
||||||
|
5. 生成测试报告
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
# 测试工程师工作规范
|
||||||
|
|
||||||
|
## 工作目录
|
||||||
|
- **主目录**: `testing/`
|
||||||
|
- **测试用例目录**: `testing/testcases/`
|
||||||
|
- **测试报告目录**: `testing/reports/`
|
||||||
|
- **测试数据目录**: `testing/data/`
|
||||||
|
- **测试脚本目录**: `testing/scripts/`
|
||||||
|
- **文档目录**: `testing/docs/`
|
||||||
|
|
||||||
|
## 工作规范
|
||||||
|
|
||||||
|
### 目录结构
|
||||||
|
```
|
||||||
|
testing/
|
||||||
|
├── testcases/ # 测试用例
|
||||||
|
│ ├── api/ # API测试用例
|
||||||
|
│ ├── ui/ # UI测试用例
|
||||||
|
│ └── integration/ # 集成测试用例
|
||||||
|
├── reports/ # 测试报告
|
||||||
|
├── data/ # 测试数据
|
||||||
|
├── scripts/ # 自动化测试脚本
|
||||||
|
└── docs/ # 测试计划和文档
|
||||||
|
```
|
||||||
|
|
||||||
|
### 测试流程
|
||||||
|
1. 在 `testing/docs/` 中编写测试计划
|
||||||
|
2. 在 `testing/testcases/` 中编写测试用例
|
||||||
|
3. 在 `testing/scripts/` 中编写自动化测试脚本
|
||||||
|
4. 在 `testing/reports/` 中记录测试结果
|
||||||
|
|
||||||
|
### 代码提交规范
|
||||||
|
- 提交信息格式: `[testing] <类型>: <描述>`
|
||||||
|
- 类型: test, bug, docs, automation
|
||||||
|
- 示例: `[testing] test: 添加用户登录API测试用例`
|
||||||
|
|
||||||
|
### 禁止事项
|
||||||
|
- ❌ 不得在 `backend/` 或 `frontend/` 目录中修改代码
|
||||||
|
- ❌ 不得跳过测试步骤直接提交报告
|
||||||
|
- ❌ 不得遗漏Bug记录
|
||||||
|
|
||||||
|
## 测试要求
|
||||||
|
|
||||||
|
### 功能测试
|
||||||
|
- 遵循后端API文档 `backend/docs/api.md`
|
||||||
|
- 覆盖所有正常和异常场景
|
||||||
|
- 记录所有发现的Bug
|
||||||
|
|
||||||
|
### UI测试
|
||||||
|
- 遵循前端设计规范 `docs/ui-design-spec.md`
|
||||||
|
- 测试所有用户交互流程
|
||||||
|
- 记录UI问题和兼容性问题
|
||||||
|
|
||||||
|
### 自动化测试
|
||||||
|
- 编写自动化测试脚本
|
||||||
|
- 定期执行回归测试
|
||||||
|
- 维护测试数据
|
||||||
|
|
||||||
|
## Bug报告要求
|
||||||
|
- Bug报告必须包含: 标题、重现步骤、预期结果、实际结果、截图/日志
|
||||||
|
- Bug等级分类: 致命、严重、一般、轻微
|
||||||
|
- 提交给技术总监进行审核
|
||||||
|
|
||||||
|
## 测试报告
|
||||||
|
- 每次测试后必须生成报告
|
||||||
|
- 报告包含: 测试范围、测试结果、Bug列表、风险评估
|
||||||
|
- 存储在 `testing/reports/` 目录
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
- 自动化测试: Selenium/Playwright/Cypress
|
||||||
|
- API测试: Postman/Insomnia/REST Assured
|
||||||
|
- 性能测试: JMeter/Locust
|
||||||
|
- 测试管理: TestRail/Jira
|
||||||
-762
@@ -1,762 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>项目信息管理系统 - UI设计图</title>
|
|
||||||
<style>
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
||||||
background: #f0f2f5;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
.design-container {
|
|
||||||
max-width: 1400px;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
.design-title {
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 40px;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
.section-title {
|
|
||||||
font-size: 24px;
|
|
||||||
color: #1890ff;
|
|
||||||
border-bottom: 3px solid #1890ff;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
margin: 40px 0 20px 0;
|
|
||||||
}
|
|
||||||
.mockup {
|
|
||||||
background: white;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
||||||
margin-bottom: 30px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.mockup-header {
|
|
||||||
background: #001529;
|
|
||||||
color: white;
|
|
||||||
padding: 16px 24px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.logo {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
.logo-icon {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
background: #1890ff;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
.user-nav {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 15px;
|
|
||||||
}
|
|
||||||
.avatar {
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
background: #1890ff;
|
|
||||||
border-radius: 50%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.layout-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 256px 1fr;
|
|
||||||
min-height: 600px;
|
|
||||||
}
|
|
||||||
.sidebar {
|
|
||||||
background: #fff;
|
|
||||||
border-right: 1px solid #e8e8e8;
|
|
||||||
padding: 20px 0;
|
|
||||||
}
|
|
||||||
.menu-item {
|
|
||||||
padding: 12px 24px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
color: #666;
|
|
||||||
cursor: pointer;
|
|
||||||
border-left: 3px solid transparent;
|
|
||||||
}
|
|
||||||
.menu-item:hover {
|
|
||||||
background: #e6f7ff;
|
|
||||||
color: #1890ff;
|
|
||||||
}
|
|
||||||
.menu-item.active {
|
|
||||||
background: #e6f7ff;
|
|
||||||
color: #1890ff;
|
|
||||||
border-left-color: #1890ff;
|
|
||||||
}
|
|
||||||
.content {
|
|
||||||
padding: 24px;
|
|
||||||
background: #f0f2f5;
|
|
||||||
}
|
|
||||||
.card {
|
|
||||||
background: white;
|
|
||||||
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;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
.stat-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(4, 1fr);
|
|
||||||
gap: 20px;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
|
||||||
.stat-card {
|
|
||||||
background: white;
|
|
||||||
padding: 20px;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
|
|
||||||
}
|
|
||||||
.stat-label {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #666;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
th {
|
|
||||||
background: #fafafa;
|
|
||||||
padding: 12px 16px;
|
|
||||||
text-align: left;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #333;
|
|
||||||
border-bottom: 1px solid #e8e8e8;
|
|
||||||
}
|
|
||||||
td {
|
|
||||||
padding: 12px 16px;
|
|
||||||
border-bottom: 1px solid #e8e8e8;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
.tag {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 2px 8px;
|
|
||||||
border-radius: 2px;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
.tag-blue { background: #e6f7ff; color: #1890ff; }
|
|
||||||
.tag-green { background: #f6ffed; color: #52c41a; }
|
|
||||||
.tag-orange { background: #fff7e6; color: #fa8c16; }
|
|
||||||
.tag-red { background: #fff1f0; color: #f5222d; }
|
|
||||||
.tag-gray { background: #f5f5f5; color: #999; }
|
|
||||||
.btn {
|
|
||||||
padding: 6px 16px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.btn-primary {
|
|
||||||
background: #1890ff;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.btn-default {
|
|
||||||
background: white;
|
|
||||||
border: 1px solid #d9d9d9;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
.btn-link {
|
|
||||||
background: none;
|
|
||||||
color: #1890ff;
|
|
||||||
padding: 0 8px;
|
|
||||||
}
|
|
||||||
.btn-danger {
|
|
||||||
background: none;
|
|
||||||
color: #ff4d4f;
|
|
||||||
padding: 0 8px;
|
|
||||||
}
|
|
||||||
.toolbar {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
.toolbar-left {
|
|
||||||
display: flex;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
.input {
|
|
||||||
padding: 6px 12px;
|
|
||||||
border: 1px solid #d9d9d9;
|
|
||||||
border-radius: 4px;
|
|
||||||
width: 200px;
|
|
||||||
}
|
|
||||||
.select {
|
|
||||||
padding: 6px 12px;
|
|
||||||
border: 1px solid #d9d9d9;
|
|
||||||
border-radius: 4px;
|
|
||||||
width: 120px;
|
|
||||||
}
|
|
||||||
.form-group {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
.form-label {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
color: #333;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
.form-input {
|
|
||||||
width: 100%;
|
|
||||||
padding: 8px 12px;
|
|
||||||
border: 1px solid #d9d9d9;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
.form-row {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
gap: 20px;
|
|
||||||
}
|
|
||||||
.login-container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
min-height: 600px;
|
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
||||||
}
|
|
||||||
.login-box {
|
|
||||||
background: white;
|
|
||||||
padding: 40px;
|
|
||||||
border-radius: 8px;
|
|
||||||
width: 400px;
|
|
||||||
box-shadow: 0 8px 24px rgba(0,0,0,0.15);
|
|
||||||
}
|
|
||||||
.login-title {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 24px;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
.login-btn {
|
|
||||||
width: 100%;
|
|
||||||
padding: 12px;
|
|
||||||
background: #1890ff;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 16px;
|
|
||||||
margin-top: 20px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.design-note {
|
|
||||||
background: #fffbe6;
|
|
||||||
border-left: 4px solid #faad14;
|
|
||||||
padding: 16px;
|
|
||||||
margin: 20px 0;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="design-container">
|
|
||||||
<h1 class="design-title">📐 项目信息管理系统 - UI设计图</h1>
|
|
||||||
|
|
||||||
<!-- 登录页 -->
|
|
||||||
<h2 class="section-title">1. 登录页面</h2>
|
|
||||||
<div class="mockup">
|
|
||||||
<div class="login-container">
|
|
||||||
<div class="login-box">
|
|
||||||
<div class="login-title">项目信息管理系统</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="form-label">用户名</label>
|
|
||||||
<input type="text" class="form-input" placeholder="请输入用户名">
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="form-label">密码</label>
|
|
||||||
<input type="password" class="form-input" placeholder="请输入密码">
|
|
||||||
</div>
|
|
||||||
<button class="login-btn">登录</button>
|
|
||||||
<div style="text-align: center; margin-top: 20px; color: #999; font-size: 12px;">
|
|
||||||
© 2026 项目信息管理系统
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 仪表盘 -->
|
|
||||||
<h2 class="section-title">2. 仪表盘页面</h2>
|
|
||||||
<div class="mockup">
|
|
||||||
<div class="mockup-header">
|
|
||||||
<div class="logo">
|
|
||||||
<div class="logo-icon"></div>
|
|
||||||
<span>项目信息管理系统</span>
|
|
||||||
</div>
|
|
||||||
<div class="user-nav">
|
|
||||||
<span>管理员</span>
|
|
||||||
<div class="avatar">管</div>
|
|
||||||
<button class="btn btn-link" style="color: white;">退出</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layout-grid">
|
|
||||||
<div class="sidebar">
|
|
||||||
<div class="menu-item active">
|
|
||||||
<span>📊</span> 仪表盘
|
|
||||||
</div>
|
|
||||||
<div class="menu-item">
|
|
||||||
<span>📄</span> 项目管理
|
|
||||||
</div>
|
|
||||||
<div class="menu-item">
|
|
||||||
<span>👥</span> 用户管理
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="content">
|
|
||||||
<div class="stat-grid">
|
|
||||||
<div class="stat-card">
|
|
||||||
<div class="stat-icon">📊</div>
|
|
||||||
<div class="stat-label">总项目数</div>
|
|
||||||
<div class="stat-value">15</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-card">
|
|
||||||
<div class="stat-icon">🔄</div>
|
|
||||||
<div class="stat-label">进行中</div>
|
|
||||||
<div class="stat-value" style="color: #52c41a;">8</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-card">
|
|
||||||
<div class="stat-icon">✅</div>
|
|
||||||
<div class="stat-label">已完成</div>
|
|
||||||
<div class="stat-value" style="color: #1890ff;">5</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-card">
|
|
||||||
<div class="stat-icon">💰</div>
|
|
||||||
<div class="stat-label">本月预算</div>
|
|
||||||
<div class="stat-value">¥50万</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-title">最近项目</div>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>项目编号</th>
|
|
||||||
<th>项目名称</th>
|
|
||||||
<th>预算</th>
|
|
||||||
<th>状态</th>
|
|
||||||
<th>创建人</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>PRJ2026001</td>
|
|
||||||
<td>某公司官网开发</td>
|
|
||||||
<td>¥50,000</td>
|
|
||||||
<td><span class="tag tag-green">进行中</span></td>
|
|
||||||
<td>张三</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>PRJ2026002</td>
|
|
||||||
<td>电商平台开发</td>
|
|
||||||
<td>¥100,000</td>
|
|
||||||
<td><span class="tag tag-blue">新建</span></td>
|
|
||||||
<td>李四</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>PRJ2026003</td>
|
|
||||||
<td>移动APP开发</td>
|
|
||||||
<td>¥150,000</td>
|
|
||||||
<td><span class="tag tag-gray">已完成</span></td>
|
|
||||||
<td>王五</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 项目管理 -->
|
|
||||||
<h2 class="section-title">3. 项目管理页面</h2>
|
|
||||||
<div class="mockup">
|
|
||||||
<div class="mockup-header">
|
|
||||||
<div class="logo">
|
|
||||||
<div class="logo-icon"></div>
|
|
||||||
<span>项目信息管理系统</span>
|
|
||||||
</div>
|
|
||||||
<div class="user-nav">
|
|
||||||
<span>管理员</span>
|
|
||||||
<div class="avatar">管</div>
|
|
||||||
<button class="btn btn-link" style="color: white;">退出</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layout-grid">
|
|
||||||
<div class="sidebar">
|
|
||||||
<div class="menu-item">
|
|
||||||
<span>📊</span> 仪表盘
|
|
||||||
</div>
|
|
||||||
<div class="menu-item active">
|
|
||||||
<span>📄</span> 项目管理
|
|
||||||
</div>
|
|
||||||
<div class="menu-item">
|
|
||||||
<span>👥</span> 用户管理
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="content">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-title">项目管理</div>
|
|
||||||
<div class="toolbar">
|
|
||||||
<div class="toolbar-left">
|
|
||||||
<input type="text" class="input" placeholder="搜索项目...">
|
|
||||||
<select class="select">
|
|
||||||
<option>所有状态</option>
|
|
||||||
<option>新建</option>
|
|
||||||
<option>进行中</option>
|
|
||||||
<option>已完成</option>
|
|
||||||
</select>
|
|
||||||
<select class="select">
|
|
||||||
<option>所有部门</option>
|
|
||||||
<option>市场部</option>
|
|
||||||
<option>技术部</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<button class="btn btn-primary">+ 新建项目</button>
|
|
||||||
</div>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>项目编号</th>
|
|
||||||
<th>合同编号</th>
|
|
||||||
<th>项目名称</th>
|
|
||||||
<th>预算</th>
|
|
||||||
<th>已付款</th>
|
|
||||||
<th>状态</th>
|
|
||||||
<th>部门</th>
|
|
||||||
<th>创建人</th>
|
|
||||||
<th>操作</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>PRJ2026001</td>
|
|
||||||
<td>CT2026001</td>
|
|
||||||
<td>某公司官网开发</td>
|
|
||||||
<td>¥50,000</td>
|
|
||||||
<td>¥25,000</td>
|
|
||||||
<td><span class="tag tag-green">进行中</span></td>
|
|
||||||
<td>市场部</td>
|
|
||||||
<td>张三</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-link">查看</button>
|
|
||||||
<button class="btn btn-link">编辑</button>
|
|
||||||
<button class="btn btn-danger">删除</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>PRJ2026002</td>
|
|
||||||
<td>CT2026002</td>
|
|
||||||
<td>电商平台开发</td>
|
|
||||||
<td>¥100,000</td>
|
|
||||||
<td>¥50,000</td>
|
|
||||||
<td><span class="tag tag-blue">新建</span></td>
|
|
||||||
<td>市场部</td>
|
|
||||||
<td>李四</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-link">查看</button>
|
|
||||||
<button class="btn btn-link">编辑</button>
|
|
||||||
<button class="btn btn-danger">删除</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>PRJ2026003</td>
|
|
||||||
<td>CT2026003</td>
|
|
||||||
<td>移动APP开发</td>
|
|
||||||
<td>¥150,000</td>
|
|
||||||
<td>¥150,000</td>
|
|
||||||
<td><span class="tag tag-gray">已完成</span></td>
|
|
||||||
<td>技术部</td>
|
|
||||||
<td>王五</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-link">查看</button>
|
|
||||||
<button class="btn btn-link">编辑</button>
|
|
||||||
<button class="btn btn-danger">删除</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>PRJ2026004</td>
|
|
||||||
<td>CT2026004</td>
|
|
||||||
<td>数据分析系统</td>
|
|
||||||
<td>¥80,000</td>
|
|
||||||
<td>¥30,000</td>
|
|
||||||
<td><span class="tag tag-green">进行中</span></td>
|
|
||||||
<td>市场部</td>
|
|
||||||
<td>张三</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-link">查看</button>
|
|
||||||
<button class="btn btn-link">编辑</button>
|
|
||||||
<button class="btn btn-danger">删除</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>PRJ2026005</td>
|
|
||||||
<td>CT2026005</td>
|
|
||||||
<td>企业OA系统</td>
|
|
||||||
<td>¥200,000</td>
|
|
||||||
<td>¥0</td>
|
|
||||||
<td><span class="tag tag-orange">已暂停</span></td>
|
|
||||||
<td>技术部</td>
|
|
||||||
<td>赵六</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-link">查看</button>
|
|
||||||
<button class="btn btn-link">编辑</button>
|
|
||||||
<button class="btn btn-danger">删除</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 用户管理 -->
|
|
||||||
<h2 class="section-title">4. 用户管理页面(仅管理员可见)</h2>
|
|
||||||
<div class="mockup">
|
|
||||||
<div class="mockup-header">
|
|
||||||
<div class="logo">
|
|
||||||
<div class="logo-icon"></div>
|
|
||||||
<span>项目信息管理系统</span>
|
|
||||||
</div>
|
|
||||||
<div class="user-nav">
|
|
||||||
<span>管理员</span>
|
|
||||||
<div class="avatar">管</div>
|
|
||||||
<button class="btn btn-link" style="color: white;">退出</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="layout-grid">
|
|
||||||
<div class="sidebar">
|
|
||||||
<div class="menu-item">
|
|
||||||
<span>📊</span> 仪表盘
|
|
||||||
</div>
|
|
||||||
<div class="menu-item">
|
|
||||||
<span>📄</span> 项目管理
|
|
||||||
</div>
|
|
||||||
<div class="menu-item active">
|
|
||||||
<span>👥</span> 用户管理
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="content">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-title">用户管理</div>
|
|
||||||
<div class="toolbar">
|
|
||||||
<div class="toolbar-left">
|
|
||||||
<input type="text" class="input" placeholder="搜索用户...">
|
|
||||||
<select class="select">
|
|
||||||
<option>所有角色</option>
|
|
||||||
<option>管理员</option>
|
|
||||||
<option>市场部</option>
|
|
||||||
<option>其他部门</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<button class="btn btn-primary">+ 新建用户</button>
|
|
||||||
</div>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>用户名</th>
|
|
||||||
<th>真实姓名</th>
|
|
||||||
<th>部门</th>
|
|
||||||
<th>角色</th>
|
|
||||||
<th>邮箱</th>
|
|
||||||
<th>状态</th>
|
|
||||||
<th>创建时间</th>
|
|
||||||
<th>操作</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>admin</td>
|
|
||||||
<td>管理员</td>
|
|
||||||
<td>管理部</td>
|
|
||||||
<td><span class="tag tag-red">管理员</span></td>
|
|
||||||
<td>admin@example.com</td>
|
|
||||||
<td><span class="tag tag-green">正常</span></td>
|
|
||||||
<td>2026-01-10</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-link">编辑</button>
|
|
||||||
<button class="btn btn-link">重置密码</button>
|
|
||||||
<button class="btn btn-link">删除</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>zhangsan</td>
|
|
||||||
<td>张三</td>
|
|
||||||
<td>市场部</td>
|
|
||||||
<td><span class="tag tag-blue">市场部</span></td>
|
|
||||||
<td>zhangsan@example.com</td>
|
|
||||||
<td><span class="tag tag-green">正常</span></td>
|
|
||||||
<td>2026-01-15</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-link">编辑</button>
|
|
||||||
<button class="btn btn-link">重置密码</button>
|
|
||||||
<button class="btn btn-danger">删除</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>lisi</td>
|
|
||||||
<td>李四</td>
|
|
||||||
<td>市场部</td>
|
|
||||||
<td><span class="tag tag-blue">市场部</span></td>
|
|
||||||
<td>lisi@example.com</td>
|
|
||||||
<td><span class="tag tag-green">正常</span></td>
|
|
||||||
<td>2026-01-16</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-link">编辑</button>
|
|
||||||
<button class="btn btn-link">重置密码</button>
|
|
||||||
<button class="btn btn-danger">删除</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>wangwu</td>
|
|
||||||
<td>王五</td>
|
|
||||||
<td>技术部</td>
|
|
||||||
<td><span class="tag tag-blue">其他部门</span></td>
|
|
||||||
<td>wangwu@example.com</td>
|
|
||||||
<td><span class="tag tag-green">正常</span></td>
|
|
||||||
<td>2026-01-17</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-link">编辑</button>
|
|
||||||
<button class="btn btn-link">重置密码</button>
|
|
||||||
<button class="btn btn-danger">删除</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>zhaoliu</td>
|
|
||||||
<td>赵六</td>
|
|
||||||
<td>技术部</td>
|
|
||||||
<td><span class="tag tag-blue">其他部门</span></td>
|
|
||||||
<td>zhaoliu@example.com</td>
|
|
||||||
<td><span class="tag tag-gray">禁用</span></td>
|
|
||||||
<td>2026-01-18</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-link">编辑</button>
|
|
||||||
<button class="btn btn-link">重置密码</button>
|
|
||||||
<button class="btn btn-danger">删除</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 新建/编辑项目表单 -->
|
|
||||||
<h2 class="section-title">5. 新建/编辑项目表单</h2>
|
|
||||||
<div class="mockup">
|
|
||||||
<div class="content">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-title">新建项目</div>
|
|
||||||
<div class="form-row">
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="form-label">项目编号 *</label>
|
|
||||||
<input type="text" class="form-input" placeholder="如:PRJ2026001">
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="form-label">合同编号 *</label>
|
|
||||||
<input type="text" class="form-input" placeholder="如:CT2026001">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="form-label">项目名称 *</label>
|
|
||||||
<input type="text" class="form-input" placeholder="请输入项目名称">
|
|
||||||
</div>
|
|
||||||
<div class="form-row">
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="form-label">预算金额 *</label>
|
|
||||||
<input type="text" class="form-input" placeholder="请输入预算金额">
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="form-label">已付款金额</label>
|
|
||||||
<input type="text" class="form-input" placeholder="请输入已付款金额">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-row">
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="form-label">所属部门 *</label>
|
|
||||||
<select class="form-input">
|
|
||||||
<option>市场部</option>
|
|
||||||
<option>技术部</option>
|
|
||||||
<option>财务部</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="form-label">项目状态 *</label>
|
|
||||||
<select class="form-input">
|
|
||||||
<option>新建</option>
|
|
||||||
<option>进行中</option>
|
|
||||||
<option>已完成</option>
|
|
||||||
<option>已暂停</option>
|
|
||||||
<option>已取消</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-row">
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="form-label">开始日期</label>
|
|
||||||
<input type="date" class="form-input">
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="form-label">结束日期</label>
|
|
||||||
<input type="date" class="form-input">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="form-label">项目描述</label>
|
|
||||||
<textarea class="form-input" rows="4" placeholder="请输入项目描述"></textarea>
|
|
||||||
</div>
|
|
||||||
<div style="display: flex; gap: 12px; justify-content: flex-end;">
|
|
||||||
<button class="btn btn-default">取消</button>
|
|
||||||
<button class="btn btn-primary">保存</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="design-note">
|
|
||||||
<strong>💡 设计说明:</strong>
|
|
||||||
<ul style="margin-top: 10px; padding-left: 20px;">
|
|
||||||
<li>整体采用Ant Design风格,简洁专业</li>
|
|
||||||
<li>深色顶部导航栏(#001529),浅色侧边栏(白色),内容区使用浅灰背景(#f0f2f5)</li>
|
|
||||||
<li>状态标签使用不同颜色区分:新建-蓝色、进行中-绿色、已完成-灰色、已暂停-橙色、已取消-红色</li>
|
|
||||||
<li>按钮样式:主操作用蓝色(#1890ff),删除操作用红色</li>
|
|
||||||
<li>表格支持搜索和筛选功能</li>
|
|
||||||
<li>所有页面共用相同的布局结构(Header + Sidebar + Content)</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Reference in New Issue
Block a user