- 范围:全仓除已完成的 game-cloud/game-admin(及排除区);91 文件 - cn.iocoder.yudao→com.wanxiang.huijing / cn.wanxiang.game→com.wanxiang.huijing.game / cn.iocoder.cloud→com.wanxiang / Yudao*→Huijing* / bare yudao→huijing - 含 contracts/api-schemas(apiInterface FQCN)、docs/architecture+agent-specs(含中文名,git ls-files -z 修复)、AGENTS.md/CLAUDE.md 等根文档 - 保留不动:上游归属 URL(gitee/github yudaocode·YunaiV,改则断链+违反署名)、game-cloud Flyway 迁移注释(保 checksum)、lockfile(装包重生) - 纯文档/字符串,零构建影响(game-cloud/game-admin 字节码未动) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
275 lines
15 KiB
YAML
275 lines
15 KiB
YAML
openapi: 3.0.3
|
||
# 契约 #1 API | 模块:feed(游戏流/双轨专区浏览/推荐)| owner:WS(feed),全员 review
|
||
# 端:/app-api(产品端 game-studio,用户 Token;匿名玩家亦可浏览游戏流)/admin-api(管理端 game-admin,RBAC 精选池运营)
|
||
# 前缀由 huijing 框架按 controller.app/admin 包名自动添加;本文件 path 直接写含前缀的完整对外路径
|
||
# 错误码段:feed = 1-103-***-***(本模块独占,禁止与他模块重叠)
|
||
# 响应统一 Huijing CommonResult 信封:{ code, data, msg };code=0 成功
|
||
# 脊柱对接:消费 project 已发布(status=4) + zone(双轨:1官方精选/2UGC普通,game_zone/game_project_zone 已建表);
|
||
# 游戏流分页(cursor) + 按 quality_score(telemetry 回灌)降序排序;排序结果可走 game_feed_rank 缓存,否则直接读 project/zone。
|
||
# 边界 OUT:不存游戏本体/Zone 实体(读 project)|不算 quality_score(消费 telemetry)|不裁决举报(转 compliance)。
|
||
info:
|
||
title: 绘境AI feed 模块 API
|
||
version: 1.0.0
|
||
description: >-
|
||
游戏流(竖屏即玩、cursor 分页/去重、quality_score 排序)+ 双轨专区浏览(官方精选/UGC 普通)
|
||
+ 互动信号写入(赞/藏/享/举报→权重)+ 分享页/OG 元数据 + 精选池运营。
|
||
覆盖产品功能 P-FED-01/02/03/04/05/06/07/08/09/10/11/13、P-PLZ-01/02、P-OPN-03。
|
||
前端据此 vite-plugin-mock 自动生成 mock。
|
||
|
||
servers:
|
||
- url: http://localhost:48080
|
||
description: 本地(Swagger/Knife4j http://localhost:48080/doc.html)
|
||
|
||
paths:
|
||
# ===========================================================================
|
||
# 游戏流(脊柱主路:消费 project status=4 + quality_score 排序 → 竖屏 cursor 流)
|
||
# ===========================================================================
|
||
/app-api/feed/stream:
|
||
get:
|
||
tags: [app-feed]
|
||
summary: 游戏流(竖屏即玩,cursor 分页,按 quality_score 降序;P-FED-01/02/13)
|
||
description: >-
|
||
默认混合流:仅取 project status=4 已发布、compliance 未下架的游戏;
|
||
排序优先读 game_feed_rank 缓存(Redis TTL 60s 兜底),否则直接按 quality_score 降序 + 新人保底/冷启动兜底。
|
||
游戏本体元信息(标题/封面/作者/包地址)来自 project 契约 #1,feed 不持久化本体。
|
||
parameters:
|
||
- { name: cursor, in: query, required: false, schema: { type: string }, description: 'cursor 游标(首屏不传;透传上页 nextCursor 翻页,T-FED-06)' }
|
||
- { name: size, in: query, required: false, schema: { type: integer, default: 10, minimum: 1, maximum: 30 }, description: 单页条数(预加载三容器,默认 10) }
|
||
responses:
|
||
'200':
|
||
description: 成功(游戏流卡片 + 下一页游标)
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/CommonResultFeedStream' }
|
||
|
||
/app-api/feed/zones:
|
||
get:
|
||
tags: [app-feed]
|
||
summary: 双轨专区列表(官方精选 / UGC 普通;P-PLZ-01/02)
|
||
description: 读 project 契约 #1 的 game_zone(type=1官方精选 2UGC普通、status=1启用),按 sort 升序返回;feed 不拥有 Zone 实体。
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/CommonResultZoneList' }
|
||
|
||
/app-api/feed/zone/stream:
|
||
get:
|
||
tags: [app-feed]
|
||
summary: 按 Zone 分区游戏流(双区独立候选,cursor 分页;P-PLZ-01/02 · T-FED-15)
|
||
description: >-
|
||
指定专区内的游戏流,候选集 = game_project_zone(zone_id) ∩ project(status=4) ∩ compliance 未下架,
|
||
同样按 quality_score 降序 + cursor 分页。授权 IP / UGC 双区候选互相隔离。
|
||
parameters:
|
||
- { name: zoneId, in: query, required: true, schema: { type: integer, format: int64 }, description: 专区 ID(game_zone.id) }
|
||
- { name: cursor, in: query, required: false, schema: { type: string }, description: cursor 游标 }
|
||
- { name: size, in: query, required: false, schema: { type: integer, default: 10, minimum: 1, maximum: 30 } }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/CommonResultFeedStream' }
|
||
|
||
# ===========================================================================
|
||
# 互动信号写入(赞/藏/享/举报 → 权重;P-FED-03/04/05/06 · T-FED-08)
|
||
# ===========================================================================
|
||
/app-api/feed/interact:
|
||
post:
|
||
tags: [app-feed]
|
||
summary: 互动信号写入(点赞/收藏/分享/举报 → 排序权重;P-FED-03/04/05/06)
|
||
description: >-
|
||
同步写互动信号流水(game_feed_interact_log,幂等去重)并产出排序加权信号;举报(action=report)同步转 compliance 受理(T-CMP-10),
|
||
feed 不裁决。累计计数最终态归 project/community,本端只负责"信号→权重"。
|
||
前端同时通过 telemetry 契约 #5 批量上报对应事件(like/favorite/share/report),两路互不替代。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/FeedInteractReqVO' }
|
||
responses:
|
||
'200':
|
||
description: 成功(返回该游戏该动作的最新聚合计数)
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/CommonResultInteractResult' }
|
||
|
||
# ===========================================================================
|
||
# 分享页 / OG 元数据 + 渠道参数(P-FED-05/07/08/09 · T-FED-09/10)
|
||
# ===========================================================================
|
||
/app-api/feed/share/{gameId}:
|
||
get:
|
||
tags: [app-feed]
|
||
summary: 分享落地页 OG 元数据 + 带渠道参数的分享链接(P-FED-07/08/09)
|
||
description: >-
|
||
返回独立分享链接(含 utm/channel 渠道参数,T-FED-10)与 OG 元数据(标题/封面/描述,供落地页 SSR 渲染、社交平台抓取)。
|
||
游戏元信息读 project 契约 #1;仅 status=4 已发布可分享,否则返回 1-103-002-001。
|
||
parameters:
|
||
- { name: gameId, in: path, required: true, schema: { type: integer, format: int64 } }
|
||
- { name: channel, in: query, required: false, schema: { type: string }, description: '渠道标识(写入分享链接 utm_source,用于渠道归因 T-FED-10)' }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/CommonResultShareMeta' }
|
||
|
||
# ===========================================================================
|
||
# 精选池运营(管理端 RBAC;P-OPN-03 · T-FED-14)
|
||
# ===========================================================================
|
||
/admin-api/feed/featured/page:
|
||
get:
|
||
tags: [admin-feed]
|
||
summary: 精选池列表(管理端 RBAC;P-OPN-03)
|
||
description: 分页查看当前进入精选池的游戏(game_feed_rank.pinned=1 或 project.featured=1 的运营加权项)。
|
||
parameters:
|
||
- { name: zoneId, in: query, required: false, schema: { type: integer, format: int64 }, description: 按专区筛选 }
|
||
- { name: pageNo, in: query, required: false, schema: { type: integer, default: 1 } }
|
||
- { name: pageSize, in: query, required: false, schema: { type: integer, default: 10 } }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/CommonResultFeaturedPage' }
|
||
|
||
/admin-api/feed/featured:
|
||
post:
|
||
tags: [admin-feed]
|
||
summary: 精选池置顶/取消 + 运营加权(管理端 RBAC;P-OPN-03 · T-FED-14)
|
||
description: >-
|
||
运营对单个游戏在游戏流/专区流中置顶或取消(写 game_feed_rank.pinned 与 boost 加权因子)。
|
||
仅 project status=4 已发布可入精选;非法目标返回 1-103-003-001。不改 project 本体,仅写排序覆盖层。
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/FeaturedReqVO' }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/CommonResultBoolean' }
|
||
|
||
components:
|
||
schemas:
|
||
# ---- Huijing CommonResult 信封 ----
|
||
CommonResultBoolean:
|
||
type: object
|
||
properties:
|
||
code: { type: integer, description: '0=成功,非0=错误码 1-103-***-***' }
|
||
data: { type: boolean }
|
||
msg: { type: string }
|
||
CommonResultFeedStream:
|
||
type: object
|
||
properties:
|
||
code: { type: integer }
|
||
data: { $ref: '#/components/schemas/FeedStreamRespVO' }
|
||
msg: { type: string }
|
||
CommonResultZoneList:
|
||
type: object
|
||
properties:
|
||
code: { type: integer }
|
||
data: { type: array, items: { $ref: '#/components/schemas/ZoneRespVO' } }
|
||
msg: { type: string }
|
||
CommonResultInteractResult:
|
||
type: object
|
||
properties:
|
||
code: { type: integer }
|
||
data: { $ref: '#/components/schemas/InteractResultRespVO' }
|
||
msg: { type: string }
|
||
CommonResultShareMeta:
|
||
type: object
|
||
properties:
|
||
code: { type: integer }
|
||
data: { $ref: '#/components/schemas/ShareMetaRespVO' }
|
||
msg: { type: string }
|
||
CommonResultFeaturedPage:
|
||
type: object
|
||
properties:
|
||
code: { type: integer }
|
||
data:
|
||
type: object
|
||
properties:
|
||
list: { type: array, items: { $ref: '#/components/schemas/FeedCardRespVO' } }
|
||
total: { type: integer, format: int64 }
|
||
msg: { type: string }
|
||
|
||
# ---- 游戏流 ----
|
||
FeedStreamRespVO:
|
||
type: object
|
||
description: 游戏流分页结果(cursor 模型,不返回 total,避免深翻页代价)
|
||
properties:
|
||
list: { type: array, items: { $ref: '#/components/schemas/FeedCardRespVO' } }
|
||
nextCursor: { type: string, description: '下一页游标;为空串表示已到底(T-FED-06)' }
|
||
hasMore: { type: boolean, description: 是否还有下一页 }
|
||
FeedCardRespVO:
|
||
type: object
|
||
description: 游戏流单卡(首屏封面 + 即玩入口;本体元信息源自 project 契约 #1,feed 不持久化)
|
||
properties:
|
||
gameId: { type: integer, format: int64, description: 游戏 ID(project.id) }
|
||
versionId: { type: integer, format: int64, description: 当前生效版本 ID(project.currentVersionId,供 runtime 即玩加载) }
|
||
title: { type: string, description: 标题(来自 project) }
|
||
coverUrl: { type: string, description: 封面图 URL(首屏卡片展示,P-FED-11) }
|
||
authorName: { type: string, description: 作者昵称(来自 project 作者元信息) }
|
||
packageUrl: { type: string, description: GamePackage manifest URL(runtime 加载,加载进度反馈 P-FED-10) }
|
||
zoneId: { type: integer, format: int64, description: 所属专区 ID(双轨归类) }
|
||
qualityScore: { type: number, format: float, description: '运营质量分(0-100),由 telemetry 回灌,作为 FeedCard 排序依据(仅展示/调试用);≠ aigc 生成质量分(0-1),两者量纲不同,不可混用' }
|
||
playCount: { type: integer, format: int64, description: 累计试玩数(project 回写) }
|
||
likeCount: { type: integer, format: int64, description: 累计点赞数(project 回写) }
|
||
liked: { type: boolean, description: 当前用户是否已赞(登录态;匿名恒为 false) }
|
||
favorited: { type: boolean, description: 当前用户是否已收藏(登录态) }
|
||
|
||
# ---- 专区 ----
|
||
ZoneRespVO:
|
||
type: object
|
||
description: 专区(读 project 契约 #1 game_zone,feed 不拥有 Zone 实体)
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
name: { type: string, description: 专区名称 }
|
||
type: { type: integer, description: '专区类型(双轨):1官方精选 2UGC普通' }
|
||
sort: { type: integer, description: 排序(升序) }
|
||
|
||
# ---- 互动 ----
|
||
FeedInteractReqVO:
|
||
type: object
|
||
required: [gameId, action]
|
||
properties:
|
||
gameId: { type: integer, format: int64, description: 目标游戏 ID }
|
||
action: { type: integer, enum: [1, 2, 3, 4], description: '互动动作:1点赞 2收藏 3分享 4举报' }
|
||
active: { type: boolean, default: true, description: '是否激活(点赞/收藏可取消:true=赞/藏,false=取消;分享/举报恒 true)' }
|
||
reason: { type: string, maxLength: 200, description: '举报理由(action=4 时必填,转 compliance 受理 T-CMP-10)' }
|
||
InteractResultRespVO:
|
||
type: object
|
||
description: 互动后该游戏该动作的最新聚合(计数最终态归 project/community,本端回显便于前端即时刷新)
|
||
properties:
|
||
gameId: { type: integer, format: int64 }
|
||
action: { type: integer, description: '1点赞 2收藏 3分享 4举报' }
|
||
active: { type: boolean, description: 该用户当前对该动作的激活态 }
|
||
totalCount: { type: integer, format: int64, description: 该动作累计计数 }
|
||
|
||
# ---- 分享 ----
|
||
ShareMetaRespVO:
|
||
type: object
|
||
description: 分享落地页 OG 元数据 + 带渠道参数的分享链接(T-FED-09/10)
|
||
properties:
|
||
gameId: { type: integer, format: int64 }
|
||
shareUrl: { type: string, description: '独立分享链接(含 utm/channel 渠道参数,P-FED-07)' }
|
||
ogTitle: { type: string, description: 'OG 标题(社交平台抓取)' }
|
||
ogImage: { type: string, description: 'OG 封面图 URL' }
|
||
ogDescription: { type: string, description: 'OG 描述' }
|
||
channel: { type: string, description: 回显的渠道标识(渠道归因 T-FED-10) }
|
||
versionId: { type: integer, format: int64, description: '当前生效版本 ID(GAP-3,与 FeedItem.versionId 同源 project.currentVersionId;仅已发布游戏回填,未发布或无生效版本留空,供分享落地页直达即玩加载)' }
|
||
|
||
# ---- 精选池运营 ----
|
||
FeaturedReqVO:
|
||
type: object
|
||
required: [gameId, pinned]
|
||
properties:
|
||
gameId: { type: integer, format: int64, description: 目标游戏 ID(须 project status=4 已发布) }
|
||
zoneId: { type: integer, format: int64, description: '作用专区 ID;不传表示作用于默认混合流' }
|
||
pinned: { type: boolean, description: 'true=置顶进精选池 / false=取消置顶' }
|
||
boost: { type: number, format: float, description: '运营加权因子(叠加到 quality_score 排序,默认 0)' }
|