# 移动端登录认证接口文档

> **模块名称**：business-mobile-gateway  
> **版本**：3.0.1  
> **更新日期**：2026-02-05  
> **基础路径**：`/mobile/member/auth`  
> **适用端**：APP、小程序、H5

---

## 一、接口规范

### 1.1 URL 格式规范

```
/mobile/member/auth/{操作}
```

**说明**：
- **固定前缀**：`/mobile`（移动端接口统一前缀）
- **模块名**：`member`（会员模块）
- **类名**：`auth`（认证相关）
- **操作**：接口操作，如 `loginByMobile`、`sendSmsCode` 等

### 1.2 请求规范

| 项目 | 规范 |
|------|------|
| **Content-Type** | `application/json;charset=UTF-8` |
| **Authorization** | `Bearer {token}`（登录后必传，登录接口不需要） |
| **X-Device-Id** | 设备唯一标识（建议传递） |
| **X-Platform** | 平台标识：`APP`、`MINI`、`H5` |
| **X-Version** | 客户端版本号 |

### 1.3 响应格式

```json
{
    "code": 200,
    "msg": "success",
    "data": {},
    "requestId": "链路追踪ID"
}
```

### 1.4 状态码说明

| 状态码 | 说明 |
|--------|------|
| 200 | 成功 |
| 400 | 参数错误 |
| 401 | 未登录/Token过期 |
| 403 | 无权限 |
| 404 | 资源不存在 |
| 500 | 服务器错误 |
| 1001 | 验证码错误 |
| 1002 | 验证码已过期 |
| 1003 | 账号已被禁用 |
| 1004 | 账号不存在 |
| 1005 | 密码错误 |

---

## 二、验证码接口

### 2.1 发送短信验证码

**接口地址**：`POST /mobile/member/auth/sendSmsCode`

**请求参数**：

```json
{
    "mobile": "13812345678",
    "scene": "LOGIN"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| mobile | String | 是 | 手机号（格式：1[3-9]开头的11位数字） |
| scene | String | 是 | 场景：`LOGIN`-登录、`REGISTER`-注册、`RESET_PWD`-重置密码、`BIND`-绑定手机 |

**响应示例**：

```json
{
    "code": 200,
    "msg": "验证码已发送",
    "data": {
        "expireSeconds": 300
    },
    "requestId": "abc123"
}
```

**说明**：
- 验证码有效期：5分钟（300秒）
- 同一手机号同一场景下，60秒内只能发送一次
- 验证码为6位数字

---

### 2.2 发送邮件验证码

**接口地址**：`POST /mobile/member/auth/sendEmailCode`

**请求参数**：

```json
{
    "email": "user@example.com",
    "scene": "LOGIN"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| email | String | 是 | 邮箱地址 |
| scene | String | 是 | 场景：`LOGIN`-登录、`REGISTER`-注册、`RESET_PWD`-重置密码、`BIND`-绑定邮箱 |

**响应示例**：

```json
{
    "code": 200,
    "msg": "验证码已发送",
    "data": {
        "expireSeconds": 300
    },
    "requestId": "abc123"
}
```

---

## 三、登录方式

### 3.1 手机验证码登录

**接口地址**：`POST /mobile/member/auth/loginByMobile`

**请求参数**：

```json
{
    "mobile": "13812345678",
    "smsCode": "123456",
    "inviteCode": "ABC123",
    "deviceId": "device_xxx",
    "platform": "APP"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| mobile | String | 是 | 手机号（格式：1[3-9]开头的11位数字） |
| smsCode | String | 是 | 短信验证码（6位数字） |
| inviteCode | String | 否 | 邀请码（新用户首次登录时可传） |
| deviceId | String | 否 | 设备ID |
| platform | String | 否 | 平台：`APP`、`MINI`、`H5` |

**响应示例**：

```json
{
    "code": 200,
    "msg": "登录成功",
    "data": {
        "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
        "tokenType": "Bearer",
        "expiresIn": 604800,
        "refreshToken": "refresh_token_xxx",
        "isNewUser": false,
        "needBindMobile": false,
        "memberId": "1234567890",
        "memberNo": "M202601240001",
        "nickname": "用户昵称",
        "avatar": "https://xxx.com/avatar.jpg",
        "mobile": "138****5678"
    },
    "requestId": "abc123"
}
```

**说明**：
- 如果手机号未注册，系统会自动创建账号并登录
- `isNewUser`：`true` 表示新用户，`false` 表示老用户
- `needBindMobile`：是否需要绑定手机号（第三方登录时可能为 `true`）

---

### 3.2 账号密码登录

**接口地址**：`POST /mobile/member/auth/loginByPassword`

**请求参数**：

```json
{
    "account": "13812345678",
    "password": "加密后的密码",
    "deviceId": "device_xxx",
    "platform": "APP"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| account | String | 是 | 账号（手机号/邮箱） |
| password | String | 是 | 密码（RSA加密后的密文，需先调用 `/mobile/member/auth/publicKey` 获取公钥） |
| deviceId | String | 否 | 设备ID |
| platform | String | 否 | 平台：`APP`、`MINI`、`H5` |

**响应示例**：同 3.1

**说明**：
- 密码必须使用 RSA 公钥加密后传输
- 获取公钥接口：`GET /mobile/member/auth/publicKey`
- 账号支持手机号或邮箱

---

### 3.3 账号密码注册

**接口地址**：`POST /mobile/member/auth/registerByPassword`

**请求参数**：

```json
{
    "account": "13812345678",
    "password": "加密后的密码",
    "inviteCode": "INVITE123",
    "deviceId": "device_xxx",
    "platform": "APP"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| account | String | 是 | 账号（手机号/邮箱） |
| password | String | 是 | 密码（RSA加密后的密文） |
| inviteCode | String | 否 | 邀请码 |
| deviceId | String | 否 | 设备ID |
| platform | String | 否 | 平台：`APP`、`MINI`、`H5` |

**响应示例**：

```json
{
    "code": 200,
    "msg": "注册成功",
    "data": {
        "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
        "tokenType": "Bearer",
        "expiresIn": 604800,
        "refreshToken": "refresh_token_xxx",
        "isNewUser": true,
        "needBindMobile": false,
        "memberId": "1234567890",
        "memberNo": "M202601240001",
        "nickname": "用户昵称",
        "avatar": "https://xxx.com/avatar.jpg",
        "mobile": "138****5678"
    },
    "requestId": "abc123"
}
```

---

### 3.4 微信小程序登录

**接口地址**：`POST /mobile/member/auth/loginByWechatMini`

**请求参数**：

```json
{
    "code": "wx_code_xxx",
    "encryptedData": "加密数据",
    "iv": "初始向量",
    "inviteCode": "ABC123"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| code | String | 是 | 微信登录code（通过 `wx.login()` 获取） |
| encryptedData | String | 否 | 加密用户数据（获取手机号时需要） |
| iv | String | 否 | 加密初始向量（获取手机号时需要） |
| inviteCode | String | 否 | 邀请码 |

**响应示例**：同 3.1

**说明**：
- 首次登录时，`isNewUser` 为 `true`
- 如果未绑定手机号，`needBindMobile` 为 `true`，需要调用绑定手机号接口

---

### 3.5 微信APP登录

**接口地址**：`POST /mobile/member/auth/loginByWechatApp`

**请求参数**：

```json
{
    "code": "wx_oauth_code",
    "inviteCode": "ABC123"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| code | String | 是 | 微信OAuth授权code |
| inviteCode | String | 否 | 邀请码 |

**响应示例**：同 3.1

---

### 3.6 微信公众号登录

**接口地址**：`POST /mobile/member/auth/loginByWechatMp`

**请求参数**：

```json
{
    "code": "wx_oauth_code",
    "inviteCode": "ABC123"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| code | String | 是 | 微信网页授权code |
| inviteCode | String | 否 | 邀请码 |

**响应示例**：同 3.1

---

### 3.7 支付宝登录

**接口地址**：`POST /mobile/member/auth/loginByAlipay`

**请求参数**：

```json
{
    "authCode": "alipay_auth_code",
    "inviteCode": "ABC123"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| authCode | String | 是 | 支付宝授权码 |
| inviteCode | String | 否 | 邀请码 |

**响应示例**：同 3.1

---

### 3.8 苹果登录

**接口地址**：`POST /mobile/member/auth/loginByApple`

**请求参数**：

```json
{
    "identityToken": "apple_identity_token",
    "authorizationCode": "apple_authorization_code",
    "fullName": {
        "familyName": "张",
        "givenName": "三"
    },
    "inviteCode": "ABC123"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| identityToken | String | 是 | Apple Identity Token |
| authorizationCode | String | 是 | Apple Authorization Code |
| fullName | Object | 否 | 用户姓名（首次授权时返回） |
| fullName.familyName | String | 否 | 姓 |
| fullName.givenName | String | 否 | 名 |
| inviteCode | String | 否 | 邀请码 |

**响应示例**：同 3.1

**说明**：
- 仅 iOS 平台支持
- `fullName` 仅在首次授权时返回，后续登录不会返回

---

### 3.9 华为账号登录

**接口地址**：`POST /mobile/member/auth/loginByHuawei`

**请求参数**：

```json
{
    "authCode": "huawei_auth_code",
    "openId": "huawei_openid",
    "accessToken": "huawei_access_token",
    "inviteCode": "ABC123"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| authCode | String | 是 | 华为授权码 |
| openId | String | 否 | 华为OpenID |
| accessToken | String | 否 | 华为AccessToken |
| inviteCode | String | 否 | 邀请码 |

**响应示例**：同 3.1

---

### 3.10 QQ登录

**接口地址**：`POST /mobile/member/auth/loginByQQ`

**请求参数**：

```json
{
    "authCode": "qq_auth_code",
    "openId": "qq_openid",
    "accessToken": "qq_access_token",
    "inviteCode": "ABC123"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| authCode | String | 是 | QQ授权码 |
| openId | String | 否 | QQ OpenID |
| accessToken | String | 否 | QQ AccessToken |
| inviteCode | String | 否 | 邀请码 |

**响应示例**：同 3.1

---

### 3.11 微博登录

**接口地址**：`POST /mobile/member/auth/loginByWeibo`

**请求参数**：

```json
{
    "authCode": "weibo_auth_code",
    "uid": "weibo_uid",
    "accessToken": "weibo_access_token",
    "inviteCode": "ABC123"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| authCode | String | 是 | 微博授权码 |
| uid | String | 否 | 微博UID（微博特有） |
| accessToken | String | 否 | 微博AccessToken |
| inviteCode | String | 否 | 邀请码 |

**响应示例**：同 3.1

---

### 3.12 抖音登录

**接口地址**：`POST /mobile/member/auth/loginByDouyin`

**请求参数**：

```json
{
    "authCode": "douyin_auth_code",
    "openId": "douyin_openid",
    "accessToken": "douyin_access_token",
    "inviteCode": "ABC123"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| authCode | String | 是 | 抖音授权码 |
| openId | String | 否 | 抖音OpenID |
| accessToken | String | 否 | 抖音AccessToken |
| inviteCode | String | 否 | 邀请码 |

**响应示例**：同 3.1

---

### 3.13 一键登录（本机号码）

**接口地址**：`POST /mobile/member/auth/loginByOneClick`

**请求参数**：

```json
{
    "token": "operator_token",
    "operator": "CMCC",
    "inviteCode": "ABC123"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| token | String | 是 | 运营商返回的token（移动/联通/电信） |
| operator | String | 是 | 运营商：`CMCC`-移动、`CUCC`-联通、`CTCC`-电信 |
| inviteCode | String | 否 | 邀请码 |

**响应示例**：同 3.1

**说明**：
- 一键登录需要集成运营商SDK（移动、联通、电信）
- 用户无需输入手机号和验证码，直接使用本机号码登录
- 如果本机号码未注册，系统会自动创建账号

---

### 3.14 二维码登录

二维码登录是一种便捷的登录方式，用户可以通过移动 App 扫描网页上的二维码完成登录。

#### 3.14.1 生成二维码登录Token

**接口地址**：`POST /mobile/member/auth/qrLogin/generate`

**请求参数**：无

**响应示例**：

```json
{
    "code": 200,
    "msg": "success",
    "data": {
        "token": "qr_1707123456789_abc123xyz",
        "expireTime": 300
    },
    "requestId": "abc123"
}
```

| 字段 | 类型 | 说明 |
|------|------|------|
| token | String | 二维码Token（用于生成二维码） |
| expireTime | Long | 二维码过期时间（秒），默认 10 分钟（600秒） |

**说明**：
- Token 格式：`qr_{timestamp}_{randomString}`
- Token 有效期：10分钟（600秒）
- 前端需要使用此 Token 生成二维码图片

---

#### 3.14.2 检查二维码登录状态

**接口地址**：`GET /mobile/member/auth/qrLogin/check?token={token}`

**请求参数**：

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| token | String | 是 | 二维码Token（URL参数） |

**响应示例**：

**状态：pending（等待扫码）**
```json
{
    "code": 200,
    "msg": "success",
    "data": {
        "status": "pending"
    },
    "requestId": "abc123"
}
```

**状态：scanned（已扫码，等待确认）**
```json
{
    "code": 200,
    "msg": "success",
    "data": {
        "status": "scanned"
    },
    "requestId": "abc123"
}
```

**状态：confirmed（已确认登录）**
```json
{
    "code": 200,
    "msg": "success",
    "data": {
        "status": "confirmed",
        "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
        "refreshToken": "refresh_token_xxx",
        "memberInfo": {
            "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
            "tokenType": "Bearer",
            "expiresIn": 604800,
            "refreshToken": "refresh_token_xxx",
            "isNewUser": false,
            "needBindMobile": false,
            "memberId": "1234567890",
            "memberNo": "M202601240001",
            "nickname": "用户昵称",
            "avatar": "https://xxx.com/avatar.jpg",
            "mobile": "138****5678"
        }
    },
    "requestId": "abc123"
}
```

**状态：expired（已过期）**
```json
{
    "code": 200,
    "msg": "success",
    "data": {
        "status": "expired"
    },
    "requestId": "abc123"
}
```

| 字段 | 类型 | 说明 |
|------|------|------|
| status | String | 状态：`pending`-等待扫码、`scanned`-已扫码、`confirmed`-已确认、`expired`-已过期 |
| accessToken | String | 登录Token（当status为confirmed时返回） |
| refreshToken | String | 刷新Token（当status为confirmed时返回） |
| memberInfo | Object | 会员信息（当status为confirmed时返回），结构同 LoginResultVO |

**说明**：
- 前端需要轮询调用此接口检查登录状态（建议每2秒轮询一次）
- 当状态为 `confirmed` 时，表示登录成功，可以获取 Token 和会员信息
- 当状态为 `expired` 时，需要重新生成二维码
- 二维码有效期：10分钟（600秒），过期后需要重新生成

---

#### 3.14.3 确认二维码登录

**接口地址**：`POST /mobile/member/auth/qrLogin/confirm`

**请求头**：需要传递 `Authorization: Bearer {token}`（移动端已登录的Token）

**请求参数**：

```json
{
    "token": "qr_1707123456789_abc123xyz"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| token | String | 是 | 二维码Token |

**响应示例**：

```json
{
    "code": 200,
    "msg": "登录成功",
    "data": null,
    "requestId": "abc123"
}
```

**说明**：
- 此接口由移动端 App 调用（扫码后确认登录）
- 移动端需要先登录（传递已登录的Token）
- 调用成功后，网页端轮询检查状态时会返回 `confirmed` 状态和登录信息

---

## 三、扫码登录流程说明

### 3.15 扫码登录完整流程

扫码登录是一种便捷的跨端登录方式，允许用户通过移动 App 扫描网页上的二维码完成登录。

#### 3.15.1 流程图

```
网页端（前端）                   后端API                    移动端（App）
    |                              |                            |
    |--1. 生成二维码Token--------->|                            |
    |<--返回Token和过期时间--------|                            |
    |                              |                            |
    |--2. 生成二维码图片（使用Token）|                            |
    |                              |                            |
    |--3. 轮询检查状态（每2秒）---->|                            |
    |<--返回status: pending--------|                            |
    |                              |                            |
    |                              |<--4. 用户扫码（解析Token）--|
    |                              |                            |
    |                              |<--5. 确认登录（带Token）----|
    |                              |--更新状态为scanned--------->|
    |                              |                            |
    |--6. 轮询检查状态------------->|                            |
    |<--返回status: scanned--------|                            |
    |                              |                            |
    |                              |<--7. 用户点击确认登录--------|
    |                              |--调用confirmQrLogin-------->|
    |                              |--更新状态为confirmed------->|
    |                              |                            |
    |--8. 轮询检查状态------------->|                            |
    |<--返回status: confirmed------|                            |
    |<--返回Token和会员信息--------|                            |
    |                              |                            |
    |--9. 保存Token，完成登录------|                            |
```

#### 3.15.2 详细步骤

**步骤1：网页端生成二维码**

1. 网页端调用 `POST /mobile/member/auth/qrLogin/generate` 生成二维码Token
2. 使用返回的 `token` 生成二维码图片
3. 二维码内容格式：`qrlogin://token={token}&url={当前页面URL}`
   - 示例：`qrlogin://token=qr_1707123456789_abc123xyz&url=https://example.com/login`

**步骤2：网页端轮询检查状态**

1. 网页端每2秒调用一次 `GET /mobile/member/auth/qrLogin/check?token={token}` 检查状态
2. 初始状态为 `pending`（等待扫码）
3. 如果超过10分钟未扫码或未确认，状态变为 `expired`，需要重新生成二维码

**步骤3：移动端扫码**

1. 用户打开移动 App，使用扫码功能扫描网页上的二维码
2. App 解析二维码内容，提取 `token` 参数
3. App 可以调用 `GET /mobile/member/auth/qrLogin/check?token={token}` 检查二维码状态
4. 如果状态为 `pending`，App 显示"确认登录"按钮

**步骤4：移动端确认登录**

1. 用户在 App 中点击"确认登录"按钮
2. App 调用 `POST /mobile/member/auth/qrLogin/confirm`，传递二维码Token
3. 注意：App 需要先登录（传递已登录的Token），才能调用确认接口
4. 后端更新二维码状态为 `scanned`，然后立即更新为 `confirmed`，并存储登录信息

**步骤5：网页端获取登录信息**

1. 网页端轮询检测到状态变为 `confirmed`
2. 从响应中获取 `accessToken`、`refreshToken` 和 `memberInfo`
3. 保存 Token 到本地存储（localStorage）
4. 跳转到首页，完成登录

#### 3.15.3 状态流转

```
pending（等待扫码）
    ↓
scanned（已扫码，等待确认）
    ↓
confirmed（已确认登录）
    ↓
expired（已过期，需要重新生成）
```

#### 3.15.4 注意事项

1. **二维码过期时间**：10分钟（600秒），过期后需要重新生成
2. **轮询频率**：建议每2秒轮询一次，避免过于频繁
3. **移动端登录要求**：移动端调用确认接口前，需要先登录（传递已登录的Token）
4. **安全性**：Token 具有唯一性和时效性，确保安全性
5. **错误处理**：
   - 如果二维码过期，前端应提示用户刷新二维码
   - 如果移动端未登录，应提示用户先登录 App
   - 如果确认失败，应提示用户重试

#### 3.15.5 前端实现示例

**生成二维码**
```javascript
// 1. 调用生成Token接口
const res = await generateQrLoginToken()
const token = res.data.token

// 2. 生成二维码图片
const qrContent = `qrlogin://token=${token}&url=${window.location.origin}`
const qrCodeUrl = await QRCode.toDataURL(qrContent)

// 3. 开始轮询检查状态
const timer = setInterval(async () => {
  const statusRes = await checkQrLoginStatus(token)
  const status = statusRes.data.status
  
  if (status === 'confirmed') {
    // 登录成功，保存Token
    localStorage.setItem('access_token', statusRes.data.accessToken)
    localStorage.setItem('memberInfo', JSON.stringify(statusRes.data.memberInfo))
    clearInterval(timer)
    // 跳转到首页
    router.push('/')
  } else if (status === 'expired') {
    // 二维码过期，提示刷新
    clearInterval(timer)
    alert('二维码已过期，请刷新')
  }
}, 2000) // 每2秒轮询一次
```

**移动端扫码确认**
```javascript
// 1. 解析二维码内容
const qrContent = 'qrlogin://token=qr_xxx&url=xxx'
const token = extractTokenFromQr(qrContent) // 提取token参数

// 2. 检查二维码状态
const statusRes = await checkQrLoginStatus(token)
if (statusRes.data.status === 'pending') {
  // 显示确认登录按钮
  showConfirmButton()
}

// 3. 用户点击确认后调用确认接口
async function confirmLogin() {
  await confirmQrLogin(token) // 需要传递已登录的Token
  // 确认成功，网页端会通过轮询获取登录信息
}
```

---

## 四、Token管理

### 4.1 刷新Token

**接口地址**：`POST /mobile/member/userCenter/refreshToken`

**请求头**：需要传递 `Authorization: Bearer {token}`

**请求参数**：

```json
{
    "refreshToken": "refresh_token_xxx"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| refreshToken | String | 是 | 刷新令牌（登录时返回的 refreshToken） |

**响应示例**：

```json
{
    "code": 200,
    "msg": "刷新成功",
    "data": {
        "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
        "tokenType": "Bearer",
        "expiresIn": 604800,
        "refreshToken": "new_refresh_token_xxx",
        "memberId": "1234567890",
        "memberNo": "M202601240001",
        "nickname": "用户昵称",
        "avatar": "https://xxx.com/avatar.jpg",
        "mobile": "138****5678"
    },
    "requestId": "abc123"
}
```

**说明**：
- Token 过期前可以调用此接口刷新
- 刷新后会返回新的 token 和 refreshToken

---

### 4.2 退出登录

**接口地址**：`POST /mobile/member/userCenter/logout`

**请求头**：需要传递 `Authorization: Bearer {token}`

**请求参数**：无

**响应示例**：

```json
{
    "code": 200,
    "msg": "退出成功",
    "data": null,
    "requestId": "abc123"
}
```

**说明**：
- 退出登录后，当前 token 立即失效
- 需要重新登录才能访问需要认证的接口

---

## 五、账号管理

### 5.1 绑定手机号

**接口地址**：`POST /mobile/member/auth/bindMobile`

**请求头**：需要传递 `Authorization: Bearer {token}`

**请求参数**：

```json
{
    "mobile": "13812345678",
    "smsCode": "123456"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| mobile | String | 是 | 手机号 |
| smsCode | String | 是 | 短信验证码（场景需为 `BIND`） |

**响应示例**：

```json
{
    "code": 200,
    "msg": "绑定成功",
    "data": {
        "mobile": "138****5678"
    },
    "requestId": "abc123"
}
```

**说明**：
- 绑定前需要先调用发送短信验证码接口（scene 为 `BIND`）
- 一个手机号只能绑定一个账号

---

### 5.2 修改密码

**接口地址**：`POST /mobile/member/userCenter/changePassword`

**请求头**：需要传递 `Authorization: Bearer {token}`

**请求参数**：

```json
{
    "oldPassword": "旧密码（RSA加密）",
    "newPassword": "新密码（RSA加密）"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| oldPassword | String | 是 | 旧密码（RSA加密后的密文） |
| newPassword | String | 是 | 新密码（RSA加密后的密文） |

**响应示例**：

```json
{
    "code": 200,
    "msg": "密码修改成功",
    "data": null,
    "requestId": "abc123"
}
```

---

### 5.3 重置密码（忘记密码）

**接口地址**：`POST /mobile/member/auth/resetPassword`

**请求参数**：

```json
{
    "account": "13812345678",
    "smsCode": "123456",
    "newPassword": "新密码（RSA加密）"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| account | String | 是 | 账号（手机号/邮箱） |
| smsCode | String | 是 | 验证码（场景需为 `RESET_PWD`） |
| newPassword | String | 是 | 新密码（RSA加密后的密文） |

**响应示例**：

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

**说明**：
- 重置前需要先调用发送验证码接口（scene 为 `RESET_PWD`）
- 如果账号是邮箱，则使用邮件验证码

---

### 5.4 注销账号

**接口地址**：`POST /mobile/member/userCenter/cancel`

**请求头**：需要传递 `Authorization: Bearer {token}`

**请求参数**：

```json
{
    "reason": "注销原因",
    "password": "密码（RSA加密）"
}
```

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| reason | String | 否 | 注销原因 |
| password | String | 是 | 密码（RSA加密后的密文，用于验证身份） |

**响应示例**：

```json
{
    "code": 200,
    "msg": "账号已注销",
    "data": null,
    "requestId": "abc123"
}
```

**说明**：
- 账号注销后，所有数据将被删除或匿名化处理
- 注销操作不可恢复，请谨慎操作

---

## 六、工具接口

### 6.1 获取加密公钥

**接口地址**：`GET /mobile/member/auth/publicKey`

**请求参数**：无

**响应示例**：

```json
{
    "code": 200,
    "msg": "success",
    "data": {
        "publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC..."
    },
    "requestId": "abc123"
}
```

**说明**：
- 用于获取 RSA 公钥，用于加密密码
- 密码传输前必须使用此公钥加密
- 公钥可能会定期更换，建议每次登录前获取

---

## 七、登录响应字段说明

### 7.1 LoginResultVO 字段说明

| 字段 | 类型 | 说明 |
|------|------|------|
| token | String | 访问令牌（用于后续接口认证） |
| tokenType | String | 令牌类型，固定为 `Bearer` |
| expiresIn | Long | 过期时间（秒），默认 7 天（604800秒） |
| refreshToken | String | 刷新令牌（用于刷新 token） |
| isNewUser | Boolean | 是否新用户：`true`-新用户，`false`-老用户 |
| needBindMobile | Boolean | 是否需要绑定手机号：`true`-需要绑定，`false`-不需要 |
| memberId | String | 会员ID |
| memberNo | String | 会员编号 |
| nickname | String | 昵称 |
| avatar | String | 头像URL |
| mobile | String | 手机号（脱敏显示，如：`138****5678`） |
| openid | String | OpenID（第三方登录时返回） |

---

## 八、接口地址速查表

| 接口 | 方法 | URL | 说明 |
|------|------|-----|------|
| **发送短信验证码** | POST | `/mobile/member/auth/sendSmsCode` | 发送短信验证码 |
| **发送邮件验证码** | POST | `/mobile/member/auth/sendEmailCode` | 发送邮件验证码 |
| **手机验证码登录** | POST | `/mobile/member/auth/loginByMobile` | 手机验证码登录 |
| **账号密码登录** | POST | `/mobile/member/auth/loginByPassword` | 账号密码登录 |
| **账号密码注册** | POST | `/mobile/member/auth/registerByPassword` | 账号密码注册 |
| **微信小程序登录** | POST | `/mobile/member/auth/loginByWechatMini` | 微信小程序登录 |
| **微信APP登录** | POST | `/mobile/member/auth/loginByWechatApp` | 微信APP登录 |
| **微信公众号登录** | POST | `/mobile/member/auth/loginByWechatMp` | 微信公众号登录 |
| **支付宝登录** | POST | `/mobile/member/auth/loginByAlipay` | 支付宝登录 |
| **苹果登录** | POST | `/mobile/member/auth/loginByApple` | 苹果登录（iOS） |
| **华为账号登录** | POST | `/mobile/member/auth/loginByHuawei` | 华为账号登录 |
| **QQ登录** | POST | `/mobile/member/auth/loginByQQ` | QQ登录 |
| **微博登录** | POST | `/mobile/member/auth/loginByWeibo` | 微博登录 |
| **抖音登录** | POST | `/mobile/member/auth/loginByDouyin` | 抖音登录 |
| **一键登录** | POST | `/mobile/member/auth/loginByOneClick` | 一键登录（本机号码） |
| **生成二维码Token** | POST | `/mobile/member/auth/qrLogin/generate` | 生成二维码登录Token |
| **检查二维码状态** | GET | `/mobile/member/auth/qrLogin/check?token={token}` | 检查二维码登录状态 |
| **确认二维码登录** | POST | `/mobile/member/auth/qrLogin/confirm` | 确认二维码登录（移动端调用） |
| **刷新Token** | POST | `/mobile/member/userCenter/refreshToken` | 刷新访问令牌 |
| **退出登录** | POST | `/mobile/member/userCenter/logout` | 退出登录 |
| **绑定手机号** | POST | `/mobile/member/auth/bindMobile` | 绑定手机号 |
| **修改密码** | POST | `/mobile/member/userCenter/changePassword` | 修改密码 |
| **重置密码** | POST | `/mobile/member/auth/resetPassword` | 重置密码（忘记密码） |
| **注销账号** | POST | `/mobile/member/userCenter/cancel` | 注销账号 |
| **获取公钥** | GET | `/mobile/member/auth/publicKey` | 获取RSA加密公钥 |

---

## 九、常见问题

### 9.1 密码加密流程

1. 调用 `GET /mobile/member/auth/publicKey` 获取 RSA 公钥
2. 使用公钥在客户端加密密码
3. 将加密后的密码传递给登录/注册接口

### 9.2 验证码使用流程

1. 调用发送验证码接口（`sendSmsCode` 或 `sendEmailCode`）
2. 用户输入收到的验证码
3. 调用登录/注册/重置密码等接口，传递验证码

### 9.3 第三方登录流程

1. 客户端调用第三方SDK获取授权码
2. 将授权码传递给对应的登录接口
3. 如果是新用户，系统自动创建账号
4. 如果未绑定手机号，`needBindMobile` 为 `true`，需要调用绑定手机号接口

### 9.4 Token 使用说明

- Token 有效期：7天（604800秒）
- Token 过期前可以调用 `refreshToken` 接口刷新
- 所有需要认证的接口都需要在请求头中传递 `Authorization: Bearer {token}`
- Token 过期后需要重新登录

---

## 十、更新日志

### v3.0.3（2026-03-19）
- 下线无服务端验证码校验的 AGC 同步登录接口：`loginByEmailAgc`、`loginByMobileAgc`（易被伪造身份）；请使用 `loginByMobile` / `loginByEmail` 并校验短信或邮箱验证码
- 下线 `encryptPassword` 调试接口（明文密码上传存在泄露风险）；客户端请使用 `publicKey` 在本地 RSA 加密后再调用登录/注册

### v3.0.2（2026-03-14）
- 新增二维码登录功能
- 支持网页端通过二维码扫码登录
- 新增三个二维码登录接口：生成Token、检查状态、确认登录
- 完善扫码登录流程说明和实现示例

### v3.0.1（2026-02-05）
- 初始版本
- 支持多种登录方式（手机验证码、账号密码、第三方登录等）
- 支持 Token 刷新和退出登录
- 支持账号管理（绑定手机号、修改密码、重置密码、注销账号）

---

**文档版本**：3.0.2  
**最后更新**：2026-03-14  
**维护者**：项目团队  
**用途**：移动端登录认证接口文档
