适用项目:phase-back-admin;对接页面:phase-front 的 /live-schedule。本文记录已实现的后端接口契约,前端由对应负责人接入,部署状态以实际环境为准。
页面需要一次获取一周中每天的日程总数。新增批量统计接口,同时为原列表接口增加 UTC 日期查询,保证日期按钮总数与对应列表使用相同的日期范围和统计规则。
POST /api/schedule/daily-counts:新增公开接口,接收 1~7 个日期,按 UTC 自然日统计,按输入顺序返回 { date, total }。GET /api/schedule/index:公开日程列表新增 date=YYYY-MM-DD;后端生成 UTC 日期范围,旧 s_time / e_time 继续兼容,但不能与 date 混传。POST /api/schedule/daily-counts一次查询多个日期的日程总数,不返回日程详情,不分页。无须登录。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
dates | string[] | 是 | 1~7 个不重复的真实日期,严格使用 YYYY-MM-DD 格式 |
其他校验规则:
dates,不提供 source_type、status、talent_id 筛选。不要通过附加这些字段期待筛选统计结果。HTTP 200,以下数量为示例:
| 字段 | 类型 | 说明 |
|---|---|---|
data | object[] | 每个请求日期对应一项,顺序与输入一致 |
data[].date | string | 对应的 YYYY-MM-DD 日期 |
data[].total | integer | 当天日程总数;没有数据时返回 0,不会省略该日期 |
total 包含 YouTube(Y2B)和 Twitch(TWITCH),包括符合当天查询条件的 UPCOMING、LIVE、COMPLETED 记录,与分页大小无关。相同数据和当前时间下,该数值等于不附加平台、艺人、状态筛选的日期列表 total。
HTTP 422:缺少 dates、数量不在 1~7 范围内、日期重复、格式错误或日期不存在,例如 2026-02-30。整个请求校验失败,不返回部分日期统计结果。
错误结构如下,提示文本随服务端语言配置变化,前端应按字段处理:
数组整体错误对应 errors.dates,单个日期错误对应 errors["dates.N"],其中 N 为从 0 开始的索引。
GET /api/schedule/index新增 date 查询,后端统一生成 UTC 自然日范围;返回结构、分页及原有筛选保持兼容。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
date | string | 否 | 新增;严格 YYYY-MM-DD 格式的真实日期,固定按 UTC 查询 |
page | integer | 否 | 页码,最小为 1,默认第 1 页 |
size | integer | 否 | 每页数量,1~50,默认 15 |
talent_id | integer | 否 | 原有艺人筛选,最小为 1 |
status | string | 否 | 原有状态筛选:UPCOMING、LIVE、COMPLETED |
source_type | string | 否 | 原有平台筛选,业务值为 Y2B、TWITCH |
s_time | integer | 否 | 原有开始时间,正整数秒级 Unix 时间戳,需与 e_time 配合 |
e_time | integer | 否 | 原有结束时间,正整数秒级 Unix 时间戳,需与 s_time 配合 |
其他校验规则:
date 时,该值不能为空,也不能同时提供 s_time 或 e_time。date 时,原时间戳查询规则保持:两个时间戳都传入才启用时间过滤,使用闭区间 [s_time, e_time]。[当天 00:00:00 UTC, 次日 00:00:00 UTC),不包含次日零点开始的记录。size 的最大值校验已修正为 50,超过时返回 HTTP 422。对应的 UTC 查询窗口:
HTTP 200。以下为空列表示例;有数据时 data 仍为原有 ScheduleResource 日程对象数组,本次未新增或移除对象字段。
HTTP 422:date 为空、日期格式错误、日期不存在,或与任一时间戳参数混传。原有分页、艺人 ID、状态及时间戳校验继续生效。
混传示例:?date=2026-09-01&s_time=1788220800。对应错误结构示例(提示语言以实际服务端为准):
两个接口共用时间窗口过滤逻辑,只统计存在关联艺人的日程,每条日程在同一天最多计一次。
| 状态 | 计入当天的规则 |
|---|---|
UPCOMING | scheduled_start_time 落在当天窗口内;即使有 actual_start_time,仍以预定时间为准 |
LIVE | 必须有实际开始时间且已经开播,开始时间早于窗口结束;实际结束时间不早于窗口开始,或结束时间为空且当前时间已到达该窗口 |
COMPLETED | 必须有实际开始时间,实际直播区间与当天有交集;若实际结束时间为空,仅计入实际开始时间所在日期 |
跨天直播可以计入多天,所以每天总数相加不是一周去重日程总数。为兼容原列表,实际结束时间恰好等于当天零点的直播仍计入当天,判断为 actual_end_time >= 当天零点。
尚未结束的 LIVE 记录不会仅因结束时间为空而计入尚未到达的未来日期。整个批量请求共用一个当前时间;统计接口与列表为独立请求,直播状态更新或时间跨日时可能短暂出现数量变化。
YYYY-MM-DD。date 关联日期按钮的总数。date,并移除原 s_time、e_time。翻页只调整 page,不必重复查询整周数量。data[].total;不要使用列表当前页的 data.length 或前端计算的总页数替代。0;成功响应中的 0 才表示当天没有数据。默认选中日期、周起始日期也应按 UTC 口径生成。如果具体直播时刻仍按用户本地时区显示,应明确标注,避免与 UTC 日期分组混淆。
s_time / e_time 秒级时间戳查询继续可用;但 Unix 时间戳本身不携带时区,浏览器本地零点生成的时间戳并不等于 UTC 零点。2026-09-01 00:00:00 对应 UTC 2026-08-31 16:00:00。新接口传 "2026-09-01" 查的是 UTC 9 月 1 日全天,两者范围不同。00:00:00 至 23:59:59 对应时间戳,才能对齐统计结果。