Files
SearcjGal-frontend/CLAUDE.md
AdingApkgg 6e170c579c feat: 移除 Quicklink 配置与相关依赖
* 从 `.env.example` 和 `env.d.ts` 中移除 `VITE_QUICKLINK_DELAY` 和 `VITE_QUICKLINK_LIMIT` 配置,简化性能设置。
* 更新 `README.md` 和相关文档,删除 Quicklink 相关的使用示例和说明。
* 在 `package.json` 中移除 `quicklink` 依赖,确保项目依赖的整洁性。
* 优化 `vite.config.ts` 和其他组件,调整性能配置以适应新的加载策略。
2025-12-21 10:45:56 +08:00

7.8 KiB

SearchGal Frontend - AI 项目上下文

本文件帮助 AI 助手理解和管理此项目。请在每次对话开始时参考此文件。

项目概述

SearchGal 是一个 Galgame 聚合搜索前端,使用现代 Web 技术构建。

  • 主题色: 艳粉色 #ff1493
  • 设计风格: 液态玻璃拟态 (Liquid Glass / Glassmorphism)
  • 目标用户: Galgame 玩家

技术栈

类别 技术 版本
框架 Vue 3 (Composition API) 3.5
语言 TypeScript 5.9
构建 Vite 7.2
状态管理 Pinia 3.0
样式 Tailwind CSS 4.1
动画 motion-v 1.7
图标 lucide-vue-next 0.561
音效 snd-lib 1.2
评论 Artalk 2.9
图片预览 @fancyapps/ui 6.1
代码编辑 vue-prism-editor + prismjs -

项目结构

src/
├── api/              # API 请求
│   └── search.ts     # SSE 流式搜索、VNDB、AI 翻译
├── components/       # Vue 组件
│   ├── SearchHeader.vue      # 搜索框 + 模式切换
│   ├── SearchResults.vue     # 搜索结果列表
│   ├── VndbPanel.vue         # VNDB 游戏信息面板
│   ├── SettingsModal.vue     # 设置面板
│   ├── CommentsModal.vue     # Artalk 评论
│   ├── SearchHistoryModal.vue # 搜索历史
│   ├── FloatingButtons.vue   # 浮动按钮 + 站点导航
│   ├── TopToolbar.vue        # 顶部工具栏
│   ├── StatsCorner.vue       # 统计角标
│   ├── UpdateToast.vue       # SW 更新提示
│   └── LiquidGlass.vue       # 液态玻璃组件
├── composables/      # 组合式函数
│   ├── useSound.ts           # snd-lib 音效封装
│   ├── useKeyboardShortcuts.ts # 全局快捷键
│   ├── usePerformance.ts     # 性能工具
│   ├── useProgress.ts        # 进度条
│   ├── useScrollLock.ts      # 滚动锁定
│   ├── useDebounce.ts        # 防抖
│   └── useClickEffect.ts     # 点击涟漪效果
├── stores/           # Pinia 状态管理
│   ├── search.ts     # 搜索状态
│   ├── ui.ts         # UI 状态 (模态框、暗色模式)
│   ├── settings.ts   # 用户设置
│   ├── history.ts    # 搜索历史
│   └── cache.ts      # 缓存管理
├── styles/           # 全局样式
│   ├── base.css      # 基础样式 + 性能工具类
│   ├── glassmorphism.css # 液态玻璃效果
│   ├── theme.css     # 主题变量
│   └── nprogress.css # 进度条样式
├── utils/            # 工具函数
│   ├── imageDB.ts    # IndexedDB 图片缓存
│   ├── persistence.ts # LocalStorage 持久化
│   ├── theme.ts      # 主题管理
│   ├── icons.ts      # 图标集中管理
│   └── urlParams.ts  # URL 参数处理
├── config/           # 配置
│   ├── index.ts      # 统一配置入口
│   └── env.ts        # 环境变量
├── App.vue           # 根组件
└── main.ts           # 入口文件

代码规范

Vue 组件

<script setup lang="ts">
// 1. 导入
import { ref, computed, watch, onMounted } from 'vue'
import { useSearchStore } from '@/stores/search'
import { playTap } from '@/composables/useSound'

// 2. Props & Emits
const props = defineProps<{ ... }>()
const emit = defineEmits<{ ... }>()

// 3. Stores
const searchStore = useSearchStore()

// 4. 响应式状态
const isLoading = ref(false)

// 5. 计算属性
const hasResults = computed(() => searchStore.results.length > 0)

// 6. 方法
function handleClick() {
  playTap()
  // ...
}

// 7. 生命周期
onMounted(() => { ... })
</script>

<template>
  <!-- 使用 Tailwind CSS  -->
</template>

<style scoped>
/* 组件特定样式 */
</style>

音效使用

import { playTap, playButton, playToggle, playSwipe, playNotification, playCelebration, playCaution, playTransitionUp, playTransitionDown, playType, playSelect } from '@/composables/useSound'

// 点击普通按钮
playTap()

// 重要按钮/功能按钮
playButton()

// 开关切换
playToggle()

// 滑动/刷新操作
playSwipe()

// 面板打开
playTransitionUp()

// 面板关闭
playTransitionDown()

// 成功操作
playCelebration()

// 警告/错误
playCaution()

// 通知
playNotification()

// 输入文字 (需节流 80ms)
playType()

// 选择列表项
playSelect()

液态玻璃效果

<!-- 使用 CSS 类 -->
<div class="liquid-glass">
  <div class="liquid-glass-effect"></div>
  <div class="liquid-glass-tint"></div>
  <div class="liquid-glass-content">
    <!-- 内容 -->
  </div>
</div>

<!-- 或使用伪元素方式 (推荐用于简单元素) -->
<button class="liquid-glass-btn">按钮</button>

动画

<script setup>
import { Motion, AnimatePresence } from 'motion-v'
</script>

<template>
  <!-- 淡入动画 -->
  <Motion
    :initial="{ opacity: 0, y: 20 }"
    :animate="{ opacity: 1, y: 0 }"
    :transition="{ duration: 0.3 }"
  >
    内容
  </Motion>

  <!-- 条件渲染动画 -->
  <AnimatePresence>
    <Motion
      v-if="visible"
      :initial="{ opacity: 0 }"
      :animate="{ opacity: 1 }"
      :exit="{ opacity: 0 }"
    >
      内容
    </Motion>
  </AnimatePresence>
</template>

常用操作

添加新组件

  1. src/components/ 创建 .vue 文件
  2. 使用 <script setup lang="ts"> 语法
  3. 导入必要的音效函数
  4. 使用 Tailwind CSS + 液态玻璃样式

添加新 Store

// src/stores/example.ts
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export const useExampleStore = defineStore('example', () => {
  // 状态
  const items = ref<string[]>([])
  
  // 计算属性
  const count = computed(() => items.value.length)
  
  // 方法
  function addItem(item: string) {
    items.value.push(item)
  }
  
  return { items, count, addItem }
})

添加模态框

  1. src/stores/ui.ts 添加状态
  2. 创建组件,使用 <Teleport to="body">
  3. 使用 playTransitionUp() / playTransitionDown() 音效
  4. 移动端全屏显示 (@media (max-width: 768px))

添加快捷键

编辑 src/composables/useKeyboardShortcuts.ts:

case 'x':
  if (!hasModifier) {
    e.preventDefault()
    playButton()
    // 执行操作
  }
  break

环境变量

主要配置在 .env 文件:

# API 端点
VITE_API_BASE_URL=https://api.example.com

# VNDB
VITE_VNDB_API_URL=https://api.vndb.org/kana

# Artalk 评论
VITE_ARTALK_SERVER=https://artalk.example.com
VITE_ARTALK_SITE=SearchGal

注意事项

  1. 不要使用 position: fixed 在有 transform 的父元素内 - 使用 <Teleport to="body">
  2. 打字音效需要节流 - 使用 80ms 间隔
  3. 模态框滚动锁定 - 使用 useScrollLock() composable
  4. 图片懒加载 - 使用原生 loading="lazy" 属性
  5. 暗色模式 - 使用 dark: Tailwind 前缀
  6. 移动端适配 - 使用 md: 断点 (768px)

常见问题

Q: 模态框位置异常?

A: 检查父元素是否有 transform,改用 <Teleport to="body">

Q: 动画不流畅?

A: 使用 CSS will-changetransform: translate3d(0,0,0) 启用 GPU 加速

Q: 音效不播放?

A: 确保导入了正确的音效函数,检查浏览器是否允许自动播放

Q: 样式被覆盖?

A: 使用 !important 或增加选择器特异性,检查 CSS 加载顺序

文件快速参考

需求 文件
搜索逻辑 src/stores/search.ts, src/api/search.ts
UI 状态 src/stores/ui.ts
音效 src/composables/useSound.ts
快捷键 src/composables/useKeyboardShortcuts.ts
液态玻璃 src/styles/glassmorphism.css
主题色 src/styles/theme.css
全局样式 src/styles/base.css
Vite 配置 vite.config.ts
入口文件 index.html, src/main.ts