# 盘古用户平台 - 接口设计文档

---

| 文档信息 | 内容 |
|---------|------|
| **文档版本** | V1.0 |
| **项目名称** | 盘古用户平台（Pangu User Platform） |
| **编写团队** | pangu |
| **创建日期** | 2026-01-31 |
| **接口基础路径** | `/api` (管理端) `/app` (移动端) `/open` (开放API) |

---

## 1. 接口规范

### 1.1 请求规范

**请求头（Header）**

| Header | 必填 | 说明 |
|--------|:----:|------|
| Authorization | 是 | Bearer {token}，登录接口除外 |
| Content-Type | 是 | application/json |

**请求方法**

| 方法 | 用途 |
|-----|------|
| GET | 查询数据 |
| POST | 新增数据 |
| PUT | 修改数据 |
| DELETE | 删除数据 |

### 1.2 响应规范

**统一响应格式**

```json
{
    "code": 200,
    "msg": "操作成功",
    "data": {}
}
```

**分页响应格式**

```json
{
    "code": 200,
    "msg": "查询成功",
    "total": 100,
    "rows": []
}
```

### 1.3 错误码定义

| 错误码 | 说明 |
|-------|------|
| 200 | 成功 |
| 400 | 请求参数错误 |
| 401 | 未登录或Token过期 |
| 403 | 无权限访问 |
| 404 | 资源不存在 |
| 500 | 服务器内部错误 |

---

## 2. 认证接口

### 2.1 后台登录

**接口地址**：`POST /api/login`

**请求参数**

```json
{
    "username": "admin",
    "password": "admin123",
    "code": "1234",
    "uuid": "xxx-xxx-xxx"
}
```

| 参数 | 类型 | 必填 | 说明 |
|-----|------|:----:|------|
| username | string | 是 | 用户名 |
| password | string | 是 | 密码 |
| code | string | 是 | 验证码 |
| uuid | string | 是 | 验证码唯一标识 |

**响应结果**

```json
{
    "code": 200,
    "msg": "操作成功",
    "token": "eyJhbGciOiJIUzUxMiJ9..."
}
```

### 2.2 获取验证码

**接口地址**：`GET /api/captchaImage`

**响应结果**

```json
{
    "code": 200,
    "msg": "操作成功",
    "img": "data:image/png;base64,...",
    "uuid": "xxx-xxx-xxx"
}
```

### 2.3 会员登录（验证码）

**接口地址**：`POST /app/login/sms`

**请求参数**

```json
{
    "phone": "13812345678",
    "code": "123456"
}
```

| 参数 | 类型 | 必填 | 说明 |
|-----|------|:----:|------|
| phone | string | 是 | 手机号 |
| code | string | 是 | 短信验证码 |

**响应结果**

```json
{
    "code": 200,
    "msg": "登录成功",
    "data": {
        "token": "eyJhbGciOiJIUzUxMiJ9...",
        "memberId": 1,
        "memberCode": "JS123456789",
        "phone": "138****5678",
        "nickname": "用户昵称",
        "avatar": "https://...",
        "identityType": "1"
    }
}
```

### 2.4 发送短信验证码

**接口地址**：`POST /app/sms/send`

**请求参数**

```json
{
    "phone": "13812345678",
    "type": "login"
}
```

| 参数 | 类型 | 必填 | 说明 |
|-----|------|:----:|------|
| phone | string | 是 | 手机号 |
| type | string | 是 | 验证码类型：login/register |

**响应结果**

```json
{
    "code": 200,
    "msg": "验证码已发送"
}
```

### 2.5 会员登录（密码）

**接口地址**：`POST /app/login/password`

**请求参数**

```json
{
    "phone": "13812345678",
    "password": "123456"
}
```

### 2.6 会员登录（微信）

**接口地址**：`POST /app/login/wechat`

**请求参数**

```json
{
    "code": "wx_login_code"
}
```

| 参数 | 类型 | 必填 | 说明 |
|-----|------|:----:|------|
| code | string | 是 | 微信登录code |

---

## 3. 学校管理接口

### 3.1 查询学校树

**接口地址**：`GET /api/school/tree`

**请求参数**

| 参数 | 类型 | 必填 | 说明 |
|-----|------|:----:|------|
| regionId | long | 否 | 区域ID |

**响应结果**

```json
{
    "code": 200,
    "msg": "查询成功",
    "data": [
        {
            "schoolId": 1,
            "schoolCode": "SCH001",
            "schoolName": "武汉市第一中学",
            "regionPath": "湖北省-武汉市-武昌区",
            "children": [
                {
                    "id": 1,
                    "gradeId": 7,
                    "gradeName": "七年级",
                    "children": [
                        {
                            "id": 1,
                            "classId": 1,
                            "className": "1班"
                        }
                    ]
                }
            ]
        }
    ]
}
```

### 3.2 查询学校列表

**接口地址**：`GET /api/school/list`

**请求参数**

| 参数 | 类型 | 必填 | 说明 |
|-----|------|:----:|------|
| schoolName | string | 否 | 学校名称（模糊查询）|
| regionId | long | 否 | 区域ID |
| status | string | 否 | 状态 |
| pageNum | int | 是 | 页码 |
| pageSize | int | 是 | 每页条数 |

**响应结果**

```json
{
    "code": 200,
    "msg": "查询成功",
    "total": 100,
    "rows": [
        {
            "schoolId": 1,
            "schoolCode": "SCH001",
            "schoolName": "武汉市第一中学",
            "schoolType": "02",
            "regionId": 111,
            "regionPath": "湖北省-武汉市-武昌区",
            "status": "0",
            "createTime": "2026-01-01 10:00:00",
            "createBy": "admin"
        }
    ]
}
```

### 3.3 新增学校

**接口地址**：`POST /api/school`

**请求参数**

```json
{
    "schoolName": "武汉市第一中学",
    "schoolType": "02",
    "regionId": 111,
    "address": "武昌区xxx路xxx号",
    "contactPerson": "张老师",
    "contactPhone": "13812345678",
    "status": "0"
}
```

### 3.4 修改学校

**接口地址**：`PUT /api/school`

**请求参数**

```json
{
    "schoolId": 1,
    "schoolName": "武汉市第一中学",
    "schoolType": "02",
    "regionId": 111,
    "status": "0"
}
```

### 3.5 删除学校

**接口地址**：`DELETE /api/school/{schoolId}`

### 3.6 为学校挂载年级

**接口地址**：`POST /api/school/bindGrades`

**请求参数**

```json
{
    "schoolId": 1,
    "gradeIds": [7, 8, 9]
}
```

### 3.7 为年级挂载班级

**接口地址**：`POST /api/school/bindClasses`

**请求参数**

```json
{
    "schoolGradeId": 1,
    "classIds": [1, 2, 3]
}
```

---

## 4. 会员管理接口

### 4.1 查询会员列表

**接口地址**：`GET /api/member/list`

**请求参数**

| 参数 | 类型 | 必填 | 说明 |
|-----|------|:----:|------|
| phone | string | 否 | 手机号 |
| nickname | string | 否 | 昵称 |
| identityType | string | 否 | 身份类型（1家长 2教师）|
| status | string | 否 | 状态 |
| beginTime | string | 否 | 注册开始时间 |
| endTime | string | 否 | 注册结束时间 |
| pageNum | int | 是 | 页码 |
| pageSize | int | 是 | 每页条数 |

**响应结果**

```json
{
    "code": 200,
    "msg": "查询成功",
    "total": 100,
    "rows": [
        {
            "memberId": 1,
            "memberCode": "JS123456789",
            "phone": "138****5678",
            "nickname": "用户昵称",
            "gender": "1",
            "birthday": "1990-01-01",
            "identityType": "1",
            "registerSource": "1",
            "registerTime": "2026-01-01 10:00:00",
            "status": "0"
        }
    ]
}
```

### 4.2 获取会员详情

**接口地址**：`GET /api/member/{memberId}`

**响应结果**

```json
{
    "code": 200,
    "msg": "查询成功",
    "data": {
        "memberId": 1,
        "memberCode": "JS123456789",
        "phone": "13812345678",
        "nickname": "用户昵称",
        "gender": "1",
        "birthday": "1990-01-01",
        "identityType": "2",
        "regionId": 111,
        "schoolId": 1,
        "schoolGradeId": 1,
        "schoolClassId": 1,
        "students": [
            {
                "studentId": 1,
                "studentName": "张三",
                "studentNo": "2026001",
                "schoolName": "武汉市第一中学",
                "gradeName": "七年级",
                "className": "1班"
            }
        ]
    }
}
```

### 4.3 新增会员

**接口地址**：`POST /api/member`

**请求参数**

```json
{
    "phone": "13812345678",
    "nickname": "用户昵称",
    "gender": "1",
    "birthday": "1990-01-01",
    "identityType": "2",
    "regionId": 111,
    "schoolId": 1,
    "schoolGradeId": 1,
    "schoolClassId": 1,
    "status": "0"
}
```

### 4.4 修改会员

**接口地址**：`PUT /api/member`

### 4.5 删除会员

**接口地址**：`DELETE /api/member/{memberId}`

### 4.6 重置密码

**接口地址**：`PUT /api/member/resetPwd/{memberId}`

**响应结果**

```json
{
    "code": 200,
    "msg": "密码重置成功",
    "data": {
        "password": "abc123"
    }
}
```

### 4.7 绑定学生

**接口地址**：`POST /api/member/bindStudent`

**请求参数**

```json
{
    "memberId": 1,
    "studentId": 1
}
```

### 4.8 解绑学生

**接口地址**：`DELETE /api/member/unbindStudent/{memberId}/{studentId}`

---

## 5. 学生管理接口

### 5.1 查询学生列表

**接口地址**：`GET /api/student/list`

**请求参数**

| 参数 | 类型 | 必填 | 说明 |
|-----|------|:----:|------|
| studentName | string | 否 | 学生姓名 |
| studentNo | string | 否 | 学号 |
| gender | string | 否 | 性别 |
| schoolId | long | 否 | 学校ID |
| schoolGradeId | long | 否 | 学校年级ID |
| schoolClassId | long | 否 | 学校班级ID |
| subjectId | long | 否 | 学科ID |
| memberPhone | string | 否 | 归属用户手机号 |
| pageNum | int | 是 | 页码 |
| pageSize | int | 是 | 每页条数 |

**响应结果**

```json
{
    "code": 200,
    "msg": "查询成功",
    "total": 100,
    "rows": [
        {
            "studentId": 1,
            "studentName": "张三",
            "studentNo": "2026001",
            "gender": "1",
            "birthday": "2015-01",
            "regionPath": "湖北省-武汉市-武昌区",
            "schoolName": "武汉市第一中学",
            "gradeName": "七年级",
            "className": "1班",
            "subjectName": "语文",
            "memberNickname": "张三爸爸",
            "memberPhone": "138****5678"
        }
    ]
}
```

### 5.2 获取学生详情

**接口地址**：`GET /api/student/{studentId}`

### 5.3 新增学生

**接口地址**：`POST /api/student`

**请求参数**

```json
{
    "studentName": "张三",
    "studentNo": "2026001",
    "gender": "1",
    "birthday": "2015-01",
    "regionId": 111,
    "schoolId": 1,
    "schoolGradeId": 1,
    "schoolClassId": 1,
    "subjectId": 1,
    "memberId": 1
}
```

### 5.4 修改学生

**接口地址**：`PUT /api/student`

### 5.5 删除学生

**接口地址**：`DELETE /api/student/{studentId}`

### 5.6 批量导入学生

**接口地址**：`POST /api/student/import`

**请求方式**：`multipart/form-data`

**请求参数**

| 参数 | 类型 | 必填 | 说明 |
|-----|------|:----:|------|
| file | file | 是 | Excel文件 |

**响应结果**

```json
{
    "code": 200,
    "msg": "导入成功",
    "data": {
        "successCount": 98,
        "failCount": 2,
        "failList": [
            {"row": 5, "reason": "学号已存在"},
            {"row": 10, "reason": "学校信息不匹配"}
        ]
    }
}
```

### 5.7 下载导入模板

**接口地址**：`GET /api/student/template`

**响应**：Excel文件下载

---

## 6. 应用管理接口

### 6.1 查询应用列表

**接口地址**：`GET /api/application/list`

**请求参数**

| 参数 | 类型 | 必填 | 说明 |
|-----|------|:----:|------|
| appName | string | 否 | 应用名称 |
| appCode | string | 否 | 应用编码 |
| status | string | 否 | 状态 |
| pageNum | int | 是 | 页码 |
| pageSize | int | 是 | 每页条数 |

### 6.2 获取应用详情

**接口地址**：`GET /api/application/{appId}`

**响应结果**

```json
{
    "code": 200,
    "msg": "查询成功",
    "data": {
        "appId": 1,
        "appCode": "YY000001",
        "appName": "AI智慧平台",
        "appSecret": "********************************",
        "status": "0",
        "apis": [
            {
                "apiCode": "STUDENT_LIST",
                "apiName": "查询学生信息",
                "apiPath": "/open/student/list"
            }
        ]
    }
}
```

### 6.3 新增应用

**接口地址**：`POST /api/application`

**请求参数**

```json
{
    "appName": "AI智慧平台",
    "appDesc": "AI教育智慧平台",
    "contactPerson": "张经理",
    "contactPhone": "13812345678",
    "status": "0",
    "apiCodes": ["STUDENT_LIST", "SCHOOL_LIST", "GRADE_LIST"]
}
```

### 6.4 修改应用

**接口地址**：`PUT /api/application`

### 6.5 删除应用

**接口地址**：`DELETE /api/application/{appId}`

### 6.6 重置密钥

**接口地址**：`PUT /api/application/resetSecret/{appId}`

**响应结果**

```json
{
    "code": 200,
    "msg": "密钥重置成功",
    "data": {
        "appSecret": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
    }
}
```

### 6.7 获取API接口列表

**接口地址**：`GET /api/application/apiList`

**响应结果**

```json
{
    "code": 200,
    "msg": "查询成功",
    "data": [
        {
            "apiCode": "STUDENT_LIST",
            "apiName": "查询学生信息",
            "apiPath": "/open/student/list",
            "apiMethod": "GET"
        }
    ]
}
```

---

## 7. 基础数据接口

### 7.1 区域管理

#### 获取区域树

**接口地址**：`GET /api/region/tree`

#### 新增区域

**接口地址**：`POST /api/region`

#### 修改区域

**接口地址**：`PUT /api/region`

#### 删除区域

**接口地址**：`DELETE /api/region/{regionId}`

### 7.2 年级管理

#### 查询年级列表

**接口地址**：`GET /api/grade/list`

#### 新增年级

**接口地址**：`POST /api/grade`

#### 修改年级

**接口地址**：`PUT /api/grade`

#### 删除年级

**接口地址**：`DELETE /api/grade/{gradeId}`

### 7.3 班级管理

#### 查询班级列表

**接口地址**：`GET /api/class/list`

#### 新增班级

**接口地址**：`POST /api/class`

#### 修改班级

**接口地址**：`PUT /api/class`

#### 删除班级

**接口地址**：`DELETE /api/class/{classId}`

### 7.4 学科管理

#### 查询学科列表

**接口地址**：`GET /api/subject/list`

#### 新增学科

**接口地址**：`POST /api/subject`

#### 修改学科

**接口地址**：`PUT /api/subject`

#### 删除学科

**接口地址**：`DELETE /api/subject/{subjectId}`

---

## 8. 开放API接口

> 供第三方应用调用，需要AppId + AppSecret签名认证

### 8.1 签名规则

**请求头**

| Header | 必填 | 说明 |
|--------|:----:|------|
| X-App-Id | 是 | 应用编码 |
| X-Timestamp | 是 | 时间戳（毫秒）|
| X-Sign | 是 | 签名 |

**签名算法**

```
1. 将所有请求参数按参数名ASCII升序排序
2. 拼接成 key1=value1&key2=value2 格式
3. 末尾追加 &appSecret=xxx
4. 对整个字符串进行MD5加密（32位大写）
```

**示例**

```
请求参数：pageNum=1&pageSize=10&schoolId=1
拼接后：pageNum=1&pageSize=10&schoolId=1&appSecret=abc123
MD5签名：E5D7C6B5A4F3E2D1C0B9A8F7E6D5C4B3
```

### 8.2 查询学生列表

**接口地址**：`GET /open/student/list`

**请求参数**

| 参数 | 类型 | 必填 | 说明 |
|-----|------|:----:|------|
| schoolId | long | 否 | 学校ID |
| gradeId | long | 否 | 年级ID |
| classId | long | 否 | 班级ID |
| pageNum | int | 是 | 页码 |
| pageSize | int | 是 | 每页条数 |

### 8.3 查询学校列表

**接口地址**：`GET /open/school/list`

**请求参数**

| 参数 | 类型 | 必填 | 说明 |
|-----|------|:----:|------|
| regionId | long | 否 | 区域ID |
| pageNum | int | 是 | 页码 |
| pageSize | int | 是 | 每页条数 |

### 8.4 查询年级列表

**接口地址**：`GET /open/grade/list`

### 8.5 查询班级列表

**接口地址**：`GET /open/class/list`

### 8.6 查询区域树

**接口地址**：`GET /open/region/tree`

### 8.7 查询会员列表

**接口地址**：`GET /open/member/list`

**请求参数**

| 参数 | 类型 | 必填 | 说明 |
|-----|------|:----:|------|
| phone | string | 否 | 手机号 |
| schoolId | long | 否 | 学校ID |
| pageNum | int | 是 | 页码 |
| pageSize | int | 是 | 每页条数 |

---

## 9. 移动端接口

### 9.1 获取当前用户信息

**接口地址**：`GET /app/member/info`

**响应结果**

```json
{
    "code": 200,
    "msg": "查询成功",
    "data": {
        "memberId": 1,
        "memberCode": "JS123456789",
        "phone": "138****5678",
        "nickname": "用户昵称",
        "avatar": "https://...",
        "gender": "1",
        "identityType": "1",
        "students": [
            {
                "studentId": 1,
                "studentName": "张三",
                "schoolName": "武汉市第一中学",
                "gradeName": "七年级",
                "className": "1班"
            }
        ]
    }
}
```

### 9.2 修改个人信息

**接口地址**：`PUT /app/member/info`

**请求参数**

```json
{
    "nickname": "新昵称",
    "avatar": "https://...",
    "gender": "1"
}
```

### 9.3 修改密码

**接口地址**：`PUT /app/member/updatePwd`

**请求参数**

```json
{
    "oldPassword": "123456",
    "newPassword": "654321"
}
```

### 9.4 获取我的学生列表

**接口地址**：`GET /app/student/myList`

### 9.5 获取学校列表

**接口地址**：`GET /app/school/list`

### 9.6 获取区域树

**接口地址**：`GET /app/region/tree`

---

## 10. 业务规则说明

> 以下业务规则来源于墨刀原型批注，接口开发时需遵守

### 10.1 学校管理

| 规则编号 | 规则描述 |
|:------:|--------|
| SCH-01 | 学校编码自动生成，格式：SCH + 年份 + 4位序号 |
| SCH-02 | 新增学校时所属地区从列表页选择的区域层级树带入，也可手动调整 |
| SCH-03 | 所属地区/学校编码/学校名称为必填 |
| SCH-04 | 学校下新增年级为选择挂载模式，非新建年级，支持多选 |
| SCH-05 | 年级下新增班级为选择挂载模式，非新建班级，支持多选 |
| SCH-06 | 删除时检查是否有子级或被学生信息引用，有则不允许删除 |
| SCH-07 | 所有删除操作均为软删除 |

### 10.2 会员管理

| 规则编号 | 规则描述 |
|:------:|--------|
| MEM-01 | 会员编号自动生成，格式：JS + 时间戳 |
| MEM-02 | 昵称未填写时自动生成 |
| MEM-03 | 出生日期和性别为选填 |
| MEM-04 | 身份类型为"教师"时，必须填写区域/学校/年级/班级 |
| MEM-05 | 身份类型为"教师"时，只能绑定同校学生 |
| MEM-06 | 身份类型为"家长"时，不显示区域信息，可绑定任意学生 |
| MEM-07 | 重置密码后弹窗显示新密码，提供复制功能 |
| MEM-08 | 删除会员需popconfirm确认，如绑定学生则不允许删除 |
| MEM-09 | 禁用会员后无法登录任何端 |
| MEM-10 | 支持三种登录方式：手机号+验证码、手机号+密码、微信登录 |

### 10.3 学生管理

| 规则编号 | 规则描述 |
|:------:|--------|
| STU-01 | 学号不允许重复，可为空 |
| STU-02 | 出生日期和性别可为空 |
| STU-03 | 学校信息（区域/学校/年级/班级）为必填 |
| STU-04 | 学生必须归属于某个会员 |

**批量导入规则：**

| 规则编号 | 规则描述 |
|:------:|--------|
| IMP-01 | 模板字段：姓名(必填)、学号(必填)、用户手机号(必填)、区域(必填)、学校(必填)、年级(必填)、班级(必填)、性别(选填)、出生年月(选填) |
| IMP-02 | 导入时校验必填字段和区域/学校/年级/班级数据一致性 |
| IMP-03 | 用户手机号已存在则挂载到已有用户 |
| IMP-04 | 用户手机号不存在则自动创建家长用户，初始密码：123456 |

### 10.4 应用管理

| 规则编号 | 规则描述 |
|:------:|--------|
| APP-01 | 应用编码自动生成，格式：YY + 6位序号 |
| APP-02 | 应用密钥（AppSecret）自动生成，32位随机字符串 |
| APP-03 | 重置密钥后弹窗显示新密钥，提供复制功能 |
| APP-04 | 删除应用需popconfirm确认 |
| APP-05 | 禁用应用后无法调用任何API |

### 10.5 区域管理

| 规则编号 | 规则描述 |
|:------:|--------|
| REG-01 | 区域名称必填 |
| REG-02 | 区域编码自动生成 |
| REG-03 | 新增下级时默认所属父级为选择的区域 |
| REG-04 | 删除区域前检查是否有子级或被引用 |

---

*文档结束*
