diff --git a/CLAUDE.md b/CLAUDE.md index b7888a8..c5a07c5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,7 +13,7 @@ npx eslint . # 代码检查(@antfu/eslint-config,Vue 支持,无 TypeS ## 技术栈 -Vue 3 (Composition API) + Vite 7 + Pinia + Vue Router + Element Plus + `vue-element-plus-x`(多媒体编辑) + Less + pnpm +Vue 3 (Composition API) + Vite 7 + Pinia + Vue Router + Element Plus + `vue-element-plus-x`(提供 Sender 输入框组件) + Less + pnpm ## 架构概览 @@ -24,9 +24,16 @@ AI 绘画/视频生成前端操作平台,通过 HTTP 接口对接算力调度 ### 关键目录 ``` +├── model-configs/ # 运维参考:模型参数配置 JSON 文件(hailuo, ltx, vidu 等,位于项目根目录) +├── config/ +│ └── plugins.js # Vite 插件配置(unplugin-auto-import + unplugin-vue-components resolver) +├── vite.config.js # 构建配置:alias(@→src, ~→根目录)、envPrefix: ['VITE','FILE']、optimizeDeps src/ -├── main.js # 入口:创建 Vue 应用,安装 Pinia/Router/VueVirtualScroller +├── main.js # 入口:创建 Vue 应用,安装 Pinia/Router/vue-virtual-scroller ├── router/index.js # 路由定义 + token 验证守卫 +├── assets/ # 静态资源 +│ ├── dialog/ # 控件区域 SVG 图标(model, proportion, quantity, time, videoPattern 等) +│ └── display/ # 结果展示区 SVG 图标(download, collection, delete, back, brush 等) ├── platforms/ # 平台包(独立、可插拔) │ ├── registry.js # 注册表:registerPlatform(id, factory) + createPlatform(type) │ ├── painting/ # Painting 平台 @@ -64,16 +71,15 @@ src/ │ ├── virtual-scroller/ # 虚拟滚动列表(自定义实现)。reverse 模式用 180deg 旋转实现底部锚定,slot 内容须反旋转 │ └── canvas/ # 图片画布编辑(圆/矩形选区,局部重绘,undo/redo) ├── views/ # 页面(home、login) -├── model-configs/ # 运维参考:模型参数配置 JSON 文件(与 API 响应格式一致) └── utils/ ├── request.js # Axios 实例 + 拦截器:统一 Auth(不带 Bearer)+ 按前缀路由 baseURL - ├── taskPolling.js # 任务生成入口:组装参数 → POST 创建任务 → 20s HTTP 轮询直至完成/失败 + ├── taskPolling.js # 任务生成入口:组装参数 → POST 创建任务 → 首次 5s + 后续 20s HTTP 轮询直至完成/失败 ├── modelApi.js # 模型业务层:localStorage 缓存 + 并发去重。平台模型列表(30s TTL) + 模型参数配置(60s TTL) ├── modelConfigHelper.js # 模型配置共享工具:syncDefaults / syncParamValues / getDimConfig / checkShowWhen ├── downloadImage.js # 图片/视频下载:fetch → Blob → 自动文件名下载 ├── uploadImage.js # 图片上传工具 ├── tokenError.js # 认证失败处理:提示后 5 秒刷新页面 - ├── encrypt.ts # 加密工具(Base64/MD5/RSA/AES,依赖 crypto-js、jsencrypt) + ├── encrypt.ts # 加密工具(⚠️ 死代码:依赖 crypto-js/jsencrypt 未安装,无任何 import 引用) └── auth.ts # token 存取工具(localStorage) ``` @@ -247,8 +253,10 @@ Video 的 `getDefaultModel()` 返回 `''`,不硬编码 UUID;模型列表加 - **模型列表缓存**:`modelApi.js` 中 `fetchPlatformModels` 使用 localStorage 30 秒 TTL + `pendingRequests` Map 并发去重。 - **模型配置缓存**:`modelApi.js` 中 `getModelConfig` 使用 localStorage 60 秒 TTL + `pendingConfigRequests` Map 并发去重。`loadModels()` 会在获取模型列表后调用 `preloadModelConfigs` 批量预加载。 - **平台包预加载**:dialogBox 顶层 `import` Painting 和 Video 平台包,触发自注册,确保首次使用时 registry 已就绪。 +- **VirtualScroller 实现说明**:虽然 `package.json` 安装了 `vue-virtual-scroller`(npm 包)并在 `main.js` 中全局注册,但 `display/index.vue` 中 `` 实际使用的是 `src/components/virtual-scroller/VirtualScroller.vue` 自定义实现(通过 `unplugin-vue-components` 自动注册的同名组件遮蔽 npm 包)。`vue-virtual-scroller` npm 包当前为冗余依赖。 - **VirtualScroller 反旋转**:组件用外层 `transform: rotate(180deg)` 实现 reverse 底部锚定。所有作为 slot 插入的内容必须在根元素加 `transform: rotate(180deg)` 反旋转,否则文字/图片会颠倒显示。参考 `src/views/home/display/components/set.vue:2`。 - **VirtualScroller 存在独立测试页**:`src/components/virtual-scroller/test.html` + `test-data.js`,可用于验证虚拟滚动行为。 +- **VirtualScroller 残留备份文件**:`src/components/virtual-scroller/VirtualScroller copy.vue` 是备份副本,不应被引用或修改。 - **Element Plus `` 不响应 `autosize` 动态变化**:`ElInput` 只在 mount 时读取 `autosize`,prop 更新时不会重新计算高度。因此 `dialogBox` 中 `Sender` 必须绑定 `:key="useDisplay.Sender_variant"`,通过强制重挂载来使新的 `autosize`(`minRows`/`maxRows`)生效。 - **Video modelSelector pattern→modelType 映射**:`getModelType()` 在 `modelSelector.vue` 中将 pattern tag 映射为 modelType——"文生视频"→`text`,"首尾帧"→`image`,"数字人"→`digitalHuman`。该值用于 imageUploader 的 `showEndFrame` 判断和上传槽位数量。 - **Video `imageUploadLimit()` 累加逻辑**:对于有多个 `imageUpload` 参数的模型(如首尾帧模型的 `firstImageUrl` + `lastImageUrl`),应累加所有 `imageUpload` 参数的 `maxCount`,而非只取第一个。否则首尾帧模型只显示一个上传槽位,尾帧上传无法触发。 @@ -314,15 +322,17 @@ Video 的 `getDefaultModel()` 返回 `''`,不硬编码 UUID;模型列表加 ### 请求拦截器路由 -拦截器统一设置 `Authorization: `(不带 Bearer 前缀),根据 URL 前缀切换后端: +拦截器统一设置 `Authorization: `(不带 Bearer 前缀),根据请求 URL 前缀(由环境变量 `VITE_API_TASK_PREFIX` / `VITE_API_PAY_PREFIX` / `VITE_API_AIGC_PREFIX` 定义)切换后端: -| URL 前缀 | 环境变量 | -|----------|----------| -| `/suanli` | `VITE_API_TASK_TARGET` | -| `/pay` | `VITE_API_PAY_TARGET` | -| `/aigc` | `VITE_API_AIGC_TARGET` | +| URL 前缀(由环境变量定义) | 目标环境变量 | +|---------------------------|-------------| +| `VITE_API_TASK_PREFIX` 对应前缀 | `VITE_API_TASK_TARGET` | +| `VITE_API_PAY_PREFIX` 对应前缀 | `VITE_API_PAY_TARGET` | +| `VITE_API_AIGC_PREFIX` 对应前缀 | `VITE_API_AIGC_TARGET` | | 其他 | `VITE_API_BASE_URL`(默认) | +**注意**:前缀字符串本身来自环境变量(如 `VITE_API_TASK_PREFIX=/suanli`),不是硬编码。`request.js` 在初始化时读取这些变量,构建 prefix→target 映射表。 + ### 平台编码映射 | 类型 | 平台编码 |