# nova-app
**Repository Path**: sean_lottery/nova-app
## Basic Information
- **Project Name**: nova-app
- **Description**: No description available
- **Primary Language**: JavaScript
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-05-26
- **Last Updated**: 2026-06-15
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# nova-app
## 项目概述
nova-app 是星轨(Nova)项目的学生端前端应用,基于 uniapp(Vue 3)构建。为林康玥(15岁,重庆初三→高一)提供 AI 学习对话界面,支持 H5 和微信小程序双端运行。
| 属性 | 内容 |
|------|------|
| 项目名称 | nova-app |
| 所属产品 | 星轨(Nova) |
| 前端框架 | uniapp(Vue 3 Composition API) |
| 状态管理 | Pinia 2.x |
| 编译目标 | H5 + 微信小程序 |
| 设计风格 | 游戏化卡片式(Gamified Card UI),深色模式默认,支持浅色模式切换 |
### 功能概览
| 功能模块 | 说明 |
|---------|------|
| 欢迎引导 | 夏夜星空背景(`StarrySky`:密星场、折线星串、柔流星、丝缎银河、薰衣草极光)+ Logo + 品牌文案 + "开始吧" CTA |
| 多端登录 | 密码登录 + 微信登录(小程序/公众号/App三端条件编译) |
| 账号注册 | 昵称+账号+密码注册 + 微信一键注册 |
| 人设选择 | 三选一人设(学长/搭档/叙述者),选中高亮发光 + 锁定持久化 |
| 今日任务 | 2×2科目卡片 + 阶段感知提示 + "开始今日学习"CTA |
| AI对话 | SSE流式打字机渲染 + 科目切换过渡动画 + 知识面板抽屉 |
| 每日完成 | 3颗发光星 + 洞察卡 + 科目完成列表 |
| 学习进度 | 总进度渐变条 + 四科进度条 + 洞察卡历史记录 |
| 20天完成 | 粒子庆祝 + 时间线回顾 + 全部洞察卡集合 |
| 双主题 | 深色(默认#0F0F1A)/ 浅色(#F5F5FA),CSS变量切换 + 持久化 |
| 响应式 | 手机/平板/PC 三断点;PC 为 CSS Grid 侧栏 + 主列(≥768px 显示侧栏,TabBar 隐藏) |
| 国际化 | vue-i18n(zh-CN / en-US);9 页壳层文案 + 登录/注册/人设;H5 全量验证,小程序以编译通过为准 |
| 离线保护 | localStorage 草稿 + API 缓存降级 + 壳层图 manifest 缓存 + 顶栏网络状态提示 |
| 壳层远程图 | Logo、人设、空态插图由后端 `GET /profile/app-assets/**` 提供;H5 用 SVG、小程序用 PNG;`RemoteImage` 占位与兜底 |
| 鉴权与引导 | 登录→人设→首页链路守卫;已登录自动跳转;各业务页 `onShow` 复检 |
| 断点续学 | 学习页 `enterStudyContext` 续聊 + localStorage 草稿;SSE 流结束兜底;连续 3 次失败引导查看进度 |
| 后端 App API | 全量对接 `/api/auth/*`、课程/进度/洞察/人设、SSE 对话(clientMessageKey 去重、409 分码) |
| 页面效果检查 | 开发环境可选开关:关闭守卫型自动跳转登录,便于不经登录直接打开各页检查 UI/动效 |
### 页面清单(9个)
| 页面 | 路径 | 说明 |
|------|------|------|
| 欢迎页 | `pages/welcome/welcome` | 首次打开品牌展示;全屏 `StarrySky` 背景 |
| 登录页 | `pages/login/login` | 密码登录 + 微信登录 |
| 注册页 | `pages/login/register` | 账号注册 + 微信注册 |
| 人设选择 | `pages/persona/persona` | 三选一锁定 |
| 首页 | `pages/index/index` | 今日任务 + CTA |
| 学习页 | `pages/study/study` | 核心AI对话页 |
| 完成页 | `pages/complete/complete` | 每日完成庆祝 |
| 进度页 | `pages/progress/progress` | 学习进度总览 |
| 20天完成 | `pages/finish/finish` | 全旅程回顾 |
### 页面访问流程
```
欢迎页 → 登录/注册 → 人设选择 → 首页(今日任务)
↑ 已登录自动跳过 ↓
学习页(核心对话)
↓
每日完成页
首页 ←→ 进度页(Tab 切换)
20 天全部完成后 → 完成庆祝页(未达条件不可进入)
```
**鉴权规则**:未登录跳转登录页;已登录但未选人设跳转人设页;登录/注册页若已登录则按状态自动进入首页或人设页(`redirectIfAlreadyAuthenticated`)。首页、学习、进度、完成、庆祝页在 `onMounted` 与 `onShow` 执行 `runAuthGuard()`。HTTP 401 经 refresh / 微信静默登录失败后 `reLaunch` 登录页;SSE 流同样支持 401 refresh 后重连。用户主动退出调用 `logout` 并携带 refreshToken 服务端失效。
**对话与乐观锁**:每轮 SSE 携带 `clientMessageKey`(UUID);网络重试复用同一 key。后端 409 按 `bizCode` 分流——已完成流视为成功并拉取历史;session 冲突自动 `new_topic` 重试一次。进入学习页时 `enterStudyContext` 按科目+知识点恢复 active session(`contextMode=continue`)或开新话题。
**开发专用 — 页面效果检查**:`.env.development` 中 `VITE_APP_PAGE_EFFECT_CHECK=true` 且重启 dev 后,关闭上述**守卫型**自动跳转(含页面守卫与 401 踢回登录),可直达任意页看 UI;登录成功后的正向导航仍保留。生产构建因 `import.meta.env.DEV` 约束恒为关闭。查未登录态 UI 需清除 `nova-auth-token` 或使用无痕窗口。
---
## 系统要求
### 硬件
| 项目 | 最低要求 |
|------|----------|
| CPU | 2 核 |
| 内存 | 4 GB |
| 磁盘 | 5 GB |
### 软件依赖
| 软件 | 版本 | 用途 |
|------|------|------|
| Node.js | 18+ LTS | 包管理 + 构建 |
| npm | 最新稳定版 | 依赖安装 |
| HBuilderX | 最新版 | IDE(推荐,uni-app可视化) |
| 微信开发者工具 | 最新稳定版 | 小程序调试 |
| Chrome | 最新版 | H5主场景调试(≥1024px) |
### 后端依赖
| 服务 | 说明 |
|------|------|
| nova-admin | 后端 API 服务,须先启动;壳层静态资源经 `GET /profile/app-assets/**` 匿名下载 |
---
## 部署指南
### 1. 安装依赖
```bash
cd nova-app
npm install
```
### 2. 必要配置
创建 `.env.development`:
```ini
VITE_API_BASE_URL=http://localhost:8880
# 页面效果检查(仅开发):true 关闭守卫型自动跳转登录,便于 UI/动效调试
VITE_APP_PAGE_EFFECT_CHECK=false
```
开发时 H5 经 Vite 将 `/api`、`/profile` 代理到 `VITE_API_BASE_URL`(默认 8880,与本地 nova-admin 端口一致)。微信小程序真机调试须将 `VITE_API_BASE_URL` 设为局域网 IP(不可用 `localhost`),并在微信公众平台配置 **downloadFile 合法域名**(与 API 同域即可同时访问 `/api` 与 `/profile`)。
创建 `.env.production`:
```ini
VITE_API_BASE_URL=https://your-server.com
```
`manifest.json` 中配置微信小程序 AppID(`mp-weixin.appid` 字段)。
### 3. 构建与部署
```bash
# 单元测试(114 项)
npm run test:unit
# 从 seed 生成 locales 并同步 pages.json 导航标题(改文案后必跑)
npm run locales:sync
# 同步 App 壳层 PNG 侧车(改 SVG 种子后;仓库根 scripts/sync-app-asset-png.mjs,runtest.ps1 会自动执行)
node ../scripts/sync-app-asset-png.mjs
# H5 端开发运行
npm run dev:h5
# H5 端生产构建
npm run build:h5
# 微信小程序开发运行
npm run dev:mp-weixin
# 微信小程序生产构建
npm run build:mp-weixin
```
H5 构建产物在 `dist/build/h5`。小程序构建产物在 `dist/build/mp-weixin`,用微信开发者工具打开上传。
仓库根目录 `build-run.ps1` 可依次编译 nova-admin、ruoyi-ui、nova-app(H5 生产构建),用于发布前全量编译检查。
### 4. Nginx 配置(H5 生产)
```nginx
server {
listen 443 ssl;
server_name your-domain.com;
# 微信小程序域名白名单
# request 合法域名: https://your-domain.com
# socket 合法域名: wss://your-domain.com
location / {
root /usr/share/nginx/html/nova-app;
index index.html;
try_files $uri $uri/ /index.html;
}
# SSE 流式对话:仅对该路径关闭 proxy_buffering,勿对整个 /api/ 或 /profile/ 全局关闭
location /api/ai/chat/stream {
proxy_pass http://127.0.0.1:8880;
proxy_set_header Host $host;
proxy_buffering off;
proxy_read_timeout 120s;
}
location /api/ {
proxy_pass http://127.0.0.1:8880;
proxy_set_header Host $host;
}
# App 壳层静态资源(与 API 同域,小程序 downloadFile 合法域名须包含此 host)
location /profile/app-assets/ {
proxy_pass http://127.0.0.1:8880;
proxy_set_header Host $host;
}
}
```
---
## 基本操作
### H5 开发启动
```bash
cd nova-app
npm run dev:h5
```
浏览器打开 `http://localhost:5173`。
#### 页面效果检查(UI/动效调试)
1. 编辑 `.env.development`,设置 `VITE_APP_PAGE_EFFECT_CHECK=true`
2. 重启 `npm run dev:h5`(环境变量在启动时注入)
3. 直接访问下方任意页面 URL,无需完整登录流程
| 场景 | 操作 |
|------|------|
| 查看未登录态 UI | 清除 localStorage 的 `nova-auth-token`,或使用无痕窗口 |
| 查看登录/注册页 | 开关开启后不会因 localStorage 残留 token 被自动跳走 |
| 401 后仍停留当前页 | 预期行为;接口可能失败或空态,不会 `reLaunch` |
| 验证登录成功动效 | 在登录页正常完成登录,`navigateByAuthState` 仍会进首页/人设 |
控制台出现 `[Auth] 页面效果检查已开启...` 表示开关生效。调试结束改回 `false` 并重启。
页面根地址:http://localhost:5173/#/
页面列表见"页面清单"章节。
欢迎页可直接访问 `http://localhost:5173/#/pages/welcome/welcome` 查看星空背景与品牌文案叠层效果。
### 夏夜星空特效(StarrySky)
可复用背景组件,源码位于 `src/effects/starry-sky/`(与 `utils` 平级的 `effects` 目录)。
```vue
```
```js
import { StarrySky, buildStarrySkyScene } from '@/effects/starry-sky'
// 或 import { StarrySky } from '@/effects'
```
| 项 | 说明 |
|----|------|
| `showLogoHalo` | 是否显示 Logo 区径向柔光,欢迎页默认 `true` |
| `seed` | 可选;固定则星场布局可复现(默认内置 seed) |
| 双端密度 | H5 场星约 240、流星 3 条;小程序场星约 132、流星 2 条,且关闭噪点层、降低 blur |
| 流星节奏 | 每条周期含约 10–20s 空闲 + 约 3–4s 划过;从屏缘随机进入后直线飞出屏外 |
| 无障碍 | 跟随全局 `prefers-reduced-motion: reduce`,动效停止后保留静态星空 |
开发调试统计:`.env.development` 中 `VITE_APP_PAGE_EFFECT_CHECK=true` 且重启 dev 后,欢迎页加载时控制台单次输出 `[StarrySky] field=…`(见 `logStarrySkyCheckOnce`)。
### 微信小程序调试
```bash
npm run dev:mp-weixin
```
生成 `dist/dev/mp-weixin`,用微信开发者工具打开。
### 切换主题
点击首页右上角头像打开菜单,切换深色/浅色模式,自动持久化。
### 切换语言
| 场景 | 入口 |
|------|------|
| PC(≥768px) | 左侧栏底部的「简体中文 / English」 |
| 手机首页 | 头像菜单 →「语言」 |
| 欢迎 / 登录 / 注册 / 人设 / 完成 / 20天完成 | 页面右上角语言切换 |
| 手机学习页 | 顶栏右侧语言切换(侧栏科目在 PC 端) |
选择后写入 `nova-locale`,各页 `onShow` 会 `syncLocaleFromStorage`;自定义导航标题随 `locale-changed` 更新。API 返回的知识点标题、洞察引用等内容仍为后端语言,不随前端 locale 变化。
### 科目切换
学习页顶部栏(手机)或 PC 侧栏点击科目,触发 300ms 全屏过渡动画后切换。
### 验证
| 验证项 | 方法 |
|--------|------|
| H5 首页加载 | 浏览器打开开发 URL,看到首页界面 |
| 后端连通 | 确保 nova-admin 启动(默认 8880),首页能获取任务列表 |
| 壳层图加载 | 后端启动后访问 `/profile/app-assets/images/logo.svg` 返回 200;欢迎页 Logo、人设页三图正常显示 |
| 欢迎页星空 | 打开 welcome 页 | 见密星、星串、偶发流星与底部极光;文案与 CTA 清晰可读;浅色主题下为薄暮色调 |
| manifest 版本 | `GET /profile/app-assets/manifest.json` 含各文件 MD5;前端 URL 带 `?v=` 参数 |
| 小程序预览 | 微信开发者工具扫码预览;真机须配置合法域名与局域网 API 基址 |
| SSE 打字机 | 学习页发送消息,AI 回复逐字显示(33ms/字) |
| 响应式适配 | 宽度 ≥768px 出现侧栏且 TabBar 隐藏;≥1024px 侧栏 240px |
| PC 内容带 | 首页/进度/完成/20天页主内容约 880px 居中 |
| PC 聊天列 | 学习页对话区最大约 1120px;分屏知识面板时聊天约占 65% |
| 侧栏中文 | 侧栏品牌为「星轨」,无乱码;图标正常 |
| 语言切换 | 侧栏或菜单切 en-US 后 Tab、placeholder 即时更新 |
| 科目切换 | 学习页切换科目,观察 300ms 过渡动画 |
| 主题切换 | 首页菜单切换,全局 CSS 变量即时切换 |
| 单元测试 | `npm run test:unit` | 114 项:SSE、鉴权、401、409、enterStudyContext、i18n、PC 布局、appAsset、`effects/starrySkyScene` 等 |
| 三工程编译 | 仓库根 `.\build-run.ps1` | nova-admin + ruoyi-ui + nova-app H5 生产构建 |
| 全量联测 | 仓库根 `runtest.ps1` | 同步 PNG → vitest → mvn test → 可选 HTTP 验收 |
| 文案同步 | 改 seed 后 `npm run locales:sync`,`zh-CN.json` 解析 `sidebar.brand` 为「星轨」 |
| 鉴权链路 | 开关为 `false` 时:未登录访问首页应跳转登录 | 登录后无人设应跳转人设页 |
| 页面效果检查 | 开关为 `true` 且重启 dev:未登录可停留学习页 | 401 不 `reLaunch`;登录成功仍可进首页 |
| 人设降级 | 远程图加载失败 | PersonaSelector 显示 NovaIcon 兜底;锁定 API 失败 Toast 并默认「学长」 |
| 完成页 | 数据加载中 | 骨架屏,不出现「第 0 天完成」 |
| 庆祝页 | Day 未满 20 且进度未满 100% | 自动回到首页 |
| 离线草稿 | 学习页输入后断网 | 草稿 localStorage 保存,重进学习页可恢复 |
| 离线壳层图 | 曾成功拉取 manifest 后断网 | 使用缓存 MD5 拼 URL;完全离线首次仍走 RemoteImage 兜底 |
### 停止
终端 `Ctrl+C` 停止开发服务器。