Files
cpzs-backend/会员码激活API使用说明.md
2025-08-01 19:09:57 +08:00

355 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 会员码管理API使用说明
## 功能概述
会员码管理系统包含两个主要功能:
1. **会员码生成**:管理员可以批量生成会员码,用于分发给用户
2. **会员码激活**:用户通过输入有效的会员码来延长或激活会员服务
系统会校验会员码的有效性,并根据会员码设定的月数来更新用户的会员到期时间。
## 接口信息
### 1. 批量生成会员码
**接口地址:** `POST /vip-code/generate`
**请求参数:**
```json
{
"numCodes": 100,
"vipExpireTime": 12
}
```
**参数说明:**
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| numCodes | Integer | 是 | 生成数量1-1000 |
| vipExpireTime | Integer | 是 | 会员有效月数 |
**响应示例:**
成功响应:
```json
{
"code": 0,
"data": 100,
"message": "ok"
}
```
失败响应:
```json
{
"code": 40000,
"data": null,
"message": "生成数量必须大于0"
}
```
### 2. 获取可用会员码
**接口地址:** `GET /vip-code/available?vipExpireTime=1`
**请求参数:**
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| vipExpireTime | Integer | 是 | 会员有效月数1或12 |
**响应示例:**
成功响应:
```json
{
"code": 0,
"data": "ABC123DEF456GHI7",
"message": "ok"
}
```
失败响应:
```json
{
"code": 40400,
"data": null,
"message": "没有找到可用的会员码"
}
```
### 3. 激活会员码
**接口地址:** `POST /user/activate-vip`
**请求参数:**
```json
{
"userId": 1,
"code": "VIP_CODE_123456"
}
```
**参数说明:**
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| userId | Long | 是 | 用户ID |
| code | String | 是 | 会员码 |
**响应示例:**
成功响应:
```json
{
"code": 0,
"data": true,
"message": "ok"
}
```
失败响应:
```json
{
"code": 40000,
"data": null,
"message": "会员码不存在或无效"
}
```
## 业务逻辑
### 会员码生成流程
1. **参数校验**
- 验证生成数量大于0且不超过1000
- 验证会员有效月数大于0
2. **生成唯一会员码**
- 使用随机算法生成16位会员码
- 检查数据库确保会员码唯一性
- 重复生成直到达到指定数量
3. **会员编号分配**
- 查询当前最大会员编号
- 从最大编号+1开始连续分配
4. **批量插入数据库**
- 使用事务确保数据一致性
- 批量插入提高性能
### 获取可用会员码流程
1. **参数校验**
- 验证会员有效月数只能是1或12
2. **数据库查询**
- 查询指定月数的未使用会员码
- 按创建时间升序排列,获取最早的一个
- 确保返回的会员码处于可用状态
3. **结果返回**
- 如果找到可用会员码,返回会员码字符串
- 如果没有找到,返回错误信息
### 会员码激活流程
1. **参数校验**
- 验证userId不为空
- 验证会员码不为空或空字符串
2. **用户存在性校验**
- 检查用户ID对应的用户是否存在
- 不存在则抛出"用户不存在"异常
3. **会员码有效性校验**
- 根据会员码查询vip_code表
- 检查会员码是否存在
- 检查会员码是否已被使用isUse字段
4. **会员时间计算**
- 获取用户当前的会员到期时间vipExpire
- 如果当前时间晚于会员到期时间或会员到期时间为空,则从当前时间开始计算
- 如果当前时间早于会员到期时间,则从会员到期时间开始计算
- 添加会员码对应的月数vipExpireTime字段
5. **数据库更新**
- 更新用户表设置isVip=1更新vipExpire为新计算的时间
- 更新会员码表设置isUse=1标记为已使用
### 数据库表结构
**vip_code表**
- `id`: 主键
- `code`: 会员码(唯一)
- `vipExpireTime`: 会员有效月数
- `vipNumber`: 会员编号
- `isUse`: 是否使用0-未使用1-已使用)
- `createTime`: 创建时间
- `updateTime`: 更新时间
**user表**
- `isVip`: 是否会员0-非会员1-会员)
- `vipExpire`: 会员到期时间
## 错误码说明
| 错误码 | 说明 |
|--------|------|
| 40000 | 参数错误用户ID为空、会员码为空、用户不存在、会员码无效等 |
| 50000 | 系统错误(数据库操作失败等) |
## 使用示例
### cURL 示例
**生成会员码:**
```bash
curl -X POST http://localhost:8080/vip-code/generate \
-H "Content-Type: application/json" \
-d '{
"numCodes": 100,
"vipExpireTime": 12
}'
```
**获取可用会员码:**
```bash
curl -X GET "http://localhost:8080/vip-code/available?vipExpireTime=1"
```
**激活会员码:**
```bash
curl -X POST http://localhost:8080/user/activate-vip \
-H "Content-Type: application/json" \
-d '{
"userId": 1,
"code": "VIP_CODE_123456"
}'
```
### JavaScript 示例
**生成会员码:**
```javascript
const generateVipCodes = async (numCodes, vipExpireTime) => {
try {
const response = await fetch('/vip-code/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
numCodes: numCodes,
vipExpireTime: vipExpireTime
})
});
const result = await response.json();
if (result.code === 0) {
console.log('会员码生成成功,数量:', result.data);
return result.data;
} else {
console.error('会员码生成失败:', result.message);
return 0;
}
} catch (error) {
console.error('请求失败:', error);
return 0;
}
};
```
**获取可用会员码:**
```javascript
const getAvailableVipCode = async (vipExpireTime) => {
try {
const response = await fetch(`/vip-code/available?vipExpireTime=${vipExpireTime}`, {
method: 'GET'
});
const result = await response.json();
if (result.code === 0) {
console.log('获取可用会员码成功:', result.data);
return result.data;
} else {
console.error('获取可用会员码失败:', result.message);
return null;
}
} catch (error) {
console.error('请求失败:', error);
return null;
}
};
```
**激活会员码:**
```javascript
const activateVipCode = async (userId, code) => {
try {
const response = await fetch('/user/activate-vip', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
userId: userId,
code: code
})
});
const result = await response.json();
if (result.code === 0) {
console.log('会员码激活成功');
return true;
} else {
console.error('会员码激活失败:', result.message);
return false;
}
} catch (error) {
console.error('请求失败:', error);
return false;
}
};
```
## 注意事项
### 会员码生成
1. **批量限制**单次最多生成1000个会员码避免系统负载过高
2. **唯一性保证**:系统会检查数据库确保生成的会员码唯一
3. **事务管理**:使用数据库事务确保批量插入的数据一致性
4. **性能优化**:使用批量插入提高大量数据的插入性能
### 获取可用会员码
1. **参数限制**只支持1个月和12个月两种类型的会员码
2. **优先级策略**:按创建时间升序返回,优先返回最早创建的会员码
3. **状态检查**:只返回未使用状态的会员码
4. **库存管理**:如果指定类型的会员码已用完,会返回相应错误信息
### 会员码激活
1. **事务管理**:整个激活过程使用数据库事务,确保数据一致性
2. **重复使用**:每个会员码只能使用一次,使用后会被标记为已使用
3. **时间计算**:会员时间会根据用户当前状态智能计算,不会丢失已有的会员时间
4. **日志记录**:所有操作都有详细的日志记录,便于问题排查
5. **异常处理**:完善的异常处理机制,提供清晰的错误信息
## 测试数据
在测试环境中可以在vip_code表中插入测试数据
```sql
INSERT INTO vip_code (id, code, vipExpireTime, vipNumber, isUse, createTime, updateTime)
VALUES (1, 'TEST_CODE_001', 1, 1001, 0, NOW(), NOW());
INSERT INTO vip_code (id, code, vipExpireTime, vipNumber, isUse, createTime, updateTime)
VALUES (2, 'TEST_CODE_002', 3, 1002, 0, NOW(), NOW());
INSERT INTO vip_code (id, code, vipExpireTime, vipNumber, isUse, createTime, updateTime)
VALUES (3, 'TEST_CODE_003', 12, 1003, 0, NOW(), NOW());
```
这些测试数据分别对应1个月、3个月和12个月的会员时长。