server/laf-cloud/signInActivity.API.md

8.4 KiB
Raw Blame History

七日签到后端接口文档

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. 推荐调用流程

  1. 玩家进入主界面后调用 signInActivityInfo。
  2. 如果返回 data: false,表示玩家尚未达到目标关卡,不展示活动。
  3. 如果返回活动对象,按照 status、canClaim、todayClaimed 和 rewards 渲染活动。
  4. 玩家点击领取时调用 signInClaim。
  5. 领取成功后,前端先检查本地是否处理过 claimId,未处理过才发放 rewards。
  6. 发奖完成后保存 claimId,并重新请求 signInActivityInfo 刷新页面状态。

活动只在 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": "未达到签到活动开启关卡"
}

达到目标关卡

用户没有活动状态时,本次请求会创建活动;已有活动状态时不会重置开始和结束时间。

{
  "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,
    "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 自然日是否已经领取
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:

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,不要完全依赖客户端本地时间。