# CYBER ✦ STAR 虚拟偶像 Top12 出道企划 · 投票网页 ## 技术栈 | 层 | 选型 | |---|---| | 框架 | Next.js 16(App Router)· React 19 · TypeScript | | 样式 | Tailwind CSS v4(CSS-first `@theme`)· Framer Motion | | 字体 | Megrim / Audiowide / Cinzel / Inter(全部 SIL OFL 商用免费)| | 数据库 | MySQL 8 · Prisma 6 ORM | | 缓存 / 限流 | Redis(`ioredis`,未配置时降级内存)| | 身份 | Auth.js v5(手机号 OTP · 可扩展微信 / QQ)| | 校验 | Zod | | 部署 | 火山引擎 ECS · 火山引擎 TOS(对象存储)| ## 本地启动 ```bash pnpm install # 安装依赖(自动 prisma generate) cp .env.example .env # 配置环境变量(首次) pnpm dev # http://localhost:3000 ``` 未配置数据库时,前端页面会回退到 `src/lib/mock-data.ts` 的 35 位艺人 mock 数据,UI 完全可用。 ## 数据库初始化(部署时) ```bash # 1. 创建 MySQL 库 + 在 .env 设置 DATABASE_URL # 2. 推送 schema 到数据库 pnpm db:push # 3. 灌入 35 位艺人 + 活动配置 pnpm db:seed # 可视化管理(可选) pnpm db:studio ``` ## 关键脚本 | 命令 | 说明 | |---|---| | `pnpm dev` | 开发服务器(Turbopack)| | `pnpm build` | 生产构建(先 prisma generate)| | `pnpm start` | 生产服务器 | | `pnpm lint` | ESLint | | `pnpm db:push` | 把 schema 推到数据库 | | `pnpm db:migrate` | 生成迁移脚本 | | `pnpm db:seed` | 灌入种子数据 | | `pnpm db:studio` | Prisma Studio(GUI)| ## 项目结构 ``` prisma/ schema.prisma # 数据库 schema(10 个模型) seed.ts # 初始化 35 位艺人 src/ app/ layout.tsx # 根布局(含氛围装饰层) page.tsx # 首页(Hero PV + Top12 + 35 卡片) artist/[id]/ # 艺人详情页 ranking/ # 排行榜(Top3 podium + 出道线 + 候补区) me/ # 个人中心 login/ # 登录页(手机号 OTP) api/ artists/ # GET 艺人列表 / 单个详情 ranking/ # GET 实时排名 vote/ # POST 投票(含风控限流 + 事务) me/ # GET 当前用户 / POST 签到 auth/ # NextAuth handlers + send-otp components/ Logo / Navigation / Footer / NavLinks HeroBanner / Top12Bar / ArtistFilters VoteModal / FloatingVoteButton / LiveBadge ui/ # Button / Countdown cards/ # ArtistCard / ArtistPortrait artist/ # 详情页组件(视频 / 画廊 / 排名卡等) ranking/ # 排行榜组件 me/ # 个人中心组件 hooks/ useRanking.ts # 实时排名轮询 hook lib/ prisma / redis / rate-limit auth / current-user / api-response cn / mock-data / mock-user types/ artist.ts ``` ## 设计资料 - 交互原型:`../交互原型线框图.html` - 视觉规范:`../视觉规范.html` · v1.1 紫调主导 - 需求文档:`../需求分析文档.md` - 参考视觉:`../参考图.png` ## 团队需配置的外部服务 | 服务 | 用途 | 环境变量 | |---|---|---| | **MySQL(火山 RDS)** | 主数据库 | `DATABASE_URL` | | **Redis(火山实例)** | 限流 / OTP 缓存 / 实时聚合 | `REDIS_URL` | | **TOS(火山对象存储)** | 立绘 / 视频 / 头像 | `TOS_*` | | **短信网关** | 手机号 OTP | `SMS_*` | | **微信开放平台** | 微信扫码登录 | `WECHAT_APP_ID` `WECHAT_APP_SECRET` | | **hCaptcha** | 反作弊验证码 | `HCAPTCHA_*` | 详见 `.env.example`。所有这些都用 TODO 注释标记在代码中,**可灰度配置 —— 没配置时功能自动降级**。 ## 开发态便利 - **登录** :`/login` 页面下,开发环境接受万能验证码 `123456` - **mock 用户** :API 调用前自动落到 `cs_user_id` cookie,可在开发面板设置 - **mock 数据** :未配 DB 时前端自动使用 `mock-data.ts` 的 35 位艺人 - **实时排名** :API 不可用时静默回退到 mock 数据 ## 设计原则 参考 `../视觉规范.html` 的 16 个章节,核心: - 紫罗兰为主调色(不是蓝),承担 CTA / 激活态 / 描边 - 装饰星标 ✦ 用于 Logo 中间,体现品牌签 - TOP12 头像方形圆角(不是圆形)— "明星卡片"质感 - VOTE NOW 紫色侧栏面板(不是普通按钮)— 视觉锚点 - 背景始终在深紫黑系,星点 + 紫雾装饰层 - 投票交互必须有动画仪式感