Files
Web_BLV_OA_Exam_Prod/.trae/documents/问卷调查系统技术架构文档.md

376 lines
9.1 KiB
Markdown
Raw Normal View History

## 1. 架构设计
```mermaid
graph TD
A[用户浏览器] --> B[React前端应用]
B --> C[Express后端服务]
C --> D[SQLite数据库]
C --> E[文件存储服务]
subgraph "前端层"
B
end
subgraph "后端服务层"
C
E
end
subgraph "数据存储层"
D
end
```
## 2. 技术选型
- **前端框架**React@18 + TypeScript
- **初始化工具**vite-init
- **UI组件库**Ant Design@5
- **状态管理**React Context + useReducer
- **后端框架**Express@4 + TypeScript
- **数据库**SQLite3
- **文件处理**multer + xlsx
- **数据验证**Joi
- **开发工具**nodemon + concurrently
## 3. 路由定义
### 前端路由
| 路由 | 用途 |
|------|------|
| / | 用户答题首页 |
| /quiz | 答题页面 |
| /result/:id | 答题结果页面 |
| /admin/login | 管理员登录 |
| /admin/dashboard | 管理后台首页 |
| /admin/questions | 题库管理 |
| /admin/config | 抽题配置 |
| /admin/statistics | 数据统计 |
### 后端API路由
| 路由 | 方法 | 用途 |
|------|------|------|
| /api/users | POST | 创建用户 |
| /api/users/:id | GET | 获取用户信息 |
| /api/questions/import | POST | Excel导入题目 |
| /api/questions | GET | 获取题目列表 |
| /api/questions | POST | 添加单题 |
| /api/questions/:id | PUT | 更新题目 |
| /api/questions/:id | DELETE | 删除题目 |
| /api/quiz/generate | POST | 生成随机试卷 |
| /api/quiz/submit | POST | 提交答题 |
| /api/quiz/results/:userId | GET | 获取用户答题记录 |
| /api/admin/login | POST | 管理员登录 |
| /api/admin/statistics | GET | 获取统计数据 |
| /api/admin/config | GET/PUT | 获取/更新抽题配置 |
## 4. API接口定义
### 4.1 用户相关接口
#### 创建用户
```
POST /api/users
```
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|--------|------|------|------|
| name | string | 是 | 用户姓名2-20位中英文 |
| phone | string | 是 | 手机号11位数字1开头第二位3-9 |
响应参数:
| 参数名 | 类型 | 描述 |
|--------|------|------|
| id | string | 用户唯一标识 |
| name | string | 用户姓名 |
| phone | string | 手机号 |
| createdAt | string | 创建时间 |
请求示例:
```json
{
"name": "张三",
"phone": "13812345678"
}
```
#### 生成随机试卷
```
POST /api/quiz/generate
```
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|--------|------|------|------|
| userId | string | 是 | 用户ID |
响应参数:
| 参数名 | 类型 | 描述 |
|--------|------|------|
| questions | array | 题目数组 |
| totalScore | number | 总分 |
| timeLimit | number | 时间限制(分钟) |
### 4.2 题库管理接口
#### Excel导入题目
```
POST /api/questions/import
```
请求参数form-data
| 参数名 | 类型 | 必填 | 描述 |
|--------|------|------|------|
| file | file | 是 | Excel文件 |
响应参数:
| 参数名 | 类型 | 描述 |
|--------|------|------|
| success | boolean | 导入是否成功 |
| imported | number | 成功导入数量 |
| errors | array | 错误信息数组 |
#### 添加单题
```
POST /api/questions
```
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|--------|------|------|------|
| content | string | 是 | 题目内容 |
| type | string | 是 | 题型single/multiple/judgment/text |
| options | array | 条件 | 选项数组(单选/多选) |
| answer | string/array | 是 | 标准答案 |
| score | number | 是 | 分值 |
### 4.3 答题相关接口
#### 提交答题
```
POST /api/quiz/submit
```
请求参数:
| 参数名 | 类型 | 必填 | 描述 |
|--------|------|------|------|
| userId | string | 是 | 用户ID |
| answers | array | 是 | 答案数组 |
答案对象结构:
| 参数名 | 类型 | 描述 |
|--------|------|------|
| questionId | string | 题目ID |
| userAnswer | string/array | 用户答案 |
| score | number | 得分 |
响应参数:
| 参数名 | 类型 | 描述 |
|--------|------|------|
| totalScore | number | 总得分 |
| correctCount | number | 正确题数 |
| totalCount | number | 总题数 |
## 5. 服务端架构图
```mermaid
graph TD
A[客户端请求] --> B[路由层]
B --> C[中间件层]
C --> D[控制器层]
D --> E[服务层]
E --> F[数据访问层]
F --> G[(SQLite数据库)]
subgraph "Express服务端"
B
C
D
E
F
end
```
### 5.1 分层设计
- **路由层**定义API端点处理请求分发
- **中间件层**:身份验证、错误处理、请求日志
- **控制器层**处理HTTP请求调用服务层
- **服务层**:业务逻辑处理,数据验证
- **数据访问层**数据库操作SQL查询执行
## 6. 数据模型
### 6.1 数据库实体关系图
```mermaid
erDiagram
USER ||--o{ QUIZ_RECORD : takes
USER ||--o{ QUIZ_ANSWER : submits
QUESTION ||--o{ QUIZ_ANSWER : answered
QUESTION ||--o{ QUIZ_CONFIG : included
USER {
string id PK
string name
string phone
datetime created_at
}
QUESTION {
string id PK
string content
string type
string options
string answer
integer score
datetime created_at
}
QUIZ_RECORD {
string id PK
string user_id FK
integer total_score
integer correct_count
datetime created_at
}
QUIZ_ANSWER {
string id PK
string record_id FK
string question_id FK
string user_answer
integer score
boolean is_correct
}
QUIZ_CONFIG {
string id PK
string config_type
string config_value
datetime updated_at
}
```
### 6.2 数据定义语言
#### 用户表
```sql
CREATE TABLE users (
id TEXT PRIMARY KEY,
name TEXT NOT NULL CHECK(length(name) >= 2 AND length(name) <= 20),
phone TEXT UNIQUE NOT NULL CHECK(length(phone) = 11 AND phone LIKE '1%' AND substr(phone, 2, 1) BETWEEN '3' AND '9'),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_users_phone ON users(phone);
CREATE INDEX idx_users_created_at ON users(created_at);
```
#### 题目表
```sql
CREATE TABLE questions (
id TEXT PRIMARY KEY,
content TEXT NOT NULL,
type TEXT NOT NULL CHECK(type IN ('single', 'multiple', 'judgment', 'text')),
options TEXT, -- JSON格式存储选项
answer TEXT NOT NULL,
score INTEGER NOT NULL CHECK(score > 0),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_questions_type ON questions(type);
CREATE INDEX idx_questions_score ON questions(score);
```
#### 答题记录表
```sql
CREATE TABLE quiz_records (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
total_score INTEGER NOT NULL,
correct_count INTEGER NOT NULL,
total_count INTEGER NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
CREATE INDEX idx_quiz_records_user_id ON quiz_records(user_id);
CREATE INDEX idx_quiz_records_created_at ON quiz_records(created_at);
```
#### 答题答案表
```sql
CREATE TABLE quiz_answers (
id TEXT PRIMARY KEY,
record_id TEXT NOT NULL,
question_id TEXT NOT NULL,
user_answer TEXT NOT NULL,
score INTEGER NOT NULL,
is_correct BOOLEAN NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (record_id) REFERENCES quiz_records(id),
FOREIGN KEY (question_id) REFERENCES questions(id)
);
CREATE INDEX idx_quiz_answers_record_id ON quiz_answers(record_id);
CREATE INDEX idx_quiz_answers_question_id ON quiz_answers(question_id);
```
#### 系统配置表
```sql
CREATE TABLE system_configs (
id TEXT PRIMARY KEY,
config_type TEXT UNIQUE NOT NULL,
config_value TEXT NOT NULL,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 初始化抽题配置
INSERT INTO system_configs (id, config_type, config_value) VALUES
('1', 'quiz_config', '{"singleRatio":40,"multipleRatio":30,"judgmentRatio":20,"textRatio":10,"totalScore":100}');
```
### 6.3 索引优化
- 用户手机号索引:加速用户查询和防重复验证
- 题目类型索引:优化按类型筛选题目性能
- 答题记录时间索引:支持按时间范围查询统计
- 外键索引:确保关联查询性能
## 7. 部署配置
### 7.1 环境变量
```env
# 服务器配置
PORT=3000
NODE_ENV=development
# 数据库配置
DB_PATH=./data/survey.db
# 管理员配置
ADMIN_USERNAME=admin
ADMIN_PASSWORD=admin123
# 文件上传配置
UPLOAD_MAX_SIZE=10MB
UPLOAD_DIR=./uploads
```
### 7.2 目录结构
```
survey-system/
├── src/
│ ├── frontend/ # React前端代码
│ ├── backend/ # Express后端代码
│ │ ├── controllers/ # 控制器
│ │ ├── services/ # 服务层
│ │ ├── models/ # 数据模型
│ │ ├── middlewares/ # 中间件
│ │ └── utils/ # 工具函数
│ ├── shared/ # 共享类型定义
│ └── data/ # 数据库文件
├── uploads/ # 文件上传目录
├── public/ # 静态资源
└── dist/ # 构建输出目录
```