diff --git a/.omc/plans/next-phase-features.md b/.omc/plans/next-phase-features.md new file mode 100644 index 0000000..6f36333 --- /dev/null +++ b/.omc/plans/next-phase-features.md @@ -0,0 +1,551 @@ +# AI 项目导航网站 - 下一阶段功能实施计划 + +**创建日期**: 2026-02-20 +**计划版本**: 1.0 +**预计工期**: 6-8 周 + +--- + +## 需求摘要 + +本计划涵盖两个并行推进的方向: + +### 方向 A - 视觉与交互体验 +提升用户体验的视觉优化,包括深浅主题切换、移动端适配、无障碍访问和布局优化。 + +### 方向 B - 质量控制体系 +建立项目审核流程和质量评分机制,确保平台内容质量,包含审核状态工作流、质量评分、垃圾内容过滤和标签规范化。 + +--- + +## 验收标准(可测试) + +### 方向 A 验收标准 +- [ ] **A1**: 用户可通过切换按钮在深色/浅色主题间切换,选择持久化到 localStorage +- [ ] **A2**: 在 375px-768px-1440px 三个断点下,所有页面布局正确无溢出 +- [ ] **A3**: 通过 Lighthouse 无障碍审计得分 >= 90 +- [ ] **A4**: 所有交互元素可通过键盘访问(Tab 导航 + Enter/Space 激活) +- [ ] **A5**: 首屏加载 LCP <= 2.5s(移动端 4G 网络) + +### 方向 B 验收标准 +- [ ] **B1**: 新项目默认状态为 `PENDING_REVIEW`,管理员可将其变为 `APPROVED`/`REJECTED` +- [ ] **B2**: 项目详情页显示质量评分(0-100),评分依据内容完整度和标签准确性 +- [ ] **B3**: 系统可自动标记疑似垃圾/低质项目(评分 < 30) +- [ ] **B4**: Tag Janitor API 支持批量标签规范化操作 +- [ ] **B5**: 审核日志记录所有状态变更(谁、何时、从什么状态改为什么状态) + +--- + +## 分阶段实施步骤 + +--- + +## 阶段 1:基础设施准备(Week 1) + +### 1.1 数据库 Schema 扩展(方向 B) + +**目标**: 为质量控制体系添加必要的数据库字段和模型 + +**涉及的文件**: +- `prisma/schema.prisma` + +**具体变更**: + +```prisma +// 新增:项目审核状态枚举 +enum ReviewStatus { + PENDING_REVIEW // 待审核 + APPROVED // 已批准 + REJECTED // 已拒绝 + FLAGGED // 已标记(可疑内容) +} + +// 修改:Project 模型添加审核和质量字段 +model Project { + // ... 现有字段 ... + + // 审核相关 + reviewStatus ReviewStatus @default(PENDING_REVIEW) + reviewedAt DateTime? + reviewedBy String? // 审核人标识(未来可关联用户系统) + + // 质量评分 + qualityScore Int? // 0-100 分 + qualityFactors Json? // 评分因素明细 + qualityUpdatedAt DateTime? + + // 索引更新 + @@index([reviewStatus], map: "idx_project_reviewStatus") + @@index([qualityScore], map: "idx_project_qualityScore") +} + +// 新增:审核日志模型 +model ReviewLog { + id String @id @default(cuid()) + projectId String + project Project @relation(fields: [projectId], references: [id], onDelete: Cascade) + fromStatus ReviewStatus + toStatus ReviewStatus + reason String? // 变更原因 + reviewedBy String? // 审核人 + createdAt DateTime @default(now()) + + @@index([projectId], map: "idx_reviewLog_projectId") + @@index([createdAt], map: "idx_reviewLog_createdAt") + @@map("review_logs") +} +``` + +**验收检查**: +```bash +pnpm prisma migrate dev --name add_review_system +pnpm prisma generate +``` + +--- + +### 1.2 主题系统基础(方向 A) + +**目标**: 建立主题切换的客户端基础设施 + +**涉及的文件**: +- `src/components/theme/ThemeProvider.tsx` (新建) +- `src/components/theme/ThemeToggle.tsx` (新建) +- `src/app/layout.tsx` +- `src/hooks/useTheme.ts` (新建) + +**具体实现要点**: + +1. **ThemeProvider.tsx**: 创建客户端主题上下文 + - 读取 localStorage 中的 `theme` 值 + - 支持 `light`、`dark`、`system` 三种模式 + - 通过 `next-themes` 或自定义 Context 实现 + +2. **ThemeToggle.tsx**: 主题切换按钮组件 + - 显示当前主题图标(太阳/月亮/系统) + - 点击切换主题 + - 适配 neo-brutalism 设计风格 + +3. **layout.tsx 修改**: 包装 ThemeProvider + ```tsx + + {children} + + ``` + +**验收检查**: +- 切换主题后刷新页面,主题保持不变 +- 系统主题变化时自动跟随(当选择 `system` 模式) + +--- + +## 阶段 2:核心功能实现(Week 2-3) + +### 2.1 主题切换 UI 集成(方向 A) + +**目标**: 将主题切换功能集成到网站导航栏 + +**涉及的文件**: +- `src/app/[locale]/layout.tsx` +- `src/components/theme/ThemeToggle.tsx` +- `src/messages/zh.json` +- `src/messages/en.json` + +**具体变更**: + +1. 在导航栏右侧添加 ThemeToggle 按钮(LocaleSwitcher 旁边) +2. 添加国际化文本: + ```json + // zh.json + "theme": { + "light": "浅色模式", + "dark": "深色模式", + "system": "跟随系统" + } + + // en.json + "theme": { + "light": "Light Mode", + "dark": "Dark Mode", + "system": "System" + } + ``` + +3. 确保所有 `dark:` Tailwind 类正确应用 + +**验收检查**: +- [ ] 导航栏显示主题切换按钮 +- [ ] 点击切换立即生效,无闪烁 +- [ ] 两种主题下所有组件颜色正确 + +--- + +### 2.2 审核状态 API(方向 B) + +**目标**: 创建项目审核相关的 API 端点 + +**涉及的文件**: +- `src/lib/validations.ts` +- `src/app/api/admin/review/route.ts` (新建) +- `src/app/api/admin/review/service.ts` (新建) +- `src/hooks/useProjects.ts` + +**具体实现**: + +1. **validations.ts**: 添加审核相关 Schema + ```typescript + export const ReviewStatusEnum = z.enum([ + "PENDING_REVIEW", "APPROVED", "REJECTED", "FLAGGED" + ]); + + export const UpdateReviewStatusSchema = z.object({ + apiKey: z.string().min(32), + projectId: z.string().min(1), + status: ReviewStatusEnum, + reason: z.string().max(500).optional(), + reviewedBy: z.string().max(100).optional(), + }); + + export const GetPendingReviewsQuerySchema = z.object({ + limit: z.coerce.number().int().positive().max(50).default(20), + offset: z.coerce.number().int().nonnegative().default(0), + sortBy: z.enum(['createdAt', 'qualityScore']).default('createdAt'), + sortOrder: z.enum(['asc', 'desc']).default('asc'), + }); + ``` + +2. **route.ts**: 实现 PATCH 端点更新审核状态 + +3. **service.ts**: 业务逻辑 + - 更新项目审核状态 + - 创建审核日志记录 + - 验证状态转换合法性 + +**验收检查**: +```bash +# 测试 API +curl -X PATCH http://localhost:3000/api/admin/review \ + -H "Content-Type: application/json" \ + -d '{"apiKey":"...","projectId":"xxx","status":"APPROVED"}' +``` + +--- + +### 2.3 质量评分系统(方向 B) + +**目标**: 实现自动计算项目质量评分的算法 + +**涉及的文件**: +- `src/lib/quality-scorer.ts` (新建) +- `src/app/api/webhook/projects/route.ts` +- `src/lib/validations.ts` + +**评分规则**(总分 100): + +| 因素 | 分值 | 说明 | +|------|------|------| +| 描述长度 | 0-15 | 10-50字=5分,50-200字=10分,200-500字=15分 | +| 内容完整性 | 0-20 | 有 content=10分,content > 200字=+10分 | +| 标签数量 | 0-15 | 1-3个=5分,4-6个=10分,7-10个=15分 | +| 链接完整性 | 0-20 | 有 GITHUB=10分,有 WEBSITE=+5分,有其他=+5分 | +| 英文翻译 | 0-15 | nameEn 存在=5分,descriptionEn 存在=5分,contentEn 存在=5分 | +| 媒体丰富度 | 0-15 | 未来扩展(截图、视频等) | + +**具体实现**: + +```typescript +// quality-scorer.ts +export function calculateQualityScore(project: ProjectInput): QualityScoreResult { + const factors: QualityFactor[] = []; + + // 描述长度评分 + const descLength = project.description.length; + let descScore = 0; + if (descLength >= 10 && descLength < 50) descScore = 5; + else if (descLength >= 50 && descLength < 200) descScore = 10; + else if (descLength >= 200 && descLength <= 500) descScore = 15; + factors.push({ name: 'descriptionLength', score: descScore, maxScore: 15 }); + + // ... 其他评分逻辑 + + return { + totalScore: factors.reduce((sum, f) => sum + f.score, 0), + factors, + flagged: totalScore < 30, // 低质量标记 + }; +} +``` + +**验收检查**: +- [ ] 新项目通过 webhook 导入时自动计算评分 +- [ ] 评分 < 30 的项目自动标记为 `FLAGGED` + +--- + +## 阶段 3:UI 完善(Week 4-5) + +### 3.1 移动端适配优化(方向 A) + +**目标**: 优化移动端布局和交互体验 + +**涉及的文件**: +- `src/app/[locale]/layout.tsx` +- `src/components/layout/MobileMenu.tsx` (新建) +- `src/components/project/ProjectCard.tsx` +- `src/components/project/ProjectList.tsx` +- `src/app/[locale]/projects/[id]/page.tsx` + +**具体变更**: + +1. **MobileMenu.tsx**: 实现汉堡菜单 + - 使用 Radix UI Dialog 或自定义实现 + - 包含导航链接、语言切换、主题切换 + - 平滑的打开/关闭动画 + +2. **layout.tsx**: 替换现有的简单按钮 + - 在移动端显示 MobileMenu + - 添加 `aria-label` 和键盘支持 + +3. **ProjectCard.tsx**: 优化移动端布局 + - 字体大小调整 + - 触摸目标至少 44x44px + - 标签横向滚动或折叠 + +**验收检查**: +- [ ] Chrome DevTools 模拟 375px 宽度下无布局溢出 +- [ ] 所有按钮/链接触摸区域 >= 44x44px +- [ ] 移动端菜单正常工作 + +--- + +### 3.2 无障碍访问优化(方向 A) + +**目标**: 通过 Lighthouse 无障碍审计 + +**涉及的文件**: +- 所有组件文件 +- `src/app/layout.tsx` + +**具体变更**: + +1. **语义化 HTML**: + - 使用 `