第一版提交,答题功能OK,题库管理待完善

This commit is contained in:
2025-12-18 19:07:21 +08:00
parent e5600535be
commit ba252b2f56
93 changed files with 20431 additions and 1 deletions

View 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导出保持格式美观

View 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/ # 构建输出目录
```