Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
6d2e92fb
authored
Jul 31, 2025
by
CaIon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: add JSONEditor component for enhanced JSON input handling
parent
590e6db6
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
638 additions
and
33 deletions
+638
-33
web/src/components/common/JSONEditor.js
+610
-0
web/src/components/table/channels/modals/EditChannelModal.jsx
+28
-33
No files found.
web/src/components/common/JSONEditor.js
0 → 100644
View file @
6d2e92fb
import
React
,
{
useState
,
useEffect
,
useCallback
}
from
'react'
;
import
{
useTranslation
}
from
'react-i18next'
;
import
{
Space
,
Button
,
Form
,
Card
,
Typography
,
Banner
,
Row
,
Col
,
InputNumber
,
Switch
,
Select
,
Input
,
}
from
'@douyinfe/semi-ui'
;
import
{
IconCode
,
IconEdit
,
IconPlus
,
IconDelete
,
IconSetting
,
}
from
'@douyinfe/semi-icons'
;
const
{
Text
}
=
Typography
;
const
JSONEditor
=
({
value
=
''
,
onChange
,
field
,
label
,
placeholder
,
extraText
,
showClear
=
true
,
template
,
templateLabel
,
editorType
=
'keyValue'
,
// keyValue, object, region
autosize
=
true
,
rules
=
[],
formApi
=
null
,
...
props
})
=>
{
const
{
t
}
=
useTranslation
();
// 初始化JSON数据
const
[
jsonData
,
setJsonData
]
=
useState
(()
=>
{
// 初始化时解析JSON数据
if
(
value
&&
value
.
trim
())
{
try
{
const
parsed
=
JSON
.
parse
(
value
);
return
parsed
;
}
catch
(
error
)
{
return
{};
}
}
return
{};
});
// 根据键数量决定默认编辑模式
const
[
editMode
,
setEditMode
]
=
useState
(()
=>
{
// 如果初始JSON数据的键数量大于10个,则默认使用手动模式
if
(
value
&&
value
.
trim
())
{
try
{
const
parsed
=
JSON
.
parse
(
value
);
const
keyCount
=
Object
.
keys
(
parsed
).
length
;
return
keyCount
>
10
?
'manual'
:
'visual'
;
}
catch
(
error
)
{
return
'visual'
;
}
}
return
'visual'
;
});
const
[
jsonError
,
setJsonError
]
=
useState
(
''
);
// 数据同步 - 当value变化时总是更新jsonData(如果JSON有效)
useEffect
(()
=>
{
try
{
const
parsed
=
value
&&
value
.
trim
()
?
JSON
.
parse
(
value
)
:
{};
setJsonData
(
parsed
);
setJsonError
(
''
);
}
catch
(
error
)
{
console
.
log
(
'JSON解析失败:'
,
error
.
message
);
setJsonError
(
error
.
message
);
// JSON格式错误时不更新jsonData
}
},
[
value
]);
// 处理可视化编辑的数据变化
const
handleVisualChange
=
useCallback
((
newData
)
=>
{
setJsonData
(
newData
);
setJsonError
(
''
);
const
jsonString
=
Object
.
keys
(
newData
).
length
===
0
?
''
:
JSON
.
stringify
(
newData
,
null
,
2
);
// 通过formApi设置值(如果提供的话)
if
(
formApi
&&
field
)
{
formApi
.
setValue
(
field
,
jsonString
);
}
onChange
?.(
jsonString
);
},
[
onChange
,
formApi
,
field
]);
// 处理手动编辑的数据变化
const
handleManualChange
=
useCallback
((
newValue
)
=>
{
onChange
?.(
newValue
);
// 验证JSON格式
if
(
newValue
&&
newValue
.
trim
())
{
try
{
const
parsed
=
JSON
.
parse
(
newValue
);
setJsonError
(
''
);
// 预先准备可视化数据,但不立即应用
// 这样切换到可视化模式时数据已经准备好了
}
catch
(
error
)
{
setJsonError
(
error
.
message
);
}
}
else
{
setJsonError
(
''
);
}
},
[
onChange
]);
// 切换编辑模式
const
toggleEditMode
=
useCallback
(()
=>
{
if
(
editMode
===
'visual'
)
{
// 从可视化模式切换到手动模式
setEditMode
(
'manual'
);
}
else
{
// 从手动模式切换到可视化模式,需要验证JSON
try
{
const
parsed
=
value
&&
value
.
trim
()
?
JSON
.
parse
(
value
)
:
{};
setJsonData
(
parsed
);
setJsonError
(
''
);
setEditMode
(
'visual'
);
}
catch
(
error
)
{
setJsonError
(
error
.
message
);
// JSON格式错误时不切换模式
return
;
}
}
},
[
editMode
,
value
]);
// 添加键值对
const
addKeyValue
=
useCallback
(()
=>
{
const
newData
=
{
...
jsonData
};
const
keys
=
Object
.
keys
(
newData
);
let
newKey
=
'key'
;
let
counter
=
1
;
while
(
newData
.
hasOwnProperty
(
newKey
))
{
newKey
=
`key
${
counter
}
`
;
counter
++
;
}
newData
[
newKey
]
=
''
;
handleVisualChange
(
newData
);
},
[
jsonData
,
handleVisualChange
]);
// 删除键值对
const
removeKeyValue
=
useCallback
((
keyToRemove
)
=>
{
const
newData
=
{
...
jsonData
};
delete
newData
[
keyToRemove
];
handleVisualChange
(
newData
);
},
[
jsonData
,
handleVisualChange
]);
// 更新键名
const
updateKey
=
useCallback
((
oldKey
,
newKey
)
=>
{
if
(
oldKey
===
newKey
)
return
;
const
newData
=
{
...
jsonData
};
const
value
=
newData
[
oldKey
];
delete
newData
[
oldKey
];
newData
[
newKey
]
=
value
;
handleVisualChange
(
newData
);
},
[
jsonData
,
handleVisualChange
]);
// 更新值
const
updateValue
=
useCallback
((
key
,
newValue
)
=>
{
const
newData
=
{
...
jsonData
};
newData
[
key
]
=
newValue
;
handleVisualChange
(
newData
);
},
[
jsonData
,
handleVisualChange
]);
// 填入模板
const
fillTemplate
=
useCallback
(()
=>
{
if
(
template
)
{
const
templateString
=
JSON
.
stringify
(
template
,
null
,
2
);
// 通过formApi设置值(如果提供的话)
if
(
formApi
&&
field
)
{
formApi
.
setValue
(
field
,
templateString
);
}
// 无论哪种模式都要更新值
onChange
?.(
templateString
);
// 如果是可视化模式,同时更新jsonData
if
(
editMode
===
'visual'
)
{
setJsonData
(
template
);
}
// 清除错误状态
setJsonError
(
''
);
}
},
[
template
,
onChange
,
editMode
,
formApi
,
field
]);
// 渲染键值对编辑器
const
renderKeyValueEditor
=
()
=>
{
const
entries
=
Object
.
entries
(
jsonData
);
return
(
<
div
className
=
"space-y-1"
>
{
entries
.
length
===
0
&&
(
<
div
className
=
"text-center py-6 px-4"
>
<
div
className
=
"text-gray-400 mb-2"
>
<
IconCode
size
=
{
32
}
/
>
<
/div
>
<
Text
type
=
"tertiary"
className
=
"text-gray-500 text-sm"
>
{
t
(
'暂无数据,点击下方按钮添加键值对'
)}
<
/Text
>
<
/div
>
)}
{
entries
.
map
(([
key
,
value
],
index
)
=>
(
<
Card
key
=
{
index
}
className
=
"!p-3 !border-gray-200 !rounded-md hover:shadow-sm transition-shadow duration-200"
>
<
Row
gutter
=
{
12
}
align
=
"middle"
>
<
Col
span
=
{
10
}
>
<
div
className
=
"space-y-1"
>
<
Text
type
=
"tertiary"
size
=
"small"
>
{
t
(
'键名'
)}
<
/Text
>
<
Input
placeholder
=
{
t
(
'键名'
)}
value
=
{
key
}
onChange
=
{(
newKey
)
=>
updateKey
(
key
,
newKey
)}
size
=
"small"
/>
<
/div
>
<
/Col
>
<
Col
span
=
{
11
}
>
<
div
className
=
"space-y-1"
>
<
Text
type
=
"tertiary"
size
=
"small"
>
{
t
(
'值'
)}
<
/Text
>
<
Input
placeholder
=
{
t
(
'值'
)}
value
=
{
value
}
onChange
=
{(
newValue
)
=>
updateValue
(
key
,
newValue
)}
size
=
"small"
/>
<
/div
>
<
/Col
>
<
Col
span
=
{
3
}
>
<
div
className
=
"flex justify-center pt-4"
>
<
Button
icon
=
{
<
IconDelete
/>
}
type
=
"danger"
theme
=
"borderless"
size
=
"small"
onClick
=
{()
=>
removeKeyValue
(
key
)}
className
=
"hover:bg-red-50"
/>
<
/div
>
<
/Col
>
<
/Row
>
<
/Card
>
))}
<
div
className
=
"flex justify-center pt-1"
>
<
Button
icon
=
{
<
IconPlus
/>
}
onClick
=
{
addKeyValue
}
size
=
"small"
theme
=
"solid"
type
=
"primary"
className
=
"shadow-sm hover:shadow-md transition-shadow px-4"
>
{
t
(
'添加键值对'
)}
<
/Button
>
<
/div
>
<
/div
>
);
};
// 渲染对象编辑器(用于复杂JSON)
const
renderObjectEditor
=
()
=>
{
const
entries
=
Object
.
entries
(
jsonData
);
return
(
<
div
className
=
"space-y-1"
>
{
entries
.
length
===
0
&&
(
<
div
className
=
"text-center py-6 px-4"
>
<
div
className
=
"text-gray-400 mb-2"
>
<
IconSetting
size
=
{
32
}
/
>
<
/div
>
<
Text
type
=
"tertiary"
className
=
"text-gray-500 text-sm"
>
{
t
(
'暂无参数,点击下方按钮添加请求参数'
)}
<
/Text
>
<
/div
>
)}
{
entries
.
map
(([
key
,
value
],
index
)
=>
(
<
Card
key
=
{
index
}
className
=
"!p-3 !border-gray-200 !rounded-md hover:shadow-sm transition-shadow duration-200"
>
<
Row
gutter
=
{
12
}
align
=
"middle"
>
<
Col
span
=
{
8
}
>
<
div
className
=
"space-y-1"
>
<
Text
type
=
"tertiary"
size
=
"small"
>
{
t
(
'参数名'
)}
<
/Text
>
<
Input
placeholder
=
{
t
(
'参数名'
)}
value
=
{
key
}
onChange
=
{(
newKey
)
=>
updateKey
(
key
,
newKey
)}
size
=
"small"
/>
<
/div
>
<
/Col
>
<
Col
span
=
{
13
}
>
<
div
className
=
"space-y-1"
>
<
Text
type
=
"tertiary"
size
=
"small"
>
{
t
(
'参数值'
)}
({
typeof
value
})
<
/Text
>
{
renderValueInput
(
key
,
value
)}
<
/div
>
<
/Col
>
<
Col
span
=
{
3
}
>
<
div
className
=
"flex justify-center pt-4"
>
<
Button
icon
=
{
<
IconDelete
/>
}
type
=
"danger"
theme
=
"borderless"
size
=
"small"
onClick
=
{()
=>
removeKeyValue
(
key
)}
className
=
"hover:bg-red-50"
/>
<
/div
>
<
/Col
>
<
/Row
>
<
/Card
>
))}
<
div
className
=
"flex justify-center pt-1"
>
<
Button
icon
=
{
<
IconPlus
/>
}
onClick
=
{
addKeyValue
}
size
=
"small"
theme
=
"solid"
type
=
"primary"
className
=
"shadow-sm hover:shadow-md transition-shadow px-4"
>
{
t
(
'添加参数'
)}
<
/Button
>
<
/div
>
<
/div
>
);
};
// 渲染参数值输入控件
const
renderValueInput
=
(
key
,
value
)
=>
{
const
valueType
=
typeof
value
;
if
(
valueType
===
'boolean'
)
{
return
(
<
div
className
=
"flex items-center"
>
<
Switch
checked
=
{
value
}
onChange
=
{(
newValue
)
=>
updateValue
(
key
,
newValue
)}
size
=
"small"
/>
<
Text
type
=
"tertiary"
size
=
"small"
className
=
"ml-2"
>
{
value
?
t
(
'true'
)
:
t
(
'false'
)}
<
/Text
>
<
/div
>
);
}
if
(
valueType
===
'number'
)
{
return
(
<
InputNumber
value
=
{
value
}
onChange
=
{(
newValue
)
=>
updateValue
(
key
,
newValue
)}
size
=
"small"
style
=
{{
width
:
'100%'
}}
step
=
{
key
===
'temperature'
?
0.1
:
1
}
precision
=
{
key
===
'temperature'
?
2
:
0
}
placeholder
=
{
t
(
'输入数字'
)}
/
>
);
}
// 字符串类型或其他类型
return
(
<
Input
placeholder
=
{
t
(
'参数值'
)}
value
=
{
String
(
value
)}
onChange
=
{(
newValue
)
=>
{
// 尝试转换为适当的类型
let
convertedValue
=
newValue
;
if
(
newValue
===
'true'
)
convertedValue
=
true
;
else
if
(
newValue
===
'false'
)
convertedValue
=
false
;
else
if
(
!
isNaN
(
newValue
)
&&
newValue
!==
''
&&
newValue
!==
'0'
)
{
convertedValue
=
Number
(
newValue
);
}
updateValue
(
key
,
convertedValue
);
}}
size
=
"small"
/>
);
};
// 渲染区域编辑器(特殊格式)
const
renderRegionEditor
=
()
=>
{
const
entries
=
Object
.
entries
(
jsonData
);
const
defaultEntry
=
entries
.
find
(([
key
])
=>
key
===
'default'
);
const
modelEntries
=
entries
.
filter
(([
key
])
=>
key
!==
'default'
);
return
(
<
div
className
=
"space-y-1"
>
{
/* 默认区域 */
}
<
Card
className
=
"!p-2 !border-blue-200 !bg-blue-50"
>
<
div
className
=
"flex items-center mb-1"
>
<
Text
strong
size
=
"small"
className
=
"text-blue-700"
>
{
t
(
'默认区域'
)}
<
/Text
>
<
/div
>
<
Input
placeholder
=
{
t
(
'默认区域,如: us-central1'
)}
value
=
{
defaultEntry
?
defaultEntry
[
1
]
:
''
}
onChange
=
{(
value
)
=>
updateValue
(
'default'
,
value
)}
size
=
"small"
/>
<
/Card
>
{
/* 模型专用区域 */
}
<
div
className
=
"space-y-1"
>
<
Text
strong
size
=
"small"
>
{
t
(
'模型专用区域'
)}
<
/Text
>
{
modelEntries
.
map
(([
modelName
,
region
],
index
)
=>
(
<
Card
key
=
{
index
}
className
=
"!p-3 !border-gray-200 !rounded-md hover:shadow-sm transition-shadow duration-200"
>
<
Row
gutter
=
{
12
}
align
=
"middle"
>
<
Col
span
=
{
10
}
>
<
div
className
=
"space-y-1"
>
<
Text
type
=
"tertiary"
size
=
"small"
>
{
t
(
'模型名称'
)}
<
/Text
>
<
Input
placeholder
=
{
t
(
'模型名称'
)}
value
=
{
modelName
}
onChange
=
{(
newKey
)
=>
updateKey
(
modelName
,
newKey
)}
size
=
"small"
/>
<
/div
>
<
/Col
>
<
Col
span
=
{
11
}
>
<
div
className
=
"space-y-1"
>
<
Text
type
=
"tertiary"
size
=
"small"
>
{
t
(
'区域'
)}
<
/Text
>
<
Input
placeholder
=
{
t
(
'区域'
)}
value
=
{
region
}
onChange
=
{(
newValue
)
=>
updateValue
(
modelName
,
newValue
)}
size
=
"small"
/>
<
/div
>
<
/Col
>
<
Col
span
=
{
3
}
>
<
div
className
=
"flex justify-center pt-4"
>
<
Button
icon
=
{
<
IconDelete
/>
}
type
=
"danger"
theme
=
"borderless"
size
=
"small"
onClick
=
{()
=>
removeKeyValue
(
modelName
)}
className
=
"hover:bg-red-50"
/>
<
/div
>
<
/Col
>
<
/Row
>
<
/Card
>
))}
<
div
className
=
"flex justify-center pt-1"
>
<
Button
icon
=
{
<
IconPlus
/>
}
onClick
=
{
addKeyValue
}
size
=
"small"
theme
=
"solid"
type
=
"primary"
className
=
"shadow-sm hover:shadow-md transition-shadow px-4"
>
{
t
(
'添加模型区域'
)}
<
/Button
>
<
/div
>
<
/div
>
<
/div
>
);
};
// 渲染可视化编辑器
const
renderVisualEditor
=
()
=>
{
switch
(
editorType
)
{
case
'region'
:
return
renderRegionEditor
();
case
'object'
:
return
renderObjectEditor
();
case
'keyValue'
:
default
:
return
renderKeyValueEditor
();
}
};
const
hasJsonError
=
jsonError
&&
jsonError
.
trim
()
!==
''
;
return
(
<
div
className
=
"space-y-1"
>
{
/* Label统一显示在上方 */
}
{
label
&&
(
<
div
className
=
"flex items-center"
>
<
Text
className
=
"text-sm font-medium text-gray-900"
>
{
label
}
<
/Text
>
<
/div
>
)}
{
/* 编辑模式切换 */
}
<
div
className
=
"flex items-center justify-between p-2 bg-gray-50 rounded-md"
>
<
div
className
=
"flex items-center gap-2"
>
{
editMode
===
'visual'
&&
(
<
Text
type
=
"tertiary"
size
=
"small"
className
=
"bg-blue-100 text-blue-700 px-2 py-0.5 rounded text-xs"
>
{
t
(
'可视化模式'
)}
<
/Text
>
)}
{
editMode
===
'manual'
&&
(
<
Text
type
=
"tertiary"
size
=
"small"
className
=
"bg-green-100 text-green-700 px-2 py-0.5 rounded text-xs"
>
{
t
(
'手动编辑模式'
)}
<
/Text
>
)}
<
/div
>
<
div
className
=
"flex items-center gap-2"
>
{
template
&&
templateLabel
&&
(
<
Button
size
=
"small"
type
=
"tertiary"
onClick
=
{
fillTemplate
}
className
=
"!text-semi-color-primary hover:bg-blue-50 text-xs"
>
{
templateLabel
}
<
/Button
>
)}
<
Space
size
=
"tight"
>
<
Button
size
=
"small"
type
=
{
editMode
===
'visual'
?
'primary'
:
'tertiary'
}
icon
=
{
<
IconEdit
/>
}
onClick
=
{
toggleEditMode
}
disabled
=
{
editMode
===
'manual'
&&
hasJsonError
}
className
=
{
editMode
===
'visual'
?
'shadow-sm'
:
''
}
>
{
t
(
'可视化'
)}
<
/Button
>
<
Button
size
=
"small"
type
=
{
editMode
===
'manual'
?
'primary'
:
'tertiary'
}
icon
=
{
<
IconCode
/>
}
onClick
=
{
toggleEditMode
}
className
=
{
editMode
===
'manual'
?
'shadow-sm'
:
''
}
>
{
t
(
'手动编辑'
)}
<
/Button
>
<
/Space
>
<
/div
>
<
/div
>
{
/* JSON错误提示 */
}
{
hasJsonError
&&
(
<
Banner
type
=
"danger"
description
=
{
`JSON 格式错误:
${
jsonError
}
`
}
className
=
"!rounded-md text-sm"
/>
)}
{
/* 编辑器内容 */
}
{
editMode
===
'visual'
?
(
<
div
>
<
Card
className
=
"!p-3 !border-gray-200 !shadow-sm !rounded-md bg-white"
>
{
renderVisualEditor
()}
<
/Card
>
{
/* 可视化模式下的额外文本显示在下方 */
}
{
extraText
&&
(
<
div
className
=
"text-xs text-gray-600 mt-0.5"
>
{
extraText
}
<
/div
>
)}
{
/* 隐藏的Form字段用于验证和数据绑定 */
}
<
Form
.
Input
field
=
{
field
}
value
=
{
value
}
rules
=
{
rules
}
style
=
{{
display
:
'none'
}}
noLabel
=
{
true
}
{...
props
}
/
>
<
/div
>
)
:
(
<
Form
.
TextArea
field
=
{
field
}
placeholder
=
{
placeholder
}
value
=
{
value
}
onChange
=
{
handleManualChange
}
showClear
=
{
showClear
}
rows
=
{
Math
.
max
(
8
,
value
?
value
.
split
(
'\n'
).
length
:
8
)}
rules
=
{
rules
}
noLabel
=
{
true
}
{...
props
}
/
>
)}
{
/* 额外文本在手动编辑模式下显示 */
}
{
extraText
&&
editMode
===
'manual'
&&
(
<
div
className
=
"text-xs text-gray-600"
>
{
extraText
}
<
/div
>
)}
<
/div
>
);
};
export
default
JSONEditor
;
\ No newline at end of file
web/src/components/table/channels/modals/EditChannelModal.jsx
View file @
6d2e92fb
...
...
@@ -48,6 +48,7 @@ import {
}
from
'@douyinfe/semi-ui'
;
import
{
getChannelModels
,
copy
,
getChannelIcon
,
getModelCategories
,
selectFilter
}
from
'../../../../helpers'
;
import
ModelSelectModal
from
'./ModelSelectModal'
;
import
JSONEditor
from
'../../../common/JSONEditor'
;
import
{
IconSave
,
IconClose
,
...
...
@@ -69,7 +70,9 @@ const STATUS_CODE_MAPPING_EXAMPLE = {
};
const
REGION_EXAMPLE
=
{
default
:
'us-central1'
,
"default"
:
'global'
,
"gemini-1.5-pro-002"
:
"europe-west2"
,
"gemini-1.5-flash-002"
:
"europe-west2"
,
'claude-3-5-sonnet-20240620'
:
'europe-west1'
,
};
...
...
@@ -1174,24 +1177,24 @@ const EditChannelModal = (props) => {
)
}
{
inputs
.
type
===
41
&&
(
<
Form
.
TextArea
<
JSONEditor
field=
'other'
label=
{
t
(
'部署地区'
)
}
placeholder=
{
t
(
'请输入部署地区,例如:
us
-
central1
\
n
支持使用模型映射格式\
n
{
\
n
"default"
:
"us-central1"
,
\
n
"claude-3-5-sonnet-20240620"
:
"europe-west1"
\
n
}
'
)
}
autosize
value=
{
inputs
.
other
||
''
}
onChange=
{
(
value
)
=>
handleInputChange
(
'other'
,
value
)
}
rules=
{
[{
required
:
true
,
message
:
t
(
'请填写部署地区'
)
}]
}
template=
{
REGION_EXAMPLE
}
templateLabel=
{
t
(
'填入模板'
)
}
editorType=
"region"
formApi=
{
formApiRef
.
current
}
extraText=
{
<
Text
className=
"!text-semi-color-primary cursor-pointer"
onClick=
{
()
=>
handleInputChange
(
'other'
,
JSON
.
stringify
(
REGION_EXAMPLE
,
null
,
2
))
}
>
{
t
(
'填入模板'
)
}
<
Text
type=
"tertiary"
size=
"small"
>
{
t
(
'设置默认地区和特定模型的专用地区'
)
}
</
Text
>
}
showClear
/>
)
}
...
...
@@ -1447,24 +1450,24 @@ const EditChannelModal = (props) => {
showClear
/>
<
Form
.
TextArea
<
JSONEditor
field=
'model_mapping'
label=
{
t
(
'模型重定向'
)
}
placeholder=
{
t
(
'此项可选,用于修改请求体中的模型名称,为一个 JSON 字符串,键为请求中模型名称,值为要替换的模型名称,例如:'
)
+
`\n${JSON.stringify(MODEL_MAPPING_EXAMPLE, null, 2)}`
}
autosize
value=
{
inputs
.
model_mapping
||
''
}
onChange=
{
(
value
)
=>
handleInputChange
(
'model_mapping'
,
value
)
}
template=
{
MODEL_MAPPING_EXAMPLE
}
templateLabel=
{
t
(
'填入模板'
)
}
editorType=
"keyValue"
formApi=
{
formApiRef
.
current
}
extraText=
{
<
Text
className=
"!text-semi-color-primary cursor-pointer"
onClick=
{
()
=>
handleInputChange
(
'model_mapping'
,
JSON
.
stringify
(
MODEL_MAPPING_EXAMPLE
,
null
,
2
))
}
>
{
t
(
'填入模板'
)
}
<
Text
type=
"tertiary"
size=
"small"
>
{
t
(
'键为请求中的模型名称,值为要替换的模型名称'
)
}
</
Text
>
}
showClear
/>
</
Card
>
...
...
@@ -1554,7 +1557,7 @@ const EditChannelModal = (props) => {
showClear
/>
<
Form
.
TextArea
<
JSONEditor
field=
'status_code_mapping'
label=
{
t
(
'状态码复写'
)
}
placeholder=
{
...
...
@@ -1562,17 +1565,17 @@ const EditChannelModal = (props) => {
'\n'
+
JSON
.
stringify
(
STATUS_CODE_MAPPING_EXAMPLE
,
null
,
2
)
}
autosize
value=
{
inputs
.
status_code_mapping
||
''
}
onChange=
{
(
value
)
=>
handleInputChange
(
'status_code_mapping'
,
value
)
}
template=
{
STATUS_CODE_MAPPING_EXAMPLE
}
templateLabel=
{
t
(
'填入模板'
)
}
editorType=
"keyValue"
formApi=
{
formApiRef
.
current
}
extraText=
{
<
Text
className=
"!text-semi-color-primary cursor-pointer"
onClick=
{
()
=>
handleInputChange
(
'status_code_mapping'
,
JSON
.
stringify
(
STATUS_CODE_MAPPING_EXAMPLE
,
null
,
2
))
}
>
{
t
(
'填入模板'
)
}
<
Text
type=
"tertiary"
size=
"small"
>
{
t
(
'键为原状态码,值为要复写的状态码,仅影响本地判断'
)
}
</
Text
>
}
showClear
/>
</
Card
>
...
...
@@ -1585,14 +1588,6 @@ const EditChannelModal = (props) => {
</
Avatar
>
<
div
>
<
Text
className=
"text-lg font-medium"
>
{
t
(
'渠道额外设置'
)
}
</
Text
>
<
div
className=
"text-xs text-gray-600"
>
<
Text
className=
"!text-semi-color-primary cursor-pointer"
onClick=
{
()
=>
window
.
open
(
'https://github.com/QuantumNous/new-api/blob/main/docs/channel/other_setting.md'
)
}
>
{
t
(
'设置说明'
)
}
</
Text
>
</
div
>
</
div
>
</
div
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment