Files
vtsuru.live/src/api/api-models.ts

1023 lines
22 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { UserConsumptionSetting } from './models/consumption'
export interface APIRoot<T> {
code: number
message: string
data: T
}
export interface PaginationResponse<T> extends APIRoot<T> {
total: number
pn: number
ps: number
more: boolean
}
export enum IndexTypes {
Default,
}
export enum SongListTypes {
Default,
}
export enum GuardLevel {
None = 0,
Zongdu = 1,
Tidu = 2,
Jianzhang = 3,
}
export interface UserBasicInfo {
name: string
id: number
isBiliAuthed: boolean
}
export interface UserInfo extends UserBasicInfo {
createAt: number
biliId?: number
biliRoomId?: number
canRequestSong: boolean
streamerInfo?: BaseStreamerModel
extra?: {
enableFunctions: FunctionTypes[]
isInBlackList: boolean
templateTypes: { [key: string]: string }
streamerInfo?: StreamerModel
allowCheckInRanking?: boolean // 是否允许查看签到排行
allowQuestionBoxUploadImage?: boolean // 是否允许问题箱上传图片
}
}
export interface EventFetcherStateModel {
online: boolean
status: { [errorCode: string]: string }
version?: string
todayReceive: number
useCookie: boolean
type: EventFetcherType
}
export enum EventFetcherType {
Application,
OBS,
Tauri,
Server,
}
export interface AccountInfo extends UserInfo {
isEmailVerified: boolean
isBiliVerified: boolean
biliVerifyCode?: string
bindEmail?: string
settings: UserSetting
consumptionSettings: UserConsumptionSetting
token: string
point: number
biliAuthCode?: string
biliAuthCodeStatus: BiliAuthCodeStatusType
eventFetcherState: EventFetcherStateModel
nextSendEmailTime?: number
isServerFetcherOnline: boolean
blackList: UserBasicInfo[]
biliBlackList: { [key: string]: string }
streamerInfo?: StreamerModel
biliUserAuthInfo?: BiliAuthModel
}
export interface BaseStreamerModel {
name: string
uId: number
roomId: number
faceUrl: string
title: string
coverUrl: string
frameUrl: string
area: string
parentArea: string
lastStreamAt: number
isStreaming: boolean
}
export interface StreamerModel extends BaseStreamerModel {
totalDanmakuCount: number
totalIncome: number
totalStreamCount: number
totalStreamTime: number
lastDanmakuCount: number
}
export enum BiliAuthCodeStatusType {
NotBind,
Active,
Notfound,
Inactive,
}
export interface Setting_SendEmail {
recieveQA: boolean
recieveQAReply: boolean
receiveOrder: boolean
}
export enum SaftyLevels {
Disabled,
Low,
Medium,
High,
}
export interface Setting_QuestionBox {
allowUnregistedUser: boolean
saftyLevel: SaftyLevels
allowImageUpload: boolean
}
export interface UserSetting {
sendEmail: Setting_SendEmail
questionBox: Setting_QuestionBox
songRequest: Setting_LiveRequest
queue: Setting_Queue
point: Setting_Point
questionDisplay: Setting_QuestionDisplay
index: Setting_Index
enableFunctions: FunctionTypes[]
indexTemplate: string | null
songListTemplate: string | null
scheduleTemplate: string | null
}
export interface Setting_Index {
allowDisplayInIndex: boolean
videos: string[]
notification: string
links: { [key: string]: string }
/**
* 自定义链接顺序(存储链接名称的有序数组)
* 旧数据无此字段时在前端初始化为 Object.keys(links)
*/
linkOrder?: string[]
}
export interface Setting_LiveRequest {
orderPrefix: string
sortType?: QueueSortType
enableOnStreaming: boolean
onlyAllowSongList: boolean
queueMaxSize: number
allowAllDanmaku: boolean
allowFromWeb: boolean
allowAnonymousFromWeb: boolean
needWearFanMedal: boolean
needJianzhang: boolean
needTidu: boolean
needZongdu: boolean
allowSC: boolean
scIgnoreLimit: boolean
scMinPrice: number
fanMedalMinLevel: number
allowReorderSong: boolean
enableCooldown: boolean
cooldownSecond: number
zongduCooldownSecond: number
tiduCooldownSecond: number
jianzhangCooldownSecond: number
allowGift: boolean
giftNames?: string[]
minGiftPrice?: number
giftFilterType: QueueGiftFilterType
allowIncreasePaymentBySendGift: boolean
allowIncreaseByAnyPayment: boolean
sendGiftIgnoreLimit: boolean
showRequireInfo: boolean
showUserName: boolean
showFanMadelInfo: boolean
obsTitle: string
obsTitleToday: string
isReverse: boolean
}
export interface Setting_Queue {
keyword: string
enableOnStreaming: boolean
matchType: KeywordMatchType
sortType?: QueueSortType
queueMaxSize: number
allowAllDanmaku: boolean
allowFromWeb: boolean
needJianzhang: boolean
needTidu: boolean
needZongdu: boolean
fanMedalMinLevel?: number
allowGift: boolean
giftNames?: string[]
minGiftPrice?: number
giftFilterType: QueueGiftFilterType
allowIncreasePaymentBySendGift: boolean
allowIncreaseByAnyPayment: boolean
sendGiftDirectJoin: boolean
sendGiftIgnoreLimit: boolean
enableCooldown: boolean
cooldownSecond: number
zongduCooldownSecond: number
tiduCooldownSecond: number
jianzhangCooldownSecond: number
showRequireInfo: boolean
showPayment: boolean
showFanMadelInfo: boolean
isReverse: boolean
}
export interface Setting_Point {
allowType: EventDataTypes[]
jianzhangPoint: number // decimal maps to number in TypeScript
tiduPoint: number // decimal maps to number in TypeScript
zongduPoint: number // decimal maps to number in TypeScript
giftPercentMap: { [key: string]: number } // Dictionary<string, double> maps to an index signature in TypeScript
scPointPercent: number // double maps to number in TypeScript
giftPointPercent: number // double maps to number in TypeScript
giftAllowType: SettingPointGiftAllowType
shouldDiscontinueWhenSoldOut: boolean
// 签到系统设置
enableCheckIn: boolean // 是否启用签到功能
checkInKeyword: string // 签到关键词
givePointsForCheckIn: boolean // 是否为签到提供积分
baseCheckInPoints: number // 基础签到积分
enableConsecutiveBonus: boolean // 是否启用连续签到奖励
bonusPointsPerDay: number // 每天额外奖励积分
maxBonusPoints: number // 最大奖励积分
allowSelfCheckIn: boolean // 是否允许自己签到
requireAuth: boolean // 是否需要认证
// 每日首次互动奖励设置
enableDailyFirstDanmaku: boolean // 是否启用每日首次弹幕奖励
dailyFirstDanmakuPoints: number // 每日首次弹幕积分
enableDailyFirstGift: boolean // 是否启用每日首次礼物奖励
dailyFirstGiftPoints: number // 每日首次礼物积分(固定积分)
useDailyFirstGiftPercent: boolean // 是否使用礼物价值比例计算
dailyFirstGiftPercent: number // 每日首次礼物价值比例
// 仅开播时生效设置
dailyFirstOnlyOnStreaming: boolean
checkInOnlyOnStreaming: boolean
}
export interface Setting_QuestionDisplay {
font?: string // Optional string, with a maximum length of 30 characters
nameFont: string // Optional string, with a maximum length of 30 characters
fontSize: number // Default is 20
fontWeight: number
nameFontSize: number // Default is 20
lineSpacing: number // Default is 0, 行间距
fontColor?: string // Optional string, must exactly be 6 characters long
nameFontColor?: string // Optional string, must exactly be 6 characters long
nameFontWeight?: number
backgroundColor?: string // Optional string, must exactly be 6 characters long
showUserName: boolean // Default is true
align: QuestionDisplayAlign // Default is QuestionDisplayAlign.Left, 对齐
showImage: boolean // Default is false
borderColor?: string
borderWidth?: number
syncScroll: boolean
currentQuestion?: number
}
export enum QuestionDisplayAlign {
Left,
Right,
Center,
}
export enum SettingPointGiftAllowType {
All,
WhiteList,
}
export enum KeywordMatchType {
Full,
Contains,
Regex,
}
export enum QueueSortType {
GuardFirst,
PaymentFist,
TimeFirst,
FansMedalFirst,
}
export enum QueueGiftFilterType {
Or,
And,
}
export enum FunctionTypes {
SongList,
QuestionBox,
Schedule,
LiveRequest,
Queue,
Point,
VideoCollect,
CheckInRanking,
}
export interface SongAuthorInfo {
name: string
id: number
}
export enum SongFrom {
Custom,
Netease,
FiveSing,
Kugou,
}
export interface SongsInfo {
id: number
key: string
name: string
translateName?: string
author: string[]
url: string
from: SongFrom
language: string[]
description?: string
tags?: string[]
createTime: number
updateTime: number
// paidSong: boolean
options?: SongRequestOption
cover?: string
}
export interface SongRequestOption {
needJianzhang: boolean
needTidu: boolean
needZongdu: boolean
scMinPrice?: number
fanMedalMinLevel?: number
}
export enum SongLanguage {
Chinese, // 中文
English, // 英文
Japanese, // 日文
Spanish, // 西班牙文
French, // 法文
Other, // 其他
}
export enum LevelTypes {
Info,
Success,
Warn,
Error,
}
export interface NotifactionInfo {
id: string
createTime: number
title: string
message: string
type: LevelTypes
}
// SENSITIVE_TERM, HATE, VIOLENCE, PORNOGRAPHY, POLITICS, ADVERTISING, AGGRESSION
export enum ViolationTypes {
SENSITIVE_TERM,
HATE,
VIOLENCE,
PORNOGRAPHY,
POLITICS,
ADVERTISING,
AGGRESSION,
}
export interface QAReviewInfo {
isApproved: boolean
saftyScore: number
violationType: ViolationTypes[]
}
export interface QAInfo {
id: number
sender: UserBasicInfo
target: UserBasicInfo
question: { message: string }
answer?: { message: string, createdAt: number }
isReaded?: boolean
isSenderRegisted: boolean
isPublic: boolean
isFavorite: boolean
sendAt: number
isAnonymous: boolean
answerImages?: UploadFileResponse[]
questionImages?: UploadFileResponse[]
tag?: string
reviewResult?: QAReviewInfo
anonymousName?: string
anonymousEmail?: string
}
export interface LotteryUserInfo {
name: string
uId: number
level?: number
avatar: string
location?: string
isVIP?: boolean
card?: LotteryUserCardInfo
visiable: boolean
}
export interface LotteryUserCardInfo {
name: string
level: number
guardLevel: number
isGuard: boolean
isCharge: boolean
}
export interface ScheduleWeekInfo {
year: number
week: number
days: ScheduleDayInfo[][]
}
export interface ScheduleDayInfo {
title: string | null
tag: string | null
tagColor: string | null
time: string | null
id: string | null
}
export interface BatchScheduleRequest {
startYear: number
startWeek: number
count: number
dayOfWeek: number
schedule: ScheduleDayInfo
}
export enum ThemeType {
Auto = 'auto',
Light = 'light',
Dark = 'dark',
}
export interface VideoCollectCreateModel {
id?: string
name: string
description: string
endAt: number
maxVideoCount: number
}
export interface VideoCollectTable {
id: string
shortId: string
name: string
description: string
createAt: number
endAt: number
isFinish: boolean
videoCount: number
maxVideoCount: number
owner: UserBasicInfo
}
export interface VideoCollectVideo {
id: string
title: string
description: string
publistTime: number
ownerName: string
ownerUId: number
cover: string
length: number
watched?: boolean
}
export enum VideoFrom {
Collect,
Spam,
}
export enum VideoStatus {
Pending,
Accepted,
Rejected,
}
export interface VideoSender {
sendAt: number
sender?: string
senderId?: number
description?: string
from: VideoFrom
}
export interface VideoInfo {
bvid: string
senders: VideoSender[]
status: VideoStatus
}
export interface VideoCollectDetail {
table: VideoCollectTable
videos: { info: VideoInfo, video: VideoCollectVideo }[]
}
export interface GameInfo {
game_id: string
}
export interface WebsocketInfo {
auth_body: string
wss_link: string[]
}
export interface AnchorInfo {
room_id: number
uname: string
uface: string
uid: number
open_id: string
}
export interface OpenLiveInfo {
game_info: GameInfo
websocket_info: WebsocketInfo
anchor_info: AnchorInfo
}
export interface OpenLiveLotteryUserInfo {
name: string
uId: number
openId: string
level?: number
avatar: string
fans_medal_level: number
fans_medal_name: string // 粉丝勋章名
fans_medal_wearing_status: boolean // 该房间粉丝勋章佩戴情况
guard_level: number
}
export enum OpenLiveLotteryType {
Waiting,
Result,
}
export interface UpdateLiveLotteryUsersModel {
users: OpenLiveLotteryUserInfo[]
resultUsers: OpenLiveLotteryUserInfo[]
type: OpenLiveLotteryType
}
export interface SongRequestInfo {
id: number
songName: string
song?: SongsInfo
status: SongRequestStatus
from: SongRequestFrom
price?: number
user?: DanmakuUserInfo
createAt: number
finishAt?: number
isInLocal?: boolean
}
export interface DanmakuUserInfo {
name: string
uid: number
oid: string
face: string
guard_level: number
fans_medal_level: number
fans_medal_name: string
fans_medal_wearing_status: boolean
}
export enum SongRequestFrom {
Manual,
Danmaku,
SC,
Web,
Gift,
}
export enum QueueFrom {
Manual,
Danmaku,
Gift,
Web,
}
export enum SongRequestStatus {
Waiting,
Singing,
Finish,
Cancel,
}
export enum QueueStatus {
Waiting,
Progressing,
Finish,
Cancel,
}
export interface EventModel {
type: EventDataTypes
uname: string
uface: string
uid: number
open_id: string
msg: string
time: number
num: number
price: number
guard_level: GuardLevel
fans_medal_level: number
fans_medal_name: string
fans_medal_wearing_status: boolean
emoji?: string
ouid: string
}
export enum EventDataTypes {
Guard,
SC,
Gift,
Message,
Like,
SCDel,
Enter,
Follow,
}
export interface ResponseQueueModel {
id: number
status: QueueStatus
from: QueueFrom
giftPrice?: number
content?: string
user?: DanmakuUserInfo
createAt: number
finishAt?: number | null
isInLocal?: boolean
}
export interface ResponseLiveInfoModel {
liveId: string
isFinish: boolean
parentArea: string
area: string
coverUrl: string
danmakusCount: number
startAt: number
stopAt: number | null
title: string
totalIncome: number
totalIncomeWithGuard: number
likeCount: number
paymentCount: number
interactionCount: number
}
export interface DanmakuModel {
id: string
uId: number
uName: string
type: EventDataTypes // Assuming EventDataTypes is an enum or type available in your TypeScript codebase
time: number
msg: string | null
price: number | null
isEmoji: boolean
num: number
ouId: string
}
export interface ResponseFeedbackModel {
message: string
type: FeedbackType
status: FeedbackStatus
replyMessage?: string
userName?: string
createAt: number
}
export enum FeedbackType {
Opinion,
Bug,
FunctionRequest,
Other,
}
export enum FeedbackStatus {
Padding,
Progressing,
Finish,
Todo,
Reject,
Developing,
}
export interface TagInfo {
name: string
color: string
}
export enum GoodsStatus {
Normal, // 商品正常
// OutOfStock, // 商品无货
Discontinued, // 商品下架
}
export enum GoodsTypes {
Physical,
Virtual,
}
// 添加密钥选择模式枚举
export enum KeySelectionMode {
None,
Random, // 随机选择
Sequential, // 顺序选择
}
export interface PointGoodsSetting {
guardFree?: { year: number, month: number }
allowGuardLevel?: GuardLevel
}
export interface ResponsePointGoodModel {
id: number
name: string
description: string
content?: string
count?: number
price: number
tags: string[]
cover?: UploadFileResponse
images: string[]
status: GoodsStatus
type: GoodsTypes
isAllowRebuy: boolean
maxBuyCount?: number
collectUrl?: string
embedCollectUrl?: boolean
isPinned: boolean
canFreeBuy: boolean
allowGuardLevel: GuardLevel
setting: PointGoodsSetting
// 购买状态信息
purchasedCount: number
hasPurchased: boolean
canPurchase: boolean
cannotPurchaseReason?: string
// 添加虚拟礼物多Key支持
virtualKeys?: string[]
keySelectionMode?: KeySelectionMode
currentKeyIndex?: number
}
export interface UploadPointGoodsModel {
id?: number
name: string
count?: number
price: number
tags: string[]
cover?: UploadFileResponse
status: GoodsStatus
type: GoodsTypes
collectUrl?: string
embedCollectUrl?: boolean
description: string
content?: string
isAllowRebuy: boolean
maxBuyCount?: number
isPinned: boolean
setting: PointGoodsSetting
// 添加虚拟礼物多Key支持
virtualKeys?: string[]
keySelectionMode?: KeySelectionMode
currentKeyIndex?: number
}
export interface AddressInfo {
id?: string
province: string
city?: string
district?: string
street?: string
address: string
phone: number
name: string
}
export interface BiliAuthBaseModel {
id: number
userId: number
openId: string
avatar: string
name: string
createAt: number
}
export interface BiliAuthModel extends BiliAuthBaseModel {
address?: AddressInfo[]
token: string
guardInfo: Record<number, GuardLevel>
}
export interface ResponsePointUserModel {
point: number
orderCount: number
isAuthed: boolean
info: BiliAuthBaseModel
updateAt: number
createAt: number
trackingNumber?: string
expressCompany?: string
}
export interface ResponsePointOrder2OwnerModel {
instanceOf: 'owner'
id: number
point: number
type: GoodsTypes
customer: BiliAuthModel
address?: AddressInfo
goods: ResponsePointGoodModel
count: number
createAt: number
updateAt: number
status: PointOrderStatus
remark?: string
trackingNumber?: string
expressCompany?: string
}
export interface ResponsePointOrder2UserModel {
instanceOf: 'user'
id: number
point: number
type: GoodsTypes
address?: AddressInfo
goods: ResponsePointGoodModel
status: PointOrderStatus
createAt: number
remark?: string
trackingNumber?: string
expressCompany?: string
}
export enum PointOrderStatus {
Pending, // 订单正在等待处理
Shipped, // 订单已发货
Completed, // 订单已完成
}
// 积分历史记录的 extra 字段类型定义
// 为了保持向后兼容并避免类型检查问题,使用通用的 extra 接口,但提供详细注释
export interface PointHistoryExtraBase {
user?: UserBasicInfo
// Danmaku 类型特有字段
danmaku?: DanmakuModel
// Manual 类型特有字段
reason?: string
// Use 类型特有字段
goods?: ResponsePointGoodModel | null
isDiscontinued?: boolean
remark?: string
// DailyFirstInteraction 类型特有字段
interactionType?: string // 'danmaku' | 'gift'
}
export interface ResponsePointHisrotyModel {
point: number
ouId: string
type: EventDataTypes
from: PointFrom
createAt: number
count: number
/**
* 根据 from 字段extra 包含不同的数据:
* - PointFrom.Danmaku: { user: UserBasicInfo, danmaku: DanmakuModel }
* - PointFrom.Manual: { user: UserBasicInfo, reason?: string }
* - PointFrom.Use: { user: UserBasicInfo, goods: ResponsePointGoodModel | null, isDiscontinued: boolean, remark?: string }
* - PointFrom.CheckIn: { user: UserBasicInfo }
* - PointFrom.DailyFirstInteraction: { user: UserBasicInfo, interactionType: string, danmaku?: DanmakuModel | null }
*/
extra?: PointHistoryExtraBase
}
export enum PointFrom {
Danmaku,
Manual,
Use,
CheckIn,
DailyFirstInteraction,
}
export interface ResponseUserIndexModel {
notification: string
videos: VideoCollectVideo[]
links: { [key: string]: string }
linkOrder?: string[]
}
// 签到排行信息
export interface CheckInRankingInfo {
ouId: string
name: string
consecutiveDays: number
points: number
lastCheckInTime: number
isAuthed: boolean
monthlyCheckInCount?: number // 本月签到次数
totalCheckInCount?: number // 总签到次数
}
// 签到结果
export interface CheckInResult {
success: boolean
message: string
points: number
consecutiveDays: number
todayRank: number
}
/**
* 文件类型枚举
*/
export enum UserFileTypes {
Image = 0,
Audio = 1,
Video = 2,
Document = 3,
Other = 4,
}
/**
* 文件存储位置枚举
*/
export enum UserFileLocation {
Local = 0,
}
/**
* 文件上传响应接口
*/
export interface UploadFileResponse {
id: number
path: string
name: string
hash: string
}
/**
* 扩展的文件信息接口,用于文件上传组件
*/
export interface ExtendedUploadFileInfo {
id: string // 文件唯一标识符
name: string // 文件名称
status: 'uploading' | 'finished' | 'error' | 'removed' // 上传状态
thumbnailUrl?: string // 缩略图URL
file?: File // 可选的文件对象
}
// 弹幕投票相关类型定义
export enum VoteResultMode {
ByCount = 0, // 按人数计票
ByGiftValue = 1, // 按礼物价值计票
}
export interface APIFileModel {
id: number
path: string
name: string
hash: string
}
export interface VoteConfig {
isEnabled: boolean
showResults: boolean
voteDurationSeconds: number
voteCommand: string
voteEndCommand: string
voteTitle: string
allowMultipleOptions: boolean
allowMultipleVotes: boolean
allowCustomOptions: boolean
logVotes: boolean
defaultOptions: string[]
backgroundFile?: APIFileModel
backgroundColor: string
textColor: string
optionColor: string
roundedCorners: boolean
displayPosition: string
allowGiftVoting: boolean
minGiftPrice?: number
voteResultMode: VoteResultMode
}
export interface VoteOption {
text: string
count: number
voters: string[]
percentage?: number // 用于OBS显示
}
export interface ResponseVoteSession {
id: number
title: string
options: VoteOption[]
startTime: number
endTime?: number
isActive: boolean
totalVotes: number
creator?: UserBasicInfo
}
export interface RequestCreateBulletVote {
title: string
options: string[]
allowMultipleVotes: boolean
durationSeconds?: number
}
export interface VoteOBSData {
title: string
options: VoteOption[]
totalVotes: number
showResults: boolean
isEnding: boolean
backgroundImage?: string
backgroundColor: string
textColor: string
optionColor: string
roundedCorners: boolean
displayPosition: string
endTime?: number
}