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