Commit 53ff1547 by 1808837298@qq.com

feat: 弃用旧的聊天配置

parent 917aa6c0
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,
"enable_online_topup": constant.PayAddress != "" && constant.EpayId != "" && constant.EpayKey != "",
"mj_notify_enabled": constant.MjNotifyEnabled,
"chats": constant.Chats,
},
})
return
......
......@@ -69,6 +69,7 @@ func InitOptionMap() {
common.OptionMap["Price"] = strconv.FormatFloat(constant.Price, 'f', -1, 64)
common.OptionMap["MinTopUp"] = strconv.Itoa(constant.MinTopUp)
common.OptionMap["TopupGroupRatio"] = common.TopupGroupRatio2JSONString()
common.OptionMap["Chats"] = constant.Chats2JsonString()
common.OptionMap["GitHubClientId"] = ""
common.OptionMap["GitHubClientSecret"] = ""
common.OptionMap["TelegramBotToken"] = ""
......@@ -248,6 +249,8 @@ func updateOptionMap(key string, value string) (err error) {
constant.WorkerValidKey = value
case "PayAddress":
constant.PayAddress = value
case "Chats":
err = constant.UpdateChatsByJsonString(value)
case "CustomCallbackAddress":
constant.CustomCallbackAddress = value
case "EpayId":
......
......@@ -10,6 +10,7 @@ import SettingsCreditLimit from '../pages/Setting/Operation/SettingsCreditLimit.
import SettingsMagnification from '../pages/Setting/Operation/SettingsMagnification.js';
import { API, showError, showSuccess } from '../helpers';
import SettingsChats from '../pages/Setting/Operation/SettingsChats.js';
const OperationSetting = () => {
let [inputs, setInputs] = useState({
......@@ -50,6 +51,7 @@ const OperationSetting = () => {
DataExportInterval: 5,
DefaultCollapseSidebar: false, // 默认折叠侧边栏
RetryTimes: 0,
Chats: "[]",
});
let [loading, setLoading] = useState(false);
......@@ -131,6 +133,10 @@ const OperationSetting = () => {
<Card style={{ marginTop: '10px' }}>
<SettingsCreditLimit options={inputs} refresh={onRefresh} />
</Card>
{/* 聊天设置 */}
<Card style={{ marginTop: '10px' }}>
<SettingsChats options={inputs} refresh={onRefresh} />
</Card>
{/* 倍率设置 */}
<Card style={{ marginTop: '10px' }}>
<SettingsMagnification options={inputs} refresh={onRefresh} />
......
......@@ -8,6 +8,7 @@ export function setStatusData(data) {
localStorage.setItem('enable_drawing', data.enable_drawing);
localStorage.setItem('enable_task', data.enable_task);
localStorage.setItem('enable_data_export', data.enable_data_export);
localStorage.setItem('chats', JSON.stringify(data.chats));
localStorage.setItem(
'data_export_default_time',
data.data_export_default_time,
......
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>
);
}
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 {
compareObjects,
API,
......@@ -74,6 +74,10 @@ export default function GeneralSettings(props) {
return (
<>
<Spin spinning={loading}>
<Banner
type='warning'
description={'聊天链接功能已经弃用,请使用下方聊天设置功能'}
/>
<Form
values={inputs}
getFormApi={(formAPI) => (refForm.current = formAPI)}
......
......@@ -49,7 +49,7 @@ const EditToken = (props) => {
group
} = inputs;
// const [visible, setVisible] = useState(false);
const [models, setModels] = useState({});
const [models, setModels] = useState([]);
const [groups, setGroups] = useState([]);
const navigate = useNavigate();
const handleInputChange = (name, value) => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment