docs: 更新 CLAUDE.md 反映后端化改造
- 删除 models/、createTask.js、modelConfig.js 引用 - 新增 modelConfigHelper.js 共享工具说明 - 更新数据流描述为 API 驱动 - 新增 number ui 类型和 showWhen 机制 - 新增模型配置缓存(60s TTL) - 删除过时的 displayNameMap 节 - 接口速查新增 config 相关 API
This commit is contained in:
parent
18e7dbc6ed
commit
b964c826ce
47
CLAUDE.md
47
CLAUDE.md
@ -33,8 +33,6 @@ src/
|
||||
│ │ ├── index.js # definePaintingPlatform():controls、state、loadConfig、buildTaskBody 等
|
||||
│ │ ├── modelSelector.vue # 模型选择器(按 API tags 分组)
|
||||
│ │ ├── imageUploader.vue # 图片上传组件
|
||||
│ │ ├── models/ # 模型参数 schema(本地 JS,待后端化)
|
||||
│ │ │ └── index.js # getModelConfig(modelName) → 查找 config
|
||||
│ │ └── controls/ # 平台专用控件
|
||||
│ │ ├── proportion.vue
|
||||
│ │ ├── dimension.vue
|
||||
@ -67,9 +65,8 @@ src/
|
||||
└── utils/
|
||||
├── request.js # Axios 实例 + 拦截器:统一 Auth(不带 Bearer)+ 按前缀路由 baseURL
|
||||
├── taskPolling.js # 任务生成入口:组装参数 → POST 创建任务 → 20s HTTP 轮询直至完成/失败
|
||||
├── modelApi.js # 模型业务层:localStorage 30s 缓存 + pendingRequests 并发去重 + 平台编码映射
|
||||
├── createTask.js # 透传层:return data.body(各平台 buildTaskBody() 已返回扁平 modelParams)
|
||||
├── modelConfig.js # Video 专用:从远程 JSON 加载 workflow 配置(含 localStorage 每日缓存)
|
||||
├── modelApi.js # 模型业务层:localStorage 缓存 + 并发去重。平台模型列表(30s TTL) + 模型参数配置(60s TTL)
|
||||
├── modelConfigHelper.js # 模型配置共享工具:syncDefaults / syncParamValues / getDimConfig / checkShowWhen
|
||||
├── downloadImage.js # 图片/视频下载:fetch → Blob → 自动文件名下载
|
||||
├── uploadImage.js # 图片上传工具
|
||||
├── tokenError.js # 认证失败处理:提示后 5 秒刷新页面
|
||||
@ -128,47 +125,54 @@ props: (config) => ({
|
||||
|
||||
- **平台切换**:`const platform = computed(() => createPlatform(props.type))`,切换时重置默认模型并加载模型列表
|
||||
- **控件渲染**:`visibleControls = platform.controls.filter(c => c.show(getCurrentConfig()))`,用 `<component :is>` + `v-bind="ctrl.props(...)"` 渲染
|
||||
- **配置获取**:`getCurrentConfig()` 返回 `platform.modelConfig?.value ?? platform.modelDisplayConfig?.value`,兼容两种配置来源
|
||||
- **配置获取**:`getCurrentConfig()` 返回 `platform.modelConfig?.value`
|
||||
- **模型切换**:`watch([model, modelType])` → `platform.loadConfig()` → `syncDefaults()` 将 schema 写入响应式 state → controls 的 `show()`/`props()` 读取 state → `visibleControls` 自动更新 → UI 重渲染
|
||||
- **任务发起**:`handleStart()` 调用 `platform.validateBeforeSubmit()` → `platform.buildTaskBody()` → `generate()`
|
||||
- **参数回填**:`fillParamsFromResult()` 委托给 `platform.fillFromResult()`
|
||||
|
||||
### 统一数据流(Painting + Video)
|
||||
|
||||
两个平台现已统一,`createTask.js` 是纯透传:
|
||||
两个平台现已统一,通过后端 API 获取模型参数配置:
|
||||
|
||||
1. 用户选择模型 → `platform.loadConfig(modelName, modelType)` 加载参数 schema
|
||||
1. 用户选择模型 → `platform.loadConfig(modelName, modelType)` → 调用 `GET /suanli/v1/models/:id/config`(优先 60s 缓存)加载参数 schema
|
||||
2. 参数 schema 驱动 `controls` 渲染 UI,用户填写参数
|
||||
3. 用户点击发送 → `handleStart()` → `platform.buildTaskBody({ prompt, referenceImages })` 返回扁平 `modelParams`
|
||||
4. `createTask(data)` 透传 `data.body`(不再做任何转换)
|
||||
5. `getModelId(type, modelName)` 查找 UUID → POST `/suanli/v1/tasks`(`X-Session-Id` header)
|
||||
6. 20s 间隔轮询直至完成/失败
|
||||
4. `taskPolling.js` 直接读取 `data.body` → `getModelId(type, modelName)` 查找 UUID → POST `/suanli/v1/tasks`(`X-Session-Id` header)
|
||||
5. 20s 间隔轮询直至完成/失败
|
||||
|
||||
### 模型参数配置
|
||||
|
||||
Painting 模型参数 schema 在 `src/platforms/painting/models/*.js` 中,参数通过 `ui` 字段映射到 UI 控件:
|
||||
模型参数配置通过后端 API `GET /suanli/v1/models/:id/config` 获取(60s localStorage 缓存),替代了旧的本地硬编码。参数通过 `ui` 字段映射到前端控件:
|
||||
|
||||
| `ui` 值 | 控件 | 说明 |
|
||||
|---------|------|------|
|
||||
| `textarea` | Sender 内置 textarea | prompt 输入框 |
|
||||
| `proportion` | `PaintingProportion` / `VideoProportion` | 比例选择 Popover(`options` 含 `custom` 时可自定义宽高) |
|
||||
| `resolution` | proportion 控件内部 | 分辨率子选项,与 proportion 共用 Popover |
|
||||
| `dimension` | `DimensionInput` | **组合模式**:单字段 `"W*H"` 格式,通过 `dimension.parse/format` 序列化 |
|
||||
| `dimensionWidth` + `dimensionHeight` | `DimensionInput` | **拆分模式**:两个独立字段,共享同一 Popover 和比例锁 |
|
||||
| `dimension` | `DimensionInput` | **组合模式**:单字段 `"W*H"` 格式,后端传 `dimension.separator`,前端生成 parse/format |
|
||||
| `dimensionWidth` + `dimensionHeight` | `DimensionInput` | **拆分模式**:两个独立字段(含 `min`/`max`),共享比例锁 |
|
||||
| `number` | proportion 控件内部 | 自定义宽高(如 Flux 的 customWidth/customHight),配合 `showWhen` 条件显示 |
|
||||
| `select` | `Select` | 通用下拉(如 quality) |
|
||||
| `quantity` | `Quantity` | 生成数量,上限由 `options` 最大值派生 |
|
||||
| `quantity` | `Quantity` | 生成数量,`options` 必须为数字数组,上限由 `Math.max()` 派生 |
|
||||
| `imageUpload` | `ImageUploader` | 参考图上传,`maxCount` 控制上限 |
|
||||
| `hidden` | 无 | 静默写入默认值 |
|
||||
|
||||
**dimension 模式区分**:通过 `getDimConfig()` 自动检测 `ui: 'dimension'`(组合)或 `ui: 'dimensionWidth'`(拆分),两种模式共用 `DimensionInput` 组件。
|
||||
**dimension 模式区分**:`getDimConfig()`(来自 `modelConfigHelper.js`)自动检测 `ui: 'dimension'`(组合)或 `ui: 'dimensionWidth'`(拆分),两种模式共用 `DimensionInput` 组件。
|
||||
|
||||
**条件显示**:`showWhen: { aspectRatio: 'custom' }` 使参数仅在 proportion 选 `custom` 时显示。
|
||||
**条件显示**:`showWhen: { aspectRatio: 'custom' }` 使参数仅在 proportion 选 `custom` 时显示。`checkShowWhen()` 在 controls 的 `show()` 回调中调用,因直接读取 reactive 的 `paramValues[key]`,computed 自动追踪依赖。
|
||||
|
||||
### `displayNameMap` 机制
|
||||
### modelConfigHelper 共享工具
|
||||
|
||||
`src/platforms/painting/models/index.js` 中 `displayNameMap` 负责将 API 返回的 `display_name` 映射到 config key。同一模型在不同 tag 下可能共用一个 `display_name`(如 `GPT-Image-2` 和 `GPT-image-2`),config key 采用内部中文名区分。
|
||||
`src/utils/modelConfigHelper.js` 提供 Painting/Video 双平台共用的 4 个纯函数:
|
||||
|
||||
**已知 bug**:`displayNameMap` 存在重复 key `'GPT-Image-2'`,第二条会覆盖第一条,导致文字生图版 GPT-Image-2 查找走 `displayNameMap` 时映射到 I2I 版。当前因 `model.value` 已是中文 config key 直达 `configs[]`,暂不触发。若后续改为按 `display_name` 查找,需修复此重复 key。
|
||||
| 函数 | 说明 |
|
||||
|------|------|
|
||||
| `syncDefaults(config, state)` | 将 API 返回的 config 同步到响应式 state。增强项:`dimension.separator` → parse/format 生成、`promptPlaceholder` 同步 |
|
||||
| `syncParamValues(config, state)` | 在 `buildTaskBody` 前将专用 ref 回写到 `paramValues` |
|
||||
| `getDimConfig(config)` | 检测 combined/split 模式 |
|
||||
| `checkShowWhen(param, paramValues)` | 检查 `showWhen` 条件 |
|
||||
|
||||
`state` 参数对象需包含 `modelConfig, paramValues, proportion, resolution, quantity, quality, customWidth, customHight, dimWidth, dimHeight, promptPlaceholder`。各平台通过包装函数(如 `syncDefaults(config) { _syncDefaults(config, paintingState) }`)适配。
|
||||
|
||||
### `$attrs` 穿透注意
|
||||
|
||||
@ -184,6 +188,7 @@ Painting 模型参数 schema 在 `src/platforms/painting/models/*.js` 中,参
|
||||
- **`sessionId`** 来自登录接口返回的 `userInfo.sessionId`,存储在 `useUserStore().userInfo` 中。`taskPolling.js` 必须使用该值,禁止随机生成。
|
||||
- **`X-Session-Id`** 自定义 header 需要 nginx 在 `/suanli/` location 的 `Access-Control-Allow-Headers` 中加入,否则 POST 请求会触发 CORS 预检失败。
|
||||
- **模型列表缓存**:`modelApi.js` 中 `fetchPlatformModels` 使用 localStorage 30 秒 TTL + `pendingRequests` Map 并发去重。
|
||||
- **模型配置缓存**:`modelApi.js` 中 `getModelConfig` 使用 localStorage 60 秒 TTL + `pendingConfigRequests` Map 并发去重。`loadModels()` 会在获取模型列表后调用 `preloadModelConfigs` 批量预加载。
|
||||
- **平台包预加载**:dialogBox 顶层 `import` Painting 和 Video 平台包,触发自注册,确保首次使用时 registry 已就绪。
|
||||
- **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`,可用于验证虚拟滚动行为。
|
||||
@ -225,6 +230,8 @@ Painting 模型参数 schema 在 `src/platforms/painting/models/*.js` 中,参
|
||||
| `requestTaskStatus` | GET `/suanli/v1/tasks/:id` | 查询单个任务状态 |
|
||||
| `requestTaskHistory` | GET `/suanli/v1/tasks/history` | 历史任务列表(支持 `user_id`/`platform_code`/`page`/`pageSize`) |
|
||||
| `fetchPlatformModels` | GET `/suanli/v1/platforms/:code/models` | 获取平台模型列表(返回 `{id, display_name, tags, disabled?}`) |
|
||||
| `requestModelConfigsBatch` | POST `/suanli/v1/models/configs` | 批量获取模型配置(body: `{ modelIds: [...] }`) |
|
||||
| `requestModelConfig` | GET `/suanli/v1/models/:id/config` | 单条模型配置(60s 缓存优先) |
|
||||
| `cancelOrCollect` | POST `/collect/toggle` | 收藏/取消收藏 |
|
||||
| `deleteGenerateHistory` | DELETE `/taskRecordHistory/delete` | 删除历史记录 |
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user