355 lines
8.5 KiB
Markdown
355 lines
8.5 KiB
Markdown
|
|
# 会员码管理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个月的会员时长。
|