数据概览
🎫
0
卡密总数
✅
0
可用卡密
🔖
0
已使用卡密
📱
0
在线设备
⏰
0
过期卡密
📈 最近活动
暂无数据
📋 卡密列表
| 卡密代码 | 类型 | 状态 | 软件 | 多开 | 设备ID | 到期时间 | 备注 | 激活时间 | 创建时间 | 操作 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 暂无数据 | |||||||||||
| 软件名称 | AppKey | AppSecret | 最大多开 | 卡密前缀 | 状态 | 卡密数 | 在线数 | 归属账号 | 创建时间 | 操作 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
|
💻
暂无软件数据
|
|||||||||||
👥
0
用户总数
💻
0
接入软件数
🎫
0
卡密总数
📱
0
在线设备
🔐 超级管理员 - 用户管理
| ID | 用户名 | 邮箱 | 角色 | 软件数 | 卡密数 | 在线设备 | 注册时间 | 操作 |
|---|---|---|---|---|---|---|---|---|
| 加载中... | ||||||||
🎭 角色列表
| 头像 | 角色ID | 名称 | 描述 | Chat | Audio | Video | 创建时间 | 操作 |
|---|---|---|---|---|---|---|---|---|
| 暂无数据 | ||||||||
| 图标 | 包名 | 备注名称 | 最新版本 | 版本数 | 文件名 | 下载地址 | 状态 | 创建时间 | 操作 |
|---|---|---|---|---|---|---|---|---|---|
| 加载中... | |||||||||
📋 基础信息
| 基础URL | http://localhost:3002 |
| 认证方式 | Bearer Token (JWT) |
| 数据格式 | JSON |
🔐 认证说明
所有需要认证的接口都需要在请求头中携带 JWT Token:
Authorization: Bearer <your_jwt_token>
🔐 签名验证(客户端API)
客户端API采用签名验证机制,更安全、更适合手机端/脚本软件接入。
公共参数
所有客户端接口都需要携带以下公共参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| app_key | string | 是 | 软件AppKey,在后台软件列表获取 |
| timestamp | number | 是 | 当前时间戳(毫秒),有效期60秒 |
| nonce | string | 是 | 随机字符串(建议UUID),60秒内不可重复 |
| sign | string | 是 | 签名,计算方式见下方 |
签名算法
sign = hmac_sha256(http_method + host + path + sorted_params + app_secret)
参数说明
| 参数 | 说明 |
|---|---|
| http_method | 请求方法,GET或POST |
| host | 域名,例如:api.example.com |
| path | 请求路径,例如:/api/client/card/activate |
| sorted_params | 1. 将全部请求参数格式化成 k=v 2. 按字母升序排列 3. 用 & 符号拼接(不包括sign参数) |
| app_secret | 软件密钥,在后台软件列表获取 |
签名示例(JavaScript)
const crypto = require('crypto');
function generateSign(method, host, path, params, appSecret) {
// 1. 参数排序并拼接
const sortedParams = Object.keys(params)
.filter(key => key !== 'sign')
.sort()
.map(key => `${key}=${params[key]}`)
.join('&');
// 2. 拼接签名字符串
const signString = method.toUpperCase() + host + path + sortedParams + appSecret;
// 3. HMAC-SHA256签名
return crypto.createHmac('sha256', appSecret).update(signString).digest('hex');
}
// 使用示例
const params = {
app_key: 'your_app_key',
card: 'ABCD-EFGH-IJKL-MNOP',
device_id: 'device123',
nonce: '359c22e4d5224771ba8e4b99cf61b372',
timestamp: Date.now()
};
const sign = generateSign('POST', 'api.example.com', '/api/client/card/activate', params, 'your_app_secret');
双向签名
接口调用成功后,响应会额外返回 nonce 和 sign 字段,用于验证服务端响应不被篡改:
sign = hmac_sha256(code + message + sorted_result + nonce + app_secret)
🔐 认证接口
用户注册
POST
/api/auth/register
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| username | string | 是 | 用户名(3-20字符) |
| string | 是 | 邮箱地址 | |
| password | string | 是 | 密码(至少6位) |
| referralCode | string | 否 | 推荐码 |
| adminCode | string | 否 | 管理员注册码 |
请求示例
{
"username": "testuser",
"email": "test@example.com",
"password": "123456"
}
响应示例
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": { "id": 1, "username": "testuser", "role": "user" }
}
用户登录
POST
/api/auth/login
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| username | string | 是 | 用户名 |
| password | string | 是 | 密码 |
响应示例
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": { "id": 1, "username": "testuser", "role": "user" }
}
获取当前用户信息
GET
/api/auth/me
需要认证
响应示例
{
"success": true,
"user": {
"id": 1,
"username": "testuser",
"email": "test@example.com",
"role": "user",
"balance": 100.00
}
}
🎫 卡密接口
生成卡密
POST
/api/cards/generate
需要认证
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| cardType | string | 是 | 卡密类型:day/week/month/quarter/year/permanent |
| count | int | 是 | 生成数量(1-100) |
| duration | int | 是 | 时长(天) |
| softwareId | int | 是 | 所属软件ID |
卡密类型说明
| 类型 | 说明 |
|---|---|
| day | 天卡 |
| week | 周卡 |
| month | 月卡 |
| quarter | 季卡 |
| year | 年卡 |
| permanent | 永久卡 |
请求示例
{
"cardType": "month",
"count": 10,
"duration": 30,
"softwareId": 1
}
获取卡密列表
GET
/api/cards
需要认证
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| status | string | 否 | 卡密状态:unused/used/expired |
| cardType | string | 否 | 卡密类型 |
| keyword | string | 否 | 搜索关键字(卡密代码/设备ID) |
| softwareName | string | 否 | 软件名称 |
| page | int | 否 | 页码(默认1) |
| limit | int | 否 | 每页数量(默认10) |
请求示例
GET /api/cards?status=unused&cardType=month&page=1&limit=20
使用卡密
POST
/api/cards/:id/use
需要认证
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| deviceId | string | 否 | 设备ID |
禁用/启用卡密
POST
/api/cards/:id/disable
需要认证
启用卡密:
POST
/api/cards/:id/enable
需要认证
💻 软件接口
创建软件
POST
/api/software
需要认证
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | 是 | 软件名称(不超过20字符) |
| multiDeviceLimit | int | 否 | 多开上限(默认1,最大10) |
| cardPrefix | string | 否 | 卡密前缀(不超过5字符) |
| deviceBind | boolean | 否 | 是否开启设备绑定 |
| description | string | 否 | 软件描述 |
响应示例
{
"success": true,
"message": "软件创建成功",
"data": {
"id": 1,
"name": "测试软件",
"app_key": "abc123...",
"app_secret": "xyz789..."
}
}
获取软件列表
GET
/api/software
需要认证
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | 否 | 软件名称(模糊搜索) |
| page | int | 否 | 页码(默认1) |
| pageSize | int | 否 | 每页数量(默认10) |
更新软件
PUT
/api/software/:id
需要认证
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | 否 | 软件名称 |
| multiDeviceLimit | int | 否 | 多开上限 |
| cardPrefix | string | 否 | 卡密前缀 |
| deviceBind | boolean | 否 | 是否开启设备绑定 |
| description | string | 否 | 软件描述 |
删除软件
DELETE
/api/software/:id
需要认证
重置AppSecret
POST
/api/software/:id/reset-secret
需要认证
禁用/启用软件
POST
/api/software/:id/disable
需要认证
启用软件:
POST
/api/software/:id/enable
需要认证
📱 客户端接口
客户端API用于手机端/脚本软件调用,使用签名验证而非JWT。
卡密激活/登录
POST
/api/client/card/activate
需要签名
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| card | string | 是 | 卡密代码 |
| device_id | string | 是 | 设备ID(手机ID) |
| device_info | string | 否 | 设备信息(JSON字符串) |
请求示例
{
"app_key": "your_app_key",
"timestamp": 1707235200000,
"nonce": "359c22e4d5224771ba8e4b99cf61b372",
"sign": "hmac_sha256_signature",
"card": "ABCD-EFGH-IJKL-MNOP",
"device_id": "android_12345678"
}
响应示例
{
"code": 0,
"success": true,
"message": "ok",
"result": {
"expires": "2024-03-18 00:00:00",
"expires_ts": 1710720000,
"card_type": "month",
"duration": 30,
"multi_device_limit": 1,
"device_bind": true
},
"server_time": 1707235200,
"nonce": "bojc2kiuof2jci9b90jg",
"sign": "response_signature"
}
心跳接口
POST
/api/client/card/heartbeat
需要签名
客户端应定期调用此接口(建议每10分钟),超过120秒未心跳会被判定离线。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| card | string | 是 | 卡密代码 |
| device_id | string | 是 | 设备ID |
响应示例
{
"code": 0,
"success": true,
"message": "ok",
"result": {
"expires": "2024-03-18 00:00:00",
"expires_ts": 1710720000,
"server_time": 1707235200
}
}
查询卡密信息
POST
/api/client/card/query
需要签名
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| card | string | 是 | 卡密代码 |
响应示例
{
"code": 0,
"success": true,
"message": "ok",
"result": {
"status": "used",
"is_disabled": false,
"card_type": "month",
"duration": 30,
"expires": "2024-03-18 00:00:00",
"expires_ts": 1710720000,
"device_id": "android_12345678",
"created_at": "2024-02-18 00:00:00",
"first_login_at": "2024-02-18 12:00:00",
"server_time": 1707235200
}
}
解绑设备
POST
/api/client/card/unbind
需要签名
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| card | string | 是 | 卡密代码 |
| device_id | string | 是 | 当前设备ID |
响应示例
{
"code": 0,
"success": true,
"message": "ok",
"result": {
"message": "设备解绑成功",
"remaining_devices": 0
}
}
⚡ 状态码说明
| 状态码 | 说明 |
|---|---|
| 200 | 请求成功 |
| 201 | 创建成功 |
| 400 | 请求参数错误 |
| 401 | 未认证/Token无效 |
| 403 | 权限不足 |
| 404 | 资源不存在 |
| 429 | 请求过于频繁 |
| 500 | 服务器内部错误 |
错误响应格式
{
"success": false,
"message": "错误描述",
"errors": [
{ "field": "username", "message": "用户名不能为空" }
]
}
📱 客户端返回码
| 返回码 | 说明 |
|---|---|
| 0 | 调用成功 |
| 400 | 参数错误 |
| 403 | 权限不足或软件被禁用 |
| 500 | 服务器错误 |
| 签名相关 | |
| 10010 | 无效的签名 |
| 10011 | 签名已过期(超过60秒) |
| 10013 | 时间戳大于当前服务器时间 |
| 10014 | 重复的nonce |
| 卡密相关 | |
| 10210 | 卡密已过期 |
| 10212 | 卡密已被冻结 |
| 10213 | 卡密超过多开上限 |
| 10215 | 只能在首次登录绑定的设备上使用 |
| 10216 | 软件未开启解绑设备功能 |
| 10217 | 超出可绑定设备上限 |
| 10218 | 卡密未激活,请先登录 |
| 10230 | 软件不存在,请检查app_key |
| 10240 | 卡密不存在 |
| 10255 | 该卡密不可解绑设备 |