chore: update default theme style

This commit is contained in:
JustSong 2025-01-31 23:08:07 +08:00
parent 38a42bb265
commit f2c7c424e9
2 changed files with 294 additions and 214 deletions

View File

@ -1,13 +1,29 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Button, Form, Header, Input, Message, Segment } from 'semantic-ui-react'; import {
Button,
Form,
Header,
Input,
Message,
Segment,
Card,
} from 'semantic-ui-react';
import { useNavigate, useParams } from 'react-router-dom'; import { useNavigate, useParams } from 'react-router-dom';
import { API, copy, getChannelModels, showError, showInfo, showSuccess, verifyJSON } from '../../helpers'; import {
API,
copy,
getChannelModels,
showError,
showInfo,
showSuccess,
verifyJSON,
} from '../../helpers';
import { CHANNEL_OPTIONS } from '../../constants'; import { CHANNEL_OPTIONS } from '../../constants';
const MODEL_MAPPING_EXAMPLE = { const MODEL_MAPPING_EXAMPLE = {
'gpt-3.5-turbo-0301': 'gpt-3.5-turbo', 'gpt-3.5-turbo-0301': 'gpt-3.5-turbo',
'gpt-4-0314': 'gpt-4', 'gpt-4-0314': 'gpt-4',
'gpt-4-32k-0314': 'gpt-4-32k' 'gpt-4-32k-0314': 'gpt-4-32k',
}; };
function type2secretPrompt(type) { function type2secretPrompt(type) {
@ -45,7 +61,7 @@ const EditChannel = () => {
model_mapping: '', model_mapping: '',
system_prompt: '', system_prompt: '',
models: [], models: [],
groups: ['default'] groups: ['default'],
}; };
const [batch, setBatch] = useState(false); const [batch, setBatch] = useState(false);
const [inputs, setInputs] = useState(originInputs); const [inputs, setInputs] = useState(originInputs);
@ -61,7 +77,7 @@ const EditChannel = () => {
ak: '', ak: '',
user_id: '', user_id: '',
vertex_ai_project_id: '', vertex_ai_project_id: '',
vertex_ai_adc: '' vertex_ai_adc: '',
}); });
const handleInputChange = (e, { name, value }) => { const handleInputChange = (e, { name, value }) => {
setInputs((inputs) => ({ ...inputs, [name]: value })); setInputs((inputs) => ({ ...inputs, [name]: value }));
@ -93,7 +109,11 @@ const EditChannel = () => {
data.groups = data.group.split(','); data.groups = data.group.split(',');
} }
if (data.model_mapping !== '') { if (data.model_mapping !== '') {
data.model_mapping = JSON.stringify(JSON.parse(data.model_mapping), null, 2); data.model_mapping = JSON.stringify(
JSON.parse(data.model_mapping),
null,
2
);
} }
setInputs(data); setInputs(data);
if (data.config !== '') { if (data.config !== '') {
@ -112,7 +132,7 @@ const EditChannel = () => {
let localModelOptions = res.data.data.map((model) => ({ let localModelOptions = res.data.data.map((model) => ({
key: model.id, key: model.id,
text: model.id, text: model.id,
value: model.id value: model.id,
})); }));
setOriginModelOptions(localModelOptions); setOriginModelOptions(localModelOptions);
setFullModels(res.data.data.map((model) => model.id)); setFullModels(res.data.data.map((model) => model.id));
@ -124,11 +144,13 @@ const EditChannel = () => {
const fetchGroups = async () => { const fetchGroups = async () => {
try { try {
let res = await API.get(`/api/group/`); let res = await API.get(`/api/group/`);
setGroupOptions(res.data.data.map((group) => ({ setGroupOptions(
key: group, res.data.data.map((group) => ({
text: group, key: group,
value: group text: group,
}))); value: group,
}))
);
} catch (error) { } catch (error) {
showError(error.message); showError(error.message);
} }
@ -141,7 +163,7 @@ const EditChannel = () => {
localModelOptions.push({ localModelOptions.push({
key: model, key: model,
text: model, text: model,
value: model value: model,
}); });
} }
}); });
@ -163,7 +185,11 @@ const EditChannel = () => {
if (inputs.key === '') { if (inputs.key === '') {
if (config.ak !== '' && config.sk !== '' && config.region !== '') { if (config.ak !== '' && config.sk !== '' && config.region !== '') {
inputs.key = `${config.ak}|${config.sk}|${config.region}`; inputs.key = `${config.ak}|${config.sk}|${config.region}`;
} else if (config.region !== '' && config.vertex_ai_project_id !== '' && config.vertex_ai_adc !== '') { } else if (
config.region !== '' &&
config.vertex_ai_project_id !== '' &&
config.vertex_ai_adc !== ''
) {
inputs.key = `${config.region}|${config.vertex_ai_project_id}|${config.vertex_ai_adc}`; inputs.key = `${config.region}|${config.vertex_ai_project_id}|${config.vertex_ai_adc}`;
} }
} }
@ -179,9 +205,12 @@ const EditChannel = () => {
showInfo('模型映射必须是合法的 JSON 格式!'); showInfo('模型映射必须是合法的 JSON 格式!');
return; return;
} }
let localInputs = {...inputs}; let localInputs = { ...inputs };
if (localInputs.base_url && localInputs.base_url.endsWith('/')) { if (localInputs.base_url && localInputs.base_url.endsWith('/')) {
localInputs.base_url = localInputs.base_url.slice(0, localInputs.base_url.length - 1); localInputs.base_url = localInputs.base_url.slice(
0,
localInputs.base_url.length - 1
);
} }
if (localInputs.type === 3 && localInputs.other === '') { if (localInputs.type === 3 && localInputs.other === '') {
localInputs.other = '2024-03-01-preview'; localInputs.other = '2024-03-01-preview';
@ -191,7 +220,10 @@ const EditChannel = () => {
localInputs.group = localInputs.groups.join(','); localInputs.group = localInputs.groups.join(',');
localInputs.config = JSON.stringify(config); localInputs.config = JSON.stringify(config);
if (isEdit) { if (isEdit) {
res = await API.put(`/api/channel/`, { ...localInputs, id: parseInt(channelId) }); res = await API.put(`/api/channel/`, {
...localInputs,
id: parseInt(channelId),
});
} else { } else {
res = await API.post(`/api/channel/`, localInputs); res = await API.post(`/api/channel/`, localInputs);
} }
@ -217,9 +249,9 @@ const EditChannel = () => {
localModelOptions.push({ localModelOptions.push({
key: customModel, key: customModel,
text: customModel, text: customModel,
value: customModel value: customModel,
}); });
setModelOptions(modelOptions => { setModelOptions((modelOptions) => {
return [...modelOptions, ...localModelOptions]; return [...modelOptions, ...localModelOptions];
}); });
setCustomModel(''); setCustomModel('');
@ -227,34 +259,45 @@ const EditChannel = () => {
}; };
return ( return (
<> <div className='dashboard-container'>
<Segment loading={loading}> <Card fluid className='chart-card'>
<Header as='h3'>{isEdit ? '更新渠道信息' : '创建新的渠道'}</Header> <Card.Content>
<Form autoComplete='new-password'> <Card.Header className='header'>
<Form.Field> {isEdit ? '更新渠道信息' : '创建新的渠道'}
<Form.Select </Card.Header>
label='类型' <Form loading={loading} autoComplete='new-password'>
name='type' <Form.Field>
required <Form.Select
search label='类型'
options={CHANNEL_OPTIONS} name='type'
value={inputs.type} required
onChange={handleInputChange} search
/> options={CHANNEL_OPTIONS}
</Form.Field> value={inputs.type}
{ onChange={handleInputChange}
inputs.type === 3 && ( />
</Form.Field>
{inputs.type === 3 && (
<> <>
<Message> <Message>
注意<strong>模型部署名称必须和模型名称保持一致</strong> One API model 注意<strong>模型部署名称必须和模型名称保持一致</strong>
参数替换为你的部署名称模型名称中的点会被剔除<a target='_blank' One API 会把请求体中的 model
href='https://github.com/songquanpeng/one-api/issues/133?notification_referrer_id=NT_kwDOAmJSYrM2NjIwMzI3NDgyOjM5OTk4MDUw#issuecomment-1571602271'>图片演示</a> 参数替换为你的部署名称模型名称中的点会被剔除
<a
target='_blank'
href='https://github.com/songquanpeng/one-api/issues/133?notification_referrer_id=NT_kwDOAmJSYrM2NjIwMzI3NDgyOjM5OTk4MDUw#issuecomment-1571602271'
>
图片演示
</a>
</Message> </Message>
<Form.Field> <Form.Field>
<Form.Input <Form.Input
label='AZURE_OPENAI_ENDPOINT' label='AZURE_OPENAI_ENDPOINT'
name='base_url' name='base_url'
placeholder={'请输入 AZURE_OPENAI_ENDPOINT例如https://docs-test-001.openai.azure.com'} placeholder={
'请输入 AZURE_OPENAI_ENDPOINT例如https://docs-test-001.openai.azure.com'
}
onChange={handleInputChange} onChange={handleInputChange}
value={inputs.base_url} value={inputs.base_url}
autoComplete='new-password' autoComplete='new-password'
@ -264,73 +307,72 @@ const EditChannel = () => {
<Form.Input <Form.Input
label='默认 API 版本' label='默认 API 版本'
name='other' name='other'
placeholder={'请输入默认 API 版本例如2024-03-01-preview该配置可以被实际的请求查询参数所覆盖'} placeholder={
'请输入默认 API 版本例如2024-03-01-preview该配置可以被实际的请求查询参数所覆盖'
}
onChange={handleInputChange} onChange={handleInputChange}
value={inputs.other} value={inputs.other}
autoComplete='new-password' autoComplete='new-password'
/> />
</Form.Field> </Form.Field>
</> </>
) )}
} {inputs.type === 8 && (
{
inputs.type === 8 && (
<Form.Field> <Form.Field>
<Form.Input <Form.Input
label='Base URL' label='Base URL'
name='base_url' name='base_url'
placeholder={'请输入自定义渠道的 Base URL例如https://openai.justsong.cn'} placeholder={
'请输入自定义渠道的 Base URL例如https://openai.justsong.cn'
}
onChange={handleInputChange} onChange={handleInputChange}
value={inputs.base_url} value={inputs.base_url}
autoComplete='new-password' autoComplete='new-password'
/> />
</Form.Field> </Form.Field>
) )}
} <Form.Field>
<Form.Field> <Form.Input
<Form.Input label='名称'
label='名称' name='name'
required placeholder={'请输入名称'}
name='name' onChange={handleInputChange}
placeholder={'请为渠道命名'} value={inputs.name}
onChange={handleInputChange} required
value={inputs.name} />
autoComplete='new-password' </Form.Field>
/> <Form.Field>
</Form.Field> <Form.Dropdown
<Form.Field> label='分组'
<Form.Dropdown placeholder={'请选择可以使用该渠道的分组'}
label='分组' name='groups'
placeholder={'请选择可以使用该渠道的分组'} required
name='groups' fluid
required multiple
fluid selection
multiple allowAdditions
selection additionLabel={'请在系统设置页面编辑分组倍率以添加新的分组:'}
allowAdditions onChange={handleInputChange}
additionLabel={'请在系统设置页面编辑分组倍率以添加新的分组:'} value={inputs.groups}
onChange={handleInputChange} autoComplete='new-password'
value={inputs.groups} options={groupOptions}
autoComplete='new-password' />
options={groupOptions} </Form.Field>
/> {inputs.type === 18 && (
</Form.Field>
{
inputs.type === 18 && (
<Form.Field> <Form.Field>
<Form.Input <Form.Input
label='模型版本' label='模型版本'
name='other' name='other'
placeholder={'请输入星火大模型版本注意是接口地址中的版本号例如v2.1'} placeholder={
'请输入星火大模型版本注意是接口地址中的版本号例如v2.1'
}
onChange={handleInputChange} onChange={handleInputChange}
value={inputs.other} value={inputs.other}
autoComplete='new-password' autoComplete='new-password'
/> />
</Form.Field> </Form.Field>
) )}
} {inputs.type === 21 && (
{
inputs.type === 21 && (
<Form.Field> <Form.Field>
<Form.Input <Form.Input
label='知识库 ID' label='知识库 ID'
@ -341,38 +383,40 @@ const EditChannel = () => {
autoComplete='new-password' autoComplete='new-password'
/> />
</Form.Field> </Form.Field>
) )}
} {inputs.type === 17 && (
{
inputs.type === 17 && (
<Form.Field> <Form.Field>
<Form.Input <Form.Input
label='插件参数' label='插件参数'
name='other' name='other'
placeholder={'请输入插件参数,即 X-DashScope-Plugin 请求头的取值'} placeholder={
'请输入插件参数,即 X-DashScope-Plugin 请求头的取值'
}
onChange={handleInputChange} onChange={handleInputChange}
value={inputs.other} value={inputs.other}
autoComplete='new-password' autoComplete='new-password'
/> />
</Form.Field> </Form.Field>
) )}
} {inputs.type === 34 && (
{
inputs.type === 34 && (
<Message> <Message>
对于 Coze 而言模型名称即 Bot ID你可以添加一个前缀 `bot-`例如`bot-123456` 对于 Coze 而言模型名称即 Bot ID你可以添加一个前缀
`bot-`例如`bot-123456`
</Message> </Message>
) )}
} {inputs.type === 40 && (
{
inputs.type === 40 && (
<Message> <Message>
对于豆包而言需要手动去 <a target="_blank" href="https://console.volcengine.com/ark/region:ark+cn-beijing/endpoint">模型推理页面</a> `ep-20240608051426-tkxvl` 对于豆包而言需要手动去{' '}
<a
target='_blank'
href='https://console.volcengine.com/ark/region:ark+cn-beijing/endpoint'
>
模型推理页面
</a>{' '}
创建推理接入点以接入点名称作为模型名称例如`ep-20240608051426-tkxvl`
</Message> </Message>
) )}
} {inputs.type !== 43 && (
{
inputs.type !== 43 && (
<Form.Field> <Form.Field>
<Form.Dropdown <Form.Dropdown
label='模型' label='模型'
@ -392,23 +436,44 @@ const EditChannel = () => {
options={modelOptions} options={modelOptions}
/> />
</Form.Field> </Form.Field>
) )}
} {inputs.type !== 43 && (
{
inputs.type !== 43 && (
<div style={{ lineHeight: '40px', marginBottom: '12px' }}> <div style={{ lineHeight: '40px', marginBottom: '12px' }}>
<Button type={'button'} onClick={() => { <Button
handleInputChange(null, { name: 'models', value: basicModels }); type={'button'}
}}>填入相关模型</Button> onClick={() => {
<Button type={'button'} onClick={() => { handleInputChange(null, {
handleInputChange(null, { name: 'models', value: fullModels }); name: 'models',
}}>填入所有模型</Button> value: basicModels,
<Button type={'button'} onClick={() => { });
handleInputChange(null, { name: 'models', value: [] }); }}
}}>清除所有模型</Button> >
填入相关模型
</Button>
<Button
type={'button'}
onClick={() => {
handleInputChange(null, {
name: 'models',
value: fullModels,
});
}}
>
填入所有模型
</Button>
<Button
type={'button'}
onClick={() => {
handleInputChange(null, { name: 'models', value: [] });
}}
>
清除所有模型
</Button>
<Input <Input
action={ action={
<Button type={'button'} onClick={addCustomModel}>填入</Button> <Button type={'button'} onClick={addCustomModel}>
填入
</Button>
} }
placeholder='输入自定义模型名称' placeholder='输入自定义模型名称'
value={customModel} value={customModel}
@ -423,37 +488,44 @@ const EditChannel = () => {
}} }}
/> />
</div> </div>
) )}
} {inputs.type !== 43 && (
{ <>
inputs.type !== 43 && (<> <Form.Field>
<Form.Field> <Form.TextArea
<Form.TextArea label='模型重定向'
label='模型重定向' placeholder={`此项可选,用于修改请求体中的模型名称,为一个 JSON 字符串,键为请求中模型名称,值为要替换的模型名称,例如:\n${JSON.stringify(
placeholder={`此项可选,用于修改请求体中的模型名称,为一个 JSON 字符串,键为请求中模型名称,值为要替换的模型名称,例如:\n${JSON.stringify(MODEL_MAPPING_EXAMPLE, null, 2)}`} MODEL_MAPPING_EXAMPLE,
name='model_mapping' null,
onChange={handleInputChange} 2
value={inputs.model_mapping} )}`}
style={{ minHeight: 150, fontFamily: 'JetBrains Mono, Consolas' }} name='model_mapping'
autoComplete='new-password' onChange={handleInputChange}
/> value={inputs.model_mapping}
</Form.Field> style={{
<Form.Field> minHeight: 150,
<Form.TextArea fontFamily: 'JetBrains Mono, Consolas',
label='系统提示词' }}
placeholder={`此项可选,用于强制设置给定的系统提示词,请配合自定义模型 & 模型重定向使用,首先创建一个唯一的自定义模型名称并在上面填入,之后将该自定义模型重定向映射到该渠道一个原生支持的模型`} autoComplete='new-password'
name='system_prompt' />
onChange={handleInputChange} </Form.Field>
value={inputs.system_prompt} <Form.Field>
style={{ minHeight: 150, fontFamily: 'JetBrains Mono, Consolas' }} <Form.TextArea
autoComplete='new-password' label='系统提示词'
/> placeholder={`此项可选,用于强制设置给定的系统提示词,请配合自定义模型 & 模型重定向使用,首先创建一个唯一的自定义模型名称并在上面填入,之后将该自定义模型重定向映射到该渠道一个原生支持的模型`}
</Form.Field> name='system_prompt'
onChange={handleInputChange}
value={inputs.system_prompt}
style={{
minHeight: 150,
fontFamily: 'JetBrains Mono, Consolas',
}}
autoComplete='new-password'
/>
</Form.Field>
</> </>
) )}
} {inputs.type === 33 && (
{
inputs.type === 33 && (
<Form.Field> <Form.Field>
<Form.Input <Form.Input
label='Region' label='Region'
@ -483,10 +555,8 @@ const EditChannel = () => {
autoComplete='' autoComplete=''
/> />
</Form.Field> </Form.Field>
) )}
} {inputs.type === 42 && (
{
inputs.type === 42 && (
<Form.Field> <Form.Field>
<Form.Input <Form.Input
label='Region' label='Region'
@ -510,16 +580,16 @@ const EditChannel = () => {
label='Google Cloud Application Default Credentials JSON' label='Google Cloud Application Default Credentials JSON'
name='vertex_ai_adc' name='vertex_ai_adc'
required required
placeholder={'Google Cloud Application Default Credentials JSON'} placeholder={
'Google Cloud Application Default Credentials JSON'
}
onChange={handleConfigChange} onChange={handleConfigChange}
value={config.vertex_ai_adc} value={config.vertex_ai_adc}
autoComplete='' autoComplete=''
/> />
</Form.Field> </Form.Field>
) )}
} {inputs.type === 34 && (
{
inputs.type === 34 && (
<Form.Input <Form.Input
label='User ID' label='User ID'
name='user_id' name='user_id'
@ -528,90 +598,101 @@ const EditChannel = () => {
onChange={handleConfigChange} onChange={handleConfigChange}
value={config.user_id} value={config.user_id}
autoComplete='' autoComplete=''
/>)
}
{
inputs.type !== 33 && inputs.type !== 42 && (batch ? <Form.Field>
<Form.TextArea
label='密钥'
name='key'
required
placeholder={'请输入密钥,一行一个'}
onChange={handleInputChange}
value={inputs.key}
style={{ minHeight: 150, fontFamily: 'JetBrains Mono, Consolas' }}
autoComplete='new-password'
/> />
</Form.Field> : <Form.Field> )}
<Form.Input {inputs.type !== 33 &&
label='密钥' inputs.type !== 42 &&
name='key' (batch ? (
required <Form.Field>
placeholder={type2secretPrompt(inputs.type)} <Form.TextArea
onChange={handleInputChange} label='密钥'
value={inputs.key} name='key'
autoComplete='new-password' required
/> placeholder={'请输入密钥,一行一个'}
</Form.Field>) onChange={handleInputChange}
} value={inputs.key}
{ style={{
inputs.type === 37 && ( minHeight: 150,
fontFamily: 'JetBrains Mono, Consolas',
}}
autoComplete='new-password'
/>
</Form.Field>
) : (
<Form.Field>
<Form.Input
label='密钥'
name='key'
required
placeholder={type2secretPrompt(inputs.type)}
onChange={handleInputChange}
value={inputs.key}
autoComplete='new-password'
/>
</Form.Field>
))}
{inputs.type === 37 && (
<Form.Field> <Form.Field>
<Form.Input <Form.Input
label='Account ID' label='Account ID'
name='user_id' name='user_id'
required required
placeholder={'请输入 Account ID例如d8d7c61dbc334c32d3ced580e4bf42b4'} placeholder={
'请输入 Account ID例如d8d7c61dbc334c32d3ced580e4bf42b4'
}
onChange={handleConfigChange} onChange={handleConfigChange}
value={config.user_id} value={config.user_id}
autoComplete='' autoComplete=''
/> />
</Form.Field> </Form.Field>
) )}
} {inputs.type !== 33 && !isEdit && (
{
inputs.type !== 33 && !isEdit && (
<Form.Checkbox <Form.Checkbox
checked={batch} checked={batch}
label='批量创建' label='批量创建'
name='batch' name='batch'
onChange={() => setBatch(!batch)} onChange={() => setBatch(!batch)}
/> />
) )}
} {inputs.type !== 3 &&
{ inputs.type !== 33 &&
inputs.type !== 3 && inputs.type !== 33 && inputs.type !== 8 && inputs.type !== 22 && ( inputs.type !== 8 &&
<Form.Field> inputs.type !== 22 && (
<Form.Input <Form.Field>
label='代理' <Form.Input
name='base_url' label='代理'
placeholder={'此项可选,用于通过代理站来进行 API 调用请输入代理站地址格式为https://domain.com'} name='base_url'
onChange={handleInputChange} placeholder={
value={inputs.base_url} '此项可选,用于通过代理站来进行 API 调用请输入代理站地址格式为https://domain.com'
autoComplete='new-password' }
/> onChange={handleInputChange}
</Form.Field> value={inputs.base_url}
) autoComplete='new-password'
} />
{ </Form.Field>
inputs.type === 22 && ( )}
{inputs.type === 22 && (
<Form.Field> <Form.Field>
<Form.Input <Form.Input
label='私有部署地址' label='私有部署地址'
name='base_url' name='base_url'
placeholder={'请输入私有部署地址格式为https://fastgpt.run/api/openapi'} placeholder={
'请输入私有部署地址格式为https://fastgpt.run/api/openapi'
}
onChange={handleInputChange} onChange={handleInputChange}
value={inputs.base_url} value={inputs.base_url}
autoComplete='new-password' autoComplete='new-password'
/> />
</Form.Field> </Form.Field>
) )}
} <Button onClick={handleCancel}>取消</Button>
<Button onClick={handleCancel}>取消</Button> <Button type={isEdit ? 'button' : 'submit'} positive onClick={submit}>
<Button type={isEdit ? 'button' : 'submit'} positive onClick={submit}>提交</Button> 提交
</Form> </Button>
</Segment> </Form>
</> </Card.Content>
</Card>
</div>
); );
}; };

View File

@ -54,7 +54,6 @@
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
font-weight: 600; font-weight: 600;
padding: 0 8px;
gap: 12px; /* 增加标题和数值之间的间距 */ gap: 12px; /* 增加标题和数值之间的间距 */
} }