# 扩展可视化倍率设置实施计划 > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **目标:** 在 ModelSettingsVisualEditor 组件中添加 5 个高级倍率字段支持(缓存、图片、音频倍率) **架构:** 扩展现有 React 组件的状态管理和表单逻辑,增加高级倍率字段的数据初始化、编辑、保存和验证功能 **技术栈:** React, Semi UI, i18n, JavaScript --- ## 文件结构 ### 修改文件 - `web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.jsx` - 主要功能实现(500+ 行) - `web/src/i18n/locales/zh-CN.json` - 中文翻译 - `web/src/i18n/locales/en.json` - 英文翻译 ### 参考文件(只读,用于理解实现模式) - `feat/channel-pricing-extended:web/src/pages/Setting/Ratio/ChannelPricingView.jsx` - 渠道价格设置的参考实现 ### 数据流向 ``` props.options (API 数据) ↓ useEffect 解析 JSON → models 状态(包含 5 个新字段) ↓ 用户编辑表单 → currentModel 状态 ↓ addOrUpdateModel → 更新 models 状态 ↓ SubmitData → 序列化 JSON → API.put('/api/option/') ``` --- ## Task 1: 添加国际化文本 **文件:** - Modify: `web/src/i18n/locales/zh-CN.json` - Modify: `web/src/i18n/locales/en.json` ### 步骤 1.1: 添加中文翻译 在 `web/src/i18n/locales/zh-CN.json` 中添加以下键值对。找到文件末尾,在最后一个键值对后添加逗号,然后添加: ```json "高级比例(留空使用默认值)": "高级比例(留空使用默认值)", "缓存读取倍率": "缓存读取倍率", "缓存创建倍率(5分钟)": "缓存创建倍率(5分钟)", "图片倍率": "图片倍率", "音频输入倍率": "音频输入倍率", "音频输出倍率": "音频输出倍率", "默认值:1.0": "默认值:1.0", "默认值:1.25": "默认值:1.25" ``` ### 步骤 1.2: 添加英文翻译 在 `web/src/i18n/locales/en.json` 中添加对应的英文翻译: ```json "高级比例(留空使用默认值)": "Advanced Ratios (Leave empty for defaults)", "缓存读取倍率": "Cache Read Ratio", "缓存创建倍率(5分钟)": "Cache Creation Ratio (5min)", "图片倍率": "Image Ratio", "音频输入倍率": "Audio Input Ratio", "音频输出倍率": "Audio Output Ratio", "默认值:1.0": "Default: 1.0", "默认值:1.25": "Default: 1.25" ``` ### 步骤 1.3: 验证 JSON 格式 确保添加的 JSON 格式正确,没有语法错误: ```bash cd web/src/i18n/locales node -e "console.log('zh-CN:', JSON.parse(require('fs').readFileSync('zh-CN.json', 'utf8'))); console.log('en:', JSON.parse(require('fs').readFileSync('en.json', 'utf8')))" ``` 预期输出:无错误,输出两个对象的内容 ### 步骤 1.4: 提交国际化更改 ```bash git add web/src/i18n/locales/zh-CN.json web/src/i18n/locales/en.json git commit -m "feat(i18n): add advanced ratio translations - Add Chinese translations for 5 advanced ratio fields - Add English translations for 5 advanced ratio fields Co-Authored-By: Claude Sonnet 4.6 " ``` --- ## Task 2: 扩展数据初始化逻辑 **文件:** - Modify: `web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.jsx:59-91` ### 步骤 2.1: 在 useEffect 中解析高级倍率 JSON 找到 `useEffect` 开始(约第 59 行),在 `try` 块中,在现有的 `const completionRatio = JSON.parse(props.options.CompletionRatio || '{}');` 之后添加: ```javascript // 新增:解析高级倍率字段 const cacheRatio = JSON.parse(props.options.CacheRatio || '{}'); const createCacheRatio = JSON.parse(props.options.CreateCacheRatio || '{}'); const imageRatio = JSON.parse(props.options.ImageRatio || '{}'); const audioRatio = JSON.parse(props.options.AudioRatio || '{}'); const audioCompletionRatio = JSON.parse(props.options.AudioCompletionRatio || '{}'); ``` ### 步骤 2.2: 扩展模型名称合并逻辑 在同一个 `useEffect` 中,找到 `const modelNames = new Set([...])`(约第 66 行),将数组扩展为: ```javascript const modelNames = new Set([ ...Object.keys(modelPrice), ...Object.keys(modelRatio), ...Object.keys(completionRatio), ...Object.keys(cacheRatio), ...Object.keys(createCacheRatio), ...Object.keys(imageRatio), ...Object.keys(audioRatio), ...Object.keys(audioCompletionRatio), ]); ``` ### 步骤 2.3: 扩展模型数据对象 在同一个 `useEffect` 中,找到 `const modelData = Array.from(modelNames).map((name) => {`(约第 72 行),在返回对象中添加新字段。找到现有的: ```javascript const comp = completionRatio[name] === undefined ? '' : completionRatio[name]; ``` 在这一行后添加: ```javascript const cacheR = cacheRatio[name] === undefined ? '' : cacheRatio[name]; const cacheCreationR = createCacheRatio[name] === undefined ? '' : createCacheRatio[name]; const imageR = imageRatio[name] === undefined ? '' : imageRatio[name]; const audioR = audioRatio[name] === undefined ? '' : audioRatio[name]; const audioCompR = audioCompletionRatio[name] === undefined ? '' : audioCompletionRatio[name]; ``` ### 步骤 2.4: 更新返回对象结构 继续在同一个 `map` 函数中,找到返回对象(约第 78 行),更新为: ```javascript return { name, price, ratio, completionRatio: comp, cacheRatio: cacheR, cacheCreationRatio: cacheCreationR, imageRatio: imageR, audioRatio: audioR, audioCompletionRatio: audioCompR, hasConflict: price !== '' && (ratio !== '' || comp !== ''), }; ``` ### 步骤 2.5: 启动开发服务器验证数据加载 ```bash cd web bun run dev ``` 访问:http://localhost:5173/setting/ratio → 切换到"可视化倍率设置"标签 打开浏览器控制台,输入: ```javascript // 检查 models 状态是否包含新字段 const tableRows = document.querySelectorAll('.semi-table-row'); console.log('Table rows count:', tableRows.length); ``` 预期:表格正常显示,无 JavaScript 错误 ### 步骤 2.6: 提交数据初始化更改 ```bash git add web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.jsx git commit -m "feat(ratio): parse advanced ratio fields in data initialization - Parse 5 new JSON fields from props.options - Extend modelNames Set to include keys from all ratio fields - Add 5 new fields to model data objects Co-Authored-By: Claude Sonnet 4.6 " ``` --- ## Task 3: 添加高级比例表单区域 **文件:** - Modify: `web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.jsx:616-737` ### 步骤 3.1: 找到插入位置 在文件中找到 `{pricingSubMode === 'token-price' && (` 块的闭合位置(约第 736 行),应该在 `)}$ 之前,`{pricingMode === 'per-request' && (` 之前。 ### 步骤 3.2: 插入高级比例表单区域 在 `{pricingSubMode === 'token-price' && (` 块的闭合 `)}` 之后,`{pricingMode === 'per-request' && (` 之前,添加: ```jsx ``` **注意缩进**:保持与周围代码一致的缩进(约 14-16 个空格) ### 步骤 3.2: 验证表单渲染 确保开发服务器仍在运行(`bun run dev`),访问:http://localhost:5173/setting/ratio 1. 点击任意模型的"编辑"按钮 2. 确认定价模式为"按量计费" 3. 向下滚动,应该能看到"高级比例(留空使用默认值)"区域 4. 确认 5 个输入框都有正确的标签和 placeholder 预期: - 新区域显示在"价格设置方式"和"固定价格"之间 - 所有 5 个字段可见且可交互 - placeholder 显示正确的默认值 ### 步骤 3.3: 测试输入验证 在高级比例区域的任意输入框中: 1. 输入负数(如 `-1`),预期:无法输入或显示验证错误 2. 输入文字(如 `abc`),预期:无法输入(InputNumber 组件自动限制) 3. 输入小数(如 `1.23`),预期:正常接受 4. 输入多位小数(如 `1.23456`),预期:step=0.01 限制 ### 步骤 3.4: 提交表单 UI 更改 ```bash git add web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.jsx git commit -m "feat(ui): add advanced ratios form section - Add Form.Section with 5 advanced ratio input fields - Configure min={0}, step={0.01} for all fields - Add placeholders showing default values - Only show when pricingMode === 'per-token' Co-Authored-By: Claude Sonnet 4.6 " ``` --- ## Task 4: 更新编辑模型逻辑 **文件:** - Modify: `web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.jsx:395-454` ### 步骤 4.1: 在 editModel 中设置表单值 找到 `editModel` 函数中的 `setTimeout` 块(约第 435 行),在 `formRef.current.setValues({` 调用中添加新字段。 找到现有的: ```javascript completionTokenPrice: modelCopy.completionTokenPrice ``` 在这一行后添加(注意在 `})` 之前添加逗号): ```javascript , // 新增:高级倍率字段 cacheRatio: modelCopy.cacheRatio, cacheCreationRatio: modelCopy.cacheCreationRatio, imageRatio: modelCopy.imageRatio, audioRatio: modelCopy.audioRatio, audioCompletionRatio: modelCopy.audioCompletionRatio ``` ### 步骤 4.2: 验证编辑回显 1. 点击已有数据的模型(如 gpt-4)的"编辑"按钮 2. 在浏览器控制台中执行: ```javascript // 检查表单值是否正确设置 const formApi = document.querySelector('[data-form-id]')?.__semi_form__; if (formApi) { console.log('Form values:', formApi.getValues()); } ``` 或者更简单:直接观察高级比例区域的输入框,如果有数据应该显示对应的值 预期: - 如果模型有高级倍率数据,输入框应显示对应值 - 如果没有数据,输入框应为空 ### 步骤 4.3: 提交编辑逻辑更改 ```bash git add web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.jsx git commit -m "feat(edit): populate advanced ratios in edit modal - Add 5 advanced ratio fields to formRef.current.setValues - Ensure existing ratio data displays correctly in edit modal Co-Authored-By: Claude Sonnet 4.6 " ``` --- ## Task 5: 更新添加/更新模型逻辑 **文件:** - Modify: `web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.jsx:334-382` ### 步骤 5.1: 在 addOrUpdateModel 中处理高级倍率字段 找到 `addOrUpdateModel` 函数(约第 334 行),在 `const updatedModel = {` 对象中添加新字段。 找到现有的: ```javascript completionRatio: values.completionRatio || '', ``` 在这一行后添加: ```javascript // 新增:高级倍率字段 cacheRatio: values.cacheRatio || '', cacheCreationRatio: values.cacheCreationRatio || '', imageRatio: values.imageRatio || '', audioRatio: values.audioRatio || '', audioCompletionRatio: values.audioCompletionRatio || '', ``` ### 步骤 5.2: 测试添加新模型 1. 点击"添加模型"按钮 2. 输入模型名称:`test-model-advanced` 3. 在高级比例区域输入测试值: - 缓存读取倍率:`0.5` - 缓存创建倍率:`1.5` - 图片倍率:`2.0` - 音频输入倍率:`1.2` - 音频输出倍率:`0.8` 4. 点击"确定" 预期: - 模型成功添加到表格 - 浏览器控制台无错误 ### 步骤 5.3: 验证数据保存到状态 在浏览器控制台中检查: ```javascript // 检查是否能在表格中看到新模型 const rows = document.querySelectorAll('.semi-table-row'); console.log('Total rows:', rows.length); // 应该比之前多 1 行 ``` ### 步骤 5.4: 提交添加/更新逻辑更改 ```bash git add web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.jsx git commit -m "feat(add): handle advanced ratios in addOrUpdateModel - Add 5 advanced ratio fields to updatedModel object - Use empty string fallback for undefined values Co-Authored-By: Claude Sonnet 4.6 " ``` --- ## Task 6: 更新保存逻辑 **文件:** - Modify: `web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.jsx:110-177` ### 步骤 6.1: 扩展 output 对象 找到 `SubmitData` 函数中的 `const output = {`(约第 112 行),在对象中添加新字段。 找到现有的: ```javascript CompletionRatio: {}, ``` 在这一行后添加: ```javascript // 新增:高级倍率字段 CacheRatio: {}, CreateCacheRatio: {}, ImageRatio: {}, AudioRatio: {}, AudioCompletionRatio: {} ``` ### 步骤 6.2: 添加数据转换逻辑 在同一个 `SubmitData` 函数中,找到 `models.forEach((model) => {` 块(约第 119 行),在现有的转换逻辑后添加。 找到: ```javascript if (model.completionRatio !== '') output.CompletionRatio[model.name] = parseFloat(model.completionRatio); ``` 在这一行后添加: ```javascript // 新增:处理高级倍率字段 if (model.cacheRatio !== '') output.CacheRatio[model.name] = parseFloat(model.cacheRatio); if (model.cacheCreationRatio !== '') output.CreateCacheRatio[model.name] = parseFloat(model.cacheCreationRatio); if (model.imageRatio !== '') output.ImageRatio[model.name] = parseFloat(model.imageRatio); if (model.audioRatio !== '') output.AudioRatio[model.name] = parseFloat(model.audioRatio); if (model.audioCompletionRatio !== '') output.AudioCompletionRatio[model.name] = parseFloat(model.audioCompletionRatio); ``` ### 步骤 6.3: 扩展 finalOutput 对象 找到 `const finalOutput = {`(约第 137 行),在对象中添加新字段。 找到现有的: ```javascript CompletionRatio: JSON.stringify(output.CompletionRatio, null, 2), ``` 在这一行后添加: ```javascript CacheRatio: JSON.stringify(output.CacheRatio, null, 2), CreateCacheRatio: JSON.stringify(output.CreateCacheRatio, null, 2), ImageRatio: JSON.stringify(output.ImageRatio, null, 2), AudioRatio: JSON.stringify(output.AudioRatio, null, 2), AudioCompletionRatio: JSON.stringify(output.AudioCompletionRatio, null, 2), ``` ### 步骤 6.4: 测试保存功能 1. 确保 Task 5.2 中添加的 `test-model-advanced` 还在表格中 2. 修改它的一些高级倍率值(如将缓存读取倍率改为 `0.8`) 3. 点击"应用更改"按钮 4. 打开浏览器网络标签,筛选 `/api/option/` 请求 预期: - 看到多个 `PUT /api/option/` 请求 - 其中包含 `CacheRatio`、`CreateCacheRatio` 等新增字段 - 请求体包含 JSON 数据,键为 `test-model-advanced` ### 步骤 6.5: 验证 API 请求体 在网络标签中点击任意一个 `/api/option/` 请求,查看"Payload"或"请求体": ```json { "key": "CacheRatio", "value": "{\n \"test-model-advanced\": 0.8\n}" } ``` 预期: - `value` 是格式化的 JSON 字符串(有缩进) - 包含正确的模型名和倍率值 ### 步骤 6.6: 提交保存逻辑更改 ```bash git add web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.jsx git commit -m "feat(save): serialize and save advanced ratio fields - Add 5 new fields to output object - Convert model data to float and populate output fields - Serialize all fields to JSON in finalOutput - Submit 7 total option fields (2 existing + 5 new) Co-Authored-By: Claude Sonnet 4.6 " ``` --- ## Task 7: 更新输入验证逻辑 **文件:** - Modify: `web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.jsx:255-270` ### 步骤 7.1: 确认 updateModel 函数 找到 `updateModel` 函数(约第 255 行),确认现有的验证逻辑: ```javascript const updateModel = (name, field, value) => { if (isNaN(value) && value !== '') { showError(t('请输入数字')); return; } // ... 更新逻辑 }; ``` **说明**:由于我们使用 `Form.InputNumber` 组件,它已经内置了数字验证,所以 `updateModel` 函数不需要修改。`isNaN` 检查已经足够处理高级倍率字段。 ### 步骤 7.2: 测试验证逻辑 在开发服务器运行的情况下: 1. 尝试在表格中直接点击模型倍率或补全倍率输入框 2. 输入文字(如 `abc`) 3. 观察是否显示错误提示"请输入数字" **注意**:由于我们现在使用 `Form.InputNumber` 而非 `Input`,高级比例字段在弹窗中,`updateModel` 函数不会被它们调用。`Form.InputNumber` 会自动限制只能输入数字。 ### 步骤 7.3: 验证空值处理 测试空值是否正确处理: 1. 编辑一个模型 2. 在高级比例区域,将所有输入框留空 3. 点击"确定" 4. 点击"应用更改" 预期: - 保存成功,无错误 - 空值保存为空字符串,后端使用默认值 ### 步骤 7.4: 提交验证相关更改 如果本任务没有代码修改,跳过提交。否则: ```bash git add web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.jsx git commit -m "feat(validation): enhance input validation for advanced ratios Co-Authored-By: Claude Sonnet 4.6 " ``` --- ## Task 8: 完整功能测试 **文件:** - Test: `web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.jsx` ### 步骤 8.1: 测试数据初始化 1. 清空浏览器缓存或使用隐私模式 2. 访问:http://localhost:5173/setting/ratio 3. 切换到"可视化倍率设置"标签 预期: - 表格正常显示 - 无 JavaScript 错误 - 表格包含所有现有模型 ### 步骤 8.2: 测试添加带高级倍率的模型 1. 点击"添加模型" 2. 输入: - 模型名称:`claude-3-5-sonnet-20241022` - 定价模式:按量计费 - 价格设置方式:按倍率设置 - 模型倍率:`1.5` - 补全倍率:`1.2` - 缓存读取倍率:`0.1` - 缓存创建倍率:`1.25` - 图片倍率:留空 - 音频输入倍率:留空 - 音频输出倍率:留空 3. 点击"确定" 预期: - 模型成功添加 - 表格中显示新模型 - 无错误提示 ### 步骤 8.3: 测试编辑高级倍率 1. 点击刚才添加的模型的"编辑"按钮 2. 修改高级倍率值: - 缓存读取倍率:`0.15` - 缓存创建倍率:`1.3` - 图片倍率:`2.5` - 音频输入倍率:`10.0` - 音频输出倍率:`20.0` 3. 点击"确定" 4. 点击"应用更改" 预期: - 编辑成功 - 显示"保存成功"提示 ### 步骤 8.4: 验证数据持久化 刷新浏览器页面,重新访问可视化倍率设置: 1. 点击刚才编辑的模型的"编辑"按钮 2. 检查高级比例区域的值是否与步骤 8.3 中设置的一致 预期: - 缓存读取倍率:显示 `0.15` - 缓存创建倍率:显示 `1.3` - 图片倍率:显示 `2.5` - 音频输入倍率:显示 `10.0` - 音频输出倍率:显示 `20.0` ### 步骤 8.5: 测试删除模型 1. 选择测试模型 2. 点击"删除"按钮 3. 确认删除 预期: - 模型从表格中移除 - 删除的高级倍率数据在保存时被清除(后续保存不会包含该模型) ### 步骤 8.6: 测试边界情况 **测试负数输入**: 1. 尝试在高级比例输入框输入 `-1` 2. 预期:`min={0}` 限制,无法输入负数 **测试小数精度**: 1. 输入 `0.123456` 2. 预期:`step={0.01}` 限制,可以输入但会保留多位小数(Semi UI InputNumber 行为) **测试空值保存**: 1. 编辑模型,清空所有高级比例输入框 2. 点击"确定",然后"应用更改" 3. 预期:保存成功,后端使用默认值 ### 步骤 8.7: 测试国际化切换 1. 在系统设置中切换到英文(如果支持) 2. 重新访问可视化倍率设置 3. 检查高级比例区域的标签是否显示为英文 预期: - "高级比例(留空使用默认值)" → "Advanced Ratios (Leave empty for defaults)" - "缓存读取倍率" → "Cache Read Ratio" - 其他字段类似 ### 步骤 8.8: 创建测试提交 如果所有测试通过,创建一个测试提交标记: ```bash git add web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.jsx git commit -m "test: verify advanced ratios functionality - Test data initialization with empty options - Test adding model with advanced ratios - Test editing advanced ratios - Test data persistence after page refresh - Test model deletion - Test edge cases (negative numbers, decimal precision, empty values) - Test internationalization (English/Chinese) All tests passed successfully. Co-Authored-By: Claude Sonnet 4.6 " ``` --- ## Task 9: 代码清理和优化 **文件:** - Modify: `web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.jsx` ### 步骤 9.1: 检查代码格式化 运行代码格式化工具(如果项目配置了): ```bash cd web bun run lint --fix ``` 预期: - 无 lint 错误 - 代码格式符合项目规范 ### 步骤 9.2: 检查 console.log 搜索并移除任何调试用的 `console.log`: ```bash cd web/src/pages/Setting/Ratio grep -n "console.log" ModelSettingsVisualEditor.jsx ``` 如果找到任何 `console.log`,删除它们。 ### 步骤 9.3: 验证组件性能 检查是否有不必要的重渲染: 1. 打开浏览器 React DevTools(如果可用) 2. 选择 "Profiler" 标签 3. 记录编辑模型时的性能 4. 检查是否有异常的重渲染 预期: - 组件重渲染次数合理 - 无明显的性能问题 ### 步骤 9.4: 提交清理更改 如果有任何清理更改: ```bash git add web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.jsx git commit -m "refactor: code cleanup and optimization - Remove debug console.log statements - Format code with linter - Verify component performance Co-Authored-By: Claude Sonnet 4.6 " ``` --- ## 验证清单 在实施完成后,验证以下所有项目: ### 功能验证 - [ ] 可以添加带有高级倍率的模型 - [ ] 可以编辑模型的高级倍率字段 - [ ] 可以删除模型 - [ ] 数据正确保存到后端 - [ ] 刷新页面后数据正确加载 - [ ] 空值字段使用默认值 ### UI/UX 验证 - [ ] 高级比例区域正确显示 - [ ] 所有 5 个字段都有正确的标签 - [ ] Placeholder 显示正确的默认值 - [ ] 输入验证正常工作(负数、非数字) - [ ] 中英文切换正常 ### 代码质量 - [ ] 无 TypeScript/JavaScript 错误 - [ ] 无 lint 错误 - [ ] 无调试 console.log - [ ] 代码格式符合项目规范 - [ ] 所有提交都有清晰的 commit message ### 数据完整性 - [ ] 前端字段名与后端 Option Key 一致 - [ ] JSON 序列化/反序列化正确 - [ ] 空值处理正确(空字符串,非 null) - [ ] 数值转换正确(parseFloat) --- ## 实施完成后的最终检查 ### 步骤 1: 查看所有提交 ```bash git log --oneline --no-merges | head -20 ``` 预期:看到一系列清晰的、原子性的提交,每个提交对应一个任务或功能点 ### 步骤 2: 验证文件更改 ```bash git diff HEAD~10 HEAD --stat ``` 预期: - `ModelSettingsVisualEditor.jsx` 有显著更改 - `zh-CN.json` 和 `en.json` 有新增翻译 - 无其他意外更改 ### 步骤 3: 最终功能测试 重复 Task 8 中的所有测试步骤,确保一切正常。 ### 步骤 4: 合并到主分支(如果需要) ```bash git checkout master git merge git push ``` --- ## 故障排查 ### 问题:表格不显示 **症状**:访问可视化倍率设置页面,表格为空 **排查**: 1. 打开浏览器控制台,检查是否有 JavaScript 错误 2. 检查 `useEffect` 中的 JSON 解析是否成功 3. 验证 `props.options` 是否包含所有必需的字段 **解决**: - 确保后端 API 返回所有 7 个字段(ModelPrice, ModelRatio, CompletionRatio, CacheRatio, CreateCacheRatio, ImageRatio, AudioRatio, AudioCompletionRatio) ### 问题:高级比例区域不显示 **症状**:编辑模型时看不到高级比例输入框 **排查**: 1. 检查定价模式是否为"按量计费"(`pricingMode === 'per-token'`) 2. 检查 Form.Section 的条件渲染 3. 验证国际化文本是否加载 **解决**: - 确保在"按量计费"模式下编辑 - 检查 `t()` 函数是否返回正确的翻译文本 ### 问题:数据保存失败 **症状**:点击"应用更改"后显示错误 **排查**: 1. 打开浏览器网络标签,检查 `/api/option/` 请求 2. 查看请求响应状态码和消息 3. 验证请求数据格式是否正确 **解决**: - 确保所有 7 个字段都包含在 `finalOutput` 中 - 检查 JSON 序列化是否正确 - 验证后端 API 是否支持所有 7 个 Option Key ### 问题:翻译文本显示为键名 **症状**:界面显示 `"高级比例(留空使用默认值)"` 而非翻译后的文本 **排查**: 1. 检查 i18n 配置文件是否正确加载 2. 验证 JSON 格式是否正确 3. 检查是否有语法错误导致整个文件无法解析 **解决**: - 修复 JSON 语法错误 - 重新加载页面 - 清除浏览器缓存 --- ## 预计时间 - Task 1 (国际化): 15 分钟 - Task 2 (数据初始化): 20 分钟 - Task 3 (表单 UI): 15 分钟 - Task 4 (编辑逻辑): 10 分钟 - Task 5 (添加/更新): 10 分钟 - Task 6 (保存逻辑): 15 分钟 - Task 7 (验证逻辑): 5 分钟 - Task 8 (完整测试): 30 分钟 - Task 9 (代码清理): 10 分钟 **总计**: 约 2.5 小时 --- ## 参考资源 ### 内部文档 - 设计规范: `docs/superpowers/specs/2026-06-04-extended-visual-ratio-settings-design.md` - 渠道价格设置实现: `feat/channel-pricing-extended:web/src/pages/Setting/Ratio/ChannelPricingView.jsx` ### API 文档 - Semi UI Form: https://douyinfe.github.io/semi-ui/form/form-inputnumber - React hooks: https://react.dev/reference/react ### 后端接口 - GET `/api/option/` - 获取所有选项 - PUT `/api/option/` - 更新单个选项(请求体: `{ key, value }`) --- **实施计划完成**