mirror of
https://github.com/linux-do/new-api.git
synced 2025-11-09 23:53:41 +08:00
feat: 弃用旧的聊天配置
This commit is contained in:
34
constant/chat.go
Normal file
34
constant/chat.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package constant
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"one-api/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Chats = []map[string]string{
|
||||||
|
{
|
||||||
|
"ChatGPT Next Web 官方示例": "https://app.nextchat.dev/#/?settings={\"key\":\"{key}\",\"url\":\"{address}\"}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Lobe Chat 官方示例": "https://chat-preview.lobehub.com/?settings={\"keyVaults\":{\"openai\":{\"apiKey\":\"{key}\",\"baseURL\":\"{address}/v1\"}}}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"AMA 问天": "ama://set-api-key?server={address}&key={key}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"OpenCat": "opencat://team/join?domain={address}&token={key}",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateChatsByJsonString(jsonString string) error {
|
||||||
|
return json.Unmarshal([]byte(jsonString), &Chats)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Chats2JsonString() string {
|
||||||
|
jsonBytes, err := json.Marshal(Chats)
|
||||||
|
if err != nil {
|
||||||
|
common.SysError("error marshalling chats: " + err.Error())
|
||||||
|
return "[]"
|
||||||
|
}
|
||||||
|
return string(jsonBytes)
|
||||||
|
}
|
||||||
@@ -63,6 +63,7 @@ func GetStatus(c *gin.Context) {
|
|||||||
"default_collapse_sidebar": common.DefaultCollapseSidebar,
|
"default_collapse_sidebar": common.DefaultCollapseSidebar,
|
||||||
"enable_online_topup": constant.PayAddress != "" && constant.EpayId != "" && constant.EpayKey != "",
|
"enable_online_topup": constant.PayAddress != "" && constant.EpayId != "" && constant.EpayKey != "",
|
||||||
"mj_notify_enabled": constant.MjNotifyEnabled,
|
"mj_notify_enabled": constant.MjNotifyEnabled,
|
||||||
|
"chats": constant.Chats,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ func InitOptionMap() {
|
|||||||
common.OptionMap["Price"] = strconv.FormatFloat(constant.Price, 'f', -1, 64)
|
common.OptionMap["Price"] = strconv.FormatFloat(constant.Price, 'f', -1, 64)
|
||||||
common.OptionMap["MinTopUp"] = strconv.Itoa(constant.MinTopUp)
|
common.OptionMap["MinTopUp"] = strconv.Itoa(constant.MinTopUp)
|
||||||
common.OptionMap["TopupGroupRatio"] = common.TopupGroupRatio2JSONString()
|
common.OptionMap["TopupGroupRatio"] = common.TopupGroupRatio2JSONString()
|
||||||
|
common.OptionMap["Chats"] = constant.Chats2JsonString()
|
||||||
common.OptionMap["GitHubClientId"] = ""
|
common.OptionMap["GitHubClientId"] = ""
|
||||||
common.OptionMap["GitHubClientSecret"] = ""
|
common.OptionMap["GitHubClientSecret"] = ""
|
||||||
common.OptionMap["TelegramBotToken"] = ""
|
common.OptionMap["TelegramBotToken"] = ""
|
||||||
@@ -248,6 +249,8 @@ func updateOptionMap(key string, value string) (err error) {
|
|||||||
constant.WorkerValidKey = value
|
constant.WorkerValidKey = value
|
||||||
case "PayAddress":
|
case "PayAddress":
|
||||||
constant.PayAddress = value
|
constant.PayAddress = value
|
||||||
|
case "Chats":
|
||||||
|
err = constant.UpdateChatsByJsonString(value)
|
||||||
case "CustomCallbackAddress":
|
case "CustomCallbackAddress":
|
||||||
constant.CustomCallbackAddress = value
|
constant.CustomCallbackAddress = value
|
||||||
case "EpayId":
|
case "EpayId":
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import SettingsCreditLimit from '../pages/Setting/Operation/SettingsCreditLimit.
|
|||||||
import SettingsMagnification from '../pages/Setting/Operation/SettingsMagnification.js';
|
import SettingsMagnification from '../pages/Setting/Operation/SettingsMagnification.js';
|
||||||
|
|
||||||
import { API, showError, showSuccess } from '../helpers';
|
import { API, showError, showSuccess } from '../helpers';
|
||||||
|
import SettingsChats from '../pages/Setting/Operation/SettingsChats.js';
|
||||||
|
|
||||||
const OperationSetting = () => {
|
const OperationSetting = () => {
|
||||||
let [inputs, setInputs] = useState({
|
let [inputs, setInputs] = useState({
|
||||||
@@ -50,6 +51,7 @@ const OperationSetting = () => {
|
|||||||
DataExportInterval: 5,
|
DataExportInterval: 5,
|
||||||
DefaultCollapseSidebar: false, // 默认折叠侧边栏
|
DefaultCollapseSidebar: false, // 默认折叠侧边栏
|
||||||
RetryTimes: 0,
|
RetryTimes: 0,
|
||||||
|
Chats: "[]",
|
||||||
});
|
});
|
||||||
|
|
||||||
let [loading, setLoading] = useState(false);
|
let [loading, setLoading] = useState(false);
|
||||||
@@ -131,6 +133,10 @@ const OperationSetting = () => {
|
|||||||
<Card style={{ marginTop: '10px' }}>
|
<Card style={{ marginTop: '10px' }}>
|
||||||
<SettingsCreditLimit options={inputs} refresh={onRefresh} />
|
<SettingsCreditLimit options={inputs} refresh={onRefresh} />
|
||||||
</Card>
|
</Card>
|
||||||
|
{/* 聊天设置 */}
|
||||||
|
<Card style={{ marginTop: '10px' }}>
|
||||||
|
<SettingsChats options={inputs} refresh={onRefresh} />
|
||||||
|
</Card>
|
||||||
{/* 倍率设置 */}
|
{/* 倍率设置 */}
|
||||||
<Card style={{ marginTop: '10px' }}>
|
<Card style={{ marginTop: '10px' }}>
|
||||||
<SettingsMagnification options={inputs} refresh={onRefresh} />
|
<SettingsMagnification options={inputs} refresh={onRefresh} />
|
||||||
|
|||||||
@@ -24,17 +24,6 @@ import {
|
|||||||
import { IconTreeTriangleDown } from '@douyinfe/semi-icons';
|
import { IconTreeTriangleDown } from '@douyinfe/semi-icons';
|
||||||
import EditToken from '../pages/Token/EditToken';
|
import EditToken from '../pages/Token/EditToken';
|
||||||
|
|
||||||
const COPY_OPTIONS = [
|
|
||||||
{ key: 'next', text: 'ChatGPT Next Web', value: 'next' },
|
|
||||||
{ key: 'ama', text: 'ChatGPT Web & Midjourney', value: 'ama' },
|
|
||||||
{ key: 'opencat', text: 'OpenCat', value: 'opencat' },
|
|
||||||
];
|
|
||||||
|
|
||||||
const OPEN_LINK_OPTIONS = [
|
|
||||||
{ key: 'ama', text: 'ChatGPT Web & Midjourney', value: 'ama' },
|
|
||||||
{ key: 'opencat', text: 'OpenCat', value: 'opencat' },
|
|
||||||
];
|
|
||||||
|
|
||||||
function renderTimestamp(timestamp) {
|
function renderTimestamp(timestamp) {
|
||||||
return <>{timestamp2string(timestamp)}</>;
|
return <>{timestamp2string(timestamp)}</>;
|
||||||
}
|
}
|
||||||
@@ -87,27 +76,6 @@ function renderStatus(status, model_limits_enabled = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const TokensTable = () => {
|
const TokensTable = () => {
|
||||||
const link_menu = [
|
|
||||||
{
|
|
||||||
node: 'item',
|
|
||||||
key: 'next',
|
|
||||||
name: 'ChatGPT Next Web',
|
|
||||||
onClick: () => {
|
|
||||||
onOpenLink('next');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{ node: 'item', key: 'ama', name: 'AMA 问天', value: 'ama' },
|
|
||||||
{
|
|
||||||
node: 'item',
|
|
||||||
key: 'next-mj',
|
|
||||||
name: 'ChatGPT Web & Midjourney',
|
|
||||||
value: 'next-mj',
|
|
||||||
onClick: () => {
|
|
||||||
onOpenLink('next-mj');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{ node: 'item', key: 'opencat', name: 'OpenCat', value: 'opencat' },
|
|
||||||
];
|
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
@@ -174,7 +142,67 @@ const TokensTable = () => {
|
|||||||
{
|
{
|
||||||
title: '',
|
title: '',
|
||||||
dataIndex: 'operate',
|
dataIndex: 'operate',
|
||||||
render: (text, record, index) => (
|
render: (text, record, index) => {
|
||||||
|
let chats = localStorage.getItem('chats');
|
||||||
|
let chatsArray = []
|
||||||
|
let chatLink = localStorage.getItem('chat_link');
|
||||||
|
let mjLink = localStorage.getItem('chat_link2');
|
||||||
|
let shouldUseCustom = true;
|
||||||
|
if (chatLink) {
|
||||||
|
shouldUseCustom = false;
|
||||||
|
chatLink += `/#/?settings={"key":"{key}","url":"{address}"}`;
|
||||||
|
chatsArray.push({
|
||||||
|
node: 'item',
|
||||||
|
key: 'default',
|
||||||
|
name: 'ChatGPT Next Web',
|
||||||
|
onClick: () => {
|
||||||
|
onOpenLink('default', chatLink, record);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (mjLink) {
|
||||||
|
shouldUseCustom = false;
|
||||||
|
mjLink += `/#/?settings={"key":"{key}","url":"{address}"}`;
|
||||||
|
chatsArray.push({
|
||||||
|
node: 'item',
|
||||||
|
key: 'mj',
|
||||||
|
name: 'ChatGPT Next Midjourney',
|
||||||
|
onClick: () => {
|
||||||
|
onOpenLink('mj', mjLink, record);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (shouldUseCustom) {
|
||||||
|
try {
|
||||||
|
// console.log(chats);
|
||||||
|
chats = JSON.parse(chats);
|
||||||
|
// check chats is array
|
||||||
|
if (Array.isArray(chats)) {
|
||||||
|
for (let i = 0; i < chats.length; i++) {
|
||||||
|
let chat = {}
|
||||||
|
chat.node = 'item';
|
||||||
|
// c is a map
|
||||||
|
// chat.key = chats[i].name;
|
||||||
|
// console.log(chats[i])
|
||||||
|
for (let key in chats[i]) {
|
||||||
|
if (chats[i].hasOwnProperty(key)) {
|
||||||
|
chat.key = i;
|
||||||
|
chat.name = key;
|
||||||
|
chat.onClick = () => {
|
||||||
|
onOpenLink(key, chats[i][key], record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chatsArray.push(chat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
showError('聊天链接配置错误,请联系管理员');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Popover
|
<Popover
|
||||||
content={'sk-' + record.key}
|
content={'sk-' + record.key}
|
||||||
@@ -203,7 +231,11 @@ const TokensTable = () => {
|
|||||||
theme='light'
|
theme='light'
|
||||||
style={{ color: 'rgba(var(--semi-teal-7), 1)' }}
|
style={{ color: 'rgba(var(--semi-teal-7), 1)' }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
onOpenLink('next', record.key);
|
if (chatsArray.length === 0) {
|
||||||
|
showError('请联系管理员配置聊天链接');
|
||||||
|
} else {
|
||||||
|
onOpenLink('default', chats[0][Object.keys(chats[0])[0]], record);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
聊天
|
聊天
|
||||||
@@ -211,50 +243,7 @@ const TokensTable = () => {
|
|||||||
<Dropdown
|
<Dropdown
|
||||||
trigger='click'
|
trigger='click'
|
||||||
position='bottomRight'
|
position='bottomRight'
|
||||||
menu={[
|
menu={chatsArray}
|
||||||
{
|
|
||||||
node: 'item',
|
|
||||||
key: 'next',
|
|
||||||
disabled: !localStorage.getItem('chat_link'),
|
|
||||||
name: 'ChatGPT Next Web',
|
|
||||||
onClick: () => {
|
|
||||||
onOpenLink('next', record.key);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: 'item',
|
|
||||||
key: 'next-mj',
|
|
||||||
disabled: !localStorage.getItem('chat_link2'),
|
|
||||||
name: 'ChatGPT Web & Midjourney',
|
|
||||||
onClick: () => {
|
|
||||||
onOpenLink('next-mj', record.key);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// node: 'item',
|
|
||||||
// key: 'lobe',
|
|
||||||
// name: 'Lobe Chat',
|
|
||||||
// onClick: () => {
|
|
||||||
// onOpenLink('lobe', record.key);
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
node: 'item',
|
|
||||||
key: 'ama',
|
|
||||||
name: 'AMA 问天(BotGem)',
|
|
||||||
onClick: () => {
|
|
||||||
onOpenLink('ama', record.key);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: 'item',
|
|
||||||
key: 'opencat',
|
|
||||||
name: 'OpenCat',
|
|
||||||
onClick: () => {
|
|
||||||
onOpenLink('opencat', record.key);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
style={{
|
style={{
|
||||||
@@ -316,7 +305,8 @@ const TokensTable = () => {
|
|||||||
编辑
|
编辑
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
),
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -330,8 +320,7 @@ const TokensTable = () => {
|
|||||||
const [searchKeyword, setSearchKeyword] = useState('');
|
const [searchKeyword, setSearchKeyword] = useState('');
|
||||||
const [searchToken, setSearchToken] = useState('');
|
const [searchToken, setSearchToken] = useState('');
|
||||||
const [searching, setSearching] = useState(false);
|
const [searching, setSearching] = useState(false);
|
||||||
const [showTopUpModal, setShowTopUpModal] = useState(false);
|
const [chats, setChats] = useState([]);
|
||||||
const [targetTokenIdx, setTargetTokenIdx] = useState(0);
|
|
||||||
const [editingToken, setEditingToken] = useState({
|
const [editingToken, setEditingToken] = useState({
|
||||||
id: undefined,
|
id: undefined,
|
||||||
});
|
});
|
||||||
@@ -376,16 +365,6 @@ const TokensTable = () => {
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onPaginationChange = (e, { activePage }) => {
|
|
||||||
(async () => {
|
|
||||||
if (activePage === Math.ceil(tokens.length / pageSize) + 1) {
|
|
||||||
// In this case we have to load more data and then append them.
|
|
||||||
await loadTokens(activePage - 1);
|
|
||||||
}
|
|
||||||
setActivePage(activePage);
|
|
||||||
})();
|
|
||||||
};
|
|
||||||
|
|
||||||
const refresh = async () => {
|
const refresh = async () => {
|
||||||
await loadTokens(activePage - 1);
|
await loadTokens(activePage - 1);
|
||||||
};
|
};
|
||||||
@@ -402,7 +381,8 @@ const TokensTable = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onOpenLink = async (type, key) => {
|
const onOpenLink = async (type, url, record) => {
|
||||||
|
// console.log(type, url, key);
|
||||||
let status = localStorage.getItem('status');
|
let status = localStorage.getItem('status');
|
||||||
let serverAddress = '';
|
let serverAddress = '';
|
||||||
if (status) {
|
if (status) {
|
||||||
@@ -413,36 +393,39 @@ const TokensTable = () => {
|
|||||||
serverAddress = window.location.origin;
|
serverAddress = window.location.origin;
|
||||||
}
|
}
|
||||||
let encodedServerAddress = encodeURIComponent(serverAddress);
|
let encodedServerAddress = encodeURIComponent(serverAddress);
|
||||||
const chatLink = localStorage.getItem('chat_link');
|
url = url.replace('{address}', encodedServerAddress);
|
||||||
const mjLink = localStorage.getItem('chat_link2');
|
url = url.replace('{key}', 'sk-' + record.key);
|
||||||
let defaultUrl;
|
// console.log(url);
|
||||||
|
// const chatLink = localStorage.getItem('chat_link');
|
||||||
if (chatLink) {
|
// const mjLink = localStorage.getItem('chat_link2');
|
||||||
defaultUrl =
|
// let defaultUrl;
|
||||||
chatLink + `/#/?settings={"key":"sk-${key}","url":"${serverAddress}"}`;
|
//
|
||||||
}
|
// if (chatLink) {
|
||||||
let url;
|
// defaultUrl =
|
||||||
switch (type) {
|
// chatLink + `/#/?settings={"key":"sk-${key}","url":"${serverAddress}"}`;
|
||||||
case 'ama':
|
// }
|
||||||
url = `ama://set-api-key?server=${encodedServerAddress}&key=sk-${key}`;
|
// let url;
|
||||||
break;
|
// switch (type) {
|
||||||
case 'opencat':
|
// case 'ama':
|
||||||
url = `opencat://team/join?domain=${encodedServerAddress}&token=sk-${key}`;
|
// url = `ama://set-api-key?server=${encodedServerAddress}&key=sk-${key}`;
|
||||||
break;
|
// break;
|
||||||
case 'lobe':
|
// case 'opencat':
|
||||||
url = `https://chat-preview.lobehub.com/?settings={"keyVaults":{"openai":{"apiKey":"sk-${key}","baseURL":"${encodedServerAddress}/v1"}}}`;
|
// url = `opencat://team/join?domain=${encodedServerAddress}&token=sk-${key}`;
|
||||||
break;
|
// break;
|
||||||
case 'next-mj':
|
// case 'lobe':
|
||||||
url =
|
// url = `https://chat-preview.lobehub.com/?settings={"keyVaults":{"openai":{"apiKey":"sk-${key}","baseURL":"${encodedServerAddress}/v1"}}}`;
|
||||||
mjLink + `/#/?settings={"key":"sk-${key}","url":"${serverAddress}"}`;
|
// break;
|
||||||
break;
|
// case 'next-mj':
|
||||||
default:
|
// url =
|
||||||
if (!chatLink) {
|
// mjLink + `/#/?settings={"key":"sk-${key}","url":"${serverAddress}"}`;
|
||||||
showError('管理员未设置聊天链接');
|
// break;
|
||||||
return;
|
// default:
|
||||||
}
|
// if (!chatLink) {
|
||||||
url = defaultUrl;
|
// showError('管理员未设置聊天链接');
|
||||||
}
|
// return;
|
||||||
|
// }
|
||||||
|
// url = defaultUrl;
|
||||||
|
// }
|
||||||
|
|
||||||
window.open(url, '_blank');
|
window.open(url, '_blank');
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export function setStatusData(data) {
|
|||||||
localStorage.setItem('enable_drawing', data.enable_drawing);
|
localStorage.setItem('enable_drawing', data.enable_drawing);
|
||||||
localStorage.setItem('enable_task', data.enable_task);
|
localStorage.setItem('enable_task', data.enable_task);
|
||||||
localStorage.setItem('enable_data_export', data.enable_data_export);
|
localStorage.setItem('enable_data_export', data.enable_data_export);
|
||||||
|
localStorage.setItem('chats', JSON.stringify(data.chats));
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'data_export_default_time',
|
'data_export_default_time',
|
||||||
data.data_export_default_time,
|
data.data_export_default_time,
|
||||||
|
|||||||
148
web/src/pages/Setting/Operation/SettingsChats.js
Normal file
148
web/src/pages/Setting/Operation/SettingsChats.js
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
import React, { useEffect, useState, useRef } from 'react';
|
||||||
|
import { Banner, Button, Col, Form, Popconfirm, Row, Space, Spin } from '@douyinfe/semi-ui';
|
||||||
|
import {
|
||||||
|
compareObjects,
|
||||||
|
API,
|
||||||
|
showError,
|
||||||
|
showSuccess,
|
||||||
|
showWarning,
|
||||||
|
verifyJSON,
|
||||||
|
verifyJSONPromise
|
||||||
|
} from '../../../helpers';
|
||||||
|
|
||||||
|
export default function SettingsChats(props) {
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [inputs, setInputs] = useState({
|
||||||
|
Chats: "[]",
|
||||||
|
});
|
||||||
|
const refForm = useRef();
|
||||||
|
const [inputsRow, setInputsRow] = useState(inputs);
|
||||||
|
|
||||||
|
async function onSubmit() {
|
||||||
|
try {
|
||||||
|
console.log('Starting validation...');
|
||||||
|
await refForm.current.validate().then(() => {
|
||||||
|
console.log('Validation passed');
|
||||||
|
const updateArray = compareObjects(inputs, inputsRow);
|
||||||
|
if (!updateArray.length) return showWarning('你似乎并没有修改什么');
|
||||||
|
const requestQueue = updateArray.map((item) => {
|
||||||
|
let value = '';
|
||||||
|
if (typeof inputs[item.key] === 'boolean') {
|
||||||
|
value = String(inputs[item.key]);
|
||||||
|
} else {
|
||||||
|
value = inputs[item.key];
|
||||||
|
}
|
||||||
|
return API.put('/api/option/', {
|
||||||
|
key: item.key,
|
||||||
|
value
|
||||||
|
});
|
||||||
|
});
|
||||||
|
setLoading(true);
|
||||||
|
Promise.all(requestQueue)
|
||||||
|
.then((res) => {
|
||||||
|
if (requestQueue.length === 1) {
|
||||||
|
if (res.includes(undefined)) return;
|
||||||
|
} else if (requestQueue.length > 1) {
|
||||||
|
if (res.includes(undefined))
|
||||||
|
return showError('部分保存失败,请重试');
|
||||||
|
}
|
||||||
|
showSuccess('保存成功');
|
||||||
|
props.refresh();
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
showError('保存失败,请重试');
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error('Validation failed:', error);
|
||||||
|
showError('请检查输入');
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
showError('请检查输入');
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function resetModelRatio() {
|
||||||
|
try {
|
||||||
|
let res = await API.post(`/api/option/rest_model_ratio`);
|
||||||
|
// return {success, message}
|
||||||
|
if (res.data.success) {
|
||||||
|
showSuccess(res.data.message);
|
||||||
|
props.refresh();
|
||||||
|
} else {
|
||||||
|
showError(res.data.message);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
showError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const currentInputs = {};
|
||||||
|
for (let key in props.options) {
|
||||||
|
if (Object.keys(inputs).includes(key)) {
|
||||||
|
if (key === 'Chats') {
|
||||||
|
const obj = JSON.parse(props.options[key]);
|
||||||
|
currentInputs[key] = JSON.stringify(obj, null, 2);
|
||||||
|
} else {
|
||||||
|
currentInputs[key] = props.options[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setInputs(currentInputs);
|
||||||
|
setInputsRow(structuredClone(currentInputs));
|
||||||
|
refForm.current.setValues(currentInputs);
|
||||||
|
}, [props.options]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Spin spinning={loading}>
|
||||||
|
<Form
|
||||||
|
values={inputs}
|
||||||
|
getFormApi={(formAPI) => (refForm.current = formAPI)}
|
||||||
|
style={{ marginBottom: 15 }}
|
||||||
|
>
|
||||||
|
<Form.Section text={'令牌聊天设置'}>
|
||||||
|
<Banner
|
||||||
|
type='warning'
|
||||||
|
description={'必须将上方聊天链接全部设置为空,才能使用下方聊天设置功能'}
|
||||||
|
/>
|
||||||
|
<Banner
|
||||||
|
type='info'
|
||||||
|
description={'链接中的{key}将自动替换为sk-xxxx,{address}将自动替换为系统设置的服务器地址,末尾不带/和/v1'}
|
||||||
|
/>
|
||||||
|
<Form.TextArea
|
||||||
|
label={'聊天配置'}
|
||||||
|
extraText={''}
|
||||||
|
placeholder={'为一个 JSON 文本'}
|
||||||
|
field={'Chats'}
|
||||||
|
autosize={{ minRows: 6, maxRows: 12 }}
|
||||||
|
trigger='blur'
|
||||||
|
stopValidateWithError
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
validator: (rule, value) => {
|
||||||
|
return verifyJSON(value);
|
||||||
|
},
|
||||||
|
message: '不是合法的 JSON 字符串'
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
onChange={(value) =>
|
||||||
|
setInputs({
|
||||||
|
...inputs,
|
||||||
|
Chats: value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Form.Section>
|
||||||
|
</Form>
|
||||||
|
<Space>
|
||||||
|
<Button onClick={onSubmit}>
|
||||||
|
保存聊天设置
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
</Spin>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect, useState, useRef } from 'react';
|
import React, { useEffect, useState, useRef } from 'react';
|
||||||
import { Button, Col, Form, Row, Spin } from '@douyinfe/semi-ui';
|
import { Banner, Button, Col, Form, Row, Spin } from '@douyinfe/semi-ui';
|
||||||
import {
|
import {
|
||||||
compareObjects,
|
compareObjects,
|
||||||
API,
|
API,
|
||||||
@@ -74,6 +74,10 @@ export default function GeneralSettings(props) {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Spin spinning={loading}>
|
<Spin spinning={loading}>
|
||||||
|
<Banner
|
||||||
|
type='warning'
|
||||||
|
description={'聊天链接功能已经弃用,请使用下方聊天设置功能'}
|
||||||
|
/>
|
||||||
<Form
|
<Form
|
||||||
values={inputs}
|
values={inputs}
|
||||||
getFormApi={(formAPI) => (refForm.current = formAPI)}
|
getFormApi={(formAPI) => (refForm.current = formAPI)}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ const EditToken = (props) => {
|
|||||||
group
|
group
|
||||||
} = inputs;
|
} = inputs;
|
||||||
// const [visible, setVisible] = useState(false);
|
// const [visible, setVisible] = useState(false);
|
||||||
const [models, setModels] = useState({});
|
const [models, setModels] = useState([]);
|
||||||
const [groups, setGroups] = useState([]);
|
const [groups, setGroups] = useState([]);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const handleInputChange = (name, value) => {
|
const handleInputChange = (name, value) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user