doge 1 天之前
父節點
當前提交
7012a43439
共有 1 個文件被更改,包括 133 次插入 和 5 次删除
  1. 133 5
      docs/前端接口/活动/资格条件与展示开关.md

+ 133 - 5
docs/前端接口/活动/资格条件与展示开关.md

@@ -1,6 +1,8 @@
-# 活动资格、获奖份数与展示开关
+# 活动管理前端接入说明
 
-活动接口支持发布平台、排序、会员资格条件及「不符合条件是否展示」。获奖份数仅用于新建的非足球首页活动,旧活动保持原金额预算规则;`type=2` 足球首页豁免。本次只改后端,不编写前端代码;本文件供接口接入参考。
+适用页面:后台活动列表、新增/编辑活动弹窗,以及会员端活动列表与详情。本文按当前后端实现整理,更新时间为 2026-10-19。
+
+活动接口支持发布平台、排序、会员资格条件及「不符合条件是否展示」。获奖份数仅用于新建的非足球首页活动,旧活动保持原金额预算规则;`type=2` 足球首页豁免。
 
 **新活动 10 份表示最多 10 位不同会员成功获奖**,不按金额或发奖次数扣减。是否可重复领奖、次数、周期及资格完全沿用具体活动原规则;份数检查通过不代表可突破这些规则。原规则允许再次获奖时,同一会员不重复占份数。
 
@@ -11,6 +13,80 @@
 - `GET /admin/ActivityReward?page=1&limit=10`:列表返回新增字段,编辑时直接回显。
 - `POST /admin/ActivityReward/submit`:不传 `id` 新增,传 `id` 编辑;新增字段放在请求根级,不能放入 `params`。
 
+后台列表 `page`、`limit` 均必填,且为大于等于 `1` 的整数;可选 `title` 模糊搜索、`type` 类型筛选。列表同时返回原活动字段和新增配置,编辑从选中记录回填,不需要新增详情接口。
+
+### 请求层与响应解析
+
+bot-28 后台、bot-28 Telegram 活动页、会员站点使用各自配置的 API 基地址和请求层:
+
+| 接口端 | 成功码 | 列表解析 | 身份 |
+|---|---|---|---|
+| bot-28 后台 | `code === 0` | 总数 `data.total`,记录 `data.data` | 现有后台登录态,`Authorization: Bearer <后台token>` |
+| bot-28 Telegram 活动页 | `code === 0` | `data` 为活动数组 | 沿用 `member_id` |
+| 会员站点 `melbet_sport-api` | `code === 1` | 总数 `data.count`,记录 `data.list` | 现有站点登录态;`Authorization` 直接放登录返回的 Token,无 Bearer 前缀 |
+
+本文请求示例表达**业务参数**,响应示例为**解密后的业务层 JSON**。站点部署启用请求/响应加密时,继续使用项目现有的加密请求封装及解密流程,再按本文读取业务字段;活动模块不新增鉴权或加密规则。配套协议见站点项目 `docs/API请求响应内容加密-前端接入说明.md`。
+
+后台列表响应示意(省略部分原有字段):
+
+```json
+{
+  "code": 0,
+  "timestamp": 1792368000,
+  "msg": "成功",
+  "data": {
+    "total": 1,
+    "data": [
+      {
+        "id": 123,
+        "title": "秋季充值活动",
+        "type": 3,
+        "quota_enabled": true,
+        "reward_quota": 10,
+        "rewarded_count": 2,
+        "budget": null,
+        "budget_used": "0.00",
+        "publish_platforms": ["PC", "H5", "APP"],
+        "register_time_limited": false,
+        "register_start_time": null,
+        "register_end_time": null,
+        "register_platforms": [],
+        "deposit_limited": false,
+        "deposit_min": null,
+        "deposit_max": null,
+        "show_ineligible": true,
+        "sort": 10,
+        "params": { "reward_ratio": 5 }
+      }
+    ]
+  }
+}
+```
+
+保存成功返回 `code=0`、`data=[]`,随后重新请求列表回显配置及只读人数;保存响应不包含新增活动 ID。失败按实际 `msg` 提示,后台参数校验错误通常为 `code=-3`,不要仅以 HTTP 200 判断业务成功。
+
+### 保存时的基础字段
+
+新增和编辑都必须提交以下完整基础表单,编辑时额外提交 `id`:
+
+| 字段 | 规则 |
+|---|---|
+| `id` | 新增省略;编辑传原记录 ID,整数且大于等于 `1` |
+| `title`、`sub_title` | 必填字符串,长度 `1`~`140` |
+| `start_time`、`end_time` | 必填日期时间,结束不早于开始;提交格式沿用原活动控件,如 `YYYY-MM-DD HH:mm:ss` |
+| `detail_image`、`pc_image`、`detail_banner`、`pc_banner` | 四个图片字段均必填,沿用现有上传后路径或 URL |
+| `status` | 必填,`1` 上架、`0` 下架 |
+| `type` | 必填整数 `1`~`6`,沿用现有类型选项;`2` 为足球首页 |
+| `lang` | 必填字符串,沿用现有语种选项,如 `zh` |
+| `content` | 原有正文,可空字符串 |
+| `params` | 原有活动类型规则对象;编辑完整保留并回传,原值为空时保持 `null` |
+
+**编辑 `params`:**后台列表将有内容的规则解析为对象,直接保留原字段再按现有活动表单修改,原值为空时继续传 `null`。省略、传 `null` 或空数组都会清空服务端规则;不能把规则对象再次编码成 JSON 字符串。本次新增配置放在根级,不覆盖或新增重复领奖规则。
+
+后台列表的原活动 `start_time/end_time` 当前返回 `YYYY-MM-DD`,控件需兼容日期值;新增注册条件的 `register_start_time/register_end_time` 使用完整日期时间。这两组字段分别回填,按项目现有日期与时区约定提交。
+
+### 新增配置字段
+
 | 字段 | 类型 / 默认值 | 表单与提交规则 |
 |---|---|---|
 | `publish_platforms` | 数组 / `[]` | 「发布平台」多选,值为 `PC`、`H5`、`APP`;空数组表示全部平台 |
@@ -35,7 +111,7 @@
 
 `quota_enabled` 误传会被忽略,编辑包括改变活动类型也不改变此标记。旧非足球活动提交非空 `reward_quota` 会被拒绝,不能转成份数活动;不要把旧金额原样改名为份数。
 
-新建非足球活动默认开启份数模式,编辑省略配置保留原值;清空平台限制传 `[]`,份数活动取消限制传 `null`。注册时间或存款选择「不限」时提交开关 `0`,后端清空旧上下限。调整份数不清零已获奖人数,不限份数也登记首次获奖会员;旧活动不参与新登记和计数。
+新建非足球活动默认开启份数模式,编辑省略**本表新增配置**时保留原值;基础必填字段仍必须提交,`params` 按上文保留。清空平台限制传 `[]`,份数活动取消限制传 `null`。注册时间或存款选择「不限」时提交开关 `0`,后端清空旧上下限。调整份数不清零已获奖人数,不限份数也登记首次获奖会员;旧活动不参与新登记和计数。
 
 未编辑的历史活动,后台列表中的平台字段可能为 `null`,回显时按 `[]`(不限)处理;保存时提交数组。
 
@@ -78,12 +154,16 @@
 
 保存成功后刷新列表;失败沿用接口 `msg` 提示。示例不提交 `quota_enabled`,由服务端创建时确定;`rewarded_count`、`budget_used` 为只读计数,误传会被忽略,页面不能重置。
 
+编辑时以完整基础表单和原有 `params` 为基础,增加 `"id": 123`;新活动调整人数时传 `reward_quota`,旧活动修改金额预算时传 `budget`。不得只提交 `{ "id": 123, "reward_quota": 10 }`,否则基础必填校验失败。
+
 ## 表单交互
 
 - 非足球首页显示上述区域。注册时间、存款选择「不限」时禁用范围输入;选择限制时要求上下限同时填写。
 - 「不符合条件是否展示」默认选「是」。说明文案可写:展示仅允许查看活动,参与及发奖仍需符合条件。
 - 编辑时按只读模式展示金额预算或获奖份数,旧活动不提供切换模式。足球首页不使用上述新增条件,后端忽略这些配置,基本字段照常校验。
 - 份数说明:只有首次正数奖励实际入账占一份,查询、符合资格、申请、余额宝本金转入均不占;首奖失败不占。满额阻止新的获奖会员,已获奖会员仍须通过具体活动原领奖规则,不重复占份数。
+- 新旧活动以服务端返回的 `quota_enabled` 判断,与开始日期、标题、当前选中的活动类型无关;改变类型也不会切换此标记。站点的布尔开关兼容 `true/false` 与 `1/0` 返回形式。
+- 数量输入保留 `0` 与 `null` 的区别:`0` 禁止新用户首次获奖,清空或选择「不限」时提交 `null`。不要通过 `value || null` 把 `0` 转成不限。
 
 例如新活动份数为 `10`:A 首次获奖 `5.00`,人数为 `1`;若原规则允许 A 再获奖 `20.00`,人数仍为 `1`;B 首次获奖后人数为 `2`。原规则只允许一次领奖的活动,A 仍不能再次领奖。
 
@@ -91,11 +171,49 @@
 
 站点 `melbet_sport-api` 使用 `GET /api/index/activity` 和 `GET /api/index/activityInfo?id=活动ID`;Telegram 活动页使用 bot-28 的 `GET /api/ActivityReward`,后者仍只返回 `type=1` 活动。
 
+站点列表请求示例:
+
+```http
+GET /api/index/activity?page=1&limit=10&page_type=1&platform=H5
+Lang: zh
+Authorization: <站点登录返回的原始Token>
+```
+
+站点实际分页参数为 `page`、`limit`,默认 `1`、`25`;`page_type=1` 分页,`0` 为非分页(最多取项目配置上限,当前为 `2000` 条)。`type` 可选;沿用原接口约定,`type=3` 查询通道组内可见活动集合,返回记录可能包含其他活动类型,应按记录自己的 `type` 展示。
+
+站点列表解密后的响应示意:
+
+```json
+{
+  "code": 1,
+  "show": 0,
+  "msg": "",
+  "data": {
+    "count": 1,
+    "list": [
+      {
+        "id": 123,
+        "title": "秋季充值活动",
+        "type": 3,
+        "quota_enabled": 1,
+        "reward_quota": 10,
+        "rewarded_count": 2,
+        "is_eligible": true,
+        "ineligible_reason": ""
+      }
+    ],
+    "extend": []
+  }
+}
+```
+
+详情成功时 `code=1`,活动对象直接放在 `data`。列表不返回 `content/params`,正文从详情读取;详情 `params` 可能为 JSON 字符串,后台编辑仍以后台列表返回的规则对象为准。站点原活动起止时间为秒级时间戳,与后台日期字符串分别处理。
+
 站点活动列表和详情均按 `Lang` 请求头筛选语种,未提供时默认 `zh`。
 
-两个入口都应显式传当前客户端 `platform=PC`、`H5` 或 `APP`。站点也支持 `platform` 请求头,并兼容 `WECHAT/微信 → H5`、`IOS/ANDROID → APP`;前端统一提交标准值即可。配置了发布平台后,未传或无法识别平台的请求看不到该活动;空数组不受此限制。不要用注册平台或浏览器标识推断当前客户端。
+两个入口都应显式传当前客户端 `platform=PC`、`H5` 或 `APP`。站点也支持 `platform` 请求头,查询参数优先,并兼容 `WECHAT/微信 → H5`、`IOS/ANDROID → APP`;前端统一提交标准值即可。配置了发布平台后,未传或无法识别平台的请求看不到该活动;空数组不受此限制。不要用注册平台或浏览器标识推断当前客户端。
 
-站点沿用现有登录态;bot-28 活动页沿用 `member_id`。返回活动新增:
+站点按现有 Token 登录态识别会员,无须提交 `member_id`;不带 Token 时按游客处理。bot-28 活动页沿用 `member_id`。返回活动新增:
 
 | 字段 | 用途 |
 |---|---|
@@ -104,6 +222,8 @@
 
 `show_ineligible=1` 时,不符合资格的会员可查看活动,页面禁用参与按钮并显示原因。游客返回 `is_eligible=false`、`ineligible_reason="请先登录"`,可引导登录。`show_ineligible=0` 时,游客及不符合资格的会员都不会收到该活动;详情接口也不能绕过隐藏规则。发布平台过滤始终生效,与展示开关无关。
 
+站点列表和详情还会按上架状态、活动起止时间、语种及现有充值通道组的活动类型限制筛选;`show_ineligible=1` 不会绕过这些可见范围。活动已隐藏时,直接访问详情 ID 也可能失败,页面展示接口 `msg` 并刷新活动列表。
+
 足球首页跳过新增的平台、资格、展示及获奖名额限制,游客也返回符合资格。其排序按默认 `0` 处理。其余活动按 `sort` 倒序、ID 倒序显示,站点过滤后再分页,数量与可见列表一致。
 
 资格结果只反映会员条件,名额满后活动仍可能展示;参与、自动奖励、余额宝新转入由后端检查所属模式及原规则。份数活动可展示 `reward_quota`、`rewarded_count`,但不能仅凭这两个数认定当前会员能否获奖;旧活动继续按 `budget`、`budget_used` 判断金额预算。
@@ -115,3 +235,11 @@
 bot-28 的 `POST /api/ActivityReward/participate` 继续提交 `member_id`、`activity_id`,增加 `platform`。接口仍仅支持 `type=1`,无论活动是否允许展示,不符合资格都不能参与。
 
 建议联调:资格边界、平台、游客、展示开关、足球首页,以及满额时新会员首奖被拒绝、已获奖会员按原规则再次获奖、首奖失败不占名额。
+
+## 交付检查
+
+- 新建非足球活动提交 `reward_quota=10`;编辑旧活动保留 `budget`,模式标记及只读计数均不提交。
+- 编辑完整回传基础必填字段和原 `params`,重复领奖次数、周期等旧规则保持原值。
+- `0`、`null`、空平台数组、关闭条件开关均按本说明提交并正确回显。
+- 后台以 `code=0` 及 `data.data` 解析;会员站点以 `code=1` 及 `data.list` 解析,保存后刷新列表。
+- 会员列表与详情都携带正确平台和语种;名额满后由服务端最终判定当前会员能否参与或获奖。