v0.11.1: 权限体系重构 + AI管线优化 + 内容整理
@@ -0,0 +1,15 @@
|
||||
# Environment variables declared in this file are NOT automatically loaded by Prisma.
|
||||
# Please add `import "dotenv/config";` to your `prisma.config.ts` file, or use the Prisma CLI with Bun
|
||||
# to load environment variables from .env files: https://pris.ly/prisma-config-env-vars.
|
||||
|
||||
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
|
||||
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
|
||||
|
||||
DATABASE_URL="mysql://mohe001:Mohe168899%23@rm-0jlbgr2rv6dj3t6jngo.mysql.rds.aliyuncs.com:3306/zhuiguang_ai?charset=utf8mb4"
|
||||
|
||||
NEXTAUTH_URL="http://localhost:8301"
|
||||
NEXTAUTH_SECRET="zhuiguang-ai-dev-secret"
|
||||
|
||||
GITHUB_TOKEN=""
|
||||
|
||||
DEEPSEEK_API_KEY="sk-91d1671855e44089b792b8147e17963f"
|
||||
@@ -34,3 +34,5 @@ yarn-error.log*
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
/src/generated/prisma
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
# 追光AI 变更日志
|
||||
|
||||
## v0.11.1 (2026-05-22) - AI发现管线质量优化
|
||||
|
||||
### 全链路测试
|
||||
- 跑通全部AI自动化管线:GitHub搜索 → DeepSeek评测 → 入库 → 内容生成
|
||||
- 2个脚本(automatic-review + daily-discover) + 4个API端点全部验证通过
|
||||
- 连测创建12条技能+评测记录,DeepSeek生成1篇日报+长文+视频脚本+社交卡片
|
||||
|
||||
### 质量过滤修复
|
||||
- **非AI项目过滤**: auto-review.mjs + daily-discover.mjs 新增 `isValidAIProject()` 函数
|
||||
- 关键词过滤: `book/guide/tutorial/awesome/interview/notes/handbook/cheatsheet/roadmap/curated-list` 等
|
||||
- 语言过滤: 纯Markdown/HTML文档Repo(Stars<5000)自动拒绝
|
||||
- 主题过滤: 有GitHub Topics的Repo必须包含AI相关Topic(ai/llm/rag/agent/gpt等)
|
||||
- 清理5条误入库非AI数据:AgentGuide、JavaGuide、pathway、StableDiffusionBook、Claude-Code-Everything
|
||||
|
||||
### JSON解析健壮性
|
||||
- 新增 `extractJSON()` 统一工具函数 → `src/lib/utils.ts`
|
||||
- 支持markdown代码块包裹(`\`\`\`json...\`\`\``)、花括号/方括号容错
|
||||
- 替换 deepseek.ts、auto-review.mjs、daily-discover.mjs、daily-reports/generate 的旧解析逻辑
|
||||
- 新增 `scripts/test-content-generation.mjs` 全管线测试脚本
|
||||
|
||||
### 新增脚本
|
||||
- `scripts/cleanup-non-ai.mjs` — 一键清理误入库非AI技能数据
|
||||
|
||||
---
|
||||
|
||||
## v0.11.0 (2026-05-22) - 权限体系重构
|
||||
|
||||
### 架构变更
|
||||
- **新增数据模型**: `Role`(角色), `Permission`(权限点), `RolePermission`(角色-权限关联) 三张表
|
||||
- **User 模型**: 新增 `roleId` 字段关联 `Role`,与原有 `role` 字符串字段并行(向后兼容)
|
||||
- 默认角色:**超级管理员**(Admin, 全部53权限)、**VIP成员**(Vip, 19个精选权限)
|
||||
|
||||
### 权限体系
|
||||
- **53个精细化权限点**,按页面分组管理:
|
||||
- 工具管理 14项 · 技能库 12项 · 评测管理 8项
|
||||
- AI发现 7项 · 内容管理 8项 · 系统管理 4项
|
||||
- 所有后台按钮/操作均已对应权限点,可逐个勾选控制
|
||||
|
||||
### 新增页面
|
||||
- **`/admin/roles` 角色权限管理**: 左侧角色列表 + 右侧按分组的权限勾选网格
|
||||
- 新建/删除自定义角色(系统角色受保护)
|
||||
- 分组全选/取消全选
|
||||
- 保存按钮实时同步到数据库
|
||||
|
||||
### 新增 API
|
||||
- `GET/POST /api/admin/roles` — 角色列表/创建
|
||||
- `PUT/DELETE /api/admin/roles/[id]` — 角色编辑/删除
|
||||
- `GET /api/admin/permissions` — 全部权限点列表
|
||||
- `GET /api/admin/user-permissions` — 用户权限查询(支持roleId/userId/当前用户)
|
||||
|
||||
### 鉴权升级
|
||||
- **middleware.ts**: 从硬编码 `role==="admin"` 改为认证检查 + 路由层委派
|
||||
- **admin-auth.ts**: `requireAdmin()` 兼容旧 `role` 字符串 + 新 `roleId` 关联角色双重逻辑
|
||||
- 新增 `requirePermission(key)` — 细粒度权限点校验
|
||||
- 新增 `getAllUserPermissions()` — 获取当前用户全部权限集合
|
||||
|
||||
### 前端工具
|
||||
- 新增 `usePermission()` hook — 提供 `can(key)`, `canAny(keys)`, `canAll(keys)` 方法
|
||||
- 侧边栏新增"角色权限"菜单入口
|
||||
|
||||
### 种子脚本
|
||||
- `scripts/seed-permissions.mjs` — 一键初始化全部权限点+角色
|
||||
|
||||
---
|
||||
|
||||
## v0.10.1 (2026-05-22) - 全面修复与优化
|
||||
|
||||
### 安全修复
|
||||
- **Admin API 鉴权增强**: 中间件matcher新增`/api/admin/:path*`路由保护,未登录或非管理员角色返回403
|
||||
- 所有关键admin路由已内置`requireAdmin()`双重校验(中间件+路由层防御深度)
|
||||
|
||||
### Bug 修复
|
||||
- **Category ID 动态化**: `skill-discoverer.ts`、`daily-discover.mjs`、`auto-review.mjs`三个文件的硬编码Category ID(120-127)替换为数据库查询+关键词匹配,消除分类错配风险
|
||||
- **reviews统计卡片**: 修复评测管理页面统计(已发布/草稿/平均评分)只显示当前页数据的问题,改为从全局groupBy统计获取
|
||||
- **内容生成日志完善**: `/api/admin/reviews/[id]/generate`成功和失败均写入`ReviewGenerationLog`
|
||||
|
||||
### 功能增强
|
||||
- **待审核技能编辑增强**: 编辑对话框新增"功能特性(JSON)"和"标签(逗号分隔)"输入框,支持直接编辑上传
|
||||
- **已发布技能编辑增强**: 编辑对话框新增"分类"下拉选择、"功能特性(JSON)"、"标签"字段,功能对齐待审核页面
|
||||
- **日报AI一键生成**: 新增`/api/admin/daily-reports/generate`端点,前端新增"一键AI生成"按钮,直接调用DeepSeek生成日报并自动填充表单,替代原有的"复制提示词→粘贴JSON"手动流程
|
||||
|
||||
### 内部改进
|
||||
- `ReviewGenerationLog`确认已在`skill-discoverer.ts`和两个脚本中正常使用,非僵尸表
|
||||
- 三个脚本文件统一使用数据库查询获取分类ID,消除代码不一致
|
||||
|
||||
---
|
||||
|
||||
## v0.10.0 (2026-05-20) - 五维评测系统
|
||||
|
||||
### 新增
|
||||
- **数据库扩展**: SkillReview模型(五维评测)、ReviewGenerationLog模型(评测日志)、ReviewStatus枚举(DRAFT/PUBLISHED/REJECTED/OUTDATED)
|
||||
- **Skill模型扩展**: 新增lastReviewedAt(最近评测时间)、githubStarsHistory(Star历史)字段,关联skillReview
|
||||
- **GitHub数据采集模块** (`src/lib/github.ts`): octokit封装,支持searchHotRepos搜索热门仓库、getRepoReadme获取README
|
||||
- **DeepSeek评测生成模块** (`src/lib/deepseek.ts`): OpenAI兼容接口,五维评测提示词模板,综合分自动校验
|
||||
- **自动化评测脚本** (`scripts/auto-review.mjs`): GitHub搜索→README获取→DeepSeek评测→入库全流程,每日限制8个
|
||||
- **评测API** (`/api/skills/[slug]/review`): 获取PUBLISHED状态的五维评测数据
|
||||
- **SkillReviewCard组件**: Chart.js雷达图+维度详情卡片,dynamic import(ssr:false),紫色主色调
|
||||
- **技能详情页集成**: 在标签卡片和评论之间展示五维评测雷达图
|
||||
- **发布评测脚本** (`scripts/publish-reviews.mjs`): 批量将DRAFT评测改为PUBLISHED
|
||||
- **测试脚本**: test-github.mjs(GitHub API)、test-deepseek.mjs(DeepSeek API)
|
||||
- **新依赖**: octokit, openai, chart.js, react-chartjs-2
|
||||
|
||||
### 修改
|
||||
- .env新增GITHUB_TOKEN、DEEPSEEK_API_KEY配置
|
||||
- 开发规则更新: 允许服务端脚本调用外部AI API,前端仍禁止
|
||||
- 迁移记录: 第10次迁移 add_skill_reviews
|
||||
|
||||
### 踩坑
|
||||
- Prisma 7.8需通过PrismaMariaDb适配器初始化,脚本中不能直接new PrismaClient()
|
||||
- Chart.js组件需dynamic import + ssr:false,不支持服务端渲染
|
||||
- 服务器环境SSL证书问题: 运行脚本需设置$env:NODE_TLS_REJECT_UNAUTHORIZED="0"
|
||||
- Chart.js font.weight只接受bold/normal/bolder/lighter,不接受数字字符串如"500"
|
||||
|
||||
---
|
||||
|
||||
## v0.9.0 (2026-05-09)
|
||||
|
||||
### 重大变更
|
||||
- **移除所有外部AI API调用**: discover-tools、discover-skills、discover-news三个API不再调用DeepSeek API,改为接收前端提交的JSON数据
|
||||
- **端口迁移**: 开发端口从3100-3110迁移至8301-8310,默认端口8301
|
||||
- **五大操作指令模式重构**: 从"一键调用API"模式改为"提示词+JSON粘贴导入"模式
|
||||
|
||||
### 新增
|
||||
- AI新闻发现页面 `/admin/discover-news`:3步流程(复制提示词→粘贴JSON→查看日报),6大分类+热度评分
|
||||
- AI新闻发现API `POST /api/admin/discover-news`:接收新闻JSON数组,自动生成今日AI日报
|
||||
- AI新闻发现API `GET /api/admin/discover-news`:获取今日AI日报
|
||||
- `fetchLogoWithMethod()` 函数:返回Logo URL + 成功方法名(如"HTML Link图标"、"OG/Twitter图片"等)
|
||||
- 检测AI工具页面增加Logo抓取功能:检测时同步抓取缺失Logo,记录成功方法名统计
|
||||
- 检测AI工具页面增加Logo抓取方法统计面板:按成功次数排序展示每种方法的效果
|
||||
- 检测AI工具页面增加Logo新抓取成功列表:展示Logo预览和使用的抓取方法名
|
||||
- 导入10天100条真实AI新闻(4月30日-5月9日)
|
||||
|
||||
### 修改
|
||||
- discover-tools API: 从调用DeepSeek API改为接收 `{tools: [...], categoryId}` JSON数组
|
||||
- discover-skills API: 从调用DeepSeek API改为接收 `{skills: [...], categoryId}` JSON数组
|
||||
- discover-tools页面: 从一键发现改为4步流程(选分类→复制提示词→粘贴JSON→抓取Logo)
|
||||
- discover-skills页面: 从一键发现改为3步流程(选分类→复制提示词→粘贴JSON)
|
||||
- discover-news页面: 从一键发现改为3步流程(复制提示词→粘贴JSON→查看日报)
|
||||
- check-tools API: 增加Logo抓取功能,返回logoFetched/logoMethod/logoUrl字段,GET请求获取HTML用于Logo抓取
|
||||
- check-tools页面: 默认选中待审核工具,4步流程卡片,增加Logo抓取方法统计和新抓取成功列表
|
||||
- update-skills页面: 去掉复制提示词,保留快速更新Star
|
||||
- logo-fetcher.ts: 新增 `fetchLogoWithMethod()` 导出,每种成功方法返回中文名称
|
||||
- package.json: 端口3100→8301
|
||||
- .env: NEXTAUTH_URL端口3100→8301
|
||||
- restart.ps1: 端口扫描范围3100-3110→8301-8310
|
||||
- project_rules.md: 端口规范8301-8310,新增强制要求;五大操作指令改为提示词+JSON粘贴模式;禁止硬编码API Key;禁止调用外部AI API
|
||||
|
||||
### 删除
|
||||
- 移除3个API文件中的DeepSeek API调用逻辑(硬编码API Key、callDeepSeek函数等)
|
||||
- 移除discover-tools页面的"一键发现"按钮和DeepSeek API调用
|
||||
- 移除discover-skills页面的"一键发现"按钮和DeepSeek API调用
|
||||
- 移除discover-news页面的DeepSeek API调用
|
||||
- 清除旧的虚构AI新闻数据
|
||||
|
||||
---
|
||||
|
||||
## v0.8.0 (2026-05-05)
|
||||
|
||||
### 新增
|
||||
- 用户系统:邮箱注册/登录、GitHub OAuth登录、用户中心页面
|
||||
- 收藏功能:工具/技能收藏、收藏列表页面、乐观更新按钮
|
||||
- 浏览历史:自动记录浏览过的工具/技能
|
||||
- 评论评价系统:ReviewSection组件,支持评分和文字评论
|
||||
- LoginModal组件:登录/注册弹窗,支持模式切换
|
||||
- FavoriteButton组件:收藏按钮,乐观更新
|
||||
- CategorySidebar组件:通用分类侧边栏
|
||||
- 用户API: `/api/user/favorites`, `/api/user/history`
|
||||
- 评论API: `/api/reviews`
|
||||
- 首页API: `/api/homepage`(含嵌套分类结构)
|
||||
|
||||
### 改进
|
||||
- **UI主题重构:暗色→浅色主题**
|
||||
- 全局CSS变量从暗色切换为浅色(background: 210 20% 98%, card: 0 0% 100%等)
|
||||
- 所有页面和组件适配浅色主题(7个前台页面+12个后台页面+5个组件)
|
||||
- 颜色规范:文字-600/-700、背景-50、边框-200/60
|
||||
- 卡片样式:bg-white/60/80 + shadow-sm,hover时bg-white + shadow-md
|
||||
- 输入框:bg-muted/50 focus:bg-white focus:ring-2 focus:ring-primary/10
|
||||
- 毛玻璃效果:bg-white/80 backdrop-blur-xl
|
||||
- 渐变文字:蓝→紫→粉渐变保持科技感
|
||||
- 移除noise纹理,新增dot-grid点阵背景
|
||||
- **层级分类导航重构**
|
||||
- 首页/技能页:左侧固定一级分类导航 + 右侧二级分类标签切换
|
||||
- 每个一级类目下有"全部"标签显示该分类下所有内容
|
||||
- 左侧导航sticky跟随页面滚动
|
||||
- **安全加固**
|
||||
- 新增admin-auth.ts中间件,requireAdmin函数
|
||||
- 28个后台API端点全部添加requireAdmin中间件验证
|
||||
- 移除硬编码API密钥,改用环境变量
|
||||
- Header组件:滚动时bg-white/80 backdrop-blur-2xl,搜索框bg-muted/50
|
||||
- Logo位置修复:Header容器宽度统一为max-w-[1440px]
|
||||
|
||||
### 修复
|
||||
- 修复webpack缓存损坏导致的页面加载失败(清除.next目录)
|
||||
- 修复左侧导航栏sticky定位不生效(flex容器添加self-start)
|
||||
- 修复Logo被左侧导航遮挡(统一容器宽度)
|
||||
|
||||
---
|
||||
|
||||
## v0.5.0 (2026-05-03)
|
||||
|
||||
### 新增
|
||||
- 待审核工具页面批量多选功能:全选/批量通过/批量拒绝
|
||||
- 待审核技能页面批量多选功能:全选/批量通过/批量拒绝
|
||||
- 待审核技能一键全部通过功能
|
||||
- 所有列表页面分页功能(每页20条)
|
||||
- 批量拒绝API: `/api/admin/pending/batch-reject`, `/api/admin/pending-skills/batch-reject`
|
||||
- 一键全部发布API: `/api/admin/pending-skills/publish-all`
|
||||
- AI技能自动探索API: `/api/admin/discover-skills/run`
|
||||
- 探索脚本存入系统配置,discover-skills页面展示脚本和调用说明
|
||||
- 一键自动探索按钮(服务端调用DeepSeek API)
|
||||
- Logo抓取策略改进:新增manifest.json解析、更多link/img匹配模式、图片URL验证
|
||||
- 工具库与脚本模块文档: `.trae/specs/modules/07-lib-and-scripts.md`
|
||||
|
||||
### 改进
|
||||
- Logo抓取引擎增强:6种策略按优先级,minFileSize降至50字节,timeout增至10秒
|
||||
- 待审核工具页面:新增Logo状态列、Logo筛选、抓取缺失Logo/重新抓取全部Logo按钮
|
||||
- 待审核技能页面:新增Star数展示、GitHub链接、分类标签
|
||||
- pending API和pending-skills API支持分页参数
|
||||
- 技术文档全面更新(7个模块文档+索引+开发规则+变更日志)
|
||||
|
||||
---
|
||||
|
||||
## v0.4.0 (2026-05-02)
|
||||
|
||||
### 新增
|
||||
- 系统配置页面:Logo抓取配置、发现提示词配置
|
||||
- 四个AI发现菜单:探索AI工具、检测AI工具、探索Skill技能、更新Skill技能
|
||||
- AI技能发现脚本 `scripts/discover-skills.mjs`
|
||||
- GitHub中文友好判断标准(4步标准)
|
||||
- 技能分类管理页面
|
||||
- DeepSeek V4 Pro API配置
|
||||
|
||||
### 改进
|
||||
- 配置驱动模式:提示词和Logo抓取策略存储在SystemConfig表
|
||||
- 去掉DeepSeek API配置功能,改为配置项驱动
|
||||
- 技能发现提示词优化
|
||||
|
||||
---
|
||||
|
||||
## v0.3.0 (2026-05-01)
|
||||
|
||||
### 新增
|
||||
- 技能库模块:Skill/PendingSkill数据模型、API、管理页面
|
||||
- API接口配置:ApiProvider数据模型和管理页面
|
||||
- 发现配置:DiscoveryConfig与分类管理集成
|
||||
- 公共Logo抓取工具 `src/lib/logo-fetcher.ts`
|
||||
- 服务重启脚本 `restart.ps1`
|
||||
|
||||
### 改进
|
||||
- 去除爬虫功能,改为AI发现模式
|
||||
- UI全面优化:暗色主题、毛玻璃效果、动画
|
||||
- 端口从3000改为3100
|
||||
|
||||
---
|
||||
|
||||
## v0.2.0 (2026-04-30)
|
||||
|
||||
### 新增
|
||||
- 后台管理页面:工具管理、分类管理、待审核工具
|
||||
- NextAuth认证系统
|
||||
- Prisma ORM + MySQL数据库
|
||||
- AI智能发现新工具功能(DeepSeek API)
|
||||
- 批量导入工具脚本
|
||||
|
||||
---
|
||||
|
||||
## v0.1.0 (2026-04-28)
|
||||
|
||||
### 新增
|
||||
- Next.js 14项目初始化
|
||||
- Tailwind CSS + shadcn/ui配置
|
||||
- 前台页面:首页、工具列表、工具详情、分类页
|
||||
- Header/Footer布局组件
|
||||
@@ -0,0 +1,126 @@
|
||||
# 追光AI 项目开发规则
|
||||
|
||||
## 端口规范
|
||||
- 开发端口: 8301-8310
|
||||
- 默认端口: 8301
|
||||
- 重启脚本仅扫描8301-8310范围
|
||||
- **强制要求:本项目端口必须锁定在8301-8310区间内,禁止使用其他端口,因为本服务器同时运行其他产品**
|
||||
|
||||
## 技术栈
|
||||
- Next.js 14 (App Router) + TypeScript
|
||||
- Tailwind CSS + shadcn/ui
|
||||
- Prisma 7.8 + MySQL (阿里云RDS)
|
||||
- NextAuth.js v4 (Credentials Provider)
|
||||
- DeepSeek API (deepseek-v4-pro) — 用于技能五维评测生成(服务端脚本调用)
|
||||
|
||||
## 代码风格
|
||||
- 不添加注释(除非明确要求)
|
||||
- 使用中文作为UI文案和提示词语言
|
||||
- TypeScript严格模式,零编译错误
|
||||
- 组件使用 `"use client"` 标记客户端组件
|
||||
- 路径别名: `@/*` → `./src/*`
|
||||
- **禁止在代码中硬编码任何AI API Key**
|
||||
- **禁止在代码中调用任何外部AI API(DeepSeek、OpenAI等)** — 前台/后台页面代码中禁止调用;服务端脚本(scripts/)中允许通过环境变量调用DeepSeek API和GitHub API
|
||||
- 所有发现/导入功能通过页面提示词+JSON粘贴方式完成,不调用外部接口
|
||||
|
||||
## 构建与检查
|
||||
- 修改代码后必须运行 `npx tsc --noEmit` 确认零错误
|
||||
- 重启服务使用 `pwsh -ExecutionPolicy Bypass -File restart.ps1`
|
||||
- 开发服务器: `npm run dev` (端口8301)
|
||||
|
||||
## 数据库
|
||||
- 云数据库: 阿里云RDS MySQL
|
||||
- 连接: `mysql://mohe001:***@rm-0jlbgr2rv6dj3t6jngo.mysql.rds.aliyuncs.com:3306/zhuiguang_ai`
|
||||
- Prisma单例模式防止热重载多实例
|
||||
- 修改Schema后: `npx prisma migrate dev --name <描述>`
|
||||
|
||||
## 认证
|
||||
- 管理员: admin@zhuiguang.ai / admin123
|
||||
- JWT Session策略
|
||||
- middleware.ts保护/admin路由(跳过/admin/login)
|
||||
- 后台API需requireAdmin中间件验证(src/lib/admin-auth.ts)
|
||||
- 用户注册/登录: NextAuth Credentials Provider,支持邮箱+密码
|
||||
|
||||
## API约定
|
||||
- 前台API: `/api/` 前缀,无需认证
|
||||
- 后台API: `/api/admin/` 前缀,需NextAuth认证
|
||||
- 分页参数: `page`(默认1), `pageSize`(默认20)
|
||||
- 返回格式: `{ data, total, page, pageSize }` 或 `{ success, error }`
|
||||
- 批量操作: body中传 `ids` 数组
|
||||
|
||||
## 页面路由
|
||||
- 前台: `/`, `/tools`, `/tools/[slug]`, `/categories/[slug]`, `/skills`, `/skills/[slug]`, `/login`, `/user`, `/user/favorites`
|
||||
- 后台: `/admin/login`, `/admin/pending`, `/admin/pending-skills`, `/admin/tools`, `/admin/skills`, `/admin/categories`, `/admin/skill-categories`, `/admin/discover-tools`, `/admin/check-tools`, `/admin/discover-skills`, `/admin/update-skills`, `/admin/discover-news`, `/admin/system-config`
|
||||
|
||||
## 五大操作指令
|
||||
|
||||
用户使用以下五个命令时,必须跳转到对应页面理解流程并按流程执行。
|
||||
所有页面均为"提示词+JSON粘贴导入"模式,不调用任何外部AI API。
|
||||
|
||||
### 探索AI工具
|
||||
- 页面: `/admin/discover-tools`
|
||||
- 流程: 选分类 → 复制提示词发给AI → 粘贴JSON → 导入审核列表 → 抓取Logo
|
||||
- 导入API: POST `/api/admin/discover-tools` body: `{ tools: [...], categoryId }`
|
||||
- API接收前端提交的工具JSON数组,自动去重导入待审核列表
|
||||
- Logo抓取API: POST `/api/admin/pending/fetch-logos`
|
||||
- 工具分类(20个): 文本生成(165), 图像生成(174), 视频生成(183), 音频与语音(191), 代码开发(199), AI Agent(208), 办公效率(216), 设计与创意(224), 营销与SEO(231), 数据分析(238), 教育与学习(245), 搜索与信息(252), 安全与合规(258), 医疗健康(264), 金融与法律(270), 电商与零售(276), 3D与游戏(282), 科学研究(288), 模型与框架(294), 聊天机器人(302)
|
||||
|
||||
### 检测AI工具
|
||||
- 页面: `/admin/check-tools`
|
||||
- 流程: 选择范围(已发布/待审核) → 一键检测+抓取Logo → 处理失效工具
|
||||
- 检测API: POST `/api/admin/check-tools` body: `{ type: "published" | "pending" }`
|
||||
- 系统自动逐一GET请求检测网站可访问性,同时自动抓取缺失Logo并记录成功方法名
|
||||
- 删除API: DELETE `/api/admin/tools/{id}` / `/api/admin/pending/{id}`
|
||||
|
||||
### 探索AI技能
|
||||
- 页面: `/admin/discover-skills`
|
||||
- 流程: 选分类 → 复制提示词发给AI → 粘贴JSON → 导入审核列表
|
||||
- 导入API: POST `/api/admin/discover-skills` body: `{ skills: [...], categoryId }`
|
||||
- API接收前端提交的技能JSON数组,自动去重导入待审核列表
|
||||
- 技能分类(20个父分类): 代码生成(1), 测试(10), 代码质量与分析(20), 安全(29), 文档(36), 架构与设计(43), 需求工程(49), DevOps与部署(56), 调试与错误处理(62), 形式化验证(69), 维护与重构(76), 版本控制与协作(82), 开发工具(86), UI/UX设计(91), 科学研究(95), 金融(103), 云服务(109), 移动开发(115), AI/ML工程(120), 营销与增长(127)
|
||||
|
||||
### 更新Skill技能
|
||||
- 页面: `/admin/update-skills`
|
||||
- 流程: 选择范围(已发布/待审核) → 一键更新 → 自动同步星级
|
||||
- 更新API: POST `/api/admin/update-stars` body: `{ type: "published" | "pending" }`
|
||||
- 系统自动从GitHub/Gitee/GitCode API获取最新星级评分并写入数据库
|
||||
|
||||
### AI新闻发现
|
||||
- 页面: `/admin/discover-news`
|
||||
- 流程: 复制提示词发给AI → 粘贴JSON → 导入今日新闻
|
||||
- 导入API: POST `/api/admin/discover-news` body: `{ items: [...] }`
|
||||
- API接收前端提交的新闻JSON数组,自动生成今日AI日报
|
||||
- 新闻分类: 产品发布/融资投资/技术突破/政策法规/开源项目/行业事件
|
||||
|
||||
### 通用执行规则
|
||||
1. **禁止调用任何外部AI API**,所有发现/导入功能通过页面提示词+JSON粘贴方式完成
|
||||
2. 页面提供提示词模板(含排除列表),用户复制发给AI助手获取JSON,粘贴到页面导入
|
||||
3. 导入API接收JSON数组,自动去重(名称+网址),导入待审核列表
|
||||
4. 导入工具后建议执行Logo抓取,确保所有工具有图标
|
||||
5. 所有提示词要求: 优先推荐国产AI工具/技能,国内可直连,中文友好
|
||||
6. 检测工具时:系统自动GET请求检测网站可访问性,同时抓取缺失Logo
|
||||
7. 更新技能时:系统自动从GitHub/Gitee/GitCode API获取最新星级
|
||||
|
||||
## 设计系统
|
||||
- 浅色主题,HSL CSS变量
|
||||
- 圆角: rounded-xl / rounded-2xl
|
||||
- 边框: border-border/40 (40%透明度)
|
||||
- 背景: bg-white/80 (毛玻璃) / bg-white/60 (卡片) / bg-muted/50 (输入框)
|
||||
- 阴影: shadow-sm (卡片) / shadow-md (悬浮)
|
||||
- 动画: transition-all duration-200
|
||||
- 自定义工具类: .glow-sm, .gradient-text, .glass, .card-shine, .dot-grid, .animate-fade-in
|
||||
- 颜色规范: 文字用 -600/-700 (非-400),背景用 -50 (非-500/10),边框用 -200/60 (非-500/20)
|
||||
- 输入框: bg-muted/50 focus:bg-white focus:ring-2 focus:ring-primary/10
|
||||
|
||||
## 环境变量
|
||||
- GITHUB_TOKEN: GitHub Personal Access Token(可选,提升API限流从60→5000次/小时)
|
||||
- DEEPSEEK_API_KEY: DeepSeek API Key(用于技能评测生成脚本)
|
||||
|
||||
## 踩坑记录
|
||||
- Next.js 14不支持useActionState,登录页用原生表单POST
|
||||
- Prisma MariaDB adapter需要连接字符串方式初始化
|
||||
- 图片域名需在next.config.mjs中配置remotePatterns
|
||||
- 热重载后需清除.next缓存: 删除.next目录后重启
|
||||
- Chart.js组件需用dynamic import + ssr: false,不支持服务端渲染
|
||||
- Prisma 7.8需通过PrismaMariaDb适配器初始化,不能直接new PrismaClient()
|
||||
- 服务器环境SSL证书问题: 运行脚本需设置$env:NODE_TLS_REJECT_UNAUTHORIZED="0"
|
||||
@@ -0,0 +1,90 @@
|
||||
# 追光AI - 模块文档索引
|
||||
|
||||
## 项目概述
|
||||
追光AI是一个AI工具与开源技能目录网站,支持提示词驱动的工具/技能发现、审核管理和前台展示。
|
||||
|
||||
## 技术栈
|
||||
|
||||
| 类别 | 技术 | 版本 |
|
||||
|------|------|------|
|
||||
| 框架 | Next.js (App Router) | 14.2.35 |
|
||||
| 语言 | TypeScript | 5.x |
|
||||
| 样式 | Tailwind CSS + shadcn/ui | 3.x |
|
||||
| 数据库 | MySQL (阿里云RDS) + Prisma | 7.8 |
|
||||
| 认证 | NextAuth.js | v4 |
|
||||
| AI | DeepSeek API (技能评测生成) | deepseek-v4-pro |
|
||||
| 图表 | Chart.js + react-chartjs-2 | 4.x |
|
||||
| 部署 | Node.js | 18+ |
|
||||
| 端口 | 8301-8310 | 默认8301 |
|
||||
|
||||
## 项目结构
|
||||
```
|
||||
zhuiguang-ai/
|
||||
├── prisma/ # 数据库Schema + 迁移 + 种子
|
||||
├── public/ # 静态资源 (logo.png, logos/)
|
||||
├── scripts/ # 独立脚本 (discover-skills, import-tools)
|
||||
├── src/
|
||||
│ ├── app/
|
||||
│ │ ├── (admin)/admin/ # 后台页面 (15个页面)
|
||||
│ │ ├── api/ # API路由 (36+个端点)
|
||||
│ │ ├── categories/ # 前台分类页
|
||||
│ │ ├── skills/ # 前台技能页
|
||||
│ │ ├── tools/ # 前台工具页
|
||||
│ │ ├── login/ # 用户登录页
|
||||
│ │ ├── user/ # 用户中心(个人资料/收藏)
|
||||
│ │ ├── globals.css # 全局样式
|
||||
│ │ ├── layout.tsx # 前台布局
|
||||
│ │ └── page.tsx # 首页
|
||||
│ ├── components/ # 组件 (Header, Footer, UI, Common)
|
||||
│ ├── lib/ # 工具库 (prisma, auth, admin-auth, github, deepseek, logo-fetcher, logo-storage, utils)
|
||||
│ └── middleware.ts # 路由保护
|
||||
├── .env # 环境变量
|
||||
├── restart.ps1 # 服务重启脚本(端口8301-8310)
|
||||
└── package.json # 依赖配置
|
||||
```
|
||||
|
||||
## 模块文档
|
||||
|
||||
| 序号 | 模块 | 文档 | 说明 |
|
||||
|------|------|------|------|
|
||||
| 01 | 数据库 | [01-database.md](./modules/01-database.md) | 数据模型、枚举、索引、迁移历史 |
|
||||
| 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组件、样式系统、设计规范 |
|
||||
| 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) | 工具函数、独立脚本、运维脚本 |
|
||||
|
||||
## 环境变量
|
||||
```
|
||||
DATABASE_URL=mysql://mohe001:***@rm-0jlbgr2rv6dj3t6jngo.mysql.rds.aliyuncs.com:3306/zhuiguang_ai
|
||||
NEXTAUTH_URL=http://localhost:8301
|
||||
NEXTAUTH_SECRET=<secret>
|
||||
GITHUB_TOKEN=<optional>
|
||||
DEEPSEEK_API_KEY=<required-for-review>
|
||||
```
|
||||
|
||||
## 核心业务流程
|
||||
```
|
||||
提示词模板(页面内嵌) → 用户复制发给AI助手 → AI返回JSON → 粘贴到页面导入
|
||||
→ PendingTool / PendingSkill (待审核)
|
||||
→ 管理员审核(编辑/发布/拒绝/批量操作)
|
||||
→ Tool / Skill (已发布)
|
||||
→ 前台展示(分类浏览/搜索/详情)
|
||||
```
|
||||
|
||||
## 关键特性
|
||||
- **提示词驱动**: 页面内嵌提示词模板(含排除列表),用户复制发给AI获取JSON后粘贴导入,不调用外部AI API
|
||||
- **Logo自动抓取**: 10种策略按优先级执行,fetchLogoWithMethod返回成功方法名,支持20+常见路径和5个Favicon服务
|
||||
- **检测+Logo联动**: 检测AI工具时同步抓取缺失Logo,记录每种抓取方法的成功次数统计
|
||||
- **双轨内容**: 工具(Tool)面向商业AI产品,技能(Skill)面向GitHub开源项目
|
||||
- **批量操作**: 批量导入、批量发布、批量拒绝、一键全部通过
|
||||
- **GitHub Star同步**: 通过GitHub API定期更新技能Star数
|
||||
- **AI新闻发现**: 提示词驱动发现AI新闻,按日生成日报,6大分类+热度评分
|
||||
- **五维评测系统**: GitHub数据采集 + DeepSeek AI评测 + 雷达图展示,5维度(capability/devExp/costLicense/community/performance)评分
|
||||
- **分页**: 所有列表页面支持分页(每页20条)
|
||||
- **浅色主题**: 科技感浅色设计系统,毛玻璃效果+渐变文字+精致阴影
|
||||
- **层级分类**: 一级分类+二级分类,左侧导航+标签切换
|
||||
- **用户系统**: 邮箱注册/登录、收藏功能、浏览历史
|
||||
- **安全加固**: 28个后台API全部添加requireAdmin中间件验证
|
||||
- **端口锁定**: 8301-8310区间,禁止使用其他端口
|
||||
@@ -0,0 +1,136 @@
|
||||
# 数据库模块
|
||||
|
||||
## 技术栈
|
||||
- Prisma 7.8 + @prisma/adapter-mariadb
|
||||
- MySQL (阿里云RDS)
|
||||
- 连接字符串: `mysql://mohe001:***@rm-0jlbgr2rv6dj3t6jngo.mysql.rds.aliyuncs.com:3306/zhuiguang_ai`
|
||||
|
||||
## 数据模型
|
||||
|
||||
### Category (工具分类)
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | Int @id @default(autoincrement()) | 主键 |
|
||||
| name | String @db.VarChar(100) | 分类名称 |
|
||||
| slug | String @unique @db.VarChar(100) | URL标识 |
|
||||
| icon | String? | 图标 |
|
||||
| parentId | Int? | 父分类ID(自引用) |
|
||||
| sortOrder | Int @default(0) | 排序权重 |
|
||||
| createdAt | DateTime | 创建时间 |
|
||||
| updatedAt | DateTime | 更新时间 |
|
||||
|
||||
### SkillCategory (技能分类)
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | Int @id @default(autoincrement()) | 主键 |
|
||||
| name | String @db.VarChar(100) | 分类名称 |
|
||||
| slug | String @unique @db.VarChar(100) | URL标识 |
|
||||
| icon | String? | 图标 |
|
||||
| parentId | Int? | 父分类ID(自引用) |
|
||||
| sortOrder | Int @default(0) | 排序权重 |
|
||||
| createdAt | DateTime | 创建时间 |
|
||||
| updatedAt | DateTime | 更新时间 |
|
||||
|
||||
### Tool (已发布工具)
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | Int @id | 主键 |
|
||||
| name | String | 工具名称 |
|
||||
| slug | String @unique | URL标识 |
|
||||
| categoryId | Int | 分类ID(必填) |
|
||||
| description | String @db.Text | 简介 |
|
||||
| logoUrl | String? | Logo地址 |
|
||||
| websiteUrl | String | 官网地址 |
|
||||
| pricingModel | PricingModel | 定价模型(free/freemium/paid/subscription) |
|
||||
| pricingDetail | String? | 定价详情 |
|
||||
| features | Json? | 功能特性数组 |
|
||||
| tags | Json? | 标签数组 |
|
||||
| viewCount | Int @default(0) | 浏览次数 |
|
||||
| status | Status @default(draft) | 状态(draft/published) |
|
||||
| createdAt/updatedAt | DateTime | 时间戳 |
|
||||
|
||||
### PendingTool (待审核工具)
|
||||
与Tool类似,但categoryId/description/websiteUrl等可为空,额外有sourceUrl和status(pending/approved/rejected)。
|
||||
|
||||
### Skill (已发布技能)
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | Int @id | 主键 |
|
||||
| name | String | 技能名称 |
|
||||
| slug | String @unique | URL标识 |
|
||||
| categoryId | Int | 分类ID(必填) |
|
||||
| description | String @db.Text | 简介 |
|
||||
| logoUrl | String? | Logo地址 |
|
||||
| sourceUrl | String | GitHub仓库地址 |
|
||||
| sourceType | String @default("gitee") | 来源类型 |
|
||||
| rating | Float @default(0) | 综合评分 |
|
||||
| features | Json? | 功能特性(含forks/language/license/topics) |
|
||||
| tags | Json? | 标签数组 |
|
||||
| viewCount | Int @default(0) | 浏览次数 |
|
||||
| status | Status | 状态 |
|
||||
| lastReviewedAt | DateTime? | 最近评测时间 |
|
||||
| githubStarsHistory | Json? | Star历史数据 |
|
||||
|
||||
### PendingSkill (待审核技能)
|
||||
与Skill类似,但多个字段可为空。
|
||||
|
||||
### SystemConfig (系统配置)
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | Int @id | 主键 |
|
||||
| key | String @unique | 配置键 |
|
||||
| value | Json | 配置值(JSON) |
|
||||
|
||||
### SkillReview (技能评测)
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | Int @id @default(autoincrement()) | 主键 |
|
||||
| skillId | Int @unique | 关联Skill(一对一) |
|
||||
| capability | Float | 场景与能力评分(1-5) |
|
||||
| devExp | Float | 开发体验评分(1-5) |
|
||||
| costLicense | Float | 成本与许可评分(1-5) |
|
||||
| community | Float | 社区健康评分(1-5) |
|
||||
| performance | Float | 性能稳定评分(1-5) |
|
||||
| overall | Float | 综合评分(五维均值) |
|
||||
| reviews | Json | 完整评测数据(含各维度summary/detail) |
|
||||
| longArticle | String? @db.Text | 长文评测 |
|
||||
| videoScript | String? @db.Text | 视频脚本 |
|
||||
| socialCards | Json? | 社交卡片数据 |
|
||||
| status | ReviewStatus @default(DRAFT) | 评测状态 |
|
||||
| reviewedAt | DateTime @updatedAt | 评测时间 |
|
||||
| createdAt | DateTime | 创建时间 |
|
||||
|
||||
### ReviewGenerationLog (评测生成日志)
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | Int @id @default(autoincrement()) | 主键 |
|
||||
| skillId | Int | 关联Skill ID |
|
||||
| status | String @db.VarChar(20) | SUCCESS/FAILED |
|
||||
| prompt | String @db.Text | 生成提示词 |
|
||||
| response | String? @db.Text | API响应内容 |
|
||||
| error | String? @db.Text | 错误信息 |
|
||||
| createdAt | DateTime | 创建时间 |
|
||||
|
||||
## 枚举
|
||||
- `PricingModel`: free, freemium, paid, subscription
|
||||
- `Status`: draft, published
|
||||
- `PendingStatus`: pending, approved, rejected
|
||||
- `ReviewStatus`: DRAFT, PUBLISHED, REJECTED, OUTDATED
|
||||
|
||||
## 索引
|
||||
- Tool: categoryId+status联合索引, name+description全文索引
|
||||
- Skill: categoryId+status联合索引
|
||||
- SkillReview: skillId索引(唯一), overall索引
|
||||
- ReviewGenerationLog: skillId索引
|
||||
|
||||
## 迁移历史
|
||||
1. init - 初始化
|
||||
2. remove_scraped_at - 移除scrapedAt字段
|
||||
3. add_discovery_configs - 添加发现配置
|
||||
4. fix_tag_pool_column - 修复标签池列
|
||||
5. add_discovery_configs_v2 - 发现配置V2
|
||||
6. add_api_providers_and_skills - 添加API提供者和技能
|
||||
7. add_skill_categories - 添加技能分类
|
||||
8. add_pendingtool_category_relation - 添加待审核工具分类关联
|
||||
9. add_hot_score - 添加热度评分
|
||||
10. add_skill_reviews - 添加技能评测表(SkillReview/ReviewGenerationLog)、Skill新增lastReviewedAt/githubStarsHistory字段
|
||||
@@ -0,0 +1,140 @@
|
||||
# API模块
|
||||
|
||||
## 前台API(无需认证)
|
||||
|
||||
### GET /api/homepage
|
||||
获取首页数据(含嵌套分类结构,一级分类+二级子分类)。
|
||||
- 返回: `{ categories: CategoryWithChildren[], skillCategories: SkillCategoryWithChildren[] }`
|
||||
|
||||
### GET /api/categories
|
||||
获取工具分类树形结构(含子分类),按sortOrder排序。
|
||||
|
||||
### GET /api/skill-categories
|
||||
获取技能分类树形结构(含子分类),按sortOrder排序。
|
||||
|
||||
### GET /api/tools
|
||||
获取已发布工具列表。
|
||||
- Query: `categoryId`, `pricingModel`, `search`, `page`(默认1), `pageSize`(默认20)
|
||||
- 返回: `{ tools: Tool[], total, page, pageSize }`
|
||||
|
||||
### GET /api/tools/[slug]
|
||||
获取工具详情(by slug),浏览计数+1。
|
||||
|
||||
### GET /api/skills
|
||||
获取已发布技能列表。
|
||||
- Query: `category`, `search`, `page`, `pageSize`
|
||||
- 返回: `{ skills: Skill[], total, page, pageSize }`
|
||||
|
||||
### GET /api/skills/[slug]
|
||||
获取技能详情(by slug),浏览计数+1。
|
||||
|
||||
### GET /api/skills/[slug]/review
|
||||
获取技能的五维评测数据(仅返回PUBLISHED状态)。
|
||||
- 返回: `{ capability, devExp, costLicense, community, performance, overall, reviews, longArticle?, videoScript?, socialCards?, reviewedAt }`
|
||||
|
||||
### GET/POST /api/auth/[...nextauth]
|
||||
NextAuth认证端点(登录/回调/CSRF等)。
|
||||
|
||||
### 用户相关API(需NextAuth用户认证)
|
||||
|
||||
| 路由 | 方法 | 功能 |
|
||||
|------|------|------|
|
||||
| /api/user/favorites | GET | 获取当前用户收藏列表(工具+技能) |
|
||||
| /api/user/favorites | POST | 添加收藏(body: { targetType, targetId }) |
|
||||
| /api/user/favorites | DELETE | 取消收藏(body: { targetType, targetId }) |
|
||||
| /api/user/history | GET | 获取浏览历史 |
|
||||
|
||||
---
|
||||
|
||||
## 后台API(需NextAuth认证)
|
||||
|
||||
### 分类管理
|
||||
|
||||
| 路由 | 方法 | 功能 |
|
||||
|------|------|------|
|
||||
| /api/admin/categories | GET | 获取所有分类(含工具数/子分类数) |
|
||||
| /api/admin/categories | POST | 创建分类 |
|
||||
| /api/admin/categories/[id] | PUT | 更新分类 |
|
||||
| /api/admin/categories/[id] | DELETE | 删除分类(有工具/子分类时拒绝) |
|
||||
| /api/admin/skill-categories | GET | 获取技能分类列表 |
|
||||
| /api/admin/skill-categories | POST | 创建技能分类 |
|
||||
| /api/admin/skill-categories/[id] | PUT | 更新技能分类 |
|
||||
| /api/admin/skill-categories/[id] | DELETE | 删除技能分类 |
|
||||
|
||||
### 工具管理
|
||||
|
||||
| 路由 | 方法 | 功能 |
|
||||
|------|------|------|
|
||||
| /api/admin/tools | GET | 获取所有工具(分页) |
|
||||
| /api/admin/tools | POST | 创建工具 |
|
||||
| /api/admin/tools/[id] | PUT | 更新工具 |
|
||||
| /api/admin/tools/[id] | DELETE | 删除工具 |
|
||||
|
||||
### 技能管理
|
||||
|
||||
| 路由 | 方法 | 功能 |
|
||||
|------|------|------|
|
||||
| /api/admin/skills | GET | 获取所有技能(分页) |
|
||||
| /api/admin/skills/[id] | PUT | 更新技能 |
|
||||
| /api/admin/skills/[id] | DELETE | 删除技能 |
|
||||
|
||||
### 待审核工具
|
||||
|
||||
| 路由 | 方法 | 功能 |
|
||||
|------|------|------|
|
||||
| /api/admin/pending | GET | 获取待审核工具列表(分页) |
|
||||
| /api/admin/pending | DELETE | 清空所有待审核工具 |
|
||||
| /api/admin/pending/[id] | PUT | 编辑待审核工具(websiteUrl变更时自动抓Logo) |
|
||||
| /api/admin/pending/[id] | DELETE | 删除单个待审核工具 |
|
||||
| /api/admin/pending/[id]/publish | POST | 发布为正式工具 |
|
||||
| /api/admin/pending/batch | POST | 批量导入(去重+自动抓Logo) |
|
||||
| /api/admin/pending/batch-publish | POST | 批量发布(ids数组) |
|
||||
| /api/admin/pending/batch-reject | POST | 批量拒绝(ids数组) |
|
||||
| /api/admin/pending/fetch-logos | POST | 批量抓取Logo(body: {scope, refetch?}) |
|
||||
|
||||
### 待审核技能
|
||||
|
||||
| 路由 | 方法 | 功能 |
|
||||
|------|------|------|
|
||||
| /api/admin/pending-skills | GET | 获取待审核技能列表(分页) |
|
||||
| /api/admin/pending-skills | DELETE | 清空所有待审核技能 |
|
||||
| /api/admin/pending-skills/[id] | PUT | 编辑待审核技能 |
|
||||
| /api/admin/pending-skills/[id] | DELETE | 删除单个待审核技能 |
|
||||
| /api/admin/pending-skills/[id]/publish | POST | 发布为正式技能 |
|
||||
| /api/admin/pending-skills/batch | POST | 批量导入(去重) |
|
||||
| /api/admin/pending-skills/batch-publish | POST | 批量发布(ids数组) |
|
||||
| /api/admin/pending-skills/batch-reject | POST | 批量拒绝(ids数组) |
|
||||
| /api/admin/pending-skills/publish-all | POST | 一键发布所有待审核技能 |
|
||||
|
||||
### AI发现与检测(提示词+JSON粘贴模式,不调用外部AI API)
|
||||
|
||||
| 路由 | 方法 | 功能 |
|
||||
|------|------|------|
|
||||
| /api/admin/discover-tools | POST | 导入工具JSON数组(body: {tools: [...], categoryId}),自动去重导入待审核列表 |
|
||||
| /api/admin/discover-skills | POST | 导入技能JSON数组(body: {skills: [...], categoryId}),自动去重导入待审核列表 |
|
||||
| /api/admin/discover-news | POST | 导入新闻JSON数组(body: {items: [...]}),自动生成今日AI日报 |
|
||||
| /api/admin/discover-news | GET | 获取今日AI日报 |
|
||||
| /api/admin/check-tools | POST | 检测工具网站可访问性+抓取缺失Logo(body: {type: "published"/"pending"}),返回logoFetched/logoMethod/logoUrl |
|
||||
| /api/admin/update-stars | POST | 更新GitHub Star数(body: {type: "published"/"pending"}) |
|
||||
|
||||
### 系统配置
|
||||
|
||||
| 路由 | 方法 | 功能 |
|
||||
|------|------|------|
|
||||
| /api/admin/system-config | GET | 获取所有配置 |
|
||||
| /api/admin/system-config | PUT | 批量更新配置(upsert) |
|
||||
|
||||
### 评论API(需NextAuth用户认证)
|
||||
|
||||
| 路由 | 方法 | 功能 |
|
||||
|------|------|------|
|
||||
| /api/reviews | GET | 获取评论列表(query: type, targetId) |
|
||||
| /api/reviews | POST | 创建评论(body: { type, targetId, content, rating? }) |
|
||||
|
||||
## SystemConfig 配置键
|
||||
|
||||
| Key | 类型 | 说明 |
|
||||
|-----|------|------|
|
||||
| discoveryPromptConfig | JSON | AI发现提示词配置(含toolPrompt/skillPrompt/newsPrompt/tagPool等) |
|
||||
| logoFetchConfig | JSON | Logo抓取策略配置 |
|
||||
| discoverSkillsScript | string | 技能探索脚本源码 |
|
||||
@@ -0,0 +1,137 @@
|
||||
# 页面模块
|
||||
|
||||
## 前台页面
|
||||
|
||||
### / (首页)
|
||||
- 文件: `src/app/page.tsx`
|
||||
- 功能: 搜索框、AI工具分类网格(一级+二级分类,左侧导航+标签切换)、技能分类网格、最新上架工具、热门工具、CTA区块
|
||||
- 数据源: `/api/homepage`, `/api/categories`, `/api/skill-categories`, `/api/tools`
|
||||
|
||||
### /tools (工具列表)
|
||||
- 文件: `src/app/tools/page.tsx`
|
||||
- 功能: 分类筛选侧边栏(一级分类)、定价模型筛选、搜索、分页
|
||||
- 数据源: `/api/categories`, `/api/tools`
|
||||
|
||||
### /tools/[slug] (工具详情)
|
||||
- 文件: `src/app/tools/[slug]/page.tsx`
|
||||
- 功能: 工具完整信息展示、浏览计数+1、收藏按钮、评论评价
|
||||
- 数据源: `/api/tools/[slug]`
|
||||
|
||||
### /categories/[slug] (分类详情)
|
||||
- 文件: `src/app/categories/[slug]/page.tsx`
|
||||
- 功能: 按分类slug展示该分类下的工具
|
||||
- 数据源: `/api/categories`, `/api/tools`
|
||||
|
||||
### /skills (技能库)
|
||||
- 文件: `src/app/skills/page.tsx`
|
||||
- 功能: 技能分类筛选(一级+二级分类,左侧导航+标签切换)、搜索
|
||||
- 数据源: `/api/skill-categories`, `/api/skills`
|
||||
|
||||
### /skills/[slug] (技能详情)
|
||||
- 文件: `src/app/skills/[slug]/page.tsx`
|
||||
- 功能: 技能完整信息展示、浏览计数+1、收藏按钮、五维评测雷达图(SkillReviewCard)、评论评价
|
||||
- 数据源: `/api/skills/[slug]`, `/api/skills/[slug]/review`
|
||||
|
||||
### /login (用户登录)
|
||||
- 文件: `src/app/login/page.tsx`
|
||||
- 功能: 用户邮箱+密码登录/注册,GitHub OAuth登录
|
||||
- 数据源: NextAuth Credentials Provider
|
||||
|
||||
### /user (用户中心)
|
||||
- 文件: `src/app/user/page.tsx`
|
||||
- 功能: 用户资料编辑、快捷入口、浏览历史
|
||||
- 数据源: NextAuth session, `/api/user/history`
|
||||
|
||||
### /user/favorites (我的收藏)
|
||||
- 文件: `src/app/user/favorites/page.tsx`
|
||||
- 功能: 收藏的工具和技能列表,支持筛选和搜索
|
||||
- 数据源: `/api/user/favorites`
|
||||
|
||||
---
|
||||
|
||||
## 后台页面
|
||||
|
||||
### /admin/login (登录)
|
||||
- 文件: `src/app/(admin)/admin/login/page.tsx`
|
||||
- 功能: 管理员登录表单,CSRF token + 原生POST
|
||||
- 凭证: admin@zhuiguang.ai / admin123
|
||||
|
||||
### /admin/pending (待审核工具)
|
||||
- 文件: `src/app/(admin)/admin/pending/page.tsx`
|
||||
- 功能: 审核列表表格、多选复选框、全选、批量通过/拒绝、抓取缺失Logo/重新抓取全部Logo、编辑弹窗、单个通过/拒绝
|
||||
- 数据源: `/api/admin/pending`, `/api/admin/pending/batch-publish`, `/api/admin/pending/batch-reject`, `/api/admin/pending/fetch-logos`
|
||||
|
||||
### /admin/pending-skills (待审核技能)
|
||||
- 文件: `src/app/(admin)/admin/pending-skills/page.tsx`
|
||||
- 功能: 审核列表表格、多选复选框、全选、批量通过/拒绝、一键全部通过、编辑弹窗、Star数展示、GitHub链接
|
||||
- 数据源: `/api/admin/pending-skills`, `/api/admin/pending-skills/batch-publish`, `/api/admin/pending-skills/batch-reject`, `/api/admin/pending-skills/publish-all`
|
||||
|
||||
### /admin/tools (已发布工具)
|
||||
- 文件: `src/app/(admin)/admin/tools/page.tsx`
|
||||
- 功能: 工具管理表格、新增/编辑/删除、分页
|
||||
- 数据源: `/api/admin/tools`, `/api/admin/categories`
|
||||
|
||||
### /admin/skills (已发布技能)
|
||||
- 文件: `src/app/(admin)/admin/skills/page.tsx`
|
||||
- 功能: 技能管理表格、编辑/删除、分页
|
||||
- 数据源: `/api/admin/skills`, `/api/admin/skill-categories`
|
||||
|
||||
### /admin/categories (工具分类管理)
|
||||
- 文件: `src/app/(admin)/admin/categories/page.tsx`
|
||||
- 功能: 分类CRUD、树形展示、排序
|
||||
- 数据源: `/api/admin/categories`
|
||||
|
||||
### /admin/skill-categories (技能分类管理)
|
||||
- 文件: `src/app/(admin)/admin/skill-categories/page.tsx`
|
||||
- 功能: 技能分类CRUD
|
||||
- 数据源: `/api/admin/skill-categories`
|
||||
|
||||
### /admin/discover-tools (探索AI工具)
|
||||
- 文件: `src/app/(admin)/admin/discover-tools/page.tsx`
|
||||
- 功能: 选分类→复制提示词→粘贴JSON→导入审核列表→抓取Logo
|
||||
- 流程: 4步流程(选分类/复制提示词/粘贴导入/抓取Logo),提示词含排除列表,JSON粘贴区+导入按钮,Logo批量抓取
|
||||
- 数据源: `/api/admin/discover-tools`, `/api/admin/pending/fetch-logos`
|
||||
|
||||
### /admin/check-tools (检测AI工具)
|
||||
- 文件: `src/app/(admin)/admin/check-tools/page.tsx`
|
||||
- 功能: 4步流程(选范围/检测+抓取/Logo方法统计/处理失效),检测可访问性同时自动抓取缺失Logo,记录成功方法名统计
|
||||
- 数据源: `/api/admin/check-tools`, `/api/admin/tools/[id]`, `/api/admin/pending/[id]`
|
||||
|
||||
### /admin/discover-skills (探索AI技能)
|
||||
- 文件: `src/app/(admin)/admin/discover-skills/page.tsx`
|
||||
- 功能: 选分类→复制提示词→粘贴JSON→导入审核列表
|
||||
- 流程: 3步流程(选分类/复制提示词/粘贴导入),提示词含排除列表,JSON粘贴区+导入按钮
|
||||
- 数据源: `/api/admin/discover-skills`
|
||||
|
||||
### /admin/update-skills (更新Skill技能)
|
||||
- 文件: `src/app/(admin)/admin/update-skills/page.tsx`
|
||||
- 功能: 3步流程(选范围/一键更新/自动同步),更新GitHub/Gitee/GitCode星级,展示Star变化表格
|
||||
- 数据源: `/api/admin/update-stars`
|
||||
|
||||
### /admin/discover-news (AI新闻发现)
|
||||
- 文件: `src/app/(admin)/admin/discover-news/page.tsx`
|
||||
- 功能: 3步流程(复制提示词/粘贴导入/查看日报),新闻6大分类+热度评分,展示今日AI日报
|
||||
- 数据源: `/api/admin/discover-news`
|
||||
|
||||
### /admin/system-config (系统配置)
|
||||
- 文件: `src/app/(admin)/admin/system-config/page.tsx`
|
||||
- 功能: Logo抓取配置、发现提示词配置等全局设置
|
||||
- 数据源: `/api/admin/system-config`
|
||||
|
||||
---
|
||||
|
||||
## 布局
|
||||
|
||||
### 前台布局
|
||||
- 文件: `src/app/layout.tsx`
|
||||
- 结构: Geist字体 → AuthProvider → Header + main + Footer
|
||||
|
||||
### 后台布局
|
||||
- 文件: `src/app/(admin)/admin/layout.tsx`
|
||||
- 结构: 左侧边栏(4组菜单) + 右侧内容区
|
||||
- 菜单分组:
|
||||
- 工具管理: 待审核工具、已发布工具、工具分类
|
||||
- 技能库: 待审核技能、已发布技能、技能分类
|
||||
- AI发现: 探索AI工具、检测AI工具、探索Skill技能、更新Skill技能、AI新闻发现
|
||||
- 系统配置: 系统配置
|
||||
- 登录页不显示侧边栏
|
||||
@@ -0,0 +1,117 @@
|
||||
# 组件与样式模块
|
||||
|
||||
## 组件
|
||||
|
||||
### 布局组件
|
||||
|
||||
#### Header (`src/components/layout/Header.tsx`)
|
||||
- 前台顶部导航栏
|
||||
- Logo + 导航链接(工具库/技能库/分类浏览) + 搜索框 + 登录/用户按钮
|
||||
- 移动端汉堡菜单
|
||||
- 滚动时背景模糊效果(bg-white/80 backdrop-blur-2xl)
|
||||
- 搜索框: bg-muted/50 focus:bg-white focus:ring-2 focus:ring-primary/10
|
||||
|
||||
#### Footer (`src/components/layout/Footer.tsx`)
|
||||
- 前台底部页脚
|
||||
- Logo + 简介 + 发现/分类/关于链接 + 社交图标(GitHub/Twitter)
|
||||
|
||||
### Provider组件
|
||||
|
||||
#### AuthProvider (`src/components/providers/auth-provider.tsx`)
|
||||
- NextAuth SessionProvider 包裹组件
|
||||
- 用于在客户端组件中访问session
|
||||
|
||||
### 公共组件
|
||||
|
||||
#### LoginModal (`src/components/common/LoginModal.tsx`)
|
||||
- 登录/注册弹窗,支持模式切换
|
||||
- 邮箱+密码认证,注册可选填昵称
|
||||
- bg-white/95 backdrop-blur-xl
|
||||
|
||||
#### SkillReviewCard (五维评测雷达图)
|
||||
- 文件: `src/components/common/SkillReviewCard.tsx`
|
||||
- 用途: 技能详情页展示五维评测雷达图和维度详情卡片
|
||||
- 依赖: chart.js, react-chartjs-2 (dynamic import, ssr: false)
|
||||
- Props: `{ slug: string }`
|
||||
- 数据源: `/api/skills/${slug}/review`
|
||||
- 五维度: 场景与能力(capability) / 开发体验(devExp) / 成本与许可(costLicense) / 社区健康(community) / 性能稳定(performance)
|
||||
- 评分色标: ≥4绿色(emerald) / ≥3黄色(amber) / <3红色(red)
|
||||
- 设计规范: 遵循浅色主题设计系统,紫色(violet)主色调雷达图
|
||||
|
||||
### ReviewSection (`src/components/common/ReviewSection.tsx`)
|
||||
- 用户评论/评价组件,支持评分和文字评论
|
||||
- 支持tool和skill两种类型
|
||||
- bg-white/80卡片,bg-white/60评论项
|
||||
|
||||
#### FavoriteButton (`src/components/common/FavoriteButton.tsx`)
|
||||
- 收藏按钮,乐观更新
|
||||
- text-gray-500 hover:text-red-500
|
||||
|
||||
#### CategorySidebar (`src/components/common/CategorySidebar.tsx`)
|
||||
- 分类侧边栏,支持搜索和分类选择
|
||||
- bg-muted/50搜索框
|
||||
|
||||
### UI组件 (shadcn/ui)
|
||||
|
||||
#### Button (`src/components/ui/button.tsx`)
|
||||
- 6种变体: default, outline, secondary, ghost, destructive, link
|
||||
- 4种尺寸: default, sm, lg, icon
|
||||
|
||||
#### Card (`src/components/ui/card.tsx`)
|
||||
- Card/CardHeader/CardTitle/CardDescription/CardContent/CardFooter
|
||||
|
||||
#### Dialog (`src/components/ui/dialog.tsx`)
|
||||
- 基于 @radix-ui/react-dialog
|
||||
- Dialog/DialogTrigger/DialogContent/DialogHeader/DialogTitle/DialogDescription/DialogFooter/DialogClose
|
||||
- 遮罩层: bg-black/80
|
||||
|
||||
---
|
||||
|
||||
## 样式系统
|
||||
|
||||
### 全局样式 (`src/app/globals.css`)
|
||||
- 浅色主题CSS变量(HSL色系)
|
||||
- shadcn/ui 主题变量
|
||||
- 自定义工具类:
|
||||
- `.glow-sm` / `.glow-md` / `.glow-lg` - 发光效果
|
||||
- `.gradient-text` - 渐变文字(蓝→紫→粉)
|
||||
- `.gradient-border` - 渐变边框
|
||||
- `.glass` / `.glass-sm` - 毛玻璃效果(bg-white/80 + backdrop-blur)
|
||||
- `.card-shine` - 卡片光泽动画
|
||||
- `.dot-grid` - 点阵网格背景
|
||||
- `.animate-fade-in` - 淡入动画
|
||||
- `.animate-slide-up` - 上滑动画
|
||||
- `.animate-float` - 浮动动画
|
||||
- `.animate-pulse-glow` - 脉冲发光
|
||||
|
||||
### Tailwind配置 (`tailwind.config.ts`)
|
||||
- 浅色模式: class策略
|
||||
- 主题色系: HSL CSS变量(background: 210 20% 98%, foreground: 222 47% 11%, primary: 221 83% 53%等)
|
||||
- 动画: fade-in, slide-up, float, glow-pulse
|
||||
- 自定义字体: Geist Sans, Geist Mono
|
||||
|
||||
### 设计规范
|
||||
- 圆角: 统一使用 rounded-xl (12px) 或 rounded-2xl (16px)
|
||||
- 边框: border-border/40 (40%透明度)
|
||||
- 背景: bg-white/80 (毛玻璃) / bg-white/60 (卡片) / bg-muted/50 (输入框)
|
||||
- 阴影: shadow-sm (卡片) / shadow-md (悬浮)
|
||||
- 间距: 统一使用 Tailwind 间距系统
|
||||
- 动画: transition-all duration-200
|
||||
|
||||
### 颜色规范(浅色主题)
|
||||
- 文字颜色: 使用 -600/-700 系列(如 text-blue-700, text-emerald-600)
|
||||
- 背景颜色: 使用 -50 系列(如 bg-blue-50, bg-emerald-50)
|
||||
- 边框颜色: 使用 -200/60 系列(如 border-blue-200/60, border-emerald-200/60)
|
||||
- 严禁使用暗色主题的 -400 文字、-500/10 背景、-500/20 边框
|
||||
- 输入框: bg-muted/50 focus:bg-white focus:ring-2 focus:ring-primary/10
|
||||
|
||||
### 定价模型颜色
|
||||
- free: bg-emerald-50 text-emerald-700 border-emerald-200/60
|
||||
- freemium: bg-blue-50 text-blue-700 border-blue-200/60
|
||||
- paid: bg-amber-50 text-amber-700 border-amber-200/60
|
||||
- subscription: bg-purple-50 text-purple-700 border-purple-200/60
|
||||
|
||||
### 来源类型颜色
|
||||
- github: bg-slate-50 text-slate-700
|
||||
- gitlab: bg-orange-50 text-orange-700
|
||||
- huggingface: bg-yellow-50 text-yellow-700
|
||||
@@ -0,0 +1,132 @@
|
||||
# AI发现模块
|
||||
|
||||
## 概述
|
||||
AI发现模块是追光AI的核心功能,采用"提示词+JSON粘贴导入"模式,用户复制页面内嵌的提示词发给AI助手,获取JSON后粘贴到页面导入,不调用任何外部AI API。
|
||||
|
||||
## 架构
|
||||
```
|
||||
页面内嵌提示词模板(含排除列表) → 用户复制发给AI助手 → AI返回JSON → 粘贴到页面 → API去重导入 → PendingTool/PendingSkill → 管理员审核 → Tool/Skill
|
||||
```
|
||||
|
||||
## 五大操作指令
|
||||
|
||||
### 探索AI工具 (`/admin/discover-tools`)
|
||||
1. 选择分类(20个工具分类)
|
||||
2. 复制提示词(自动注入排除列表)
|
||||
3. 粘贴AI返回的JSON到输入框
|
||||
4. 点击导入按钮,API自动去重导入待审核列表
|
||||
5. 可选:批量抓取Logo
|
||||
|
||||
### 检测AI工具 (`/admin/check-tools`)
|
||||
1. 选择范围(已发布/待审核)
|
||||
2. 一键检测+抓取Logo
|
||||
3. 系统自动逐一GET请求检测网站可访问性
|
||||
4. 同时自动抓取缺失Logo,记录成功方法名
|
||||
5. 展示Logo抓取方法统计(按成功次数排序)
|
||||
6. 失效工具可一键删除
|
||||
|
||||
### 探索AI技能 (`/admin/discover-skills`)
|
||||
1. 选择分类(20个技能分类)
|
||||
2. 复制提示词(自动注入排除列表)
|
||||
3. 粘贴AI返回的JSON到输入框
|
||||
4. 点击导入按钮,API自动去重导入待审核列表
|
||||
|
||||
### 更新Skill技能 (`/admin/update-skills`)
|
||||
1. 选择范围(已发布/待审核)
|
||||
2. 一键更新Star
|
||||
3. 系统自动从GitHub/Gitee/GitCode API获取最新星级
|
||||
4. 展示Star变化表格(上升/下降/不变)
|
||||
|
||||
### AI新闻发现 (`/admin/discover-news`)
|
||||
1. 复制新闻发现提示词
|
||||
2. 粘贴AI返回的JSON到输入框
|
||||
3. 点击导入按钮,自动生成今日AI日报
|
||||
4. 新闻6大分类:产品发布/融资投资/技术突破/政策法规/开源项目/行业事件
|
||||
5. 每条新闻含热度评分(1-100)
|
||||
|
||||
## Logo抓取引擎 (`src/lib/logo-fetcher.ts`)
|
||||
|
||||
### 核心API
|
||||
- `fetchLogo(websiteUrl, html?): Promise<string>` — 返回Logo URL
|
||||
- `fetchLogoWithMethod(websiteUrl, html?): Promise<{url, method}>` — 返回Logo URL + 成功方法名
|
||||
|
||||
### 抓取策略(按优先级,共10种)
|
||||
1. **HTML Link图标**: 解析 `<link rel="icon/apple-touch-icon">` 标签
|
||||
2. **OG/Twitter图片**: 解析 `<meta property="og:image">` 标签
|
||||
3. **HTML Manifest**: 解析 `manifest.json` 中的icons数组
|
||||
4. **HTML img标签**: 查找class/alt含"logo"的img标签
|
||||
5. **Header区域Logo**: 解析header/nav区域内的img标签
|
||||
6. **SVG Logo**: 查找内联SVG logo
|
||||
7. **常见路径**: 尝试 /apple-touch-icon.png, /logo.png, /favicon.ico 等
|
||||
8. **Favicon服务**:
|
||||
- favicon.im
|
||||
- Google Favicons (sz=128/64)
|
||||
- Clearbit
|
||||
- DuckDuckGo
|
||||
- Favicon Grabr (API解析)
|
||||
- Icon Horse (API解析)
|
||||
9. **Brandfetch品牌库**: 通过Brandfetch API获取品牌Logo
|
||||
10. **截图兜底**: 通过截图服务获取网站截图
|
||||
|
||||
### 配置项
|
||||
- `enabledMethods`: 启用的抓取方法
|
||||
- `commonPaths`: 常见图标路径列表
|
||||
- `faviconServices`: Favicon服务列表
|
||||
- `minFileSize`: 最小文件大小(默认50字节)
|
||||
- `requestTimeout`: 请求超时(默认10秒)
|
||||
|
||||
### Logo本地存储 (`src/lib/logo-storage.ts`)
|
||||
- `downloadLogo(url, filename): Promise<string>` — 下载Logo到 `/public/logos/` 目录
|
||||
- 返回本地路径如 `/logos/filename.png`
|
||||
|
||||
## 脚本
|
||||
|
||||
### discover-skills.mjs
|
||||
- 独立运行的AI技能发现脚本
|
||||
- 遍历20个技能分类,每类调用DeepSeek API推荐10个GitHub开源项目
|
||||
- 通过 `/api/admin/pending-skills/batch` 批量导入
|
||||
- 每分类间隔3秒避免限流
|
||||
- 自动排除已收录技能
|
||||
|
||||
### import-tools-batch1.mjs / import-tools-batch2.mjs
|
||||
- 硬编码的AI工具数据导入脚本
|
||||
- 通过 `/api/admin/pending/batch` 批量导入
|
||||
|
||||
## 自动化评测流程
|
||||
|
||||
### 架构概览
|
||||
```
|
||||
GitHub API (octokit) → 搜索热门仓库 → 获取README
|
||||
↓
|
||||
DeepSeek API (openai兼容) → 五维评测生成 → JSON解析+校验
|
||||
↓
|
||||
Prisma → Skill记录 + SkillReview记录 + ReviewGenerationLog日志
|
||||
↓
|
||||
前端 → /api/skills/[slug]/review → SkillReviewCard雷达图展示
|
||||
```
|
||||
|
||||
### 评测脚本 (scripts/auto-review.mjs)
|
||||
- 搜索关键词: ai agent, llm framework, rag, prompt engineering
|
||||
- 每日限制: 8个项目 (DAILY_LIMIT可配置)
|
||||
- 最低Star数: 500
|
||||
- 去重: 通过sourceUrl检查是否已存在
|
||||
- 综合分校验: 自动计算五维均分,偏差>0.3时修正
|
||||
- 评测状态: 初始为DRAFT,需手动或通过脚本改为PUBLISHED
|
||||
|
||||
### 五维评测维度
|
||||
| 维度 | 字段 | 说明 |
|
||||
|------|------|------|
|
||||
| 场景与能力 | capability | 场景覆盖度和核心能力 |
|
||||
| 开发体验 | devExp | 安装、文档、API易用性 |
|
||||
| 成本与许可 | costLicense | 硬件成本、API定价、许可证风险 |
|
||||
| 社区健康 | community | Issue响应、PR频率、生态 |
|
||||
| 性能稳定 | performance | 运行效率、稳定性、输出质量 |
|
||||
|
||||
### 评测标签分类
|
||||
LLM框架, Agent框架, RAG, 提示工程, 多模态, 代码助手, 模型训练, 数据工程, 部署工具, 评测工具, 安全对齐, 其他
|
||||
|
||||
### 发布评测脚本 (scripts/publish-reviews.mjs)
|
||||
- 将DRAFT状态评测改为PUBLISHED
|
||||
- 同时将对应Skill状态从draft改为published
|
||||
|
||||
## 踩坑记录
|
||||
@@ -0,0 +1,58 @@
|
||||
# 认证模块
|
||||
|
||||
## 技术栈
|
||||
- NextAuth.js v4
|
||||
- Credentials Provider(用户名密码 + 用户邮箱密码)
|
||||
- JWT Session策略
|
||||
|
||||
## 配置 (`src/lib/auth.ts`)
|
||||
|
||||
### 管理员认证
|
||||
- 唯一凭证: `admin@zhuiguang.ai` / `admin123`
|
||||
- 硬编码在auth.ts中,非数据库查询
|
||||
|
||||
### 用户认证
|
||||
- 邮箱+密码注册/登录
|
||||
- 用户数据存储在User表
|
||||
- 密码bcrypt加密
|
||||
|
||||
### Session策略
|
||||
- 使用JWT,不使用数据库session
|
||||
- JWT密钥: `NEXTAUTH_SECRET` 环境变量
|
||||
|
||||
### 回调函数
|
||||
- `jwt`: 登录时将用户信息加入token
|
||||
- `session`: 将token中的用户信息传递给session
|
||||
|
||||
## 路由保护 (`src/middleware.ts`)
|
||||
|
||||
### 保护规则
|
||||
- 保护 `/admin` 下所有路由
|
||||
- 跳过 `/admin/login`
|
||||
- 使用NextAuth middleware进行认证检查
|
||||
|
||||
### 登录流程
|
||||
1. 访问 `/admin/*` → middleware检查session
|
||||
2. 未登录 → 重定向到 `/admin/login`
|
||||
3. 登录页提交表单 → Server Action验证凭证
|
||||
4. 验证成功 → 重定向到 `/admin`
|
||||
|
||||
## 管理员API认证 (`src/lib/admin-auth.ts`)
|
||||
|
||||
### requireAdmin中间件
|
||||
- 所有 `/api/admin/` 路由必须使用requireAdmin中间件
|
||||
- 验证流程: 检查session → 验证邮箱是否为admin@zhuiguang.ai
|
||||
- 已覆盖28个后台API端点
|
||||
|
||||
## 登录页
|
||||
- 管理员登录: `src/app/(admin)/admin/login/page.tsx` (原生HTML表单 + CSRF Token)
|
||||
- 用户登录: `src/app/login/page.tsx` (NextAuth Credentials + GitHub OAuth)
|
||||
- 用户登录弹窗: `src/components/common/LoginModal.tsx`
|
||||
|
||||
## 环境变量
|
||||
```
|
||||
NEXTAUTH_URL=http://localhost:3100
|
||||
NEXTAUTH_SECRET=<secret>
|
||||
GITHUB_ID=<github-oauth-id>
|
||||
GITHUB_SECRET=<github-oauth-secret>
|
||||
```
|
||||
@@ -0,0 +1,110 @@
|
||||
# 工具库与脚本模块
|
||||
|
||||
## 工具库 (`src/lib/`)
|
||||
|
||||
### src/lib/github.ts (GitHub数据采集)
|
||||
- 依赖: octokit
|
||||
- 认证: process.env.GITHUB_TOKEN (可选,提升限流60→5000次/小时)
|
||||
- `searchHotRepos(query, minStars, maxResults)`: 搜索热门仓库,按Star降序
|
||||
- `getRepoReadme(owner, repo)`: 获取仓库README内容(base64解码)
|
||||
- `GitHubRepo` 接口: id, full_name, html_url, description, stargazers_count, forks_count, language, license, topics, updated_at, readme
|
||||
|
||||
### src/lib/deepseek.ts (DeepSeek评测生成)
|
||||
- 依赖: openai (兼容OpenAI接口)
|
||||
- 认证: process.env.DEEPSEEK_API_KEY
|
||||
- baseURL: https://api.deepseek.com/v1
|
||||
- 模型: deepseek-v4-pro
|
||||
- `generateReview(repoName, description, stars, license, readme)`: 调用DeepSeek生成五维评测
|
||||
- `ReviewDimension` 接口: { score, summary, detail }
|
||||
- `ReviewResult` 接口: capability, devExp, costLicense, community, performance, overall, tags
|
||||
- 综合分校验: 自动计算五维均分,偏差>0.3时修正
|
||||
- JSON提取: 兼容markdown代码块包裹的响应
|
||||
|
||||
### prisma.ts - 数据库客户端
|
||||
- Prisma单例模式,防止开发环境热重载创建多实例
|
||||
- 使用PrismaMariaDb adapter
|
||||
- 连接池配置
|
||||
|
||||
### auth.ts - 认证配置
|
||||
- NextAuth配置导出
|
||||
- Credentials Provider(管理员+用户)
|
||||
- JWT策略
|
||||
- GitHub OAuth Provider
|
||||
- 导出GET/POST handler
|
||||
|
||||
### admin-auth.ts - 管理员API认证
|
||||
- 导出 `requireAdmin()` 中间件函数
|
||||
- 验证session中邮箱是否为admin@zhuiguang.ai
|
||||
- 所有 `/api/admin/` 路由必须使用此中间件
|
||||
- 返回401/403错误响应
|
||||
|
||||
### utils.ts - 工具函数
|
||||
- `cn()`: 合并clsx + tailwind-merge的className工具
|
||||
|
||||
### logo-fetcher.ts - Logo抓取引擎
|
||||
- 导出 `fetchLogo(websiteUrl, html?): Promise<string>` — 返回Logo URL
|
||||
- 导出 `fetchLogoWithMethod(websiteUrl, html?): Promise<LogoFetchResult>` — 返回 `{url, method}`
|
||||
- 10种抓取策略按优先级执行
|
||||
- 支持从SystemConfig读取配置
|
||||
- 每种成功方法返回中文名称(如"HTML Link图标"、"OG/Twitter图片"等)
|
||||
- 详见 [05-ai-discovery.md](./05-ai-discovery.md)
|
||||
|
||||
### logo-storage.ts - Logo本地存储
|
||||
- 导出 `downloadLogo(url, filename): Promise<string>`
|
||||
- 下载远程Logo到 `/public/logos/` 目录
|
||||
- 返回本地路径如 `/logos/filename.png`
|
||||
|
||||
---
|
||||
|
||||
## 脚本 (`scripts/`)
|
||||
|
||||
### discover-skills.mjs - AI技能发现
|
||||
- 独立运行的Node.js脚本
|
||||
- 遍历20个技能分类,每类调用DeepSeek API推荐10个GitHub开源项目
|
||||
- 通过 `/api/admin/pending-skills/batch` 批量导入
|
||||
- 自动排除已收录技能
|
||||
- 每分类间隔3秒
|
||||
- 运行: `node scripts/discover-skills.mjs`
|
||||
|
||||
### import-tools-batch1.mjs - 第一批工具导入
|
||||
- 硬编码约80个国产AI工具
|
||||
- 分类: 文本生成(165)/图像生成(174)/视频生成(183)/音频与语音(191)
|
||||
|
||||
### import-tools-batch2.mjs - 第二批工具导入
|
||||
- 硬编码约200个国产AI工具
|
||||
- 分类: 代码开发/AI Agent/办公效率/设计创意/营销SEO/数据分析/教育学习/搜索信息/安全合规/医疗健康/金融法律/电商零售/3D游戏/科学研究/模型框架/聊天机器人
|
||||
|
||||
---
|
||||
|
||||
## 运维脚本
|
||||
|
||||
### scripts/auto-review.mjs (自动化评测脚本)
|
||||
- 依赖: @prisma/client, @prisma/adapter-mariadb, octokit, openai
|
||||
- 流程: GitHub搜索→README获取→DeepSeek评测→Skill入库→SkillReview入库→日志记录
|
||||
- 配置: SEARCH_QUERIES(4个关键词), MIN_STARS(500), MAX_PER_QUERY(5), DAILY_LIMIT(8)
|
||||
- 去重: 通过sourceUrl检查
|
||||
- slug生成: repo full_name转小写+连字符
|
||||
- 默认分类ID: 120 (AI/ML工程)
|
||||
- 运行: `$env:NODE_TLS_REJECT_UNAUTHORIZED="0"; node scripts/auto-review.mjs`
|
||||
|
||||
### scripts/publish-reviews.mjs (发布评测脚本)
|
||||
- 将DRAFT状态SkillReview改为PUBLISHED
|
||||
- 将对应draft状态Skill改为published
|
||||
|
||||
### scripts/test-github.mjs (GitHub API测试)
|
||||
- 测试searchHotRepos和getRepoReadme功能
|
||||
- 运行: `$env:NODE_TLS_REJECT_UNAUTHORIZED="0"; node -r dotenv/config scripts/test-github.mjs`
|
||||
|
||||
### scripts/test-deepseek.mjs (DeepSeek API测试)
|
||||
- 测试generateReview功能,使用langflow作为测试用例
|
||||
- 运行: `$env:NODE_TLS_REJECT_UNAUTHORIZED="0"; node scripts/test-deepseek.mjs`
|
||||
|
||||
### restart.ps1 - 服务重启
|
||||
- PowerShell脚本
|
||||
- 扫描8301-8310端口
|
||||
- 杀死占用进程
|
||||
- 执行 `npm run dev` 启动服务(端口8301)
|
||||
- 运行: `pwsh -ExecutionPolicy Bypass -File restart.ps1`
|
||||
|
||||
### temp_clear.mjs - 临时清理
|
||||
- 清空pending_tools表
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"代码生成"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"测试"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"代码质量与分析"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"安全"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"文档"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"架构与设计"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"需求工程"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"DevOps 与部署"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"调试与错误处理"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"形式化验证"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"维护与重构"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"版本控制与协作"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"开发工具"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"UI/UX 设计"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"科学研究"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"金融"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"云服务"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"移动开发"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"AI/ML 工程"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,20 @@
|
||||
你是AI编程技能专家。请为"营销与增长"领域推荐 12 个真实存在且活跃的AI编程技能(Prompt/Agent/Workflow/开源项目)。
|
||||
|
||||
严格要求:
|
||||
1. 优先推荐 Gitee(gitee.com)和 GitCode(gitcode.com)上的国内开源项目,也接受少量优秀的国际开源项目
|
||||
2. 推荐的技能必须是真实可用的AI编程技能,可以是开源项目、Prompt模板、AI Agent配置或自动化工作流
|
||||
3. sourceUrl必须是真实可访问的链接(Gitee仓库、GitCode仓库、GitHub仓库等)
|
||||
4. 每个技能的name、sourceUrl必须唯一,不能与已有技能重复
|
||||
5. 技能应该有实用价值,能直接用于编程开发场景
|
||||
6. rating为该技能在来源平台上的用户评分(1.0-5.0分),如无评分则根据star数和活跃度估算
|
||||
|
||||
每个技能包含以下字段:
|
||||
- name: 技能名称(简洁明了,如"React组件生成器"、"SQL注入检测Agent")
|
||||
- description: 一句话中文简介(50字以内,突出核心能力和使用场景)
|
||||
- sourceUrl: 来源链接(Gitee仓库URL、GitCode仓库URL或GitHub仓库URL,必须以http://或https://开头)
|
||||
- sourceType: 来源类型,只能是以下之一:"gitee"、"gitcode"、"github"、"other"
|
||||
- rating: 用户评分(1.0-5.0之间的浮点数,如4.5、3.8)
|
||||
- features: 功能特性数组(3-5个关键特性,每个特性10字以内)
|
||||
- tags: 标签数组(3-5个标签,从限定标签池中选取:代码生成、代码审查、自动化测试、安全检测、文档生成、DevOps、重构、调试、AI Agent、Prompt工程、RAG、MCP、前端开发、后端开发、移动开发、云原生、开源项目、中文优化、开箱即用、企业级)
|
||||
|
||||
返回纯JSON数组,不要包含任何其他文字、markdown标记或代码块标记。
|
||||
@@ -0,0 +1,162 @@
|
||||
[
|
||||
{
|
||||
"index": 1,
|
||||
"categoryId": 1,
|
||||
"categoryName": "代码生成",
|
||||
"filename": "01_代码生成.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"categoryId": 10,
|
||||
"categoryName": "测试",
|
||||
"filename": "02_测试.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"categoryId": 20,
|
||||
"categoryName": "代码质量与分析",
|
||||
"filename": "03_代码质量与分析.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"categoryId": 29,
|
||||
"categoryName": "安全",
|
||||
"filename": "04_安全.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"categoryId": 36,
|
||||
"categoryName": "文档",
|
||||
"filename": "05_文档.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"categoryId": 43,
|
||||
"categoryName": "架构与设计",
|
||||
"filename": "06_架构与设计.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 7,
|
||||
"categoryId": 49,
|
||||
"categoryName": "需求工程",
|
||||
"filename": "07_需求工程.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 8,
|
||||
"categoryId": 56,
|
||||
"categoryName": "DevOps 与部署",
|
||||
"filename": "08_DevOps 与部署.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 9,
|
||||
"categoryId": 62,
|
||||
"categoryName": "调试与错误处理",
|
||||
"filename": "09_调试与错误处理.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 10,
|
||||
"categoryId": 69,
|
||||
"categoryName": "形式化验证",
|
||||
"filename": "10_形式化验证.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 11,
|
||||
"categoryId": 76,
|
||||
"categoryName": "维护与重构",
|
||||
"filename": "11_维护与重构.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 12,
|
||||
"categoryId": 82,
|
||||
"categoryName": "版本控制与协作",
|
||||
"filename": "12_版本控制与协作.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 13,
|
||||
"categoryId": 86,
|
||||
"categoryName": "开发工具",
|
||||
"filename": "13_开发工具.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 14,
|
||||
"categoryId": 91,
|
||||
"categoryName": "UI/UX 设计",
|
||||
"filename": "14_UI-UX 设计.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 15,
|
||||
"categoryId": 95,
|
||||
"categoryName": "科学研究",
|
||||
"filename": "15_科学研究.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 16,
|
||||
"categoryId": 103,
|
||||
"categoryName": "金融",
|
||||
"filename": "16_金融.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 17,
|
||||
"categoryId": 109,
|
||||
"categoryName": "云服务",
|
||||
"filename": "17_云服务.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 18,
|
||||
"categoryId": 115,
|
||||
"categoryName": "移动开发",
|
||||
"filename": "18_移动开发.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 19,
|
||||
"categoryId": 120,
|
||||
"categoryName": "AI/ML 工程",
|
||||
"filename": "19_AI-ML 工程.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
},
|
||||
{
|
||||
"index": 20,
|
||||
"categoryId": 127,
|
||||
"categoryName": "营销与增长",
|
||||
"filename": "20_营销与增长.txt",
|
||||
"currentCount": 0,
|
||||
"needCount": 10
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"style": "base-nova",
|
||||
"rsc": true,
|
||||
"tsx": true,
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.ts",
|
||||
"css": "src/app/globals.css",
|
||||
"baseColor": "neutral",
|
||||
"cssVariables": true,
|
||||
"prefix": ""
|
||||
},
|
||||
"iconLibrary": "lucide",
|
||||
"rtl": false,
|
||||
"aliases": {
|
||||
"components": "@/components",
|
||||
"utils": "@/lib/utils",
|
||||
"ui": "@/components/ui",
|
||||
"lib": "@/lib",
|
||||
"hooks": "@/hooks"
|
||||
},
|
||||
"menuColor": "default",
|
||||
"menuAccent": "subtle",
|
||||
"registries": {}
|
||||
}
|
||||
@@ -1,4 +1,78 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {};
|
||||
const nextConfig = {
|
||||
images: {
|
||||
remotePatterns: [
|
||||
{
|
||||
protocol: "https",
|
||||
hostname: "**",
|
||||
},
|
||||
],
|
||||
minimumCacheTTL: 3600,
|
||||
formats: ["image/avif", "image/webp"],
|
||||
},
|
||||
compress: true,
|
||||
poweredByHeader: false,
|
||||
reactStrictMode: true,
|
||||
webpack: (config, { isServer }) => {
|
||||
config.watchOptions = {
|
||||
...config.watchOptions,
|
||||
ignored: [
|
||||
"**/node_modules/**",
|
||||
"**/.git/**",
|
||||
"**/System Volume Information/**",
|
||||
"**/DumpStack.log.tmp",
|
||||
"**/pagefile.sys",
|
||||
],
|
||||
poll: false,
|
||||
};
|
||||
return config;
|
||||
},
|
||||
onDemandEntries: {
|
||||
maxInactiveAge: 60 * 1000,
|
||||
pagesBufferLength: 5,
|
||||
},
|
||||
experimental: {
|
||||
optimizeCss: false,
|
||||
},
|
||||
headers: async () => {
|
||||
const isDev = process.env.NODE_ENV === "development";
|
||||
|
||||
const headers = [
|
||||
{
|
||||
source: "/api/:path*",
|
||||
headers: [
|
||||
{ key: "X-Content-Type-Options", value: "nosniff" },
|
||||
{ key: "X-Frame-Options", value: "DENY" },
|
||||
{ key: "X-XSS-Protection", value: "1; mode=block" },
|
||||
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
|
||||
],
|
||||
},
|
||||
{
|
||||
source: "/logos/:path*",
|
||||
headers: [
|
||||
{ key: "Cache-Control", value: isDev ? "no-cache" : "public, max-age=86400, immutable" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
if (isDev) {
|
||||
headers.push({
|
||||
source: "/(.*)",
|
||||
headers: [
|
||||
{ key: "Cache-Control", value: "no-store, no-cache, must-revalidate, proxy-revalidate" },
|
||||
],
|
||||
});
|
||||
} else {
|
||||
headers.push({
|
||||
source: "/_next/static/:path*",
|
||||
headers: [
|
||||
{ key: "Cache-Control", value: "public, max-age=31536000, immutable" },
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return headers;
|
||||
},
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
|
||||
@@ -3,22 +3,47 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"dev": "next dev --turbo --port 8301",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"start": "next start --port 8301",
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@base-ui/react": "^1.4.1",
|
||||
"@prisma/adapter-mariadb": "^7.8.0",
|
||||
"@prisma/client": "^7.8.0",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
"@types/bcryptjs": "^2.4.6",
|
||||
"axios": "^1.15.2",
|
||||
"bcryptjs": "^3.0.3",
|
||||
"chart.js": "^4.5.1",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"lucide-react": "^1.11.0",
|
||||
"next": "14.2.35",
|
||||
"next-auth": "^4.24.14",
|
||||
"octokit": "^5.0.5",
|
||||
"openai": "^6.38.0",
|
||||
"prisma": "^7.8.0",
|
||||
"react": "^18",
|
||||
"react-chartjs-2": "^5.3.1",
|
||||
"react-dom": "^18",
|
||||
"next": "14.2.35"
|
||||
"shadcn": "^4.5.0",
|
||||
"tailwind-merge": "^3.5.0",
|
||||
"tw-animate-css": "^1.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"dotenv": "^17.4.2",
|
||||
"mysql2": "^3.22.3",
|
||||
"postcss": "^8",
|
||||
"tailwindcss": "^3.4.1"
|
||||
"tailwindcss": "^3.4.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5"
|
||||
},
|
||||
"prisma": {
|
||||
"seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// This file was generated by Prisma, and assumes you have installed the following:
|
||||
// npm install --save-dev prisma dotenv
|
||||
import "dotenv/config";
|
||||
import { defineConfig } from "prisma/config";
|
||||
|
||||
export default defineConfig({
|
||||
schema: "prisma/schema.prisma",
|
||||
migrations: {
|
||||
path: "prisma/migrations",
|
||||
seed: 'ts-node --compiler-options {"module":"CommonJS"} prisma/seed.ts',
|
||||
},
|
||||
datasource: {
|
||||
url: process.env["DATABASE_URL"],
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,66 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE `categories` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(50) NOT NULL,
|
||||
`slug` VARCHAR(50) NOT NULL,
|
||||
`icon` VARCHAR(100) NULL,
|
||||
`parent_id` INTEGER NULL,
|
||||
`sort_order` INTEGER NOT NULL DEFAULT 0,
|
||||
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updated_at` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `categories_slug_key`(`slug`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `tools` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`slug` VARCHAR(100) NOT NULL,
|
||||
`category_id` INTEGER NOT NULL,
|
||||
`description` TEXT NOT NULL,
|
||||
`logo_url` VARCHAR(255) NULL,
|
||||
`website_url` VARCHAR(255) NOT NULL,
|
||||
`pricing_model` ENUM('free', 'freemium', 'paid', 'subscription') NOT NULL DEFAULT 'freemium',
|
||||
`pricing_detail` VARCHAR(200) NULL,
|
||||
`features` JSON NULL,
|
||||
`tags` JSON NULL,
|
||||
`view_count` INTEGER NOT NULL DEFAULT 0,
|
||||
`status` ENUM('draft', 'published') NOT NULL DEFAULT 'draft',
|
||||
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updated_at` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `tools_slug_key`(`slug`),
|
||||
INDEX `tools_category_id_status_idx`(`category_id`, `status`),
|
||||
FULLTEXT INDEX `tools_name_description_idx`(`name`, `description`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `pending_tools` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`slug` VARCHAR(100) NULL,
|
||||
`category_id` INTEGER NULL,
|
||||
`description` TEXT NULL,
|
||||
`logo_url` VARCHAR(255) NULL,
|
||||
`website_url` VARCHAR(255) NULL,
|
||||
`pricing_model` ENUM('free', 'freemium', 'paid', 'subscription') NULL DEFAULT 'freemium',
|
||||
`pricing_detail` VARCHAR(200) NULL,
|
||||
`features` JSON NULL,
|
||||
`tags` JSON NULL,
|
||||
`source_url` VARCHAR(255) NULL,
|
||||
`scraped_at` DATETIME(3) NULL,
|
||||
`status` ENUM('pending', 'approved', 'rejected') NOT NULL DEFAULT 'pending',
|
||||
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updated_at` DATETIME(3) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `categories` ADD CONSTRAINT `categories_parent_id_fkey` FOREIGN KEY (`parent_id`) REFERENCES `categories`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `tools` ADD CONSTRAINT `tools_category_id_fkey` FOREIGN KEY (`category_id`) REFERENCES `categories`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `scraped_at` on the `pending_tools` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE `pending_tools` DROP COLUMN `scraped_at`;
|
||||
@@ -0,0 +1,13 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE `discovery_configs` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`category_id` INTEGER NULL,
|
||||
`prompt` TEXT NOT NULL,
|
||||
`tagPool` JSON NULL,
|
||||
`temperature` DOUBLE NOT NULL DEFAULT 0.7,
|
||||
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updated_at` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `discovery_configs_category_id_key`(`category_id`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `tagPool` on the `discovery_configs` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE `discovery_configs` DROP COLUMN `tagPool`,
|
||||
ADD COLUMN `tag_pool` JSON NULL;
|
||||
@@ -0,0 +1,4 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `discovery_configs` ADD COLUMN `apiBaseUrl` VARCHAR(255) NULL,
|
||||
ADD COLUMN `apiKey` VARCHAR(255) NULL,
|
||||
ADD COLUMN `modelName` VARCHAR(100) NULL;
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `apiBaseUrl` on the `discovery_configs` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `apiKey` on the `discovery_configs` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `modelName` on the `discovery_configs` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE `discovery_configs` DROP COLUMN `apiBaseUrl`,
|
||||
DROP COLUMN `apiKey`,
|
||||
DROP COLUMN `modelName`,
|
||||
ADD COLUMN `api_provider_id` INTEGER NULL;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `skills` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`slug` VARCHAR(100) NOT NULL,
|
||||
`category_id` INTEGER NOT NULL,
|
||||
`description` TEXT NOT NULL,
|
||||
`logo_url` VARCHAR(255) NULL,
|
||||
`source_url` VARCHAR(255) NOT NULL,
|
||||
`source_type` VARCHAR(20) NOT NULL DEFAULT 'github',
|
||||
`features` JSON NULL,
|
||||
`tags` JSON NULL,
|
||||
`view_count` INTEGER NOT NULL DEFAULT 0,
|
||||
`status` ENUM('draft', 'published') NOT NULL DEFAULT 'draft',
|
||||
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updated_at` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `skills_slug_key`(`slug`),
|
||||
INDEX `skills_category_id_status_idx`(`category_id`, `status`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `pending_skills` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`slug` VARCHAR(100) NULL,
|
||||
`category_id` INTEGER NULL,
|
||||
`description` TEXT NULL,
|
||||
`logo_url` VARCHAR(255) NULL,
|
||||
`source_url` VARCHAR(255) NULL,
|
||||
`source_type` VARCHAR(20) NULL,
|
||||
`features` JSON NULL,
|
||||
`tags` JSON NULL,
|
||||
`status` ENUM('pending', 'approved', 'rejected') NOT NULL DEFAULT 'pending',
|
||||
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updated_at` DATETIME(3) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `api_providers` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(50) NOT NULL,
|
||||
`baseUrl` VARCHAR(255) NOT NULL,
|
||||
`apiKey` VARCHAR(255) NOT NULL,
|
||||
`model` VARCHAR(100) NOT NULL,
|
||||
`isDefault` BOOLEAN NOT NULL DEFAULT false,
|
||||
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updated_at` DATETIME(3) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `skills` ADD CONSTRAINT `skills_category_id_fkey` FOREIGN KEY (`category_id`) REFERENCES `categories`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,23 @@
|
||||
-- DropForeignKey
|
||||
ALTER TABLE `skills` DROP FOREIGN KEY `skills_category_id_fkey`;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `skill_categories` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(50) NOT NULL,
|
||||
`slug` VARCHAR(50) NOT NULL,
|
||||
`icon` VARCHAR(100) NULL,
|
||||
`parent_id` INTEGER NULL,
|
||||
`sort_order` INTEGER NOT NULL DEFAULT 0,
|
||||
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updated_at` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `skill_categories_slug_key`(`slug`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `skill_categories` ADD CONSTRAINT `skill_categories_parent_id_fkey` FOREIGN KEY (`parent_id`) REFERENCES `skill_categories`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `skills` ADD CONSTRAINT `skills_category_id_fkey` FOREIGN KEY (`category_id`) REFERENCES `skill_categories`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `pending_tools` ADD CONSTRAINT `pending_tools_category_id_fkey` FOREIGN KEY (`category_id`) REFERENCES `categories`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE `daily_report_items` ADD COLUMN `hot_score` INT NOT NULL DEFAULT 0;
|
||||
@@ -0,0 +1,44 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `skills` ADD COLUMN `last_reviewed_at` DATETIME(3) NULL,
|
||||
ADD COLUMN `github_stars_history` JSON NULL;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `skill_reviews` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`skill_id` INTEGER NOT NULL,
|
||||
`capability` DOUBLE NOT NULL,
|
||||
`dev_exp` DOUBLE NOT NULL,
|
||||
`cost_license` DOUBLE NOT NULL,
|
||||
`community` DOUBLE NOT NULL,
|
||||
`performance` DOUBLE NOT NULL,
|
||||
`overall` DOUBLE NOT NULL,
|
||||
`reviews` JSON NOT NULL,
|
||||
`long_article` TEXT NULL,
|
||||
`video_script` TEXT NULL,
|
||||
`social_cards` JSON NULL,
|
||||
`status` ENUM('DRAFT', 'PUBLISHED', 'REJECTED', 'OUTDATED') NOT NULL DEFAULT 'DRAFT',
|
||||
`reviewed_at` DATETIME(3) NOT NULL,
|
||||
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
UNIQUE INDEX `skill_reviews_skill_id_key`(`skill_id`),
|
||||
INDEX `skill_reviews_skill_id_idx`(`skill_id`),
|
||||
INDEX `skill_reviews_overall_idx`(`overall`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `review_generation_logs` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`skill_id` INTEGER NOT NULL,
|
||||
`status` VARCHAR(20) NOT NULL,
|
||||
`prompt` TEXT NOT NULL,
|
||||
`response` TEXT NULL,
|
||||
`error` TEXT NULL,
|
||||
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
INDEX `review_generation_logs_skill_id_idx`(`skill_id`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `skill_reviews` ADD CONSTRAINT `skill_reviews_skill_id_fkey` FOREIGN KEY (`skill_id`) REFERENCES `skills`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (e.g., Git)
|
||||
provider = "mysql"
|
||||
@@ -0,0 +1,404 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "mysql"
|
||||
}
|
||||
|
||||
model Category {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @db.VarChar(50)
|
||||
slug String @unique @db.VarChar(50)
|
||||
icon String? @db.VarChar(100)
|
||||
parentId Int? @map("parent_id")
|
||||
sortOrder Int @default(0) @map("sort_order")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
tools Tool[]
|
||||
pendingTools PendingTool[]
|
||||
parent Category? @relation("CategoryToCategory", fields: [parentId], references: [id])
|
||||
children Category[] @relation("CategoryToCategory")
|
||||
|
||||
@@map("categories")
|
||||
}
|
||||
|
||||
model SkillCategory {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @db.VarChar(50)
|
||||
slug String @unique @db.VarChar(50)
|
||||
icon String? @db.VarChar(100)
|
||||
parentId Int? @map("parent_id")
|
||||
sortOrder Int @default(0) @map("sort_order")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
skills Skill[]
|
||||
pendingSkills PendingSkill[]
|
||||
parent SkillCategory? @relation("SkillCategoryToSkillCategory", fields: [parentId], references: [id])
|
||||
children SkillCategory[] @relation("SkillCategoryToSkillCategory")
|
||||
|
||||
@@map("skill_categories")
|
||||
}
|
||||
|
||||
model Tool {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @db.VarChar(100)
|
||||
slug String @unique @db.VarChar(100)
|
||||
categoryId Int @map("category_id")
|
||||
description String @db.Text
|
||||
logoUrl String? @map("logo_url") @db.VarChar(255)
|
||||
websiteUrl String @map("website_url") @db.VarChar(255)
|
||||
pricingModel PricingModel @default(freemium) @map("pricing_model")
|
||||
pricingDetail String? @map("pricing_detail") @db.VarChar(200)
|
||||
features Json?
|
||||
tags Json?
|
||||
viewCount Int @default(0) @map("view_count")
|
||||
status Status @default(draft)
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
category Category @relation(fields: [categoryId], references: [id])
|
||||
favorites Favorite[]
|
||||
browsingHistory BrowsingHistory[]
|
||||
reviews Review[]
|
||||
collectionItems CollectionItem[]
|
||||
|
||||
@@index([categoryId, status])
|
||||
@@fulltext([name, description])
|
||||
@@map("tools")
|
||||
}
|
||||
|
||||
model PendingTool {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @db.VarChar(100)
|
||||
slug String? @db.VarChar(100)
|
||||
categoryId Int? @map("category_id")
|
||||
description String? @db.Text
|
||||
logoUrl String? @map("logo_url") @db.VarChar(255)
|
||||
websiteUrl String? @map("website_url") @db.VarChar(255)
|
||||
pricingModel PricingModel? @default(freemium) @map("pricing_model")
|
||||
pricingDetail String? @map("pricing_detail") @db.VarChar(200)
|
||||
features Json?
|
||||
tags Json?
|
||||
sourceUrl String? @map("source_url") @db.VarChar(255)
|
||||
status PendingStatus @default(pending)
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
category Category? @relation(fields: [categoryId], references: [id])
|
||||
|
||||
@@map("pending_tools")
|
||||
}
|
||||
|
||||
model Skill {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @db.VarChar(100)
|
||||
slug String @unique @db.VarChar(100)
|
||||
categoryId Int @map("category_id")
|
||||
description String @db.Text
|
||||
logoUrl String? @map("logo_url") @db.VarChar(255)
|
||||
sourceUrl String @map("source_url") @db.VarChar(255)
|
||||
sourceType String @default("gitee") @map("source_type") @db.VarChar(20)
|
||||
rating Float @default(0) @db.Float
|
||||
features Json?
|
||||
tags Json?
|
||||
viewCount Int @default(0) @map("view_count")
|
||||
status Status @default(draft)
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
category SkillCategory @relation(fields: [categoryId], references: [id])
|
||||
favorites Favorite[]
|
||||
browsingHistory BrowsingHistory[]
|
||||
reviews Review[]
|
||||
collectionItems CollectionItem[]
|
||||
skillReview SkillReview?
|
||||
|
||||
lastReviewedAt DateTime? @map("last_reviewed_at")
|
||||
githubStarsHistory Json? @map("github_stars_history")
|
||||
|
||||
@@index([categoryId, status])
|
||||
@@map("skills")
|
||||
}
|
||||
|
||||
model PendingSkill {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @db.VarChar(100)
|
||||
slug String? @db.VarChar(100)
|
||||
categoryId Int? @map("category_id")
|
||||
description String? @db.Text
|
||||
logoUrl String? @map("logo_url") @db.VarChar(255)
|
||||
sourceUrl String? @map("source_url") @db.VarChar(255)
|
||||
sourceType String? @map("source_type") @db.VarChar(20)
|
||||
rating Float @default(0) @db.Float
|
||||
features Json?
|
||||
tags Json?
|
||||
status PendingStatus @default(pending)
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
category SkillCategory? @relation(fields: [categoryId], references: [id])
|
||||
|
||||
@@map("pending_skills")
|
||||
}
|
||||
|
||||
enum PricingModel {
|
||||
free
|
||||
freemium
|
||||
paid
|
||||
subscription
|
||||
}
|
||||
|
||||
enum Status {
|
||||
draft
|
||||
published
|
||||
}
|
||||
|
||||
enum PendingStatus {
|
||||
pending
|
||||
approved
|
||||
rejected
|
||||
}
|
||||
|
||||
model SystemConfig {
|
||||
id Int @id @default(autoincrement())
|
||||
key String @unique @db.VarChar(50)
|
||||
value Json
|
||||
@@map("system_configs")
|
||||
}
|
||||
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
email String @unique @db.VarChar(255)
|
||||
passwordHash String? @db.VarChar(255)
|
||||
name String? @db.VarChar(100)
|
||||
avatarUrl String?
|
||||
oauthProvider String? @db.VarChar(50)
|
||||
oauthId String? @unique @db.VarChar(255)
|
||||
role String @default("user") @db.VarChar(20)
|
||||
roleId Int? @map("role_id")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
assignedRole Role? @relation(fields: [roleId], references: [id])
|
||||
favorites Favorite[]
|
||||
browsingHistory BrowsingHistory[]
|
||||
reviews Review[]
|
||||
collections Collection[]
|
||||
|
||||
@@unique([oauthProvider, oauthId])
|
||||
@@map("users")
|
||||
}
|
||||
|
||||
model Role {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @db.VarChar(50)
|
||||
slug String @unique @db.VarChar(50)
|
||||
isSystem Boolean @default(false) @map("is_system")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
permissions RolePermission[]
|
||||
users User[]
|
||||
|
||||
@@map("roles")
|
||||
}
|
||||
|
||||
model Permission {
|
||||
id Int @id @default(autoincrement())
|
||||
groupName String @map("group_name") @db.VarChar(50)
|
||||
name String @db.VarChar(50)
|
||||
key String @unique @db.VarChar(80)
|
||||
sortOrder Int @default(0) @map("sort_order")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
rolePermissions RolePermission[]
|
||||
|
||||
@@index([groupName, sortOrder])
|
||||
@@map("permissions")
|
||||
}
|
||||
|
||||
model RolePermission {
|
||||
roleId Int @map("role_id")
|
||||
permissionId Int @map("permission_id")
|
||||
|
||||
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
|
||||
permission Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@id([roleId, permissionId])
|
||||
@@map("role_permissions")
|
||||
}
|
||||
|
||||
model Favorite {
|
||||
id Int @id @default(autoincrement())
|
||||
userId Int @map("user_id")
|
||||
toolId Int? @map("tool_id")
|
||||
skillId Int? @map("skill_id")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
tool Tool? @relation(fields: [toolId], references: [id], onDelete: Cascade)
|
||||
skill Skill? @relation(fields: [skillId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([userId, toolId])
|
||||
@@unique([userId, skillId])
|
||||
@@index([userId])
|
||||
@@map("favorites")
|
||||
}
|
||||
|
||||
model BrowsingHistory {
|
||||
id Int @id @default(autoincrement())
|
||||
userId Int @map("user_id")
|
||||
toolId Int? @map("tool_id")
|
||||
skillId Int? @map("skill_id")
|
||||
viewedAt DateTime @default(now()) @updatedAt @map("viewed_at")
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
tool Tool? @relation(fields: [toolId], references: [id], onDelete: Cascade)
|
||||
skill Skill? @relation(fields: [skillId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([userId, toolId])
|
||||
@@unique([userId, skillId])
|
||||
@@index([userId, viewedAt])
|
||||
@@map("browsing_histories")
|
||||
}
|
||||
|
||||
model Review {
|
||||
id Int @id @default(autoincrement())
|
||||
userId Int @map("user_id")
|
||||
toolId Int? @map("tool_id")
|
||||
skillId Int? @map("skill_id")
|
||||
rating Int?
|
||||
comment String @db.Text
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
tool Tool? @relation(fields: [toolId], references: [id], onDelete: Cascade)
|
||||
skill Skill? @relation(fields: [skillId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([userId, toolId])
|
||||
@@unique([userId, skillId])
|
||||
@@index([toolId, createdAt])
|
||||
@@index([skillId, createdAt])
|
||||
@@map("reviews")
|
||||
}
|
||||
|
||||
model Collection {
|
||||
id Int @id @default(autoincrement())
|
||||
userId Int @map("user_id")
|
||||
name String @db.VarChar(50)
|
||||
description String? @db.Text
|
||||
sortOrder Int @default(0) @map("sort_order")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
items CollectionItem[]
|
||||
|
||||
@@index([userId])
|
||||
@@map("collections")
|
||||
}
|
||||
|
||||
model CollectionItem {
|
||||
id Int @id @default(autoincrement())
|
||||
collectionId Int @map("collection_id")
|
||||
toolId Int? @map("tool_id")
|
||||
skillId Int? @map("skill_id")
|
||||
addedAt DateTime @default(now()) @map("added_at")
|
||||
|
||||
collection Collection @relation(fields: [collectionId], references: [id], onDelete: Cascade)
|
||||
tool Tool? @relation(fields: [toolId], references: [id], onDelete: Cascade)
|
||||
skill Skill? @relation(fields: [skillId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([collectionId, toolId])
|
||||
@@unique([collectionId, skillId])
|
||||
@@index([collectionId])
|
||||
@@map("collection_items")
|
||||
}
|
||||
|
||||
model DailyReport {
|
||||
id Int @id @default(autoincrement())
|
||||
date DateTime @unique @db.Date
|
||||
title String @db.VarChar(200)
|
||||
summary String? @db.Text
|
||||
hotCount Int @default(0) @map("hot_count")
|
||||
coverUrl String? @map("cover_url") @db.VarChar(255)
|
||||
status Status @default(draft)
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
items DailyReportItem[]
|
||||
|
||||
@@index([date])
|
||||
@@index([status])
|
||||
@@map("daily_reports")
|
||||
}
|
||||
|
||||
model DailyReportItem {
|
||||
id Int @id @default(autoincrement())
|
||||
reportId Int @map("report_id")
|
||||
sortOrder Int @default(0) @map("sort_order")
|
||||
category String @default("tech") @db.VarChar(20)
|
||||
title String @db.VarChar(200)
|
||||
summary String? @db.Text
|
||||
detail String? @db.Text
|
||||
sourceUrl String? @map("source_url") @db.VarChar(500)
|
||||
imageUrl String? @map("image_url") @db.VarChar(255)
|
||||
hotScore Int @default(0) @map("hot_score")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
report DailyReport @relation(fields: [reportId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([reportId, sortOrder])
|
||||
@@map("daily_report_items")
|
||||
}
|
||||
|
||||
model SkillReview {
|
||||
id Int @id @default(autoincrement())
|
||||
skillId Int @unique @map("skill_id")
|
||||
skill Skill @relation(fields: [skillId], references: [id])
|
||||
|
||||
capability Float
|
||||
devExp Float @map("dev_exp")
|
||||
costLicense Float @map("cost_license")
|
||||
community Float
|
||||
performance Float
|
||||
overall Float
|
||||
|
||||
reviews Json
|
||||
|
||||
longArticle String? @map("long_article") @db.Text
|
||||
videoScript String? @map("video_script") @db.Text
|
||||
socialCards Json? @map("social_cards")
|
||||
|
||||
status ReviewStatus @default(DRAFT)
|
||||
reviewedAt DateTime @updatedAt @map("reviewed_at")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
@@index([skillId])
|
||||
@@index([overall])
|
||||
@@map("skill_reviews")
|
||||
}
|
||||
|
||||
model ReviewGenerationLog {
|
||||
id Int @id @default(autoincrement())
|
||||
skillId Int @map("skill_id")
|
||||
status String @db.VarChar(20)
|
||||
prompt String @db.Text
|
||||
response String? @db.Text
|
||||
error String? @db.Text
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
@@index([skillId])
|
||||
@@map("review_generation_logs")
|
||||
}
|
||||
|
||||
enum ReviewStatus {
|
||||
DRAFT
|
||||
PUBLISHED
|
||||
REJECTED
|
||||
OUTDATED
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import { PrismaMariaDb } from "@prisma/adapter-mariadb";
|
||||
|
||||
const adapter = new PrismaMariaDb(process.env.DATABASE_URL!);
|
||||
const prisma = new PrismaClient({ adapter });
|
||||
|
||||
const categories = [
|
||||
{ name: "文本生成", slug: "text-generation", icon: "", sortOrder: 1 },
|
||||
{ name: "图像生成", slug: "image-generation", icon: "", sortOrder: 2 },
|
||||
{ name: "视频生成", slug: "video-generation", icon: "", sortOrder: 3 },
|
||||
{ name: "音频处理", slug: "audio-processing", icon: "", sortOrder: 4 },
|
||||
{ name: "代码助手", slug: "code-assistant", icon: "", sortOrder: 5 },
|
||||
{ name: "办公效率", slug: "office-efficiency", icon: "", sortOrder: 6 },
|
||||
{ name: "AI 角色", slug: "ai-character", icon: "", sortOrder: 7 },
|
||||
{ name: "设计工具", slug: "design-tools", icon: "", sortOrder: 8 },
|
||||
{ name: "数据分析", slug: "data-analysis", icon: "", sortOrder: 9 },
|
||||
{ name: "内容检测", slug: "content-detection", icon: "", sortOrder: 10 },
|
||||
];
|
||||
|
||||
async function main() {
|
||||
console.log("Seeding categories...");
|
||||
|
||||
for (const category of categories) {
|
||||
await prisma.category.upsert({
|
||||
where: { slug: category.slug },
|
||||
update: { name: category.name, sortOrder: category.sortOrder },
|
||||
create: category,
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`Seeded ${categories.length} categories.`);
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 514 B |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 633 B |
|
After Width: | Height: | Size: 17 KiB |
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 582.36 178.41" style="enable-background:new 0 0 582.36 178.41;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_1_);}
|
||||
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
|
||||
.st2{fill:#002941;}
|
||||
.st3{fill-rule:evenodd;clip-rule:evenodd;fill:#002941;}
|
||||
.st4{fill:#666666;}
|
||||
</style>
|
||||
<g>
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="14.1598" y1="166.454" x2="165.3124" y2="11.5845">
|
||||
<stop offset="0.1326" style="stop-color:#E84709"/>
|
||||
<stop offset="1" style="stop-color:#F19200"/>
|
||||
</linearGradient>
|
||||
<path class="st0" d="M0.35,0h178.41v178.41H0.35V0z"/>
|
||||
<path class="st1" d="M90.15,138.74c15.31-33.86,49.32-57.44,88.86-57.58v5.97c-43.49,0.14-79.89,30.39-89.44,71
|
||||
c-7.7-33.76-33.92-60.46-67.42-68.84C62.42,79.49,92.34,43.25,92.48,0h6.33c0,39.95-23.94,74.3-58.25,89.51
|
||||
C62.54,99.25,80.25,116.85,90.15,138.74z M0.35,85.33c-0.12,0-0.24,0-0.35,0v-5.97c0.12,0,0.24,0,0.35,0
|
||||
c43.83,0,79.36-35.53,79.36-79.36h5.97C85.68,47.13,47.48,85.33,0.35,85.33z M0.65,73.39c-0.22,0-0.43-0.01-0.65-0.01v-4.77
|
||||
c0.12,0,0.24,0.01,0.35,0.01c37.57,0,68.02-30.46,68.02-68.02c0-0.2-0.01-0.4-0.02-0.6h5.38c0,0.1,0,0.2,0,0.3
|
||||
C73.75,40.67,41.02,73.39,0.65,73.39z M85.08,178.41h-5.97C78.79,134.94,43.52,99.78,0,99.65v-5.97
|
||||
C46.81,93.82,84.76,131.64,85.08,178.41z M73.74,178.41h-5.38c-0.32-37.29-30.64-67.43-68.01-67.43c-0.12,0-0.24,0.01-0.35,0.01
|
||||
v-5.37c0.22,0,0.43-0.01,0.65-0.01C40.92,105.62,73.58,138.18,73.74,178.41z M179.01,93.69v5.97c-43.47,0.19-78.68,35.32-79,78.76
|
||||
h-5.97C94.36,131.68,132.25,93.88,179.01,93.69z M179.01,105.62v5.39c-36.93,0.51-66.74,30.43-67.06,67.4h-5.38
|
||||
C106.73,138.4,139.04,105.97,179.01,105.62z"/>
|
||||
<path class="st2" d="M576.41,98.13V19h5.95v79.13H576.41z M547.12,22.06h5.95V94.2h-5.95V22.06z M505.24,93.94
|
||||
c10.49-9.26,13.12-17.91,13.12-35.55V31.35h0.01c-0.25-3.95-4.27-4.75-4.97-4.86l-50,0.01l-3.58,12.09h20.9
|
||||
c6.03,0,11.02,4.98,11.02,11V97.8c0-0.01-4.98,0-11.02,0h-43.19c-6.03,0-11.1-4.98-11.1-11V49.59c0-2.95,0.01-10.03,0.01-11.01
|
||||
c0-0.02,8.02,0,11.1,0h16.18l3.58-12.09h-36.17v-5.82c0,0,95.72,0.01,92.14,0.01c0.41,0,0.79,0.02,1.15,0.06
|
||||
c2.78,0.21,4.89,1.23,6.73,3.07c2.84,2.84,3.1,6.39,3.11,7.53h0.04v27.04c0,19.74-2.94,29.35-15.01,40L505.24,93.94z M432.44,86.8
|
||||
c0,2.8,2.19,5.07,5.07,5.07h43.19c2.8,0,5.07,0.03,5.07,0.01V70.82h-53.34V86.8z M432.48,44.53c-0.02,0-0.03,2.18-0.03,5.07v15.2
|
||||
h53.34v-15.2c0-2.88-2.27-5.07-5.07-5.07H432.48z"/>
|
||||
<path class="st2" d="M301.96,30.36h9.5v15.28h-9.5v5.51h9.5V86.9h5.34V68.53h7.85v-5.51h-7.85V51.15h7.85v-5.51h-7.85V30.36h7.85
|
||||
v-5.51h-7.85V19h-5.34v5.85h-9.5V30.36z"/>
|
||||
<path class="st2" d="M371.05,64.5c2.35,7.48,3.78,15.44,4.03,22.48h5.38c-0.19-5.86-1.31-17.29-6.46-30.42l-0.06-0.14l0.06-0.14
|
||||
l6.22-14.23v-7.76c0-5.28-0.09-7.5-2.28-9.28c-2.18-1.77-5.31-1.77-9.64-1.77h-11.57v5.51h11.57c6.45,0,6.7,0.21,6.7,5.54
|
||||
l-0.03,6.68l-3.92,8.97l-0.31-0.62c-2.04-4.07-4.15-7.57-6.43-10.71h-7.09c4.3,5.06,7.96,11.05,10.87,17.82l0.06,0.14l-0.06,0.14
|
||||
l-13.2,30.26h5.71l10.18-23.31L371.05,64.5z"/>
|
||||
<path class="st2" d="M351.02,92.84V19h-25.68v5.51h3.9l0.02,58.86l0,0c0,2.29,0.81,3.14,3.21,2.63l0,0l13.23-2.77v9.62h-28.36
|
||||
c-8.24,0-9.91-1.11-9.91-6.62v-23.2h-5.33v23.2c0,12.13,9.54,12.13,15.24,12.13h63.16v-5.51H351.02z M345.68,38.61h-8.23v5.51h8.23
|
||||
v13.41h-8.23V61l0.01-0.1c0,1.15,0.88,2.07,1.99,2.12h6.23V77.6l-10.26,2.15c-0.59,0.06-0.83-0.19-0.85-0.8V24.51h11.11V38.61z"/>
|
||||
<path class="st3" d="M400.97,54.1c2.48,0,4.48,2.01,4.48,4.48c0,2.48-2.01,4.48-4.48,4.48c-2.48,0-4.48-2.01-4.48-4.48
|
||||
C396.49,56.11,398.5,54.1,400.97,54.1z"/>
|
||||
<path class="st2" d="M211.45,27.43h2.6c0,0-0.05,9.26-0.05,17.13c0,9.91,10.3,10.88,10.3,10.88h2.65v12.87h-14.89v5.95h14.89
|
||||
c0,0,0,17.35,0,13.54c0,7.14,7.12,7.48,7.12,7.48l15.82-1.14l-0.79-5.95l-11.48,1.13c0,0-4.72,0.52-4.72-4.95
|
||||
c0-4.72,0-10.11,0-10.11h15.32v-5.95h-15.32V55.45h2.45c6.04,0,11.03-4.99,11.03-11.03V34.34h-5.95v10.07
|
||||
c0,2.8-2.28,5.04-5.08,5.04h-8.15c0,0-6.73,0.49-6.73-5.07c0-6.43,0-16.96,0-16.96h28.46v-5.95h-37.48V27.43z M253.31,44.59
|
||||
l14.97,24.95c-5.25,10.51-11.38,18.48-18.04,25.04l4.2,4.2c6.39-6.3,12.26-13.66,17.51-23.29l13.92,23.12l5.17-3.06l-15.94-26.36
|
||||
c4.38-9.63,7.6-17.92,10.49-32.28c0,0,0.43-1.17,0.05-3.4c-0.44-2.59-2.55-5.86-7.86-5.83c-8.81,0.06-17.64,0-17.64,0l1.23-7.71
|
||||
l-6.04-0.96l-2.28,14.62h20.17c4.33,0,6.38,2.11,5.41,5.94c-2.44,9.65-4.29,16.18-7.28,23.39l-12.96-21.45L253.31,44.59z"/>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st4" d="M231.11,141.72v-0.15c1.97-0.66,3.13-2.66,3.13-4.74c0-3.97-3.25-5.4-7.76-5.4h-6.8v21.96h7.34
|
||||
c4.86,0,8.41-2.09,8.41-6.44C235.43,143.95,233.61,142.25,231.11,141.72z M223.14,134.11h3.04c3.1,0,4.65,0.87,4.65,3.16
|
||||
c0,2.06-1.4,3.31-4.74,3.31h-2.95V134.11z M226.63,150.67h-3.49v-7.46h3.49c3.49,0,5.4,1.07,5.4,3.55
|
||||
C232.03,149.44,230.06,150.67,226.63,150.67z M263.93,136.55c-3.85,0-7.49,3.31-7.49,8.65c0,5.4,3.55,8.56,8,8.56
|
||||
c2.15,0,4.03-0.72,5.55-1.73l-1.19-2.18c-1.19,0.78-2.45,1.22-3.91,1.22c-2.83,0-4.8-1.88-5.07-5.01h10.65
|
||||
c0.09-0.39,0.15-1.07,0.15-1.73C270.61,139.69,268.28,136.55,263.93,136.55z M259.78,143.72c0.33-2.89,2.15-4.48,4.21-4.48
|
||||
c2.39,0,3.67,1.64,3.67,4.48H259.78z M298.62,143.8c-1.79-0.66-3.49-1.19-3.49-2.6c0-1.13,0.84-2.03,2.63-2.03
|
||||
c1.37,0,2.54,0.6,3.67,1.43l1.61-2.12c-1.34-1.04-3.13-1.94-5.34-1.94c-3.61,0-5.82,2.06-5.82,4.8c0,2.77,2.51,3.94,4.68,4.77
|
||||
c1.79,0.69,3.64,1.34,3.64,2.83c0,1.25-0.92,2.21-2.89,2.21c-1.76,0-3.19-0.72-4.65-1.88l-1.61,2.21
|
||||
c1.58,1.31,3.91,2.27,6.18,2.27c4.06,0,6.24-2.24,6.24-4.98C303.46,145.68,300.92,144.67,298.62,143.8z M334.4,150.76
|
||||
c-3.88,0-6.33-3.19-6.33-8.41c0-5.16,2.63-8.32,6.42-8.32c1.79,0,3.16,0.81,4.3,1.97l1.88-2.21c-1.34-1.46-3.49-2.77-6.24-2.77
|
||||
c-5.55,0-9.91,4.3-9.91,11.46c0,7.19,4.24,11.31,9.76,11.31c2.83,0,5.07-1.13,6.83-3.16l-1.85-2.18
|
||||
C337.95,149.86,336.39,150.76,334.4,150.76z M371.6,136.55c-2.24,0-3.88,1.22-5.31,2.6l0.12-3.25v-6.3h-3.4v23.78h3.4v-11.64
|
||||
c1.46-1.46,2.51-2.24,4.03-2.24c1.94,0,2.77,1.13,2.77,3.97v9.91h3.43v-10.32C376.64,138.88,375.09,136.55,371.6,136.55z
|
||||
M406.18,136.55c-2.63,0-4.92,1.07-6.62,2.15l1.28,2.33c1.4-0.9,3.01-1.67,4.74-1.67c2.42,0,3.1,1.67,3.13,3.58
|
||||
c-6.83,0.75-9.82,2.57-9.82,6.09c0,2.89,2,4.74,4.83,4.74c1.97,0,3.73-0.98,5.22-2.27h0.09l0.3,1.88h2.8v-9.88
|
||||
C412.15,139.15,410.27,136.55,406.18,136.55z M408.71,149.15c-1.34,1.22-2.51,1.91-3.94,1.91c-1.46,0-2.57-0.66-2.57-2.27
|
||||
c0-1.85,1.64-3.07,6.5-3.67V149.15z M443.92,136.55c-2.24,0-3.91,1.22-5.43,2.69h-0.09l-0.27-2.27h-2.8v16.41h3.4v-11.64
|
||||
c1.46-1.46,2.51-2.24,4.03-2.24c1.94,0,2.77,1.13,2.77,3.97v9.91h3.43v-10.32C448.96,138.88,447.41,136.55,443.92,136.55z
|
||||
M480.86,136.55c-2.24,0-3.91,1.22-5.43,2.69h-0.09l-0.27-2.27h-2.8v16.41h3.4v-11.64c1.46-1.46,2.51-2.24,4.03-2.24
|
||||
c1.94,0,2.77,1.13,2.77,3.97v9.91h3.43v-10.32C485.9,138.88,484.35,136.55,480.86,136.55z M515.52,136.55
|
||||
c-3.85,0-7.49,3.31-7.49,8.65c0,5.4,3.55,8.56,8,8.56c2.15,0,4.03-0.72,5.55-1.73l-1.19-2.18c-1.19,0.78-2.45,1.22-3.91,1.22
|
||||
c-2.83,0-4.8-1.88-5.07-5.01h10.65c0.09-0.39,0.15-1.07,0.15-1.73C522.21,139.69,519.88,136.55,515.52,136.55z M511.38,143.72
|
||||
c0.33-2.89,2.15-4.48,4.21-4.48c2.39,0,3.67,1.64,3.67,4.48H511.38z M548.61,150.97c-0.42,0-0.84-0.33-0.84-1.25V129.6h-3.4
|
||||
v19.93c0,2.66,0.92,4.24,3.4,4.24c0.84,0,1.43-0.12,1.85-0.27l-0.45-2.6C548.88,150.97,548.76,150.97,548.61,150.97z
|
||||
M577.43,143.8c-1.79-0.66-3.49-1.19-3.49-2.6c0-1.13,0.84-2.03,2.63-2.03c1.37,0,2.54,0.6,3.67,1.43l1.61-2.12
|
||||
c-1.34-1.04-3.13-1.94-5.34-1.94c-3.61,0-5.82,2.06-5.82,4.8c0,2.77,2.51,3.94,4.68,4.77c1.79,0.69,3.64,1.34,3.64,2.83
|
||||
c0,1.25-0.92,2.21-2.89,2.21c-1.76,0-3.19-0.72-4.65-1.88l-1.61,2.21c1.58,1.31,3.91,2.27,6.18,2.27c4.06,0,6.24-2.24,6.24-4.98
|
||||
C582.26,145.68,579.73,144.67,577.43,143.8z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg width="46" height="40" viewBox="0 0 46 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M29.491 0.691513H15.2473L10.505 10.7684H29.491V0.691513ZM38.9579 17.8406L36.5917 11.4927L34.2255 17.8406L27.8309 20.1895L34.2255 22.5385L36.5917 28.8864L38.9579 22.5385L45.3524 20.1895L38.9579 17.8406ZM10.505 29.6145H29.491V39.6913H14.1613L10.505 29.6145ZM0.352827 10.767L0.3526 29.6145H10.5037L10.5037 10.767H0.352827Z" fill="#683BFF"/>
|
||||
<path d="M36.6385 11.4754L36.5917 11.3497L36.5448 11.4754L34.1867 17.8018L27.8137 20.1428L27.6859 20.1897L27.8137 20.2366L34.1867 22.5777L36.5448 28.904L36.5917 29.0297L36.6385 28.904L38.9967 22.5777L45.3697 20.2366L45.4975 20.1897L45.3697 20.1428L38.9967 17.8018L36.6385 11.4754Z" fill="#6FEA2A" stroke="black" stroke-width="0.1"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 823 B |
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 465 B |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 949 B |
|
After Width: | Height: | Size: 949 B |
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 205 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 125 KiB |
|
After Width: | Height: | Size: 17 KiB |