第一版提交,答题功能OK,题库管理待完善
This commit is contained in:
103
.trae/documents/问卷调查系统产品需求文档.md
Normal file
103
.trae/documents/问卷调查系统产品需求文档.md
Normal file
@@ -0,0 +1,103 @@
|
||||
## 1. 产品概述
|
||||
|
||||
问卷调查系统是一个功能完善的在线考试平台,支持多种题型、随机抽题、免注册答题等特性。系统主要解决企业、教育机构等组织的在线测评需求,提供便捷的题库管理和答题体验。
|
||||
|
||||
目标用户包括需要组织问卷调查的管理员和参与答题的普通用户,系统通过简化操作流程和提供友好的界面设计,提升在线测评的效率和用户体验。
|
||||
|
||||
## 2. 核心功能
|
||||
|
||||
### 2.1 用户角色
|
||||
|
||||
| 角色 | 注册方式 | 核心权限 |
|
||||
|------|----------|----------|
|
||||
| 普通用户 | 免注册,答题前填写基本信息 | 参与答题、查看答题结果 |
|
||||
| 管理员 | 系统预设账号登录 | 题库管理、配置抽题规则、查看统计数据 |
|
||||
|
||||
### 2.2 功能模块
|
||||
|
||||
问卷调查系统包含以下主要页面:
|
||||
|
||||
1. **用户答题页**:信息收集、题目展示、答题交互、结果提交
|
||||
2. **管理员登录页**:管理员身份验证
|
||||
3. **题库管理页**:Excel导入、题目编辑、题库查看
|
||||
4. **抽题配置页**:题型比例设置、总分配置、抽题规则管理
|
||||
5. **数据统计页**:答题记录查看、统计分析、数据导出
|
||||
|
||||
### 2.3 页面详情
|
||||
|
||||
| 页面名称 | 模块名称 | 功能描述 |
|
||||
|----------|----------|----------|
|
||||
| 用户答题页 | 信息收集模块 | 收集用户姓名(2-20字符中英文)和中国手机号(11位数字,1开头,第二位3-9),提供实时格式验证和错误提示 |
|
||||
| 用户答题页 | 题目展示模块 | 根据配置随机展示题目,支持单选、多选、判断、文字描述四种题型,题目内容清晰展示 |
|
||||
| 用户答题页 | 答题交互模块 | 单选题提供4个选项单选,多选题提供4-6个选项多选,判断题提供正确/错误选择,文字描述题提供文本输入框 |
|
||||
| 用户答题页 | 结果提交模块 | 收集所有答案,计算得分,保存答题记录,显示答题完成状态 |
|
||||
| 管理员登录页 | 身份验证模块 | 提供用户名密码登录界面,验证管理员身份,支持记住登录状态 |
|
||||
| 题库管理页 | Excel导入模块 | 支持上传Excel文件,验证文件格式,解析题目内容,批量导入题库,提供导入错误明细 |
|
||||
| 题库管理页 | 题目编辑模块 | 支持单题添加、编辑、删除,提供题型选择、内容编辑、选项设置、答案配置、分值设定 |
|
||||
| 题库管理页 | 题库查看模块 | 分页展示所有题目,支持按题型筛选,显示题目内容、题型、分值等关键信息 |
|
||||
| 抽题配置页 | 题型比例设置 | 设置单选、多选、判断、文字描述四种题型的比例,确保总和为100% |
|
||||
| 抽题配置页 | 总分配置模块 | 设置试卷总分,系统根据题型比例和各题分值自动计算各题型题目数量 |
|
||||
| 数据统计页 | 答题记录查看 | 展示所有用户答题记录,包括用户信息、答题时间、总得分等 |
|
||||
| 数据统计页 | 统计分析模块 | 按题型统计正确率,按时间统计答题趋势,支持数据筛选和排序 |
|
||||
| 数据统计页 | 数据导出模块 | 支持导出答题记录、统计报表,提供Excel格式导出 |
|
||||
|
||||
## 3. 核心流程
|
||||
|
||||
### 普通用户流程
|
||||
用户访问系统 → 填写个人信息(姓名+手机号)→ 系统验证信息格式 → 进入答题页面 → 系统根据配置随机抽题 → 用户逐题作答 → 提交答案 → 系统计算得分 → 保存答题记录 → 显示答题完成
|
||||
|
||||
### 管理员流程
|
||||
管理员登录 → 进入后台管理 → 题库管理(Excel导入/手动编辑)→ 抽题配置(设置题型比例和总分)→ 数据统计(查看答题记录和统计分析)
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[用户访问] --> B{是否管理员}
|
||||
B -->|是| C[管理员登录]
|
||||
B -->|否| D[填写个人信息]
|
||||
C --> E[后台管理首页]
|
||||
D --> F[信息验证]
|
||||
F --> G[开始答题]
|
||||
E --> H[题库管理]
|
||||
E --> I[抽题配置]
|
||||
E --> J[数据统计]
|
||||
H --> K[Excel导入/题目编辑]
|
||||
I --> L[设置题型比例和总分]
|
||||
G --> M[随机抽题展示]
|
||||
M --> N[答题完成]
|
||||
N --> O[计算得分并保存]
|
||||
```
|
||||
|
||||
## 4. 用户界面设计
|
||||
|
||||
### 4.1 设计风格
|
||||
- **主色调**:蓝色系(#1890ff)为主,体现专业和可信赖感
|
||||
- **辅助色**:灰色系(#f0f2f5)用于背景和分隔
|
||||
- **按钮样式**:圆角矩形设计,主要按钮使用主色调,次要按钮使用边框样式
|
||||
- **字体选择**:系统默认字体,标题16-18px,正文14px,小字12px
|
||||
- **布局风格**:卡片式布局,内容分区清晰,留白适当
|
||||
- **图标风格**:使用简洁的线性图标,保持视觉一致性
|
||||
|
||||
### 4.2 页面设计概述
|
||||
|
||||
| 页面名称 | 模块名称 | UI元素 |
|
||||
|----------|----------|--------|
|
||||
| 用户答题页 | 信息收集模块 | 居中卡片布局,白色背景,输入框带边框和圆角,错误提示使用红色文字,验证通过显示绿色勾选图标 |
|
||||
| 用户答题页 | 题目展示模块 | 题目编号和内容为黑色文字,选项使用单选/多选按钮,选中状态使用主色调高亮,题目间有明显分隔线 |
|
||||
| 用户答题页 | 答题交互模块 | 单选题使用圆形单选按钮,多选题使用方形复选框,判断题使用按钮式选择,文字描述题使用多行文本域 |
|
||||
| 管理员登录页 | 身份验证模块 | 简洁的登录表单,居中显示,包含用户名密码输入框和登录按钮,支持记住密码选项 |
|
||||
| 题库管理页 | Excel导入模块 | 拖拽上传区域,显示上传进度,错误信息使用红色警告框展示,成功导入显示绿色确认消息 |
|
||||
| 题库管理页 | 题目列表模块 | 表格形式展示,每行显示题目关键信息,操作按钮使用图标+文字,支持分页和筛选 |
|
||||
| 抽题配置页 | 比例设置模块 | 滑块或数字输入框设置百分比,实时显示当前比例总和,超出100%时显示警告 |
|
||||
| 数据统计页 | 图表展示模块 | 使用柱状图展示题型正确率,折线图展示答题趋势,表格展示详细数据,支持导出按钮 |
|
||||
|
||||
### 4.3 响应式设计
|
||||
- **桌面优先**:基础设计以桌面端为主,确保功能完整性
|
||||
- **移动端适配**:使用媒体查询实现响应式布局,移动端采用单列布局
|
||||
- **触摸优化**:按钮和交互元素在移动端增大点击区域,支持触摸滑动操作
|
||||
- **断点设置**:768px作为移动端和桌面端的分界点
|
||||
|
||||
### 4.4 数据可视化
|
||||
- **图表类型**:使用ECharts或Chart.js实现数据可视化
|
||||
- **颜色配置**:图表颜色与主色调保持一致,使用蓝色系渐变
|
||||
- **交互效果**:支持图表悬停显示详细数据,点击切换不同统计维度
|
||||
- **导出功能**:支持图表和数据表格的Excel导出,保持格式美观
|
||||
376
.trae/documents/问卷调查系统技术架构文档.md
Normal file
376
.trae/documents/问卷调查系统技术架构文档.md
Normal file
@@ -0,0 +1,376 @@
|
||||
## 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/ # 构建输出目录
|
||||
```
|
||||
Reference in New Issue
Block a user