132 lines
4.4 KiB
Markdown
132 lines
4.4 KiB
Markdown
# 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 紫色侧栏面板(不是普通按钮)— 视觉锚点
|
||
- 背景始终在深紫黑系,星点 + 紫雾装饰层
|
||
- 投票交互必须有动画仪式感
|