drama.js
2.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import * as v from 'valibot'
/**
* 付费墙描述:drama 是否/如何收费(剧情线/结局解锁)。
* `unlock_cost`/`user_credits`/`vip_tier` 由 server(S2 sk-facade)按需下发,驱动解锁弹窗的
* 「需 N 点 · 你有 M 点」与「开 VIP」指向;全为可选,缺省时弹窗降级为纯订阅引导。
* @typedef {{
* locked: boolean,
* price?: number,
* currency?: string,
* unlock_cost?: number,
* user_credits?: number,
* vip_tier?: string
* }} PaywallT
*/
export const Paywall = v.object({
locked: v.boolean(),
price: v.optional(v.number()),
currency: v.optional(v.string()),
/** 解锁本条剧情线所需点数(后端按规则计算下发)。 */
unlock_cost: v.optional(v.number()),
/** 当前账户点数余额(解锁弹窗实时显示,禁用判定依据)。 */
user_credits: v.optional(v.number()),
/** 「开通 VIP」指向的档位标识(如 vip-yearly)。 */
vip_tier: v.optional(v.string()),
})
/**
* drama 列表项形状:Feed 刷剧与剧本库共用。
* @typedef {{
* id: string,
* title: string,
* cover: string,
* locale: string,
* heat?: number,
* paywall?: PaywallT
* }} DramaT
*/
export const Drama = v.object({
id: v.string(),
title: v.string(),
cover: v.string(),
locale: v.string(),
heat: v.optional(v.number()),
paywall: v.optional(Paywall),
})
/**
* 高阶分页信封工厂:`Page(itemSchema)` 产出该 item 的分页 schema,复用同一信封结构。
* 统一分页形状供 Feed / 剧本库等所有列表接口共用。
* @param {import('valibot').GenericSchema} itemSchema 任意 item 的 Valibot schema
* @returns {import('valibot').GenericSchema} 该 item 的分页信封 schema
*/
export function Page(itemSchema) {
return v.object({
items: v.array(itemSchema),
page: v.number(),
page_size: v.number(),
total: v.number(),
has_more: v.boolean(),
})
}
/**
* 分页信封类型(泛型 item)。
* @template T
* @typedef {{ items: T[], page: number, page_size: number, total: number, has_more: boolean }} PageT
*/