数据准确性 - 票数初始为 0,不再用 Math.sqrt 公式造假票 - 排序 tiebreaker 统一为 votes desc + no asc,确保稳定 - store.rank() 与 sortArtists() 行为对齐 Top12 / 出道位 - Top12Bar 仅收纳真正有票的人(votes > 0),0 票时显示"出道位尚未产生"空态 - ArtistCard / RankingRow / SearchModal / MyFanSupport / RankCard 的 inTop12 高亮全部加 votes > 0 守卫 - ArtistFilters 新增"实时排名 / 编号顺序"分段切换 + 首页 sortKey 状态 领奖台 (Top3Podium) - 1 人有票即可显示领奖台(此前要求 >= 3 人才显示) - 缺位的 #2/#3 用"虚位以待"占位卡片填充,与正式卡片同 3:4 比例对齐 - 全员 0 票时三张全部显示虚位以待 - 卡片间距拉大到 gap-8 sm:gap-12 排行榜页 (/ranking) - API 票数与本地乐观投票取 max() 合并,避免 API 落后覆盖本地新票 - 合并后重新排序与赋 rank - 仅 >= 12 人有票才显示出道线分隔与复活位标记 - 复活位 gapToDebut 计算修正 跨日额度 - selectRemaining 按 quotaDate 判断是否跨日,跨日自动回满额(此前会卡在昨日剩余值) 搜索 (SearchModal) - 改为订阅 store 拿活的票数,投票后立即反映 - 默认"热门 Top12"只在真正有票时显示,否则降级为"推荐艺人 · 编号顺序" - 票数显示统一走 formatVotes(0 票不再显示 0.0w) 人物详情 - 36 人真实数据接入,移除全部静态数据(slogan/birthday/cv/themeColor) - 接入人物小传 docx 数据(年龄/身高/性格/口头禅/技能/赛道/座右铭/长简介) - 视频区与版心同宽 + 首帧自动作为封面 + 整区点击播放/暂停 + 可拖拽进度条 - 表演图片改为三张氛围图竖向 3:4,左对齐 - 移除分享按钮,投票按钮全宽 个人页 (/me) - 移除等级/邀请好友/签到/编辑资料等静态数据 - 退出登录按钮在移动端 icon-only 显示(此前 sm:hidden 导致移动端无法登出) - 我的应援 list 基于真实 myVotesByArtist 派生,凯之类的投票真正同步过去 导航 - 余票徽章未登录态显示 0/0,已登录显示 N/10 - 登录/注册按钮样式与登录后头像胶囊保持一致(紫色实心) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
72 lines
1.8 KiB
TypeScript
72 lines
1.8 KiB
TypeScript
export type ArtistTag =
|
||
| "rock"
|
||
| "pop"
|
||
| "chinese"
|
||
| "hiphop"
|
||
| "folk"
|
||
| "jazz";
|
||
|
||
export interface Artist {
|
||
/** 唯一 ID(如 001 ~ 036) */
|
||
id: string;
|
||
/** 编号字符串(如 "001") */
|
||
no: string;
|
||
/** 中文名(来自小传) */
|
||
name: string;
|
||
/** 英文名 / 艺名(来自小传) */
|
||
enName: string;
|
||
/** 年龄(来自小传) */
|
||
age?: number;
|
||
/** 性别(来自小传) */
|
||
gender?: "M" | "F";
|
||
/** 长简介 / 人物小传(来自小传) */
|
||
bio: string;
|
||
/** 立绘主图 URL */
|
||
portrait: string;
|
||
/** 圆形头像 URL(暂未使用) */
|
||
avatar: string;
|
||
/** 表演视频 URL(来自 solo.mp4,缺失则 undefined) */
|
||
videoUrl?: string;
|
||
/** 视频封面图 */
|
||
videoPoster?: string;
|
||
/** 表演图片轮播(三视图 + 氛围图 2/3) */
|
||
gallery: string[];
|
||
/** 实力标签(用于筛选) */
|
||
tags: ArtistTag[];
|
||
/** 身高 cm(来自小传) */
|
||
height: number;
|
||
/** 当前票数 */
|
||
votes: number;
|
||
/** 当前排名 (1-36) */
|
||
rank: number;
|
||
/** 座右铭(来自小传) */
|
||
motto?: string;
|
||
/** 性格描述(来自小传) */
|
||
personality?: string;
|
||
/** 口头禅(来自小传) */
|
||
catchphrase?: string;
|
||
/** 核心技能(来自小传) */
|
||
skills?: string;
|
||
/** 核心赛道(来自小传) */
|
||
track?: string;
|
||
}
|
||
|
||
export const TAG_LABEL: Record<ArtistTag, string> = {
|
||
rock: "摇滚",
|
||
pop: "流行",
|
||
chinese: "国风",
|
||
hiphop: "嘻哈说唱",
|
||
folk: "民谣治愈",
|
||
jazz: "爵士",
|
||
};
|
||
|
||
export type RankCategory = "gold" | "silver" | "bronze" | "top12" | "candidate";
|
||
|
||
export function getRankCategory(rank: number): RankCategory {
|
||
if (rank === 1) return "gold";
|
||
if (rank === 2) return "silver";
|
||
if (rank === 3) return "bronze";
|
||
if (rank <= 12) return "top12";
|
||
return "candidate";
|
||
}
|