diff --git a/web/src/components/common/ui/JSONEditor.jsx b/web/src/components/common/ui/JSONEditor.jsx index d89753872..21530db39 100644 --- a/web/src/components/common/ui/JSONEditor.jsx +++ b/web/src/components/common/ui/JSONEditor.jsx @@ -60,6 +60,7 @@ const JSONEditor = ({ editorType = 'keyValue', rules = [], formApi = null, + renderStringValueSuffix, ...props }) => { const { t } = useTranslation(); @@ -335,7 +336,7 @@ const JSONEditor = ({ ]); // 渲染值输入控件(支持嵌套) - const renderValueInput = (pairId, value) => { + const renderValueInput = (pairId, pairKey, value) => { const valueType = typeof value; if (valueType === 'boolean') { @@ -387,6 +388,7 @@ const JSONEditor = ({ { let convertedValue = newValue; if (newValue === 'true') convertedValue = true; @@ -470,7 +472,9 @@ const JSONEditor = ({ )} - {renderValueInput(pair.id, pair.value)} + + {renderValueInput(pair.id, pair.key, pair.value)} + + - - )} + > + + {ionetMetadata?.deployment_id && ( + + )} + + + )} - setChannelSearchValue(value)} - renderOptionItem={renderChannelOption} - onChange={(value) => handleInputChange('type', value)} - disabled={isIonetLocked} - /> + setChannelSearchValue(value)} + renderOptionItem={renderChannelOption} + onChange={(value) => handleInputChange('type', value)} + disabled={isIonetLocked} + /> {inputs.type === 20 && ( { style={{ width: '100%' }} value={inputs.aws_key_type || 'ak_sk'} onChange={(value) => { - handleChannelOtherSettingsChange('aws_key_type', value); + handleChannelOtherSettingsChange( + 'aws_key_type', + value, + ); }} extraText={t( 'AK/SK 模式:使用 AccessKey 和 SecretAccessKey;API Key 模式:使用 API Key', @@ -1834,7 +1886,9 @@ const EditChannelModal = (props) => { placeholder={ inputs.type === 33 ? inputs.aws_key_type === 'api_key' - ? t('请输入 API Key,一行一个,格式:APIKey|Region') + ? t( + '请输入 API Key,一行一个,格式:APIKey|Region', + ) : t( '请输入密钥,一行一个,格式:AccessKey|SecretAccessKey|Region', ) @@ -1849,85 +1903,87 @@ const EditChannelModal = (props) => { autoComplete='new-password' onChange={(value) => handleInputChange('key', value)} disabled={isIonetLocked} - extraText={ -
- {isEdit && - isMultiKeyChannel && - keyMode === 'append' && ( - - {t( - '追加模式:新密钥将添加到现有密钥列表的末尾', - )} - + extraText={ +
+ {isEdit && + isMultiKeyChannel && + keyMode === 'append' && ( + + {t( + '追加模式:新密钥将添加到现有密钥列表的末尾', + )} + + )} + {isEdit && ( + )} - {isEdit && ( - - )} - {batchExtra} -
- } - showClear - /> - ) - ) : ( - <> - {inputs.type === 41 && - (inputs.vertex_key_type || 'json') === 'json' ? ( - <> - {!batch && ( -
- - {t('密钥输入方式')} - - - - - + {batchExtra}
- )} + } + showClear + /> + ) + ) : ( + <> + {inputs.type === 41 && + (inputs.vertex_key_type || 'json') === 'json' ? ( + <> + {!batch && ( +
+ + {t('密钥输入方式')} + + + + + +
+ )} {batch && ( { inputs.type === 33 ? inputs.aws_key_type === 'api_key' ? t('请输入 API Key,格式:APIKey|Region') - : t('按照如下格式输入:AccessKey|SecretAccessKey|Region') + : t( + '按照如下格式输入:AccessKey|SecretAccessKey|Region', + ) : t(type2secretPrompt(inputs.type)) } rules={ @@ -2258,86 +2316,86 @@ const EditChannelModal = (props) => { /> )} - {inputs.type === 3 && ( - <> - -
- + - handleInputChange('base_url', value) - } - showClear - disabled={isIonetLocked} + className='!rounded-lg' /> -
-
- - handleInputChange('other', value) - } - showClear - /> -
-
- - handleChannelOtherSettingsChange( - 'azure_responses_version', - value, - ) - } - showClear - /> -
- - )} +
+ + handleInputChange('base_url', value) + } + showClear + disabled={isIonetLocked} + /> +
+
+ + handleInputChange('other', value) + } + showClear + /> +
+
+ + handleChannelOtherSettingsChange( + 'azure_responses_version', + value, + ) + } + showClear + /> +
+ + )} - {inputs.type === 8 && ( - <> - -
- + - handleInputChange('base_url', value) - } - showClear - disabled={isIonetLocked} + className='!rounded-lg' /> -
- - )} +
+ + handleInputChange('base_url', value) + } + showClear + disabled={isIonetLocked} + /> +
+ + )} {inputs.type === 37 && ( { } showClear disabled={isIonetLocked} - extraText={t( - '对于官方渠道,new-api已经内置地址,除非是第三方代理站点或者Azure的特殊接入地址,否则不需要填写', + extraText={t( + '对于官方渠道,new-api已经内置地址,除非是第三方代理站点或者Azure的特殊接入地址,否则不需要填写', + )} + /> +
+ )} + + {inputs.type === 22 && ( +
+ + handleInputChange('base_url', value) + } + showClear + disabled={isIonetLocked} />
)} - {inputs.type === 22 && ( -
- - handleInputChange('base_url', value) - } - showClear - disabled={isIonetLocked} - /> -
- )} - - {inputs.type === 36 && ( -
- - handleInputChange('base_url', value) - } - showClear - disabled={isIonetLocked} - /> -
- )} - - {inputs.type === 45 && !doubaoApiEditUnlocked && ( -
- + {inputs.type === 36 && ( +
+ handleInputChange('base_url', value) - } - optionList={[ - { - value: 'https://ark.cn-beijing.volces.com', - label: 'https://ark.cn-beijing.volces.com', - }, - { - value: 'https://ark.ap-southeast.bytepluses.com', - label: 'https://ark.ap-southeast.bytepluses.com', - }, - { - value: 'doubao-coding-plan', - label: 'Doubao Coding Plan', - }, - ]}defaultValue='https://ark.cn-beijing.volces.com' - disabled={isIonetLocked} - /> -
- )} + } + showClear + disabled={isIonetLocked} + /> +
+ )} + + {inputs.type === 45 && !doubaoApiEditUnlocked && ( +
+ + handleInputChange('base_url', value) + } + optionList={[ + { + value: 'https://ark.cn-beijing.volces.com', + label: 'https://ark.cn-beijing.volces.com', + }, + { + value: + 'https://ark.ap-southeast.bytepluses.com', + label: + 'https://ark.ap-southeast.bytepluses.com', + }, + { + value: 'doubao-coding-plan', + label: 'Doubao Coding Plan', + }, + ]} + defaultValue='https://ark.cn-beijing.volces.com' + disabled={isIonetLocked} + /> +
+ )} )} @@ -2531,79 +2592,81 @@ const EditChannelModal = (props) => { )} {inputs.type === 4 && isEdit && ( - - )} - - - {modelGroups && - modelGroups.length > 0 && - modelGroups.map((group) => ( - ))} - - } - /> + )} + + + {modelGroups && + modelGroups.length > 0 && + modelGroups.map((group) => ( + + ))} + + } + /> { templateLabel={t('填入模板')} editorType='keyValue' formApi={formApiRef.current} + renderStringValueSuffix={({ pairKey, value }) => { + if (!MODEL_FETCHABLE_TYPES.has(inputs.type)) { + return null; + } + const disabled = !String(pairKey ?? '').trim(); + return ( + +