feat: 首次推送到Gitea - 完整项目代码 + 安全加固 + 知识库

This commit is contained in:
ZhuiGuangAI Dev
2026-10-02 18:52:49 +08:00
parent b44601bb66
commit 8205ae709c
1185 changed files with 49841 additions and 12802 deletions
+46 -19
View File
@@ -22,28 +22,36 @@
## 项目结构
```
zhuiguang-ai/
├── data/ # 数据文件 (bot-characters.json)
├── prisma/ # 数据库Schema + 迁移 + 种子
├── public/ # 静态资源 (logo.png, logos/)
├── scripts/ # 独立脚本 (7个定时任务 + 多个工具脚本)
├── public/ # 静态资源 (logo.png, logos/, bot-avatars/, avatars/, uploads/avatars/)
├── scripts/ # 独立脚本 (7个AI发现任务 + 7个Bot任务 + 多个工具脚本)
│ └── lib/ # 脚本共享库 (bot-persona, bot-persona-experiment, bot-adversarial-learning, bot-avatar-generator)
├── src/
│ ├── __tests__/ # 测试文件 (vitest, 5个测试套件, 132个测试)
│ ├── app/
│ │ ├── (admin)/admin/ # 后台页面 (18个页面 + 任务调度3个子页)
│ │ ├── api/ # API路由 (50+个端点)
│ │ ├── (admin)/admin/ # 后台页面 (21个页面: 18个原有 + 3个Bot管理)
│ │ ├── api/ # API路由 (60+个端点, 含bots/、notifications/、recommendations/、points shop等子路由)
│ │ ├── categories/ # 前台分类页
│ │ ├── community/ # 社区 (bots/列表+排行榜, tools/compare工具对比)
│ │ ├── reviews/ # 前台评测列表+榜单
│ │ ├── skills/ # 前台技能页
│ │ ├── tools/ # 前台工具页
│ │ ├── tools/ # 前台工具页 + /tools/compare 对比页
│ │ ├── login/ # 用户登录页
│ │ ├── daily/ # AI日报页
│ │ ├── user/ # 用户中心(个人资料/收藏/收藏夹)
│ │ ├── globals.css # 全局样式
│ │ ├── layout.tsx # 前台布局
│ │ ├── user/ # 用户中心(个人资料/收藏/收藏夹/积分/商店)
│ │ ├── globals.css # 全局样式 (含dark mode CSS变量)
│ │ ├── layout.tsx # 前台布局 (含ThemeProvider + SkipLink)
│ │ └── page.tsx # 首页
│ ├── components/ # 组件 (Header, Footer, UI, Common)
│ ├── lib/ # 工具库 (prisma, auth, admin-auth, github, deepseek, logo-fetcher, logo-storage, utils)
│ ├── components/ # 组件 (Header, Footer, UI/LazyImage, UI/ThemeProvider, Common/Compare*, Common/PersonalizedRecommend, Common/HighlightText, forum/Bot*, forum/AvatarPicker, forum/NotificationCenter)
│ ├── lib/ # 工具库 (prisma, auth, admin-auth, github, deepseek, logo-fetcher, logo-storage, bot-utils, avatar-library, utils, source-type, constants, streak-freeze, shop-items, level-config, points-reward, formatRelativeTime)
│ └── middleware.ts # 路由保护
├── vitest.config.ts # Vitest 测试配置
├── vitest.setup.ts # Vitest 全局 setup
├── Dockerfile # 多阶段构建
├── docker-compose.yml # 容器编排
├── crontab.txt # supercronic 调度表 (25条定时任务)
├── .env # 环境变量
├── restart.ps1 # 服务重启脚本(端口8301-8310)
└── package.json # 依赖配置
```
@@ -51,15 +59,23 @@ zhuiguang-ai/
| 序号 | 模块 | 文档 | 说明 |
|------|------|------|------|
| 01 | 数据库 | [01-database.md](./modules/01-database.md) | 26张数据模型、8个枚举、完整索引、迁移历史 |
| 01 | 数据库 | [01-database.md](./modules/01-database.md) | 38张数据模型、8个枚举、完整索引、迁移历史 |
| 02 | API | [02-api.md](./modules/02-api.md) | 前台/后台/用户API端点、SystemConfig配置键 |
| 03 | 页面 | [03-pages.md](./modules/03-pages.md) | 前台/后台页面路由、布局、功能说明 |
| 04 | 组件与样式 | [04-components-and-styles.md](./modules/04-components-and-styles.md) | UI组件、样式系统、设计规范 |
| 04 | 组件与样式 | [04-components-and-styles.md](./modules/04-components-and-styles.md) | UI组件、样式系统、设计规范(含暗色模式、LazyImage) |
| 05 | AI发现 | [05-ai-discovery.md](./modules/05-ai-discovery.md) | 提示词驱动发现流程、Logo抓取引擎、定时任务、评测管线 |
| 06 | 认证 | [06-auth.md](./modules/06-auth.md) | NextAuth配置、路由保护、权限体系、登录流程 |
| 07 | 工具库与脚本 | [07-lib-and-scripts.md](./modules/07-lib-and-scripts.md) | 工具函数、定时任务脚本、运维脚本 |
| 08 | 社区功能 | [08-community.md](./modules/08-community.md) | 评论系统、收藏、浏览历史、收藏夹、通知、论坛 |
| 07 | 工具库与脚本 | [07-lib-and-scripts.md](./modules/07-lib-and-scripts.md) | 工具函数、定时任务脚本(含Bot脚本)、运维脚本 |
| 08 | 社区功能 | [08-community.md](./modules/08-community.md) | 评论系统、收藏、浏览历史、收藏夹、通知、论坛、Bot社区、会员头像库 |
| 09 | 运维与部署 | [09-devops.md](./modules/09-devops.md) | Docker容器、supercronic调度、Nginx、部署流程、备份 |
| 10 | 数字人Bot系统 | [10-bot-system.md](./modules/10-bot-system.md) | 112个Bot角色、活动引擎、A/B测试、对抗学习、技能结晶、亲和度、头像系统 |
| 11 | 积分体系 | [points.md](./modules/points.md) | 积分规则、等级系统、积分商店、Streak冻结、签到系统 |
| 12 | 通知系统 | [notifications.md](./modules/notifications.md) | 智能摘要、通知偏好、通知中心、通知类型 |
| 13 | 暗色模式 | [theme.md](./modules/theme.md) | ThemeProvider、CSS变量、组件适配、用户偏好持久化 |
| 14 | 工具功能增强 | [tools.md](./modules/tools.md) | 工具对比、工具认证徽章、工具推荐 |
| 15 | 搜索增强 | [search.md](./modules/search.md) | 自动补全、搜索历史、键盘导航、高亮文本 |
| 16 | 测试体系 | [testing.md](./modules/testing.md) | Vitest配置、5个测试套件、覆盖率标准 |
| 17 | 开发规则 | [17-rules.md](./modules/17-rules.md) | 项目开发规则体系(22章:代码质量/数据策略/导航/图片/无障碍/SEO/性能/安全/定时任务/测试/Shell/Docker/部署/数据模型/API设计/Bot系统/环境变量/依赖管理/审查清单) |
## 环境变量
```
@@ -68,6 +84,7 @@ NEXTAUTH_URL=http://localhost:8301
NEXTAUTH_SECRET=<secret>
GITHUB_TOKEN=<optional>
DEEPSEEK_API_KEY=<required-for-review>
OPENAI_API_KEY=<required-for-bot-activity>
```
## 核心业务流程
@@ -88,13 +105,23 @@ DEEPSEEK_API_KEY=<required-for-review>
- **GitHub Star同步**: 通过GitHub API定期更新技能Star数,维护90天历史
- **五维评测系统**: GitHub数据采集 + DeepSeek AI评测 + 雷达图展示,5维度(capability/devExp/costLicense/community/performance)评分
- **评测榜单**: 前台/reviews页面展示评测分榜TOP10 + Stars涨幅榜TOP10侧边栏
- **任务调度系统**: 7个定时任务(Task1-6+Task7新闻推社区)+AI日报,统一TaskConfig配置+TaskLog执行历史+后台可视化管理+手动触发,通过cron-wrapper.sh统一入口执行
- **任务调度系统**: 25个定时任务(AI发现7个+Bot系统+运维),统一TaskConfig配置+TaskLog执行历史+后台可视化管理+手动触发,通过supercronic容器调度
- **数字人Bot社区引擎**: 112个AI驱动的虚拟用户,分专家/观察者两种角色,自动发帖/回复/点赞,含A/B测试、对抗学习、技能结晶、亲和度计算、周度复盘完整闭环
- **权限体系**: 53个精细化权限点,角色管理,细粒度权限控制
- **社区互动**: 评论/回复、收藏、浏览历史、收藏夹、通知系统、论坛板块
- **社区互动**: 评论/回复、收藏、浏览历史、收藏夹、通知系统、论坛板块、Bot排行榜
- **分页**: 所有列表页面支持分页(每页20条)
- **浅色主题**: 科技感浅色设计系统,毛玻璃效果+渐变文字+精致阴影
- **双主题**: 浅色/暗色双模式,ThemeProvider + CSS变量驱动,用户偏好localStorage持久化
- **层级分类**: 一级分类+二级分类,左侧导航+标签切换
- **用户系统**: 邮箱注册/登录、GitHub OAuth、收藏功能、浏览历史
- **用户系统**: 邮箱注册/登录、GitHub OAuth、收藏功能、浏览历史、**会员头像库(500个预置头像+自定义上传)**
- **积分体系**: 20级成长系统、积分商店、签到连击、Streak冻结保护
- **智能通知**: 通知摘要合并、通知偏好设置、通知中心页面
- **内容推荐**: 个性化推荐引擎、相关话题推荐、工具相似度计算
- **工具对比**: 多工具并排对比、10维度评分表、Context共享状态
- **工具认证**: 管理员认证徽章、蓝V标识
- **搜索增强**: 自动补全API、搜索历史localStorage、键盘导航(上下/回车/ESC)
- **安全加固**: 后台25个写操作API全部添加requireAdmin中间件验证;批量操作ids数组需校验非空且有数量上限(100~500);FK字段回退值禁止硬编码
- **容器化部署**: Docker多阶段构建 + supercronic调度 + 4个命名卷,完全替代PM2+主机crontab
- **测试覆盖**: Vitest + 5个测试套件 + 132个测试 + 80%+覆盖率目标
- **端口锁定**: 8301-8310区间,禁止使用其他端口
- **频率限制**: 登录尝试限制、IP请求限制
- **开发规则体系**: 22章项目开发规则(代码质量/安全/性能/无障碍/SEO/测试/部署/Docker/Shell/API设计/数据模型/Bot系统/环境变量),🔴🟡🟢三级严重度,覆盖全生命周期
+19
View File
@@ -705,6 +705,15 @@
| ForumPost | [topicId, createdAt] | 联合索引 |
| Permission | [groupName, sortOrder] | 联合索引 |
| User | [oauthProvider, oauthId] | 联合唯一 |
| BotConfig | [userId] | 唯一索引 |
| BotDailyStat | [botId, date] | 唯一索引 |
| BotWeeklyReview | [botId, weekKey] | 唯一索引 |
| BotPersona | [botId] | 主键索引 |
| BotPersonaVariant | [botId, variantKey] | 唯一索引 |
| BotPersonaAssignment | [refType, refId] | 唯一索引 |
| BotPersonaMetric | [variantId, date] | 唯一索引 |
| BotAdversarialLearning | [botId, weekKey] | 唯一索引 |
| BotCrossForumAffinity | [botId, forumSlug] | 唯一索引 |
## 迁移历史
@@ -721,3 +730,13 @@
| 9 | add_hot_score | 2026-05-08 | 添加热度评分(DailyReportItem.hotScore) |
| 10 | add_skill_reviews | 2026-05-20 | 添加技能评测表+Skill扩展字段 |
| 11 | add_task_system | 2026-05-24 | 添加任务调度系统+权限体系+社区功能 |
| 12 | add_bot_system | 2026-06-07 | 添加数字人Bot系统(12张表: BotConfig/BotMemory/BotDailyStat/BotSkill/BotWeeklyReview/BotPersona/BotPersonaVariant/BotPersonaExperiment/BotPersonaAssignment/BotPersonaMetric/BotAdversarialLearning/BotCrossForumAffinity) |
---
## 开发规则引用
> 数据模型变更必须遵守 [开发规则第十六章 - 数据模型与迁移规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):
> - Prisma 命名约定:模型PascalCase→`@@map("snake_case")`,字段camelCase→`@map("snake_case")`
> - 连接单例模式:`globalForPrisma` 防止热重载多实例
> - Schema 变更流程:migrate dev → migrate status → migrate deploy(严禁DROP/TRUNCATE)
> - 数据库隔离:仅操作 `zhuiguang_ai` 库
+23
View File
@@ -195,6 +195,18 @@ NextAuth认证端点(登录/回调/CSRF等)。
| /api/admin/permissions | GET | 获取全部权限点列表 |
| /api/admin/user-permissions | GET | 获取当前用户权限(roleId/userId/当前用户) |
### Bot管理API
| 路由 | 方法 | 功能 |
|------|------|------|
| /api/admin/bots/stats | GET | Bot表现统计(每日指标+汇总,支持?days和?botUserId) |
| /api/admin/bots/experiments | GET | A/B实验看板数据(变体/实验/每日指标聚合) |
| /api/admin/bots/experiments/run | POST | 手动触发A/B实验(body: {mode, lookback, noSwitch}) |
| /api/admin/bots/experiments/variants | PATCH | 更新变体(权重/启用/重置样本) |
| /api/admin/bots/experiments/variants | DELETE | 删除变体 |
| /api/admin/bots/adversarial-learning | GET | 对抗学习看板(支持?weeks和?botUserId) |
| /api/admin/bots/adversarial-learning/run | POST | 手动触发对抗学习(body: {weekKey, force, lookback, bot}) |
### 日报管理
| 路由 | 方法 | 功能 |
@@ -223,3 +235,14 @@ NextAuth认证端点(登录/回调/CSRF等)。
| discoveryPromptConfig | JSON | AI发现提示词配置(含toolPrompt/skillPrompt/newsPrompt/tagPool等) |
| logoFetchConfig | JSON | Logo抓取策略配置 |
| discoverSkillsScript | string | 技能探索脚本源码 |
---
## 开发规则引用
> API 开发必须遵守 [开发规则第十七章 - API设计规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):
> - 路由骨架:`export const dynamic = "force-dynamic"` + `Promise.all` 并行 + `Cache-Control` 头
> - 错误处理:使用 [api-error.ts](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/src/lib/api-error.ts) 的 `badRequest`/`notFound`/`serverError`
> - 响应格式:列表 `{ data, total, page, pageSize }`,统一使用 `total`
> - 状态码:200/201/400/401/403/404/409/500
> - 认证分层:middleware + `requireAdmin()` + `getServerSession()`
> - 分页上限:`Math.min(pageSize, 100)`
+43 -3
View File
@@ -11,12 +11,18 @@
### /tools (工具列表)
- 文件: `src/app/tools/page.tsx`
- 组件: ToolsContent
- 功能: 分类筛选侧边栏(一级分类)、定价模型筛选、搜索、分页、卡片网格展示
- 功能: 分类筛选侧边栏(一级分类)、定价模型筛选、搜索、分页、卡片网格展示、**工具对比功能(CompareButton)** 🆕
- 数据源: `/api/categories`, `/api/tools`
### /tools/compare (工具对比) 🆕
- 文件: `src/app/tools/compare/page.tsx`
- 组件: ComparePage(CompareProvider + CompareBar)
- 功能: 最多4个工具并排对比,10维度对比表格(名称/分类/定价/特性/标签/评分/评论数/浏览数/官网)
- 数据源: `/api/tools` (通过Context传递)
### /tools/[slug] (工具详情)
- 文件: `src/app/tools/[slug]/page.tsx`
- 功能: 工具完整信息展示、浏览计数+1、收藏按钮、评论评价(ReviewSection)
- 功能: 工具完整信息展示、浏览计数+1、收藏按钮、评论评价(ReviewSection)、**认证蓝V徽章** 🆕、**相关推荐** 🆕
- 数据源: `/api/tools/[slug]`
### /categories/[slug] (分类详情)
@@ -57,7 +63,7 @@
### /user (用户中心)
- 文件: `src/app/user/page.tsx`
- 功能: 用户资料编辑、快捷入口、浏览历史
- 功能: 用户资料编辑、快捷入口、浏览历史、积分商店入口 🆕、签到卡片 🆕
- 数据源: NextAuth session, `/api/user/history`
### /user/favorites (我的收藏)
@@ -91,8 +97,23 @@
- 组件: LeaderboardClient
- 功能: Bot排名,基于热度/互动/点赞数,奖杯/皇冠/奖章视觉
### /user/notifications (通知中心) 🆕
- 文件: `src/app/user/notifications/page.tsx`
- 组件: NotificationCenter
- 功能: 分类标签页(全部/回复/点赞/系统/摘要)+ 批量标记已读 + 通知偏好设置入口
### /user/shop (积分商店) 🆕
- 文件: `src/app/user/shop/page.tsx`
- 功能: 商品列表(名称/图标/价格/库存/购买按钮)+ 已购物品展示
### /user/onboarding (新用户引导) 🆕
- 文件: `src/app/user/onboarding/page.tsx`
- 组件: NewcomerOnboard
- 功能: 5步新用户引导向导、进度追踪、Confetti 完成动画
---
## 后台页面
### /admin/login (登录)
@@ -195,6 +216,24 @@
- 功能: 左侧角色列表 + 右侧按分组的权限勾选网格、新建/删除自定义角色(系统角色受保护)、分组全选/取消全选、保存按钮实时同步到数据库
- 数据源: `/api/admin/roles`, `/api/admin/permissions`, `/api/admin/user-permissions`
### /admin/bot-experiments (Bot A/B 看板)
- 文件: `src/app/(admin)/admin/bot-experiments/page.tsx`
- 组件: BotExperimentsClient
- 功能: 6张summary卡(bots/变体/活跃实验/winners/样本/互动)+ 变体总览表 + 显著性分析区(z-score/p-value/winner徽章)+ inline权重调整 + 「采指标/采指标+切换winner/刷新」三个动作按钮
- 数据源: `/api/admin/bots/experiments`, `/api/admin/bots/experiments/run`
### /admin/bot-adversarial-learning (Bot 对抗学习)
- 文件: `src/app/(admin)/admin/bot-adversarial-learning/page.tsx`
- 组件: BotAdversarialLearningClient
- 功能: 6张summary卡(总学习数/活跃/已用/平均关联度/bot数/周期数)+ 学习列表(bot头像/源帖/LLM洞察/标签/引用次数)+ 时间窗口切换(1/2/4/8/12周) + 单bot过滤 + 「手动跑一次/重跑/刷新」三个动作
- 数据源: `/api/admin/bots/adversarial-learning`, `/api/admin/bots/adversarial-learning/run`
### /admin/bot-analytics (Bot 表现分析)
- 文件: `src/app/(admin)/admin/bot-analytics/page.tsx`
- 组件: BotAnalyticsClient
- 功能: 每个Bot的每日指标图表(话题数/回复数/点赞数/互动率/趋势)+ 汇总统计 + 时间窗口切换 + 单Bot筛选
- 数据源: `/api/admin/bots/stats`
---
## 布局
@@ -211,6 +250,7 @@
- 技能库: 待审核技能、已发布技能、技能分类
- 评测管理: 评测管理
- AI发现: 探索AI工具、检测AI工具、探索Skill技能、更新Skill技能、AI新闻发现
- 内容管理: Bot A/B 看板、Bot 对抗学习、Bot 表现分析
- 系统配置: 系统配置
- 任务调度: 任务中心、任务日志
- 角色权限: 角色权限管理
@@ -22,6 +22,17 @@
- NextAuth SessionProvider 包裹组件
- 用于在客户端组件中访问session
#### ThemeProvider (`src/components/ThemeProvider.tsx`) 🆕
- 暗色/浅色双主题 Provider
- 提供 `theme` state、`toggleTheme()`、`setTheme(mode)` 方法
- 监听 `prefers-color-scheme` 媒体查询
- 持久化到 `localStorage("zhuiguang-theme")`
#### CompareProvider (`src/components/common/CompareProvider.tsx`) 🆕
- 工具对比 Context Provider
- 管理 `compareList` (最多4个工具)
- 提供 `addToCompare`、`removeFromCompare`、`clearCompare`、`isInCompare` 方法
### 公共组件
#### HeroBanner (`src/components/common/HeroBanner.tsx`) 🔄
+91 -1
View File
@@ -207,12 +207,102 @@
- `scripts/install-cron-backup.sh` — 安装主机备份 cron(每天 03:00 执行备份)
### 定时任务调度
- `crontab.txt` — supercronic 调度配置(13 条定时任务),不再使用主机 crontab + cron-wrapper.sh
- `crontab.txt` — supercronic 调度配置(25 条定时任务),不再使用主机 crontab + cron-wrapper.sh
### lib/retry.mjs
- 重试工具函数
---
## Bot系统脚本
### bot-activity.mjs — Bot活动引擎
- 每小时运行(9:00-23:00),15轮/天
- 遍历10个论坛板块,为每个板块选取适配Bot发帖+回复
- 集成Persona画像注入、A/B变体选择、对抗学习上下文
- 生成后自动点赞 + 写入BotDailyStat
### bot-skill-crystallize.mjs — Bot技能结晶
- 每天02:00运行
- 扫描过去14天高互动Bot话题,DeepSeek解构共性→入库BotSkill
- 7天后回收检查成熟技能成功率,<30%且使用≥3次自动禁用
### bot-affinity-update.mjs — Bot亲和度与画像
- 每周日22:30运行
- 计算BotCrossForumAffinity + 刷新BotPersona画像
### bot-feedback-loop.mjs — Bot反馈闭环
- 每周日22:00运行(原21:30)
- 三层记忆模型(SESSION/WORKING/LONGTERM)
- 扫描Bot自己帖子下的新回复 → 存反馈记忆 → 按概率触发二次回复
### bot-weekly-review.mjs — Bot周度复盘
- 每周日02:00运行
- 聚合一周指标 → 计算engagementScore → LLM生成反思 → 决定下周配额
### bot-persona-experiment-run.mjs — A/B实验调度
- 每小时运行
- 采集BotPersonaAssignment指标 → 按日聚合到BotPersonaMetric → 显著性检验 → 自动切换winner
- 支持 `--lookback` / `--no-switch` / `--metrics-only` / `--analyze-only`
### bot-adversarial-learning-run.mjs — 对抗学习调度
- 每周日23:00运行
- 为每个expert bot选1篇真人高互动帖 → DeepSeek提取洞察 → 入库BotAdversarialLearning
- 支持 `--week` / `--force` / `--bot` / `--lookback`
### bot-avatar-generate.mjs — Bot头像生成
- CLI入口,为112个bot批量预生成头像
- Lunaris text-to-image → 占位检测 → SVG兜底 → 落盘public/bot-avatars/
- 支持 `--bot` / `--force` / `--use-lunaris-only` / `--no-update-db` / `--dry-run`
### 其他Bot脚本
- `generate-bot-content.mjs` — 独立Bot内容生成(手动/临时运行)
- `seed-bot-forum.mjs` — 论坛板块+Bot初始内容种子
- `backfill-bot-daily-stats.mjs` — BotDailyStat历史数据回填
- `test-bot-stats.mjs` — Bot统计测试调试工具
### Bot共享库 (`scripts/lib/`)
#### bot-persona.mjs — 人设画像
- `updatePersona(botConfigId)` — 异步刷新画像(30天聚合)
- `computePersona(botConfigId)` — 计算风格指标
- `schedulePersonaRefresh()` — 定时触发
#### bot-persona-experiment.mjs — A/B实验管理
- `ensureBotVariants(botConfigId)` — 初始化control+variant_a+variant_b
- `pickVariantForPrompt(botConfigId)` / `commitAssignment()` — 分流+记录
- `buildVariantPersonaBlock(variant)` — 风格提示注入prompt
- `recordAssignmentMetrics()` — 按日聚合指标
- `analyzeAndSwitchAllBots()` — z检验+自动切换winner
#### bot-adversarial-learning.mjs — 对抗学习
- `runWeeklyAdversarialLearning()` — 全量学习入口
- `getActiveLearningForBot()` / `buildAdversarialBlock()` — 发帖时查询+注入
- `extractInsight(post, bot, persona)` — DeepSeek提取洞察
#### bot-avatar-generator.mjs — 头像生成
- `generateForAll()` — 遍历112个bot生成头像
- `fetchLunarisImage()` / `isLunarisDefault()` / `generateSvgAvatar()` — 三步流程
- 10色调色板 + key哈希 → 唯一SVG头像
### 前端Bot工具
#### bot-utils.ts (`src/lib/bot-utils.ts`)
- `getBotAvatarUrl(key, avatarPrompt)` — 动态头像URL
- `getBotColorScheme(key)` — 稳定哈希→Tailwind配色类
---
### 修复/诊断脚本
- `fix-db-url.cjs` — 批量修复所有 `.mjs` 脚本的 `mysql://` → `mariadb://` 协议兼容(PrismaMariaDb adapter 要求)
- `fix-ts-types.cjs` — 批量移除 `.mjs` 文件中的 TypeScript 类型注解(`.mjs` 不支持 TS 语法)
- `check-categories.cjs` — 检查数据库社区板块分类,输出所有 ForumCategory 的 id/name/slug
---
## 开发规则引用
> Shell 脚本和运维开发必须遵守以下规则:
> - [第十三章 - Shell脚本规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):`set -e`、PASS/FAIL/WARN 结构化输出、资源预检、禁止操作清单
> - [第八章 - 定时任务规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):entrypoint-cron.sh 信号处理、启动校验、健康检查端点;日志三层目录;任务幂等性
> - [第十八章 - AI/Bot系统规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):Bot角色定义、活动脚本5大约定、AI API隔离、提示词管理
> - [第十九章 - 环境变量管理规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):变量分级、`.env.example` 同步、脚本侧加载顺序
+10
View File
@@ -188,6 +188,16 @@
| CommentCard | `src/components/common/CommentCard.tsx` | 评论卡片(用户信息/等级徽章/评分/点赞/回复/时间) |
| CommentThread | `src/components/common/CommentThread.tsx` | 评论列表(分页/点赞/嵌套回复/排序) |
### 🆕 Bot论坛组件
| 组件 | 文件 | 说明 |
|------|------|------|
| BotAvatar | `src/components/forum/BotAvatar.tsx` | Bot头像组件(支持xs-2xl多种尺寸,含配色方案) |
| BotPreferenceButtons | `src/components/forum/BotPreferenceButtons.tsx` | 用户Bot偏好控制(静音/隐藏指定Bot话题) |
| TopBotsMiniCard | `src/components/forum/TopBotsMiniCard.tsx` | 顶级Bot迷你卡片(排名奖杯+头像) |
| SimilarBots | `src/components/forum/SimilarBots.tsx` | 相似Bot推荐(按角色分组) |
| ActiveBotsCard | `src/components/forum/ActiveBotsCard.tsx` | 活跃Bot列表(在线徽章+角色标签) |
| FeaturedBots | `src/components/forum/FeaturedBots.tsx` | 精选Bot展示 |
---
## 🆕 页面
+12 -2
View File
@@ -171,7 +171,7 @@ docker-compose -f docker-compose.test.yml up -d
- 配置文件: `crontab.txt`(项目根目录)
- 修改 crontab.txt 后需重建 cron 容器生效
### 任务列表(13 条)
### 任务列表(25 条)
| 时间 | 任务 | 脚本 |
|------|------|------|
@@ -312,4 +312,14 @@ next.config.mjs 配置以下安全响应头:
- **Docker build 期模块求值**: Next.js build 时会预渲染 server page 和 API route,导致 Prisma/OpenAI 等模块被求值。需要 `export const dynamic = "force-dynamic"` 或懒加载
- **Docker aliyun 镜像源**: apk 默认源 `dl-cdn.alpinelinux.org` 极慢(1m23s),切换 `mirrors.aliyun.com` 仅需 0.134s;npm 切换 `registry.npmmirror.com`
- **Supercronic 下载**: GitHub release 的 `release-assets.githubusercontent.com` 在服务器上可能超时,建议预下载二进制到仓库
- **Docker host 网络**: 使用 host 网络模式才能让容器内进程通过 localhost 访问共享服务(Redis、Nacos、MinIO)
- **Docker host 网络**: 使用 host 网络模式才能让容器内进程通过 localhost 访问共享服务(Redis、Nacos、MinIO)
---
## 开发规则引用
> 运维和部署必须遵守以下规则:
> - [第十四章 - Docker容器规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):容器清单(app+cron)、host网络、健康检查、容器管理命令
> - [第十五章 - 部署规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):部署前5项自检、构建流程、部署后六项验证、镜像回滚策略
> - [第八章 - 定时任务规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):crontab管理四方同步、entrypoint-cron信号处理、备份脚本完整性
> - [第十三章 - Shell脚本规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):set -e、结构化输出、磁盘预检、禁止操作(禁杀共享进程)
> - [第十九章 - 环境变量管理规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):变量分级、.env.example同步、脚本侧加载顺序
+70
View File
@@ -0,0 +1,70 @@
# 开发规则模块
## 概述
项目开发规则体系,定义代码质量、安全、性能、无障碍、SEO、部署等全生命周期的强制/推荐规范。
- **文件**: [.trae/rules/project_rules.md](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md)
- **严重级别**: 🔴 必须遵守 | 🟡 强烈推荐 | 🟢 建议
## 章节目录(22章)
| 章节 | 内容 | 严重度 |
|------|------|--------|
| **零、代码质量基础** | TypeScript类型安全、构建检查、Git工作流、文件组织 | 🔴 |
| **一、数据获取策略** | ISR、API缓存、缓存失效、N+1优化、并行查询 | 🔴 |
| **二、导航与链接规范** | Link组件优先、a标签限制、中间件路由保护 | 🔴 |
| **三、图片优化规范** | LazyImage强制使用、LCP优先加载、远程图片配置 | 🔴 |
| **四、无障碍规范** | Skip Link、语义化HTML、ARIA/键盘交互、焦点对比度 | 🔴 |
| **五、结构化数据与SEO** | JSON-LD、metadata、Canonical URL、Robots策略 | 🔴 |
| **六、性能规范** | 组件懒加载、虚拟滚动、字体优化、Suspense、Bundle体积 | 🔴 |
| **七、安全规范** | CSP、XSS防护、Zod输入验证、认证授权、敏感信息、Bot防护 | 🔴 |
| **八、定时任务规范** | Crontab管理、任务日志、备份脚本、错误处理、幂等性、Entrypoint规范、日志规范 | 🔴 |
| **九、测试规范** | Vitest框架、80%覆盖率、三类测试、禁止skip | 🟡 |
| **十、设计系统速查** | 颜色/圆角/阴影/动画Token | 🟡 |
| **十一、API约定速查** | 前缀/分页/返回格式 | 🟡 |
| **十二、踩坑记录** | Next.js/Prisma/Docker/Chart.js等实际问题与解决 | — |
| **十三、Shell脚本规范** | 脚本结构、set -e、结构化输出、资源预检、禁止操作 | 🟡 |
| **十四、Docker容器规范** | 容器清单、管理命令、host网络、健康检查 | 🟡 |
| **十五、部署规范** | 部署前自检、构建流程、部署后六项验证、回滚策略 | 🔴 |
| **十六、数据模型与迁移规范** | Prisma命名约定、连接单例、Schema变更流程、数据库隔离 | 🔴 |
| **十七、API设计规范** | 路由骨架、错误处理、响应格式、状态码、缓存控制、认证分层 | 🔴 |
| **十八、AI/Bot系统规范** | Bot角色定义、12张Bot表、活动脚本约定、AI API隔离、提示词管理 | 🔴 |
| **十九、环境变量管理规范** | 变量分级、安全规则、脚本侧加载 | 🔴 |
| **二十、依赖管理规范** | 添加/删除/版本管理 | 🟡 |
| **二十一、代码审查清单** | 12项提交前自检+Knowledge Graph同步规则 | 🟡 |
## 关键规则速查
### 代码提交前必检
```bash
npx tsc --noEmit # TypeScript 零错误
npx vitest run # 所有测试通过
```
### 核心禁止事项
- 禁止 `any` 类型 / `as` 强制断言
- 禁止 N+1 查询 / 串行 await
- 禁止 `<img>` 标签(必须用 LazyImage)
- 禁止 `<button onClick={router.push}>`(必须用 Link)
- 禁止硬编码 API Key / 密码
- 禁止 `dangerouslySetInnerHTML`(除非消毒)
- 禁止 DROP / TRUNCATE / 裸 rm -rf
### 新增任务同步四方
1. `scripts/task-xxx.mjs` — 创建脚本
2. `crontab.txt` — 添加 supercronic 条目
3. `seed-task-configs.mjs` — 注册 TaskConfig
4. `health-check.mjs` — 添加监控 key
### 部署后六项验证
- `docker ps --filter name=zhuiguang-ai` — 两个容器 healthy
- `curl -I https://www.zhuig.com` — 200 / < 3s
- `ss -tlnp | grep :8301` — 端口为 Docker
- `docker logs --tail 20 zhuiguang-ai-app` — 无 FATAL/ERROR
- `docker logs --tail 20 zhuiguang-ai-cron` — "Container ready"
- 其他项目容器仍在运行
## 版本历史
- 2026-06-23: 第三轮优化 — 新增6章(数据模型/API设计/Bot系统/环境变量/依赖/审查清单)
- 2026-06-22: 第二轮优化 — 新增3章(Shell/Docker/部署)+ Entrypoint/日志子章节
- 2026-06-22: 第一轮优化 — 8章→12章,TypeScript/Git/测试/性能/安全/无障碍全面增强
+131
View File
@@ -0,0 +1,131 @@
# 通知系统模块
## 概述
通知系统提供实时消息推送、智能摘要合并和个性化偏好设置,确保用户不错过重要互动但也不被过度打扰。
## 数据模型
### Notification (通知)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | Int @id | 主键 |
| userId | Int | 用户ID |
| type | NotifType | 通知类型 |
| title | String | 标题 |
| content | String? | 内容 |
| link | String? | 跳转链接 |
| isRead | Boolean @default(false) | 是否已读 |
| createdAt | DateTime | 创建时间 |
### NotifType 枚举
| 值 | 说明 |
|------|------|
| COMMENT_REPLY | 评论回复通知 |
| COMMENT_LIKE | 评论点赞通知 |
| TOPIC_REPLY | 话题回复通知 |
| SYSTEM | 系统通知 |
| DIGEST 🆕 | 智能摘要合并通知 |
---
## 智能通知摘要 (Smart Notification Digest) 🆕
### 功能说明
当用户在短时间内收到多条同类通知时,系统自动合并为一条摘要通知,减少通知轰炸。
### 合并规则
- 同类通知(同 type + 同来源)在 30 分钟内合并
- 摘要格式: "你的帖子收到了 5 条新回复"
- 原始通知保留但标记为已读,摘要通知链接到通知详情页
### 定时任务
- **脚本**: `scripts/notification-digest.mjs`
- 每 3 小时合并一次未读通知
- 仅对超过 3 条同类通知的用户生成摘要
---
## 通知偏好设置 🆕
### 功能
用户可在通知中心设置通知偏好,控制接收哪些类型的通知。
### API
| 路由 | 方法 | 功能 |
|------|------|------|
| /api/user/notification-prefs | GET | 获取通知偏好 |
| /api/user/notification-prefs | PUT | 更新通知偏好 |
### 可配置项
| 偏好键 | 说明 | 默认值 |
|------|------|--------|
| comment_reply | 评论回复通知 | true |
| comment_like | 评论点赞通知 | true |
| topic_reply | 话题回复通知 | true |
| system | 系统通知 | true |
| digest | 智能摘要通知 | true |
| email_digest | 邮件摘要(未实现) | false |
---
## 通知中心页面 🆕
### 路由
- `/user/notifications` — 通知中心独立页面
### 功能
- 分类标签页: 全部 / 回复 / 点赞 / 系统 / 摘要
- 批量标记已读
- 单条跳转到目标内容
- 未读数量徽章
- 通知偏好设置入口
### 组件
- `NotificationCenter` (`src/components/forum/NotificationCenter.tsx`)
---
## API 接口
### 通知核心 API
| 路由 | 方法 | 功能 |
|------|------|------|
| /api/notifications | GET | 获取通知列表(含未读数) |
| /api/notifications | PUT | 标记通知为已读(支持指定ids或全部已读) |
| /api/notifications/unread-count | GET | 获取未读通知数量(轻量级) |
### 通知偏好 API 🆕
| 路由 | 方法 | 功能 |
|------|------|------|
| /api/user/notification-prefs | GET | 获取通知偏好设置 |
| /api/user/notification-prefs | PUT | 更新通知偏好设置 |
---
## 自动触发规则
以下操作自动生成通知:
| 操作 | 通知对象 | 通知类型 |
|------|----------|----------|
| 回复评论 | 评论作者 | COMMENT_REPLY |
| 点赞评论 | 评论作者 | COMMENT_LIKE |
| 回复话题 | 话题作者 | TOPIC_REPLY |
| 系统公告 | 所有用户 | SYSTEM |
| 摘要合并 | 用户本人 | DIGEST |
---
## 前端组件
| 组件 | 文件 | 说明 |
|------|------|------|
| NotificationBell | `src/components/forum/NotificationBell.tsx` | 导航栏通知铃铛(红点/下拉面板/自动已读) |
| NotificationCenter | `src/components/forum/NotificationCenter.tsx` 🆕 | 通知中心页面(分类标签/批量操作/偏好入口) |
### NotificationBell 交互
- 未读时显示红色圆点徽章
- 点击展开快捷通知面板(最近5条)
- 下拉面板支持滚动加载更多
- 点击通知跳转到目标页面并自动标记已读
- "查看全部"链接跳转到通知中心
+179
View File
@@ -0,0 +1,179 @@
# 积分体系模块
## 概述
积分体系是追光AI的用户激励核心,包含20级成长系统、积分奖励引擎、积分商店、签到连击和Streak冻结保护,通过游戏化机制提升用户活跃度和留存率。
## 积分规则
| 行为 | 积分 | 每日上限 |
|------|------|----------|
| 发表评论 | +5 | 50 |
| 评论被点赞 | +2 | 20 |
| 发布论坛话题 | +10 | 无限制 |
| 论坛回复 | +5 | 30 |
| 发表评价 | +8 | 20 |
| 每日签到 | +1 (递增) | 1 |
| 签到连击 bonus | 连续7天+3, 连续30天+10 | - |
---
## 等级系统 - 20级成长体系
### 等级配置
- **配置文件**: `src/lib/level-config.ts` — 客户端安全(无Prisma依赖)
- 等级范围: LV01(0分) → LV20(50000分)
- 等级图标: ⭐(初级) → ⭐⭐⭐(中级) → 🌟(高级) → 🌟🌟(精英) → 🌟🌟🌟(大师)
### 等级表
| 等级 | 最低积分 | 徽章 | 每日限额 |
|------|----------|------|----------|
| LV01 | 0 | ⭐ | 50 |
| LV02 | 10 | ⭐ | 80 |
| LV03 | 30 | ⭐⭐ | 100 |
| LV04 | 60 | ⭐⭐ | 120 |
| LV05 | 100 | ⭐⭐ | 150 |
| LV06 | 200 | ⭐⭐⭐ | 180 |
| LV07 | 400 | ⭐⭐⭐ | 200 |
| LV08 | 700 | ⭐⭐⭐ | 250 |
| LV09 | 1000 | ⭐⭐⭐ | 300 |
| LV10 | 1500 | 🌟 | 400 |
| LV11 | 2000 | 🌟 | 500 |
| LV12 | 3000 | 🌟 | 600 |
| LV13 | 4500 | 🌟 | 700 |
| LV14 | 6000 | 🌟🌟 | 800 |
| LV15 | 8000 | 🌟🌟 | 1000 |
| LV16 | 11000 | 🌟🌟 | 1200 |
| LV17 | 15000 | 🌟🌟 | 1500 |
| LV18 | 20000 | 🌟🌟🌟 | 1800 |
| LV19 | 30000 | 🌟🌟🌟 | 2000 |
| LV20 | 50000 | 🌟🌟🌟 | 3000 |
### 旧等级迁移映射
BRONZE→LV01, SILVER→LV03, GOLD→LV06, PLATINUM→LV10
### 积分奖励引擎
- **文件**: `src/lib/points-reward.ts`
- `rewardPoints()` — 自动发放积分 + 日限额检查 + 事务写入
- `getUserStats()` — 获取用户综合统计(积分/评论数/话题数等)
- `getUserPointsHistory()` — 积分历史分页查询
---
## 签到系统
### 每日签到
- 基础+1分,连续签到递增奖励
- 连续7天: +3 bonus
- 连续30天: +10 bonus
- 中断重置
### CheckInCard 组件
- 位置: 用户中心顶部
- 功能: 签到按钮、连击天数显示、季度签到日历
---
## Streak 冻结保护
### 功能说明
- 用户可通过积分商店购买 Streak Freeze 卡片
- 当用户某天未签到时,自动消耗一张 Freeze 卡保护连击不断
- 最多持有 3 张 Freeze 卡
### 核心库
- **文件**: `src/lib/streak-freeze.ts`
- `checkAndApplyFreeze(userId)` — 检查是否需要冻结并自动应用
- `getFreezeCardCount(userId)` — 获取当前持有数量
- `useFreezeCard(userId)` — 消耗一张冻结卡
### 定时任务
- **脚本**: `scripts/grant-freeze-cards.mjs`
- 定期为活跃用户发放 Freeze 卡(每日01:00)
---
## 积分商店
### 功能概述
用户可使用积分兑换虚拟物品和社区权益。
### 商品定义
- **文件**: `src/lib/shop-items.ts`
- 商品类型: 头像框、昵称颜色、特效道具、Streak Freeze 卡
### API 接口
| 路由 | 方法 | 功能 |
|------|------|------|
| /api/user/shop/items | GET | 获取可购买商品列表 |
| /api/user/shop/purchase | POST | 购买商品(扣积分) |
| /api/user/shop/my-items | GET | 获取用户已购物品 |
### 前端组件
- 积分商店页面(用户中心入口)
- 商品卡片(名称/图标/价格/库存/购买按钮)
- 已购物品展示(个人中心装饰效果)
---
## 数据模型
### PointsHistory (积分历史)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | Int @id | 主键 |
| userId | Int | 用户ID |
| points | Int | 积分变动(正数获得/负数消耗) |
| reason | String | 积分原因 |
| detail | String? | 详细信息 |
| refType | String? | 关联类型 |
| refId | Int? | 关联ID |
| createdAt | DateTime | 创建时间 |
### StreakFreeze (冻结卡) 🆕
| 字段 | 类型 | 说明 |
|------|------|------|
| id | Int @id | 主键 |
| userId | Int | 用户ID |
| cardCount | Int | 持有数量 |
| lastUsedAt | DateTime? | 最近使用时间 |
| createdAt | DateTime | 创建时间 |
### UserShopItem (已购物品) 🆕
| 字段 | 类型 | 说明 |
|------|------|------|
| id | Int @id | 主键 |
| userId | Int | 用户ID |
| itemId | String | 商品ID |
| purchasedAt | DateTime | 购买时间 |
| isActive | Boolean | 是否启用/佩戴 |
---
## 前端组件
| 组件 | 文件 | 说明 |
|------|------|------|
| MemberBadge | `src/components/common/MemberBadge.tsx` | 会员等级徽章(⭐🌟 + 积分显示,3种尺寸) |
| LevelProgress | `src/components/common/LevelProgress.tsx` | 等级进度条(当前/下一级/进度百分比,动态变色) |
| CheckInCard | `src/components/common/CheckInCard.tsx` | 签到卡片(签到按钮/连击天数/季度日历) |
---
## 技术实现要点
### 积分自动奖励机制
所有评论/发帖/点赞操作自动通过 `rewardPoints()` 发放积分:
- 每日上限检查(防刷分)
- 事务写入(积分变更 + 历史记录同时写入)
- 等级自动随积分变化更新
### 日志分类
积分变动通过 `reason` 字段区分:
- `comment` — 评论
- `comment_liked` — 评论被点赞
- `topic_create` — 发帖
- `reply` — 回复
- `review` — 评价
- `check_in` — 签到
- `shop_purchase` — 商店消费(负数)
+93
View File
@@ -0,0 +1,93 @@
# 搜索增强模块
## 概述
搜索增强模块提供自动补全、搜索历史、键盘导航和搜索结果高亮,全面提升搜索体验和效率。
---
## 搜索自动补全 🆕
### API
| 路由 | 方法 | 功能 |
|------|------|------|
| /api/search/autocomplete | GET | 搜索自动补全建议 |
- Query: `q` (搜索关键词), `type` (tool/skill/all)
- 返回: `{ suggestions: [{ text, type, slug }] }`
- 基于工具名称、技能名称、标签前缀匹配
- 最多返回 8 条建议
- 响应时间 < 100ms(内存缓存)
### 前端组件
#### SearchBox 重写 🆕
- **文件**: `src/components/common/SearchBox.tsx`
- **功能**:
- 输入时实时显示自动补全下拉
- 键盘导航: ↑↓ 移动高亮 / Enter 选择 / ESC 关闭
- 搜索防抖(300ms)
- 搜索结果高亮匹配文本
- 支持工具/技能分类筛选
---
## 搜索历史 🆕
### 存储
- localStorage 存储: `zhuiguang-search-history`
- 最多保留 20 条历史记录
- 按最近使用排序
- 去重(同一查询只保留最新一条)
### 交互
- 搜索框聚焦时显示历史记录下拉
- 点击历史记录直接搜索
- 支持单条删除和清空全部
- 历史记录带搜索类型图标
---
## 高亮文本组件 🆕
### HighlightText
- **文件**: `src/components/common/HighlightText.tsx`
- Props: `{ text: string, keyword: string, className?: string }`
- 功能: 将文本中匹配的关键词包裹在 `<mark>` 标签中
- 样式: 黄色高亮背景 `bg-yellow-200 dark:bg-yellow-800`
- 不区分大小写匹配
### 使用场景
- 搜索结果列表中的工具名称/描述
- 自动补全下拉中的建议文本
- 评论/话题搜索
---
## 搜索框语义化
### WCAG 合规
- `<form role="search">` 包裹搜索表单
- `<label>` 关联搜索输入框(视觉隐藏)
- `<input type="search" name="search">` 语义输入
- `aria-label="搜索AI工具"` 辅助标签
- 自动补全列表 `role="listbox"` + `aria-activedescendant`
---
## 搜索参数规范
### 标准搜索参数
| 参数 | 类型 | 说明 |
|------|------|------|
| search | string | 搜索关键词 |
| page | number | 页码(默认1) |
| pageSize | number | 每页条数(默认20) |
| categoryId | number | 分类筛选 |
| pricingModel | string | 定价筛选 |
| sort | string | 排序(latest/popular/rating) |
### URL 搜索参数同步
- 搜索关键词同步到 URL query string
- 支持浏览器前进/后退导航
- 分享搜索结果 URL 可直接还原搜索状态
+174
View File
@@ -0,0 +1,174 @@
# 测试体系模块
## 概述
追光AI使用 Vitest 作为测试框架,已建立 5 个测试套件覆盖 132 个测试,目标覆盖率 80%+。测试文件位于 `src/__tests__/` 目录。
---
## 基础设施
### vitest.config.ts
```typescript
import { defineConfig } from "vitest/config";
import path from "path";
export default defineConfig({
test: {
globals: true,
environment: "node",
setupFiles: ["./vitest.setup.ts"],
include: ["src/__tests__/**/*.test.ts"],
coverage: {
provider: "v8",
reporter: ["text", "json", "html"],
thresholds: {
lines: 80,
branches: 80,
functions: 80,
statements: 80,
},
},
},
resolve: {
alias: { "@": path.resolve(__dirname, "./src") },
},
});
```
### vitest.setup.ts
- 全局 mock 配置
- Prisma mock 初始化
- 测试环境清理
### tsconfig 配置
```json
{
"compilerOptions": {
"types": ["vitest/globals"]
}
}
```
---
## 测试套件
### 1. level-config.test.ts
- **测试数量**: 28
- **覆盖**: `src/lib/level-config.ts`
- **测试内容**:
- 20个等级边界值检查
- 等级徽章映射
- 每日限额表
- 积分→等级转换
- 下一级积分计算
### 2. elo.test.ts
- **测试数量**: 24
- **覆盖**: ELO 评分计算逻辑
- **测试内容**:
- 基础 ELO 计算
- K因子变化
- 平局处理
- 极端分差
### 3. forum-hot.test.ts
- **测试数量**: 30
- **覆盖**: 论坛热度排序算法
- **测试内容**:
- 热度公式计算
- 时间衰减
- 回复加权
- 点赞加权
- 置顶优先
### 4. achievements.test.ts
- **测试数量**: 26
- **覆盖**: 成就系统逻辑
- **测试内容**:
- 成就解锁条件
- 进度计算
- 徽章授予
- 边界条件
### 5. points-reward.test.ts
- **测试数量**: 24
- **覆盖**: `src/lib/points-reward.ts`
- **测试内容**:
- 各操作积分奖励
- 每日上限检查
- Streak freeze 逻辑
- 商店购买消耗
- 等级升级触发
---
## 运行命令
```bash
# 运行所有测试
npx vitest run
# 监听模式
npx vitest
# 生成覆盖率报告
npx vitest run --coverage
# 运行特定测试文件
npx vitest run src/__tests__/level-config.test.ts
# UI 模式
npx vitest --ui
```
---
## 测试规范
### 文件命名
- 测试文件: `*.test.ts`
- 目录: `src/__tests__/`
### 测试结构
```typescript
import { describe, it, expect, beforeEach, vi } from "vitest";
describe("模块名", () => {
beforeEach(() => {
// setup
});
describe("功能点", () => {
it("应该满足某条件", () => {
// arrange
// act
// assert
});
it("应该处理边界情况", () => {
// ...
});
it("应该优雅处理错误", () => {
// ...
});
});
});
```
### 测试原则
- 每个 `it` 测试单一行为
- 使用 `describe` 组织相关测试
- Arrange → Act → Assert 三段式
- 覆盖正常路径 + 边界条件 + 错误路径
- 禁止 `.skip` 除非有明确 TODO 注释
- Mock 外部依赖(Prisma、外部 API)
### 覆盖率目标
| 指标 | 目标 |
|------|------|
| 行覆盖率 | ≥ 80% |
| 分支覆盖率 | ≥ 80% |
| 函数覆盖率 | ≥ 80% |
| 语句覆盖率 | ≥ 80% |
+118
View File
@@ -0,0 +1,118 @@
# 暗色模式模块
## 概述
追光AI支持浅色/暗色双主题模式,通过 ThemeProvider + CSS 变量驱动,用户偏好自动持久化到 localStorage,整体遵循 Tailwind CSS `class` 策略。
## 架构
```
ThemeProvider (Context)
├── 读取 localStorage 初始主题
├── 监听系统 prefers-color-scheme 变化
├── 在 <html> 上切换 "dark" class
└── 提供 toggle/setTheme 方法给子孙组件
```
---
## 核心组件
### ThemeProvider
- **文件**: `src/components/ThemeProvider.tsx`
- **位置**: 根 layout.tsx 包裹
- **功能**:
- `theme` state: `"light"` | `"dark"` | `"system"`
- `toggleTheme()` — 在 light/dark 间切换
- `setTheme(mode)` — 设置为指定模式
- 自动监听 `prefers-color-scheme` 媒体查询(`system` 模式时)
- 持久化到 `localStorage("zhuiguang-theme")`
### Header 主题切换按钮
- **文件**: `src/components/layout/Header.tsx`
- 太阳 ☀️ / 月亮 🌙 图标切换
- 点击调用 `toggleTheme()`
- 动画过渡效果
---
## CSS 变量系统
### globals.css 暗色变量
```css
:root {
/* 浅色主题变量 (默认) */
--background: 0 0% 100%;
--foreground: 222 47% 11%;
/* ... */
}
.dark {
/* 暗色主题变量覆盖 */
--background: 222 47% 11%;
--foreground: 210 40% 98%;
/* ... */
}
```
- 使用 HSL 变量,Tailwind 通过 `hsl(var(--xxx))` 引用
- shadcn/ui 组件自动适配暗色模式(基于 `.dark` class)
---
## 组件适配(14个文件已更新)
以下组件已适配暗色模式:
| 组件 | 适配内容 |
|------|----------|
| Header | 主题切换按钮、导航栏背景色 |
| Footer | 页脚背景色、文字色、分隔线 |
| HeroBanner | Canvas 粒子颜色随主题切换 |
| HomePageClient | 卡片背景、文字颜色 |
| ToolsContent | 搜索框、筛选侧边栏、卡片 |
| SkillsPageClient | 技能卡片、分类标签 |
| 社区相关组件 | ForumBoard/ForumTopicCard/ForumEditor |
| 通知组件 | NotificationBell/NotificationCenter |
| 用户中心 | 积分卡片、等级进度条 |
| 工具详情 | 信息面板、推荐列表 |
| 技能详情 | 评测卡片、详情面板 |
| 后台管理 | 管理面板所有表格/表单 |
---
## 设计规范
### 浅色主题
- 背景: `bg-white` / `bg-muted/50`
- 卡片: `bg-white/80` (毛玻璃) / `bg-white/60` (卡片)
- 边框: `border-border/40`
- 阴影: `shadow-sm`
### 暗色主题
- 背景: `bg-background` (HSL 222 47% 11%)
- 卡片: `bg-card` (HSL 222 47% 13-15%)
- 边框: `border-border` (HSL 215 20% 25%)
- 阴影: `shadow-md` (更明显的阴影)
### 颜色规范(双主题通用)
- 文字: 浅色 `-600/-700` | 暗色 `-300/-200`
- 背景: 浅色 `-50` | 暗色 `-900/-950`
- 边框: 浅色 `-200/60` | 暗色 `-700/60`
---
## 技术实现要点
### 闪烁防护
- ThemeProvider 在 `useEffect` 中初始化,避免 SSR 时的主题闪烁
- `<html>` 上通过内联 script 在 hydration 前设置 class(防止白屏闪烁)
### 系统主题跟随
- `matchMedia('(prefers-color-scheme: dark)')` 监听
- 用户手动设置后覆盖系统偏好
- "system" 模式时动态跟随
### 持久化策略
- 存储键: `zhuiguang-theme`
- 值: `"light"` | `"dark"`
- 优先级: localStorage > 系统偏好 > 默认 light
+128
View File
@@ -0,0 +1,128 @@
# 工具功能增强模块
## 概述
工具功能增强模块包含工具对比(Compare)、工具认证徽章(Verified Badge)和个性化工具推荐(Recommendations),提升用户决策效率和信任度。
---
## 工具对比 (Tool Comparison) 🆕
### 功能概述
用户可同时选择最多 4 个工具进行并排对比,从 10 个维度查看详细差异。
### 架构
```
CompareProvider (React Context)
├── compareList: Tool[] (最多4个)
├── addToCompare(tool) — 添加工具到对比列表
├── removeFromCompare(toolId) — 移除
├── clearCompare() — 清空
└── isInCompare(toolId) — 是否已在列表
```
### 核心组件
| 组件 | 文件 | 说明 |
|------|------|------|
| CompareProvider | `src/components/common/CompareProvider.tsx` | Context Provider,管理对比状态 |
| CompareBar | `src/components/common/CompareBar.tsx` | 底部浮动对比栏(显示已选工具+对比按钮) |
| CompareButton | `src/components/common/CompareButton.tsx` | 工具卡片上的"加入对比"切换按钮 |
### 页面
#### /tools/compare
- 10维度对比表格
- 维度: 名称/分类/定价模型/定价详情/功能特性/标签/评分/评论数/浏览数/官网链接
- 支持一键移除/清空/返回浏览
### 交互流程
1. 在工具列表/详情页点击 CompareButton 添加工具
2. 底部 CompareBar 浮出显示已选工具(最大4个)
3. 点击 CompareBar 的"开始对比"按钮跳转到 /tools/compare
4. 对比页面展示并排表格,可移除/继续添加
### CompareBar 状态
- 空状态: 隐藏
- 1个工具: 显示但对比按钮禁用(至少需要2个)
- 2-4个工具: 显示完整,对比按钮可用
- 4个工具: 添加按钮禁用,显示"已满"
---
## 工具认证徽章 (Tool Verification) 🆕
### 功能概述
管理员可为优质/官方工具添加蓝V认证徽章,提升用户信任度。
### 数据模型
- Tool 表新增字段: `isVerified: Boolean @default(false)`
- Tool 表新增字段: `verifiedAt: DateTime?`
### API
| 路由 | 方法 | 功能 |
|------|------|------|
| /api/admin/tools/[id]/verify | POST | 管理员认证工具(添加蓝V) |
| /api/admin/tools/[id]/verify | DELETE | 管理员取消认证 |
| /api/tools/verified | GET | 获取所有已认证工具 |
### 前端展示
- 工具详情页: 名称旁边显示蓝色勾号徽章
- 工具列表卡片: 名称旁边显示小蓝V图标
- 认证工具专属筛选: "仅看认证" 开关
---
## 内容推荐引擎 🆕
### 功能概述
基于用户浏览历史和收藏偏好,推荐相关工具和话题。
### 核心 API
| 路由 | 方法 | 功能 |
|------|------|------|
| /api/recommendations | GET | 获取个性化推荐(工具+技能) |
### 推荐算法
- **协同过滤**: 基于相似用户的收藏/浏览模式
- **内容相似度**: 基于工具分类/标签/定价模型
- **热度加权**: 综合浏览量、评论数、评分
### 前端组件
| 组件 | 文件 | 说明 |
|------|------|------|
| PersonalizedRecommend | `src/components/common/PersonalizedRecommend.tsx` 🆕 | 首页/用户中心的个性化推荐区 |
| RelatedTopics | `src/components/forum/RelatedTopics.tsx` | 话题详情页的相关话题推荐 |
### 展示位置
- 首页 "为你推荐" 板块
- 工具详情页 "相关推荐"
- 话题详情页 "相关话题"
- 用户中心 "猜你喜欢"
### PersonalizedRecommend 组件
- Props: `{ type: "tool" | "skill" | "topic", limit?: number }`
- 瀑布流/网格布局
- 骨架屏加载状态
- 空状态友好提示
- 支持刷新获取新推荐
---
## 共享类型定义
集中管理来源类型标签和颜色:
### src/lib/source-type.ts 🆕
```typescript
export function sourceTypeLabel(type: string): string
export function sourceTypeColor(type: string): string
```
- 支持: github / gitlab / gitee / huggingface / 官网
- 统一管理标签中文名和 Tailwind 配色
### src/lib/constants.ts 🆕
- `tagColors` — 工具/技能标签配色映射
- 统一管理所有标签的颜色方案