11 KiB
七日签到后端接口文档
1. 基本约定
- 基础地址:
https://<APPID>.laf.run - 数据格式:
application/json - 时区:UTC+8
- 活动周期:触发当天为第 1 个自然日,第 15 天 00:00 结束
- 签到规则:14 个自然日内累计领取 7 次,允许断签,每个自然日最多领取一次
- 适用用户库:仅主游戏
users;gameName: "iaa"不支持签到活动 - 身份校验:请求携带登录接口返回的
uid和token - 通用成功码:
code: 1 - 通用失败码:
code: 0
签到奖励由后端校验并记录,实际金币、道具、无限体力和猫皮肤仍由前端根据领取接口返回的 rewards 发放。前端必须使用 claimId 做发奖幂等。
2. 推荐调用流程
- 玩家进入主界面后调用
signInActivityInfo。 - 如果返回
data: false,表示玩家尚未达到目标关卡,不展示活动。 - 符合领取条件时,服务端保存领取前的展示快照,再异步执行并等待领取落库。
- 如果
data.todayClaim非空,前端检查其claimId是否已处理,未处理才发放todayClaim.rewards并保存处理标记。 - 按照领取前的
status、canClaim、todayClaimed和rewards渲染活动。本次请求触发自动领取时canClaim: true,当档奖励的claimed: false,便于播放领取展示;前端完成发奖后更新本地状态,不再需要调用signInClaim。当天再次请求会返回已领取状态。
当天重复请求会返回同一个 todayClaim,用于首次响应丢失后的重试;它不表示本次新增领取。必须按 claimId 去重,不能每次收到就发奖。此接口具有写入行为,不应被预加载或轮询当作纯查询使用。todayClaim 只返回当天记录,不包含跨日未处理奖励的补领机制。
活动只在 users.levelAmount 达到目标关卡且没有活动状态的用户首次调用 signInActivityInfo 时创建。login 和 setUserLevel 均不读取签到配置、不判断签到资格,也不创建签到活动。
3. 查询签到活动信息
POST /signInActivityInfo
云函数同时配置了 GET 和 POST;客户端统一使用 POST。
请求参数
interface SignInActivityInfoRequest {
uid: string;
token: string;
gameName?: string;
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
uid |
string | 是 | 用户 _id |
token |
string | 是 | 登录令牌 |
gameName |
string | 否 | 不传表示主游戏;传 iaa 会被拒绝 |
未达到目标关卡
{
"code": 1,
"data": false,
"msg": "未达到签到活动开启关卡"
}
达到目标关卡
用户没有活动状态时,本次请求会创建活动;已有活动状态时不会重置开始和结束时间。
活动进行中且当天未领取时,本次请求会自动领取下一档奖励。当天已领、活动完成或过期时不新增领取记录。status、claimedCount、todayClaimed、canClaim、nextRewardDay 和 rewards[].claimed 均为本次自动领取前的快照;todayClaim 为落库后的当天领取凭据。数据库写入失败时返回失败或抛出服务端错误,不返回虚假的领取成功。
例如已有 Day 1、2 记录,本次自动领取 Day 3:返回 claimedCount: 2、todayClaimed: false、canClaim: true、nextRewardDay: 3,Day 1、2 的 claimed 为 true,Day 3~7 为 false,同时 todayClaim.rewardDay: 3。当天再次请求则返回 claimedCount: 3、todayClaimed: true、canClaim: false 和 Day 3 的 claimed: true。第 7 次领取的首次响应同样保留 status: active,再次请求才显示 completed。并发请求可能均读到领取前快照,前端发奖始终按 claimId 去重,不能只依赖 canClaim。
{
"code": 1,
"data": {
"serverNow": 1788310800000,
"activityId": "seven_day_sign_in_v1",
"status": "active",
"triggerLevel": 23,
"triggerReached": true,
"startAt": 1788278400000,
"endAt": 1789488000000,
"claimedCount": 0,
"todayClaimed": false,
"todayClaim": {
"claimId": "71b4...9a2f",
"rewardDay": 1,
"rewards": [{ "type": "infinite_health", "count": 900 }]
},
"canClaim": true,
"nextRewardDay": 1,
"rewards": [
{
"day": 1,
"items": [
{ "type": "infinite_health", "count": 900 }
],
"claimed": false
}
]
},
"msg": "成功"
}
返回字段
| 字段 | 类型 | 说明 |
|---|---|---|
serverNow |
number | 服务器当前毫秒时间戳 |
activityId |
string | 用户参与的活动配置 ID |
status |
string | active、completed 或 expired |
triggerLevel |
number | 活动开启目标关卡,当前配置为 23 |
triggerReached |
boolean | 服务端根据 users.levelAmount 确认的关卡是否达标 |
startAt |
number | 活动第 1 天 UTC+8 零点时间戳 |
endAt |
number | 活动结束时间戳,不包含该时刻 |
claimedCount |
number | 本次自动领取前的已领取奖励天数,范围 0~7 |
todayClaimed |
boolean | 本次自动领取前,当前 UTC+8 自然日是否已经领取 |
todayClaim |
object | null | 当天领取凭据:claimId: string、rewardDay: number、rewards: RewardItem[];当天无记录为 null,重复请求返回相同凭据 |
canClaim |
boolean | 本次自动领取前是否可领,用于展示领取过程,不代表响应后还能再次领取 |
nextRewardDay |
number | null | 下一档奖励序号;当前不可领取时为 null |
rewards |
RewardDay[] | 完整七天奖励及每档领取状态 |
状态说明:
| 状态 | 说明 |
|---|---|
active |
活动期内且尚未领取满 7 天 |
completed |
已领取全部 7 天奖励 |
expired |
已到第 15 天 00:00 且未领取满 7 天 |
4. 领取签到奖励
POST /signInClaim
保留兼容旧客户端,与活动信息接口复用同一领取实现。新流程无需额外调用;活动信息接口自动领取后,当天调用此接口会返回“今天已经领取”。
客户端不能指定领取第几天。后端按照当前累计领取次数自动发放下一档配置,并使用用户、活动和自然日生成唯一 claimId。
请求参数
interface SignInClaimRequest {
uid: string;
token: string;
gameName?: string;
}
成功响应
{
"code": 1,
"data": {
"claimId": "71b4...9a2f",
"rewardDay": 1,
"rewards": [
{ "type": "infinite_health", "count": 900 }
],
"claimedCount": 1,
"todayClaimed": true,
"completed": false
},
"msg": "领取成功"
}
返回字段
| 字段 | 类型 | 说明 |
|---|---|---|
claimId |
string | 本次领取唯一标识,前端发奖幂等键 |
rewardDay |
number | 本次领取的奖励序号,范围 1~7 |
rewards |
RewardItem[] | 本次需要由前端发放的奖励 |
claimedCount |
number | 领取成功后的累计领取天数 |
todayClaimed |
boolean | 成功时固定为 true |
completed |
boolean | 本次领取后是否已经领满 7 天 |
5. 奖励数据结构
interface RewardDay {
day: number;
items: RewardItem[];
claimed: boolean;
}
interface RewardItem {
type: "coin" | "freeze" | "hammer" | "magic_wand" | "infinite_health" | "cat_skin";
count: number;
itemId?: number;
}
type |
含义 | count 单位 |
额外字段 |
|---|---|---|---|
coin |
金币 | 个 | 无 |
hammer |
锤子 | 个 | 无 |
freeze |
冻结道具 | 个 | 无 |
magic_wand |
魔法棒 | 个 | 无 |
infinite_health |
无限体力 | 秒 | 无 |
cat_skin |
猫皮肤 | 个 | 必须提供正整数 itemId |
当前七天配置:
| Day | 奖励数据 | 展示含义 |
|---|---|---|
| 1 | infinite_health: 900 |
无限体力 15 分钟 |
| 2 | hammer: 1 |
锤子 ×1 |
| 3 | infinite_health: 1800 |
无限体力 30 分钟 |
| 4 | freeze: 1、magic_wand: 1 |
冻结 ×1、魔法棒 ×1 |
| 5 | coin: 600 |
金币 ×600 |
| 6 | hammer: 1、freeze: 1、magic_wand: 1 |
三种道具各 ×1 |
| 7 | infinite_health: 3600、cat_skin: 1, itemId: 12 |
无限体力 1 小时、专属猫 12 |
6. 错误响应
两个签到接口共用的错误:
code |
data |
msg |
触发条件 |
|---|---|---|---|
| 0 | null | 未获取到uid |
未传 uid |
| 0 | null | 七日签到仅支持主游戏 |
gameName 为 iaa |
| 0 | null | 未获取到用户信息 |
用户不存在 |
| 0 | null | token校验失败 |
token 不匹配 |
| 0 | null | 签到活动配置不存在或配置无效 |
找不到配置、配置非法或同时启用多条配置 |
signInActivityInfo 特有错误:
code |
data |
msg |
|---|---|---|
| 0 | null | 签到活动开启失败 |
signInClaim 特有错误:
code |
data |
msg |
|---|---|---|
| 0 | null | 签到活动尚未开启 |
| 0 | null | 七日签到奖励已全部领取 |
| 0 | null | 七日签到活动已结束 |
| 0 | null | 今天已经领取 |
| 0 | null | 签到奖励配置异常 |
7. 数据库配置
配置集合:sign_in_activity_config
- 必须且只能存在一条
enabled: true的有效配置。 - 当前可导入配置文件:
laf-cloud/sign-in-activity-config.json。 - 用户开始活动后通过
activityId继续读取配置,因此旧配置可以禁用,但在参与用户全部结束前不能删除。
用户活动状态写入 users.signInActivity。数据库中使用 JSON 字符串保存,读取时由服务端解析为下述结构;这样可以兼容字段原值为 null 的用户,并避免 Laf 将对象更新展开成点路径后触发 MongoDB 错误:
interface SignInActivityState {
activityId: string;
startAt: number;
endAt: number;
activatedAt: number;
completedAt: number | null;
}
领取记录集合:sign_in_activity_claims
- 每次领取保存奖励序号、奖励快照和领取时间。
- 记录
_id与claimId相同,由uid + activityId + UTC+8自然日计算 SHA-256。 - 同一用户、同一活动、同一自然日的并发请求只能成功写入一条记录。
8. 前端接入注意事项
- 不要根据客户端本地关卡自行判定资格;服务端使用
users.levelAmount判断,以signInActivityInfo返回值为准。 data: false是正常成功响应,不应作为网络或服务器错误处理。- 领取成功不代表后端已经增加资产;前端负责发奖。
- 前端必须保存已处理的
claimId,避免重复回调造成重复发奖。 infinite_health.count单位是秒。- Day 7 的
cat_skin.itemId当前为 12,客户端必须先支持猫 12 的资源、展示和幂等写入catArr。 - 倒计时使用
serverNow和endAt,不要完全依赖客户端本地时间。
9. 单账号测试接口
测试环境可发布 POST /signInTestAdmin,用一个账号快速准备未达标、待领取 Day 1~7、当天已领、过期和完成状态。该接口的密钥配置、参数和测试顺序见 laf-cloud/signInActivity.TESTING.md;禁止在正式环境发布。