From 052f9c5ed9743528ae0f00097d5812f5680a4e51 Mon Sep 17 00:00:00 2001 From: AdingApkgg Date: Thu, 27 Nov 2025 18:21:09 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E6=94=AF=E6=8C=81=E4=B8=8EPWA=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=A2=9E=E5=BC=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 更新 `.gitignore` 文件以包含环境变量文件 `.env` 和相关配置。 * 在 `env.d.ts` 中定义环境变量类型,支持 API 配置、功能开关和主题设置。 * 更新 `index.html`,添加 PWA 相关的 manifest 和 meta 标签,提升应用的安装体验。 * 引入 `lazysizes` 和 `quicklink` 以优化图片加载和链接预加载,提升性能。 * 更新多个组件以使用新的 UI 状态管理,确保一致性和可读性。 * 删除不再使用的 Font Awesome 图标,替换为 lucide-vue-next 图标,提升视觉一致性。 * 更新 `README.md`,添加环境变量配置说明和项目文档链接。 --- .env.development | 11 ++ .env.example | 77 ++++++++ .env.production | 10 ++ .gitignore | 5 + README.md | 49 ++++- docs/ENV_CONFIG.md | 270 ++++++++++++++++++++++++++++ docs/ENV_GUIDE.md | 218 +++++++++++++++++++++++ docs/ENV_USAGE_EXAMPLES.md | 271 ++++++++++++++++++++++++++++ docs/PINIA_GUIDE.md | 276 +++++++++++++++++++++++++++++ env.d.ts | 68 +++++++ index.html | 16 ++ package.json | 3 +- pnpm-lock.yaml | 56 +++++- public/browserconfig.xml | 11 ++ public/feed.xml | 69 ++++++++ public/gamepad-solid.svg | 1 - public/llms.txt | 61 +++++++ public/manifest.json | 83 +++++++++ public/sw.js | 6 +- src/api/search.ts | 2 +- src/components/CommentsModal.vue | 14 +- src/components/FloatingButtons.vue | 90 +++++----- src/components/SettingsModal.vue | 2 +- src/components/VndbPanel.vue | 12 +- src/config/env.ts | 107 +++++++++++ src/config/index.ts | 221 +++++++++++++++++++++++ src/main.ts | 38 +++- src/stores/cache.ts | 244 +++++++++++++++++++++++++ src/stores/history.ts | 150 ++++++++++++++++ src/stores/index.ts | 10 ++ src/stores/plugins.ts | 140 +++++++++++++++ src/stores/search.ts | 67 +++++-- src/stores/settings.ts | 119 +++++++++++++ src/stores/ui.ts | 205 +++++++++++++++++++++ src/vite-env.d.ts | 63 +++++++ 35 files changed, 2946 insertions(+), 99 deletions(-) create mode 100644 .env.development create mode 100644 .env.example create mode 100644 .env.production create mode 100644 docs/ENV_CONFIG.md create mode 100644 docs/ENV_GUIDE.md create mode 100644 docs/ENV_USAGE_EXAMPLES.md create mode 100644 docs/PINIA_GUIDE.md create mode 100644 public/browserconfig.xml create mode 100644 public/feed.xml delete mode 100644 public/gamepad-solid.svg create mode 100644 public/llms.txt create mode 100644 public/manifest.json create mode 100644 src/config/env.ts create mode 100644 src/config/index.ts create mode 100644 src/stores/cache.ts create mode 100644 src/stores/history.ts create mode 100644 src/stores/index.ts create mode 100644 src/stores/plugins.ts create mode 100644 src/stores/settings.ts create mode 100644 src/stores/ui.ts create mode 100644 src/vite-env.d.ts diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..3e0523c --- /dev/null +++ b/.env.development @@ -0,0 +1,11 @@ +# 开发环境配置 + +# API 配置(开发环境可以使用本地 API) +VITE_API_BASE_URL=https://cfapi.searchgal.homes +# VITE_API_BASE_URL=http://localhost:8787 + +# 开发配置 +VITE_ENABLE_DEBUG=true +VITE_ENABLE_MOCK=false + +# 其他配置继承自 .env diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..d2fbdf6 --- /dev/null +++ b/.env.example @@ -0,0 +1,77 @@ +# SearchGal Frontend 环境变量配置模板 +# 复制此文件为 .env 并根据需要修改配置 + +# ============================================ +# 应用信息 +# ============================================ +VITE_APP_TITLE=SearchGal - Galgame 聚合搜索 +VITE_APP_DESCRIPTION=多平台 Galgame 资源聚合搜索引擎 +VITE_APP_VERSION=1.0.0 + +# ============================================ +# API 配置 +# ============================================ +VITE_API_BASE_URL=https://cfapi.searchgal.homes +VITE_API_TIMEOUT=30000 +VITE_TRANSLATE_API_URL=https://translate.searchgal.homes +VITE_VNDB_API_URL=https://api.vndb.org/kana/v1 + +# ============================================ +# 外部服务 +# ============================================ +VITE_STATUS_URL=https://status.searchgal.homes +VITE_ARTALK_SERVER=https://artalk.saop.cc +VITE_IMAGE_API_URL=https://api.illlights.com/v1/img + +# ============================================ +# 网站信息 +# ============================================ +VITE_SITE_URL=https://searchgal.homes +VITE_SITE_NAME=SearchGal +VITE_GITHUB_URL=https://github.com/Moe-Sakura/frontend + +# ============================================ +# 功能开关 +# ============================================ +VITE_ENABLE_COMMENTS=true +VITE_ENABLE_VNDB=true +VITE_ENABLE_AI_TRANSLATE=true +VITE_ENABLE_PWA=true +VITE_ENABLE_ANALYTICS=false + +# ============================================ +# 搜索配置 +# ============================================ +VITE_SEARCH_COOLDOWN=30000 +VITE_DEFAULT_RESULTS_PER_PAGE=10 +VITE_LOAD_MORE_COUNT=20 +VITE_MAX_SEARCH_HISTORY=50 + +# ============================================ +# 缓存配置(单位:毫秒) +# ============================================ +VITE_CACHE_VNDB_DURATION=1800000 +VITE_CACHE_SEARCH_DURATION=600000 +VITE_CACHE_IMAGE_DURATION=3600000 +VITE_MAX_CACHE_SIZE=100 + +# ============================================ +# 主题配置 +# ============================================ +VITE_THEME_PRIMARY=#ff1493 +VITE_THEME_ACCENT=#d946ef +VITE_THEME_BACKGROUND_LIGHT=#fff5fa +VITE_THEME_BACKGROUND_DARK=#1e293b + +# ============================================ +# 性能配置 +# ============================================ +VITE_QUICKLINK_DELAY=500 +VITE_QUICKLINK_LIMIT=10 +VITE_LAZY_LOAD_THRESHOLD=0.5 + +# ============================================ +# 开发配置 +# ============================================ +VITE_ENABLE_DEBUG=false +VITE_ENABLE_MOCK=false diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..5385a42 --- /dev/null +++ b/.env.production @@ -0,0 +1,10 @@ +# 生产环境配置 + +# API 配置 +VITE_API_BASE_URL=https://cfapi.searchgal.homes + +# 开发配置 +VITE_ENABLE_DEBUG=false +VITE_ENABLE_MOCK=false + +# 其他配置继承自 .env diff --git a/.gitignore b/.gitignore index fe63289..5f4744a 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,8 @@ dist-ssr .history .pnpm-store .pnpm-lock.yaml + +# 环境变量文件 +.env +.env.local +.env.*.local diff --git a/README.md b/README.md index 8127d87..33a7a3e 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,9 @@ - 💬 **评论系统** - 基于 Artalk 的评论功能 - 🖼️ **随机背景** - IndexedDB 缓存的随机背景图片系统 - 📱 **响应式设计** - 完美适配桌面和移动设备 -- ⚡ **性能优化** - Pace.js 加载进度、Fancybox 图片预览、懒加载等 +- ⚡ **性能优化** - Pace.js 加载进度、Fancybox 图片预览、Lazysizes 懒加载、Quicklink 预加载 +- 📲 **PWA 支持** - 可安装为桌面/移动应用,支持离线访问 +- 📡 **RSS 订阅** - 订阅更新动态 ## 🛠️ 技术栈 @@ -31,12 +33,14 @@ ### UI 框架 - **Tailwind CSS 4.1** - 实用优先的 CSS 框架 -- **Font Awesome 7** - 图标库 +- **Lucide Icons** - 现代化 SVG 图标库 ### 功能库 - **Artalk 2.9** - 评论系统 - **Fancybox 6** - 图片和内容预览 - **Pace.js 1.2** - 页面加载进度条 +- **Lazysizes 5.3** - 高性能图片懒加载 +- **Quicklink 2.3** - 智能预加载 ### API 集成 - **Cloudflare Workers API** - 搜索聚合后端 @@ -55,6 +59,15 @@ git clone https://github.com/Moe-Sakura/frontend.git cd frontend ``` +### 配置环境变量 +```bash +# 复制环境变量模板 +cp .env.example .env + +# 根据需要修改 .env 文件中的配置 +# 详见 docs/ENV_GUIDE.md +``` + ### 安装依赖 ```bash pnpm install @@ -205,6 +218,13 @@ pnpm run build 项目不需要环境变量配置,所有 API 端点都在代码中硬编码或支持用户自定义。 +## 🤖 LLM 友好 + +本项目遵循 [llms.txt](https://llmstxt.org/) 规范,为 AI 助手和大语言模型提供了结构化的项目文档。 + +- 📄 访问 `/llms.txt` 获取项目的 LLM 友好文档 +- 🔗 在线地址: [searchgal.homes/llms.txt](https://searchgal.homes/llms.txt) + ## 🤝 贡献 欢迎提交 Issue 和 Pull Request! @@ -222,6 +242,31 @@ pnpm run build - 使用 Tailwind CSS 进行样式编写 - 保持代码简洁和可读性 +## 📝 环境变量 + +项目使用环境变量进行配置管理,所有配置项都可以通过 `.env` 文件进行自定义。 + +### 快速配置 + +```bash +# 复制模板文件 +cp .env.example .env + +# 编辑配置(可选) +vim .env +``` + +### 主要配置项 + +- **API 地址**:`VITE_API_BASE_URL` +- **功能开关**:`VITE_ENABLE_COMMENTS`、`VITE_ENABLE_VNDB` 等 +- **主题颜色**:`VITE_THEME_PRIMARY`、`VITE_THEME_ACCENT` +- **性能配置**:缓存时长、搜索冷却时间等 + +详细配置说明请查看: +- 📘 [环境变量配置指南](./docs/ENV_GUIDE.md) +- 📘 [环境变量使用示例](./docs/ENV_USAGE_EXAMPLES.md) + ## 📄 许可证 本项目采用 [MIT](LICENSE) 许可证。 diff --git a/docs/ENV_CONFIG.md b/docs/ENV_CONFIG.md new file mode 100644 index 0000000..be6829d --- /dev/null +++ b/docs/ENV_CONFIG.md @@ -0,0 +1,270 @@ +# 环境变量配置指南 + +SearchGal 使用 `.env` 文件进行全局配置管理。 + +## 快速开始 + +1. 复制示例文件: +```bash +cp .env.example .env +``` + +2. 根据需要修改 `.env` 文件中的配置 + +3. 重启开发服务器使配置生效 + +## 配置文件 + +- `.env` - 本地环境配置(不提交到 Git) +- `.env.example` - 配置示例(提交到 Git) +- `src/config/env.ts` - 配置读取和类型定义 + +## 使用方法 + +### 方式 1:直接导入配置对象(推荐) + +```typescript +import { CONFIG } from '@/config' + +// 使用 API 配置 +const apiUrl = CONFIG.api.defaultApiUrl +console.log(apiUrl) // https://cfapi.searchgal.homes + +// 使用功能开关 +if (CONFIG.features.enableComments) { + // 初始化评论系统 +} + +// 使用搜索配置 +const cooldown = CONFIG.search.cooldown +console.log(cooldown) // 30000 +``` + +### 方式 2:按需导入 + +```typescript +import { API_CONFIG, FEATURE_FLAGS, SEARCH_CONFIG } from '@/config' + +// API 配置 +console.log(API_CONFIG.defaultApiUrl) + +// 功能开关 +console.log(FEATURE_FLAGS.enableVndb) + +// 搜索配置 +console.log(SEARCH_CONFIG.defaultMode) +``` + +### 方式 3:直接访问环境变量(不推荐) + +```typescript +// ❌ 不推荐:需要手动处理类型和默认值 +const apiUrl = import.meta.env.VITE_DEFAULT_API_URL + +// ✅ 推荐:使用配置对象,有类型提示和默认值 +import { API_CONFIG } from '@/config' +const apiUrl = API_CONFIG.defaultApiUrl +``` + +## 配置分类 + +### 1. API 配置 (`API_CONFIG`) + +```typescript +API_CONFIG.defaultApiUrl // 默认搜索 API +API_CONFIG.vndbApiUrl // VNDB API +API_CONFIG.translateApiUrl // AI 翻译 API +API_CONFIG.statusApiUrl // 状态检查 API +API_CONFIG.randomImageApi // 随机背景图片 API +``` + +### 2. 应用配置 (`APP_CONFIG`) + +```typescript +APP_CONFIG.name // 应用名称 +APP_CONFIG.title // 应用标题 +APP_CONFIG.description // 应用描述 +APP_CONFIG.url // 网站 URL +``` + +### 3. 功能开关 (`FEATURE_FLAGS`) + +```typescript +FEATURE_FLAGS.enablePwa // PWA 支持 +FEATURE_FLAGS.enableSw // Service Worker +FEATURE_FLAGS.enableComments // 评论系统 +FEATURE_FLAGS.enableVndb // VNDB 集成 +FEATURE_FLAGS.enableTranslate // AI 翻译 +FEATURE_FLAGS.enableHistory // 搜索历史 +FEATURE_FLAGS.enableCache // 缓存系统 +FEATURE_FLAGS.enablePerformance // 性能监控 +FEATURE_FLAGS.enableDevLogs // 开发日志 +``` + +### 4. 搜索配置 (`SEARCH_CONFIG`) + +```typescript +SEARCH_CONFIG.defaultMode // 默认搜索模式 +SEARCH_CONFIG.cooldown // 搜索冷却时间(毫秒) +SEARCH_CONFIG.defaultResultsPerPage // 默认显示结果数 +SEARCH_CONFIG.loadMoreCount // 每次加载更多的数量 +SEARCH_CONFIG.maxHistoryItems // 最大历史记录数 +``` + +### 5. 缓存配置 (`CACHE_CONFIG`) + +```typescript +CACHE_CONFIG.vndbCacheDuration // VNDB 缓存时长(毫秒) +CACHE_CONFIG.searchCacheDuration // 搜索结果缓存时长(毫秒) +CACHE_CONFIG.imageCacheDuration // 图片缓存时长(毫秒) +CACHE_CONFIG.maxCacheSize // 最大缓存数量 +``` + +### 6. UI 配置 (`UI_CONFIG`) + +```typescript +UI_CONFIG.themePrimary // 主题主色调 +UI_CONFIG.themeAccent // 主题强调色 +UI_CONFIG.toastDuration // Toast 通知默认时长(毫秒) +UI_CONFIG.scrollOffset // 滚动偏移量(像素) +UI_CONFIG.scrollTopThreshold // 回到顶部按钮显示阈值(像素) +``` + +### 7. 第三方服务 (`THIRD_PARTY_CONFIG`) + +```typescript +THIRD_PARTY_CONFIG.artalkServer // Artalk 服务器地址 +THIRD_PARTY_CONFIG.artalkSite // Artalk 站点名称 +THIRD_PARTY_CONFIG.busuanziEnabled // 不蒜子统计 +``` + +### 8. 性能配置 (`PERFORMANCE_CONFIG`) + +```typescript +PERFORMANCE_CONFIG.quicklinkDelay // Quicklink 预加载延迟(毫秒) +PERFORMANCE_CONFIG.quicklinkLimit // Quicklink 预加载限制 +PERFORMANCE_CONFIG.statusCheckInterval // 状态检查间隔(毫秒) +PERFORMANCE_CONFIG.statusCheckTimeout // 状态检查超时(毫秒) +``` + +### 9. 开发配置 (`DEV_CONFIG`) + +```typescript +DEV_CONFIG.port // 开发服务器端口 +DEV_CONFIG.hmr // 热更新 +DEV_CONFIG.sourcemap // Source Map +DEV_CONFIG.isDev // 是否开发环境 +DEV_CONFIG.isProd // 是否生产环境 +DEV_CONFIG.mode // 运行模式 +``` + +## 实际使用示例 + +### 示例 1:在 Store 中使用 + +```typescript +// src/stores/cache.ts +import { CACHE_CONFIG } from '@/config' + +export const useCacheStore = defineStore('cache', () => { + const vndbCacheDuration = ref(CACHE_CONFIG.vndbCacheDuration) + const searchCacheDuration = ref(CACHE_CONFIG.searchCacheDuration) + const maxCacheSize = ref(CACHE_CONFIG.maxCacheSize) + + // ... +}) +``` + +### 示例 2:在组件中使用 + +```vue + +``` + +### 示例 3:在 API 调用中使用 + +```typescript +// src/api/search.ts +import { API_CONFIG } from '@/config' + +export async function searchGame(query: string) { + const response = await fetch(`${API_CONFIG.defaultApiUrl}/search`, { + method: 'POST', + body: JSON.stringify({ query }), + }) + return response.json() +} +``` + +### 示例 4:条件渲染 + +```vue + + + +``` + +## 环境区分 + +Vite 支持多环境配置: + +- `.env` - 所有环境加载 +- `.env.local` - 所有环境加载,但会被 git 忽略 +- `.env.development` - 开发环境 +- `.env.production` - 生产环境 + +优先级:`.env.[mode].local` > `.env.[mode]` > `.env.local` > `.env` + +## 注意事项 + +1. **环境变量必须以 `VITE_` 开头**才能在客户端代码中访问 +2. **修改 .env 后需要重启开发服务器** +3. **不要在 .env 中存储敏感信息**(如密钥、密码) +4. **使用配置对象而不是直接访问环境变量**,获得更好的类型支持 +5. **生产环境的配置**应该通过构建工具或部署平台设置 + +## 类型安全 + +所有配置都有完整的 TypeScript 类型支持: + +```typescript +import type { AppConfig } from '@/config' + +// 获取完整配置的类型 +const config: AppConfig = CONFIG + +// 自动补全和类型检查 +config.api.defaultApiUrl // ✅ 类型安全 +config.api.invalidKey // ❌ 编译错误 +``` + +## 调试 + +开发环境下,配置会自动打印到控制台: + +```javascript +// 打开浏览器控制台查看 +📦 Application Config: { + api: {...}, + app: {...}, + features: {...}, + ... +} +``` + +可以通过 `VITE_ENABLE_DEV_LOGS=false` 关闭此功能。 + diff --git a/docs/ENV_GUIDE.md b/docs/ENV_GUIDE.md new file mode 100644 index 0000000..0681c80 --- /dev/null +++ b/docs/ENV_GUIDE.md @@ -0,0 +1,218 @@ +# 环境变量配置指南 + +SearchGal Frontend 使用环境变量来管理各种配置项,实现开发和生产环境的分离。 + +## 文件说明 + +- `.env` - 所有环境的默认配置 +- `.env.development` - 开发环境特定配置 +- `.env.production` - 生产环境特定配置 +- `.env.example` - 配置模板文件(供参考) + +## 快速开始 + +1. 复制示例文件: +```bash +cp .env.example .env +``` + +2. 根据需要修改 `.env` 文件中的配置 + +3. 启动开发服务器: +```bash +pnpm dev +``` + +## 配置项说明 + +### 应用信息 + +| 变量名 | 说明 | 默认值 | +|--------|------|--------| +| `VITE_APP_TITLE` | 应用标题 | SearchGal - Galgame 聚合搜索 | +| `VITE_APP_DESCRIPTION` | 应用描述 | 多平台 Galgame 资源聚合搜索引擎 | +| `VITE_APP_VERSION` | 应用版本 | 1.0.0 | + +### API 配置 + +| 变量名 | 说明 | 默认值 | +|--------|------|--------| +| `VITE_API_BASE_URL` | 搜索 API 地址 | https://cfapi.searchgal.homes | +| `VITE_API_TIMEOUT` | API 超时时间(毫秒) | 30000 | +| `VITE_TRANSLATE_API_URL` | 翻译 API 地址 | https://translate.searchgal.homes | +| `VITE_VNDB_API_URL` | VNDB API 地址 | https://api.vndb.org/kana/v1 | + +### 外部服务 + +| 变量名 | 说明 | 默认值 | +|--------|------|--------| +| `VITE_STATUS_URL` | 状态检查 URL | https://status.searchgal.homes | +| `VITE_ARTALK_SERVER` | Artalk 评论服务器 | https://artalk.saop.cc | +| `VITE_IMAGE_API_URL` | 随机图片 API | https://api.illlights.com/v1/img | + +### 网站信息 + +| 变量名 | 说明 | 默认值 | +|--------|------|--------| +| `VITE_SITE_URL` | 网站 URL | https://searchgal.homes | +| `VITE_SITE_NAME` | 网站名称 | SearchGal | +| `VITE_GITHUB_URL` | GitHub 仓库 | https://github.com/Moe-Sakura/frontend | + +### 功能开关 + +| 变量名 | 说明 | 默认值 | +|--------|------|--------| +| `VITE_ENABLE_COMMENTS` | 启用评论功能 | true | +| `VITE_ENABLE_VNDB` | 启用 VNDB 集成 | true | +| `VITE_ENABLE_AI_TRANSLATE` | 启用 AI 翻译 | true | +| `VITE_ENABLE_PWA` | 启用 PWA 功能 | true | +| `VITE_ENABLE_ANALYTICS` | 启用统计分析 | false | + +### 搜索配置 + +| 变量名 | 说明 | 默认值 | +|--------|------|--------| +| `VITE_SEARCH_COOLDOWN` | 搜索冷却时间(毫秒) | 30000 | +| `VITE_DEFAULT_RESULTS_PER_PAGE` | 默认每页结果数 | 10 | +| `VITE_LOAD_MORE_COUNT` | 加载更多数量 | 20 | +| `VITE_MAX_SEARCH_HISTORY` | 最大历史记录数 | 50 | + +### 缓存配置 + +| 变量名 | 说明 | 默认值 | +|--------|------|--------| +| `VITE_CACHE_VNDB_DURATION` | VNDB 缓存时长(毫秒) | 1800000 (30分钟) | +| `VITE_CACHE_SEARCH_DURATION` | 搜索缓存时长(毫秒) | 600000 (10分钟) | +| `VITE_CACHE_IMAGE_DURATION` | 图片缓存时长(毫秒) | 3600000 (60分钟) | +| `VITE_MAX_CACHE_SIZE` | 最大缓存项数 | 100 | + +### 主题配置 + +| 变量名 | 说明 | 默认值 | +|--------|------|--------| +| `VITE_THEME_PRIMARY` | 主色调 | #ff1493 | +| `VITE_THEME_ACCENT` | 强调色 | #d946ef | +| `VITE_THEME_BACKGROUND_LIGHT` | 浅色背景 | #fff5fa | +| `VITE_THEME_BACKGROUND_DARK` | 深色背景 | #1e293b | + +### 性能配置 + +| 变量名 | 说明 | 默认值 | +|--------|------|--------| +| `VITE_QUICKLINK_DELAY` | Quicklink 延迟(毫秒) | 500 | +| `VITE_QUICKLINK_LIMIT` | Quicklink 限制数 | 10 | +| `VITE_LAZY_LOAD_THRESHOLD` | 懒加载阈值 | 0.5 | + +### 开发配置 + +| 变量名 | 说明 | 默认值 | +|--------|------|--------| +| `VITE_ENABLE_DEBUG` | 启用调试模式 | false | +| `VITE_ENABLE_MOCK` | 启用 Mock 数据 | false | + +## 使用方法 + +### 1. 在代码中使用配置 + +```typescript +import { config } from '@/config' + +// 使用 API 地址 +const apiUrl = config.api.baseUrl + +// 检查功能开关 +if (config.features.comments) { + // 启用评论功能 +} + +// 使用搜索配置 +const cooldown = config.search.cooldown +``` + +### 2. 使用工具函数 + +```typescript +import { devLog, devWarn, devError, isDev, isProd } from '@/config' + +// 开发环境日志(只在 VITE_ENABLE_DEBUG=true 时显示) +devLog('Debug message') +devWarn('Warning message') +devError('Error message') + +// 环境判断 +if (isDev) { + console.log('Running in development mode') +} + +if (isProd) { + console.log('Running in production mode') +} +``` + +### 3. 直接访问环境变量 + +```typescript +// 不推荐:直接访问(无类型安全) +const apiUrl = import.meta.env.VITE_API_BASE_URL + +// 推荐:通过 config 对象访问(有类型安全) +const apiUrl = config.api.baseUrl +``` + +## 环境变量优先级 + +Vite 环境变量加载优先级(从高到低): + +1. `.env.[mode].local` (如 `.env.development.local`) +2. `.env.[mode]` (如 `.env.development`) +3. `.env.local` +4. `.env` + +**注意**:`.local` 文件会被 `.gitignore` 忽略,不会提交到仓库。 + +## 本地开发配置 + +如果需要本地特定配置,创建 `.env.local` 文件: + +```bash +# .env.local (不会被提交到 Git) +VITE_API_BASE_URL=http://localhost:8787 +VITE_ENABLE_DEBUG=true +``` + +## 生产环境配置 + +在 CI/CD 或服务器上设置环境变量,或使用 `.env.production` 文件。 + +## 注意事项 + +1. **只有 `VITE_` 前缀的变量会被暴露到客户端代码** +2. **不要在环境变量中存储敏感信息**(如密钥、密码) +3. **修改环境变量后需要重启开发服务器** +4. **`.env.local` 文件不会被提交到仓库** + +## 故障排查 + +### 环境变量没有生效 + +1. 检查变量名是否以 `VITE_` 开头 +2. 重启开发服务器 (`pnpm dev`) +3. 检查 `.env` 文件语法是否正确 +4. 使用 `console.log(config)` 查看加载的配置 + +### 类型错误 + +确保 `src/vite-env.d.ts` 文件存在并包含正确的类型定义。 + +## 相关文件 + +- `src/config/index.ts` - 配置工具类 +- `src/vite-env.d.ts` - TypeScript 类型定义 +- `.env` - 默认配置文件 +- `.env.example` - 配置模板 + +## 更多信息 + +- [Vite 环境变量文档](https://vitejs.dev/guide/env-and-mode.html) +- [SearchGal 项目文档](./README.md) + diff --git a/docs/ENV_USAGE_EXAMPLES.md b/docs/ENV_USAGE_EXAMPLES.md new file mode 100644 index 0000000..b63d8a1 --- /dev/null +++ b/docs/ENV_USAGE_EXAMPLES.md @@ -0,0 +1,271 @@ +# 环境变量使用示例 + +## 迁移现有代码到使用环境变量 + +### 1. API 调用 + +**之前(硬编码):** +```typescript +const response = await fetch('https://cfapi.searchgal.homes/search') +``` + +**之后(使用配置):** +```typescript +import { config } from '@/config' + +const response = await fetch(`${config.api.baseUrl}/search`) +``` + +### 2. 搜索冷却时间 + +**之前:** +```typescript +const COOLDOWN_MS = 30 * 1000 +``` + +**之后:** +```typescript +import { config } from '@/config' + +const cooldown = config.search.cooldown +``` + +### 3. Store 初始化 + +**在 stores/cache.ts 中:** +```typescript +import { config } from '@/config' + +export const useCacheStore = defineStore('cache', () => { + const vndbCacheDuration = ref(config.cache.vndbDuration) + const searchCacheDuration = ref(config.cache.searchDuration) + const maxCacheSize = ref(config.cache.maxSize) + // ... +}) +``` + +**在 stores/history.ts 中:** +```typescript +import { config } from '@/config' + +export const useHistoryStore = defineStore('history', () => { + const maxHistoryItems = ref(config.search.maxSearchHistory) + // ... +}) +``` + +**在 stores/search.ts 中:** +```typescript +import { config } from '@/config' + +export const useSearchStore = defineStore('search', () => { + const searchDisabled = computed(() => { + const now = Date.now() + return isSearching.value || (now - lastSearchTime.value < config.search.cooldown) + }) + // ... +}) +``` + +### 4. Artalk 评论系统 + +**在 CommentsModal.vue 中:** +```typescript +import { config } from '@/config' + +function initArtalk() { + if (!config.features.comments) { + return // 如果评论功能被禁用,不初始化 + } + + artalkInstance = Artalk.init({ + el: '#Comments', + pageKey: config.site.url, + pageTitle: config.app.title, + server: config.services.artalkServer, + site: config.site.name, + darkMode: 'auto', + }) +} +``` + +### 5. Quicklink 配置 + +**在 main.ts 中:** +```typescript +import { listen } from 'quicklink' +import { config } from '@/config' + +window.addEventListener('load', () => { + listen({ + delay: config.performance.quicklinkDelay, + limit: config.performance.quicklinkLimit, + ignores: [/\/api\//, /artalk/], + }) +}) +``` + +### 6. 状态检查 + +**在 SearchHeader.vue 中:** +```typescript +import { config } from '@/config' + +async function checkStatus() { + try { + const controller = new window.AbortController() + const timeoutId = setTimeout(() => controller.abort(), 5000) + + await fetch(config.services.statusUrl, { + method: 'HEAD', + mode: 'no-cors', + signal: controller.signal, + }) + + clearTimeout(timeoutId) + statusOnline.value = true + } catch (_error) { + statusOnline.value = false + } +} +``` + +### 7. 随机背景图片 + +**在 App.vue 中:** +```typescript +import { config } from '@/config' + +async function loadRandomImage() { + try { + const timestamp = Date.now() + const imageUrl = `${config.services.imageApiUrl}?t=${timestamp}` + // ... + } catch (error) { + // ... + } +} +``` + +### 8. 调试日志 + +**使用工具函数:** +```typescript +import { devLog, devWarn, devError } from '@/config' + +// 这些日志只在开发环境且 VITE_ENABLE_DEBUG=true 时显示 +devLog('Fetching data from API...') +devWarn('API response is slow') +devError('API request failed') +``` + +### 9. 功能开关 + +**条件渲染:** +```vue + + + +``` + +### 10. 主题颜色 + +**使用环境变量定义的颜色:** +```typescript +import { config } from '@/config' + +// 动态设置 CSS 变量 +document.documentElement.style.setProperty('--theme-primary', config.theme.primary) +document.documentElement.style.setProperty('--theme-accent', config.theme.accent) +``` + +## 完整示例:API 工具类 + +```typescript +// src/utils/request.ts +import { config, devLog, devError } from '@/config' + +class ApiClient { + private baseUrl: string + private timeout: number + + constructor() { + this.baseUrl = config.api.baseUrl + this.timeout = config.api.timeout + } + + async request(endpoint: string, options: RequestInit = {}) { + const url = `${this.baseUrl}${endpoint}` + + devLog('API Request:', url, options) + + const controller = new AbortController() + const timeoutId = setTimeout(() => controller.abort(), this.timeout) + + try { + const response = await fetch(url, { + ...options, + signal: controller.signal, + }) + + clearTimeout(timeoutId) + + devLog('API Response:', response.status, response.statusText) + + return response + } catch (error) { + clearTimeout(timeoutId) + devError('API Error:', error) + throw error + } + } +} + +export const apiClient = new ApiClient() +``` + +## 环境特定逻辑 + +```typescript +import { isDev, isProd, config } from '@/config' + +// 开发环境特定逻辑 +if (isDev) { + // 启用 Vue DevTools + if (window.__VUE_DEVTOOLS_GLOBAL_HOOK__) { + window.__VUE_DEVTOOLS_GLOBAL_HOOK__.Vue = app + } +} + +// 生产环境特定逻辑 +if (isProd && config.features.analytics) { + // 初始化统计工具 + initAnalytics() +} + +// Mock 数据 +if (config.dev.mock) { + import('./mocks').then(({ setupMocks }) => { + setupMocks() + }) +} +``` + diff --git a/docs/PINIA_GUIDE.md b/docs/PINIA_GUIDE.md new file mode 100644 index 0000000..1ec873a --- /dev/null +++ b/docs/PINIA_GUIDE.md @@ -0,0 +1,276 @@ +# Pinia Store 使用指南 + +SearchGal 使用 Pinia 进行状态管理,已充分优化和模块化。 + +## Store 模块 + +### 1. Search Store (`useSearchStore`) +**用途**:管理搜索相关的状态和逻辑 + +```typescript +import { useSearchStore } from '@/stores' + +const searchStore = useSearchStore() + +// 状态 +searchStore.searchQuery // 搜索关键词 +searchStore.searchMode // 搜索模式 ('game' | 'patch') +searchStore.platformResults // 平台搜索结果 +searchStore.vndbInfo // VNDB 游戏信息 +searchStore.isSearching // 是否正在搜索 +searchStore.searchProgress // 搜索进度 + +// 计算属性 +searchStore.hasResults // 是否有搜索结果 +searchStore.isVndbMode // 是否为 VNDB 模式 +searchStore.searchDisabled // 是否禁用搜索(冷却时间) + +// 方法 +searchStore.setSearchQuery('关键词') +searchStore.setSearchMode('game') +searchStore.startSearch() +searchStore.endSearch() +searchStore.setPlatformResult('platform', data) +searchStore.loadMoreResults('platform', 20) +searchStore.clearResults() +``` + +### 2. UI Store (`useUIStore`) +**用途**:管理UI相关状态(主题、模态框、通知等) + +```typescript +import { useUIStore } from '@/stores' + +const uiStore = useUIStore() + +// 主题 +uiStore.isDarkMode +uiStore.toggleDarkMode() +uiStore.setDarkMode(true) + +// 模态框 +uiStore.isCommentsModalOpen +uiStore.isVndbPanelOpen +uiStore.isSettingsModalOpen +uiStore.toggleCommentsModal() +uiStore.closeAllModals() + +// Toast 通知 +uiStore.showToast('success', '操作成功!', 3000) +uiStore.showToast('error', '操作失败!') + +// 浮动按钮 +uiStore.showScrollToTop +uiStore.showPlatformNav +uiStore.togglePlatformNav() + +// 加载状态 +uiStore.setLoading(true, '加载中...') +uiStore.setLoading(false) +``` + +### 3. Settings Store (`useSettingsStore`) +**用途**:管理用户设置 + +```typescript +import { useSettingsStore } from '@/stores' + +const settingsStore = useSettingsStore() + +// 访问设置 +settingsStore.settings.customApi +settingsStore.settings.autoLoadMore +settingsStore.settings.resultsPerPage + +// 更新单个设置 +settingsStore.updateSetting('resultsPerPage', 20) + +// 批量更新 +settingsStore.updateSettings({ + customApi: 'https://api.example.com', + autoLoadMore: true, +}) + +// 重置设置 +settingsStore.resetSettings() + +// 导入导出 +const json = settingsStore.exportSettings() +settingsStore.importSettings(json) +``` + +### 4. History Store (`useHistoryStore`) +**用途**:管理搜索历史 + +```typescript +import { useHistoryStore } from '@/stores' + +const historyStore = useHistoryStore() + +// 访问历史 +historyStore.searchHistory // 所有历史 +historyStore.recentHistory // 最近10条 +historyStore.popularQueries // 热门查询 + +// 添加历史 +historyStore.addHistory({ + query: '关键词', + mode: 'game', + resultCount: 10, +}) + +// 删除历史 +historyStore.removeHistory(0) +historyStore.removeHistoryByQuery('关键词') +historyStore.clearHistory() + +// 搜索历史 +const results = historyStore.searchInHistory('关键词') + +// 统计信息 +const stats = historyStore.getHistoryStats() +``` + +### 5. Cache Store (`useCacheStore`) +**用途**:管理缓存数据 + +```typescript +import { useCacheStore } from '@/stores' + +const cacheStore = useCacheStore() + +// VNDB 缓存 +cacheStore.cacheVndbInfo('query', vndbData) +const cached = cacheStore.getVndbInfo('query') +const hasCache = cacheStore.hasVndbCache('query') + +// 搜索结果缓存 +cacheStore.cacheSearchResults('query', 'game', results) +const results = cacheStore.getSearchResults('query', 'game') + +// 清理缓存 +cacheStore.clearVndbCache() +cacheStore.clearSearchCache() +cacheStore.clearAllCache() +cacheStore.cleanExpiredCache() // 清理过期缓存 + +// 缓存统计 +const stats = cacheStore.getCacheStats() +``` + +## Store 插件 + +### 开发环境日志 +在开发环境自动记录所有 action 调用和状态变化 + +### 性能监控 +自动记录每个 action 的执行时间和调用次数 + +```typescript +// 获取性能统计 +const stats = searchStore.getPerformanceStats() +console.log(stats) +// { +// startSearch: { calls: 5, avgDuration: '12.50ms', totalDuration: '62.50ms' }, +// ... +// } +``` + +### 错误处理 +自动捕获和记录 store 中的错误 + +## 最佳实践 + +### 1. 组件中使用 Store +```vue + +``` + +### 2. Store 之间通信 +```typescript +// 在 searchStore 中使用 historyStore +const historyStore = useHistoryStore() +const cacheStore = useCacheStore() + +// 搜索完成后添加历史 +historyStore.addHistory({...}) + +// 使用缓存 +const cached = cacheStore.getVndbInfo(query) +if (cached) { + // 使用缓存数据 +} +``` + +### 3. 响应式更新 +```typescript +// ✅ 正确:使用 ref 或 computed +const searchQuery = computed(() => searchStore.searchQuery) + +// ❌ 错误:直接解构会失去响应性 +const { searchQuery } = searchStore + +// ✅ 正确:使用 storeToRefs +import { storeToRefs } from 'pinia' +const { searchQuery } = storeToRefs(searchStore) +``` + +### 4. 性能优化 +```typescript +// 使用缓存避免重复请求 +function searchGame(query: string) { + // 检查缓存 + const cached = cacheStore.getSearchResults(query, 'game') + if (cached) { + searchStore.setPlatformResult('platform', cached) + return + } + + // 执行搜索并缓存结果 + // ... +} +``` + +## 调试技巧 + +### 1. Vue DevTools +安装 Vue DevTools 扩展,可以实时查看所有 store 的状态 + +### 2. 控制台日志 +开发环境会自动记录所有 action 和状态变化 + +### 3. 性能分析 +```javascript +// 在控制台查看性能统计 +console.log(useSearchStore().getPerformanceStats()) +console.log(useCacheStore().getCacheStats()) +console.log(useHistoryStore().getHistoryStats()) +``` + +### 4. 手动清理 +```javascript +// 清除所有缓存 +useCacheStore().clearAllCache() + +// 清除历史记录 +useHistoryStore().clearHistory() + +// 重置设置 +useSettingsStore().resetSettings() +``` + diff --git a/env.d.ts b/env.d.ts index 6800fc0..af85660 100644 --- a/env.d.ts +++ b/env.d.ts @@ -20,3 +20,71 @@ interface Window { } } } + +// 环境变量类型定义 +interface ImportMetaEnv { + // API 配置 + readonly VITE_DEFAULT_API_URL: string + readonly VITE_VNDB_API_URL: string + readonly VITE_TRANSLATE_API_URL: string + readonly VITE_STATUS_API_URL: string + readonly VITE_RANDOM_IMAGE_API: string + + // 应用配置 + readonly VITE_APP_NAME: string + readonly VITE_APP_TITLE: string + readonly VITE_APP_DESCRIPTION: string + readonly VITE_APP_URL: string + + // 功能开关 + readonly VITE_ENABLE_PWA: string + readonly VITE_ENABLE_SW: string + readonly VITE_ENABLE_COMMENTS: string + readonly VITE_ENABLE_VNDB: string + readonly VITE_ENABLE_TRANSLATE: string + readonly VITE_ENABLE_HISTORY: string + readonly VITE_ENABLE_CACHE: string + readonly VITE_ENABLE_PERFORMANCE: string + readonly VITE_ENABLE_DEV_LOGS: string + + // 搜索配置 + readonly VITE_DEFAULT_SEARCH_MODE: string + readonly VITE_SEARCH_COOLDOWN: string + readonly VITE_DEFAULT_RESULTS_PER_PAGE: string + readonly VITE_LOAD_MORE_COUNT: string + readonly VITE_MAX_HISTORY_ITEMS: string + + // 缓存配置 + readonly VITE_VNDB_CACHE_DURATION: string + readonly VITE_SEARCH_CACHE_DURATION: string + readonly VITE_IMAGE_CACHE_DURATION: string + readonly VITE_MAX_CACHE_SIZE: string + + // UI 配置 + readonly VITE_THEME_PRIMARY: string + readonly VITE_THEME_ACCENT: string + readonly VITE_TOAST_DURATION: string + readonly VITE_SCROLL_OFFSET: string + readonly VITE_SCROLL_TOP_THRESHOLD: string + + // 第三方服务 + readonly VITE_ARTALK_SERVER: string + readonly VITE_ARTALK_SITE: string + readonly VITE_BUSUANZI_ENABLED: string + + // 性能配置 + readonly VITE_QUICKLINK_DELAY: string + readonly VITE_QUICKLINK_LIMIT: string + readonly VITE_STATUS_CHECK_INTERVAL: string + readonly VITE_STATUS_CHECK_TIMEOUT: string + + // 开发配置 + readonly VITE_DEV_PORT: string + readonly VITE_HMR: string + readonly VITE_SOURCEMAP: string +} + +interface ImportMeta { + readonly env: ImportMetaEnv +} + diff --git a/index.html b/index.html index 44f273e..32700b8 100644 --- a/index.html +++ b/index.html @@ -50,6 +50,22 @@ + + + + + + + + + + + + + + + + diff --git a/package.json b/package.json index f3fb5a1..03a9521 100644 --- a/package.json +++ b/package.json @@ -27,11 +27,12 @@ }, "dependencies": { "@fancyapps/ui": "^6.1.5", - "@fortawesome/fontawesome-free": "^7.1.0", "artalk": "^2.9.1", + "lazysizes": "^5.3.2", "lucide-vue-next": "^0.555.0", "pace-js": "^1.2.4", "pinia": "^3.0.4", + "quicklink": "^3.0.1", "vue": "^3.5.24" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c03f507..23a1252 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,12 +11,12 @@ importers: '@fancyapps/ui': specifier: ^6.1.5 version: 6.1.5 - '@fortawesome/fontawesome-free': - specifier: ^7.1.0 - version: 7.1.0 artalk: specifier: ^2.9.1 version: 2.9.1(marked@14.1.4) + lazysizes: + specifier: ^5.3.2 + version: 5.3.2 lucide-vue-next: specifier: ^0.555.0 version: 0.555.0(vue@3.5.24(typescript@5.9.3)) @@ -26,6 +26,9 @@ importers: pinia: specifier: ^3.0.4 version: 3.0.4(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3)) + quicklink: + specifier: ^3.0.1 + version: 3.0.1 vue: specifier: ^3.5.24 version: 3.5.24(typescript@5.9.3) @@ -286,10 +289,6 @@ packages: '@fancyapps/ui@6.1.5': resolution: {integrity: sha512-uFNm+rlrVMD8vqnthVC0l9ME+V8HRUma5LLpkR/2DACUNKSpE8qppcns0ZITcODdUmV/dGxPHTnymihohp2/Og==} - '@fortawesome/fontawesome-free@7.1.0': - resolution: {integrity: sha512-+WxNld5ZCJHvPQCr/GnzCTVREyStrAJjisUPtUxG5ngDA8TMlPnKp6dddlTpai4+1GNmltAeuk1hJEkBohwZYA==} - engines: {node: '>=6'} - '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -978,6 +977,9 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + lazysizes@5.3.2: + resolution: {integrity: sha512-22UzWP+Vedi/sMeOr8O7FWimRVtiNJV2HCa+V8+peZOw6QbswN9k58VUhd7i6iK5bw5QkYrF01LJbeJe0PV8jg==} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -1179,6 +1181,21 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + quicklink@3.0.1: + resolution: {integrity: sha512-sAMEpcCUCzjet214qVCm1hzxeF0YLo4wyphkIifeemmofk1vMrc5Sg/iNH32SKAIXqYvO6SPZgEP8obi9Ait9g==} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + react-dom: ^16.8.0 || ^17 || ^18 || ^19 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + regexparam@1.3.0: + resolution: {integrity: sha512-6IQpFBv6e5vz1QAqI+V4k8P2e/3gRrqfCJ9FI+O1FLQTO+Uz6RXZEZOPmTJ6hlGj7gkERzY5BRCv09whKP96/g==} + engines: {node: '>=6'} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -1195,6 +1212,10 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + route-manifest@1.0.0: + resolution: {integrity: sha512-qn0xJr4nnF4caj0erOLLAHYiNyzqhzpUbgDQcEHrmBoG4sWCDLnIXLH7VccNSxe9cWgbP2Kw/OjME+eH3CeRSA==} + engines: {node: '>= 6'} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -1250,6 +1271,10 @@ packages: engines: {node: '>=10'} hasBin: true + throttles@1.0.1: + resolution: {integrity: sha512-fab7Xg+zELr9KOv4fkaBoe/b3L0GMGLd0IBSCn16GoE/Qx6/OfCr1eGNyEcDU2pUA79qQfZ8kPQWlRuok4YwTw==} + engines: {node: '>=6'} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} @@ -1510,8 +1535,6 @@ snapshots: '@fancyapps/ui@6.1.5': {} - '@fortawesome/fontawesome-free@7.1.0': {} - '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.7': @@ -2209,6 +2232,8 @@ snapshots: dependencies: json-buffer: 3.0.1 + lazysizes@5.3.2: {} + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -2369,6 +2394,13 @@ snapshots: queue-microtask@1.2.3: {} + quicklink@3.0.1: + dependencies: + route-manifest: 1.0.0 + throttles: 1.0.1 + + regexparam@1.3.0: {} + resolve-from@4.0.0: {} reusify@1.1.0: {} @@ -2403,6 +2435,10 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.53.2 fsevents: 2.3.3 + route-manifest@1.0.0: + dependencies: + regexparam: 1.3.0 + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -2450,6 +2486,8 @@ snapshots: source-map-support: 0.5.21 optional: true + throttles@1.0.1: {} + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) diff --git a/public/browserconfig.xml b/public/browserconfig.xml new file mode 100644 index 0000000..5e5f277 --- /dev/null +++ b/public/browserconfig.xml @@ -0,0 +1,11 @@ + + + + + + + #ff1493 + + + + diff --git a/public/feed.xml b/public/feed.xml new file mode 100644 index 0000000..29910aa --- /dev/null +++ b/public/feed.xml @@ -0,0 +1,69 @@ + + + + SearchGal - Galgame 聚合搜索 + https://searchgal.homes + 多平台 Galgame 资源聚合搜索引擎,提供实时流式搜索、游戏信息展示和 AI 翻译功能 + zh-CN + 2025-01-27T00:00:00Z + + SearchGal Frontend + + https://searchgal.homes/favicon.svg + SearchGal + https://searchgal.homes + + + + SearchGal 正式上线 + https://searchgal.homes + SearchGal 正式上线!提供多平台 Galgame 资源聚合搜索,支持实时流式响应、VNDB 游戏信息展示、AI 智能翻译等功能。采用 Vue 3 + TypeScript + Tailwind CSS 构建,提供艳粉色主题和液态玻璃拟态效果的现代化界面。 + 2025-01-27T00:00:00Z + https://searchgal.homes + 公告 + Galgame + 搜索引擎 + + + + 功能更新:Lucide Icons 图标库 + https://searchgal.homes + 完成从 Font Awesome 到 Lucide Icons 的全面迁移,所有组件图标已更新为 SVG 组件,支持动态尺寸和更好的性能优化。 + 2025-01-27T00:00:00Z + https://searchgal.homes/updates/lucide-icons + 更新 + 技术 + + + + 新增:LLMs.txt 支持 + https://searchgal.homes/llms.txt + 为 AI 助手和大语言模型添加了 llms.txt 文件,提供结构化的项目文档,方便开发者和 AI 工具快速了解项目架构。 + 2025-01-27T00:00:00Z + https://searchgal.homes/updates/llms-txt + 更新 + AI + + + + 性能优化:Lazysizes + Quicklink + https://searchgal.homes + 集成 Lazysizes 高性能图片懒加载库和 Quicklink 智能预加载功能,大幅提升页面加载速度和用户体验。 + 2025-01-27T00:00:00Z + https://searchgal.homes/updates/performance + 更新 + 性能 + + + + PWA 支持 + https://searchgal.homes/manifest.json + 添加 PWA (Progressive Web App) 支持,用户可以将 SearchGal 安装到设备主屏幕,享受类原生应用体验。 + 2025-01-27T00:00:00Z + https://searchgal.homes/updates/pwa + 更新 + PWA + + + + diff --git a/public/gamepad-solid.svg b/public/gamepad-solid.svg deleted file mode 100644 index 932964d..0000000 --- a/public/gamepad-solid.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/llms.txt b/public/llms.txt new file mode 100644 index 0000000..d9eb83d --- /dev/null +++ b/public/llms.txt @@ -0,0 +1,61 @@ +# SearchGal Frontend + +> Galgame 聚合搜索前端 - 基于 Vue 3 + TypeScript + Tailwind CSS 构建的现代化 Web 应用,提供多平台 Galgame 资源聚合搜索、实时流式响应、游戏信息展示和 AI 翻译功能。 + +重要特性: + +- **流式搜索**:使用 Server-Sent Events (SSE) 实时推送多个平台的搜索结果 +- **状态管理**:Pinia 管理全局搜索状态和平台结果 +- **UI 设计**:艳粉色(#ff1493)主题 + 液态玻璃拟态效果(glassmorphism) +- **图标系统**:使用 Lucide Icons 替代 Font Awesome,支持动态组件渲染 +- **响应式布局**:Tailwind CSS 实现移动端和桌面端适配 +- **性能优化**:Lazysizes 懒加载、Quicklink 智能预加载 +- **PWA 支持**:可安装为桌面/移动应用,支持离线访问 +- **外部集成**:VNDB 游戏数据库、Artalk 评论系统、AI 翻译服务 + +## 核心文档 + +- [README](https://github.com/Moe-Sakura/frontend/blob/main/README.md): 项目概述、技术栈、安装和开发指南 +- [响应式设计](https://github.com/Moe-Sakura/frontend/blob/main/docs/RESPONSIVE_DESIGN.md): 移动端适配和响应式设计规范 +- [主题系统](https://github.com/Moe-Sakura/frontend/blob/main/docs/THEME_SYSTEM.md): 艳粉色配色方案和液态玻璃效果实现 +- [贡献指南](https://github.com/Moe-Sakura/frontend/blob/main/docs/CONTRIBUTING.md): 如何参与项目开发 + +## 关键组件 + +- [App.vue](https://github.com/Moe-Sakura/frontend/blob/main/src/App.vue): 应用根组件,管理暗色模式、自定义 CSS 和随机背景 +- [SearchHeader.vue](https://github.com/Moe-Sakura/frontend/blob/main/src/components/SearchHeader.vue): 搜索输入框、模式切换、状态检测和使用说明 +- [SearchResults.vue](https://github.com/Moe-Sakura/frontend/blob/main/src/components/SearchResults.vue): 搜索结果展示,支持"加载更多"功能 +- [VndbPanel.vue](https://github.com/Moe-Sakura/frontend/blob/main/src/components/VndbPanel.vue): VNDB 游戏信息面板,包含 AI 翻译功能 + +## API 和状态管理 + +- [search.ts (API)](https://github.com/Moe-Sakura/frontend/blob/main/src/api/search.ts): SSE 流式搜索、VNDB 数据获取、AI 翻译 API +- [search.ts (Store)](https://github.com/Moe-Sakura/frontend/blob/main/src/stores/search.ts): Pinia 状态管理,处理搜索状态、平台结果和分页 + +## 工具函数 + +- [imageDB.ts](https://github.com/Moe-Sakura/frontend/blob/main/src/utils/imageDB.ts): IndexedDB 图片缓存系统 +- [persistence.ts](https://github.com/Moe-Sakura/frontend/blob/main/src/utils/persistence.ts): LocalStorage 数据持久化(搜索历史、自定义设置) +- [theme.ts](https://github.com/Moe-Sakura/frontend/blob/main/src/utils/theme.ts): 主题管理和自定义 CSS 注入 +- [icons.ts](https://github.com/Moe-Sakura/frontend/blob/main/src/utils/icons.ts): Lucide Icons 集中管理 + +## 样式系统 + +- [theme.css](https://github.com/Moe-Sakura/frontend/blob/main/src/styles/theme.css): 艳粉色主题 CSS 变量和渐变类 +- [glassmorphism.css](https://github.com/Moe-Sakura/frontend/blob/main/src/styles/glassmorphism.css): 液态玻璃拟态效果样式 +- [tailwind.config.js](https://github.com/Moe-Sakura/frontend/blob/main/tailwind.config.js): Tailwind CSS 自定义配置 + +## Optional + +- [CHANGELOG](https://github.com/Moe-Sakura/frontend/blob/main/docs/CHANGELOG.md): 版本更新记录 +- [CODE_OF_CONDUCT](https://github.com/Moe-Sakura/frontend/blob/main/docs/CODE_OF_CONDUCT.md): 社区行为准则 +- [Favicon 指南](https://github.com/Moe-Sakura/frontend/blob/main/docs/FAVICON_GUIDE.md): 网站图标设计规范 +- [RSS Feed](https://searchgal.homes/feed.xml): RSS 订阅源 +- [PWA Manifest](https://searchgal.homes/manifest.json): PWA 配置文件 +- [Vue 3 文档](https://vuejs.org/guide/introduction.html): Vue 3 官方指南 +- [Tailwind CSS 文档](https://tailwindcss.com/docs): Tailwind CSS 官方文档 +- [Pinia 文档](https://pinia.vuejs.org/): Pinia 状态管理文档 +- [Lucide Icons](https://lucide.dev/icons/): Lucide 图标库参考 +- [Lazysizes](https://github.com/aFarkas/lazysizes): 高性能图片懒加载库 +- [Quicklink](https://getquick.link/): 智能预加载库 + diff --git a/public/manifest.json b/public/manifest.json new file mode 100644 index 0000000..253be51 --- /dev/null +++ b/public/manifest.json @@ -0,0 +1,83 @@ +{ + "name": "SearchGal - Galgame 聚合搜索", + "short_name": "SearchGal", + "description": "多平台 Galgame 资源聚合搜索引擎", + "start_url": "/", + "display": "standalone", + "background_color": "#fff5fa", + "theme_color": "#ff1493", + "orientation": "portrait-primary", + "scope": "/", + "lang": "zh-CN", + "dir": "ltr", + "icons": [ + { + "src": "/favicon.svg", + "sizes": "any", + "type": "image/svg+xml", + "purpose": "any maskable" + }, + { + "src": "/favicon-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/favicon-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any" + } + ], + "categories": ["entertainment", "games", "utilities"], + "screenshots": [ + { + "src": "/screenshot-desktop.png", + "sizes": "1920x1080", + "type": "image/png", + "form_factor": "wide" + }, + { + "src": "/screenshot-mobile.png", + "sizes": "750x1334", + "type": "image/png", + "form_factor": "narrow" + } + ], + "shortcuts": [ + { + "name": "游戏模式搜索", + "short_name": "游戏搜索", + "description": "快速搜索游戏资源", + "url": "/?mode=game", + "icons": [ + { + "src": "/favicon.svg", + "sizes": "any" + } + ] + }, + { + "name": "高级模式搜索", + "short_name": "高级搜索", + "description": "高级工具和资源搜索", + "url": "/?mode=advanced", + "icons": [ + { + "src": "/favicon.svg", + "sizes": "any" + } + ] + } + ], + "share_target": { + "action": "/", + "method": "GET", + "params": { + "title": "title", + "text": "text" + } + } +} + diff --git a/public/sw.js b/public/sw.js index 359a299..0f51ae6 100644 --- a/public/sw.js +++ b/public/sw.js @@ -1,8 +1,10 @@ -// 简单的 Service Worker - 只缓存静态资源 -const CACHE_NAME = 'searchgal-cache-v1'; +// Service Worker - PWA 支持 +const CACHE_NAME = 'searchgal-cache-v2'; const STATIC_CACHE = [ '/', '/index.html', + '/manifest.json', + '/favicon.svg', ]; // 安装事件 diff --git a/src/api/search.ts b/src/api/search.ts index 9dcd44e..cf259ff 100644 --- a/src/api/search.ts +++ b/src/api/search.ts @@ -72,7 +72,7 @@ export async function searchGameStream( onPlatformResult?: (data: PlatformResult) => void onComplete?: () => void onError?: (error: string) => void - } + }, ) { try { // 从 searchParams 中获取 API 地址,默认使用 Cloudflare Workers API diff --git a/src/components/CommentsModal.vue b/src/components/CommentsModal.vue index 5585478..c742ead 100644 --- a/src/components/CommentsModal.vue +++ b/src/components/CommentsModal.vue @@ -9,7 +9,7 @@ leave-to-class="opacity-0" >
@@ -23,7 +23,7 @@ leave-to-class="opacity-0 scale-95" >
@@ -51,11 +51,11 @@