-
-
-
-
-
-
+
+
+
{
+ manageToken(record.id, 'delete', record).then(() => {
+ removeRecord(record.key);
+ });
+ }}
+ >
+
+ 删除
+
+
+ {record.status === 1 ? (
+
{
+ manageToken(record.id, 'disable', record);
+ }}
+ >
+ 禁用
+
+ ) : (
+
{
+ manageToken(record.id, 'enable', record);
+ }}
+ >
+ 启用
+
+ )}
+
{
+ setEditingToken(record);
+ setShowEdit(true);
+ }}
+ >
+ 编辑
+
+
+ );
+ },
},
];
@@ -330,8 +320,7 @@ const TokensTable = () => {
const [searchKeyword, setSearchKeyword] = useState('');
const [searchToken, setSearchToken] = useState('');
const [searching, setSearching] = useState(false);
- const [showTopUpModal, setShowTopUpModal] = useState(false);
- const [targetTokenIdx, setTargetTokenIdx] = useState(0);
+ const [chats, setChats] = useState([]);
const [editingToken, setEditingToken] = useState({
id: undefined,
});
@@ -376,16 +365,6 @@ const TokensTable = () => {
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 () => {
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 serverAddress = '';
if (status) {
@@ -413,36 +393,39 @@ const TokensTable = () => {
serverAddress = window.location.origin;
}
let encodedServerAddress = encodeURIComponent(serverAddress);
- const chatLink = localStorage.getItem('chat_link');
- const mjLink = localStorage.getItem('chat_link2');
- let defaultUrl;
-
- if (chatLink) {
- defaultUrl =
- chatLink + `/#/?settings={"key":"sk-${key}","url":"${serverAddress}"}`;
- }
- let url;
- switch (type) {
- case 'ama':
- url = `ama://set-api-key?server=${encodedServerAddress}&key=sk-${key}`;
- break;
- case 'opencat':
- url = `opencat://team/join?domain=${encodedServerAddress}&token=sk-${key}`;
- break;
- case 'lobe':
- url = `https://chat-preview.lobehub.com/?settings={"keyVaults":{"openai":{"apiKey":"sk-${key}","baseURL":"${encodedServerAddress}/v1"}}}`;
- break;
- case 'next-mj':
- url =
- mjLink + `/#/?settings={"key":"sk-${key}","url":"${serverAddress}"}`;
- break;
- default:
- if (!chatLink) {
- showError('管理员未设置聊天链接');
- return;
- }
- url = defaultUrl;
- }
+ url = url.replace('{address}', encodedServerAddress);
+ url = url.replace('{key}', 'sk-' + record.key);
+ // console.log(url);
+ // const chatLink = localStorage.getItem('chat_link');
+ // const mjLink = localStorage.getItem('chat_link2');
+ // let defaultUrl;
+ //
+ // if (chatLink) {
+ // defaultUrl =
+ // chatLink + `/#/?settings={"key":"sk-${key}","url":"${serverAddress}"}`;
+ // }
+ // let url;
+ // switch (type) {
+ // case 'ama':
+ // url = `ama://set-api-key?server=${encodedServerAddress}&key=sk-${key}`;
+ // break;
+ // case 'opencat':
+ // url = `opencat://team/join?domain=${encodedServerAddress}&token=sk-${key}`;
+ // break;
+ // case 'lobe':
+ // url = `https://chat-preview.lobehub.com/?settings={"keyVaults":{"openai":{"apiKey":"sk-${key}","baseURL":"${encodedServerAddress}/v1"}}}`;
+ // break;
+ // case 'next-mj':
+ // url =
+ // mjLink + `/#/?settings={"key":"sk-${key}","url":"${serverAddress}"}`;
+ // break;
+ // default:
+ // if (!chatLink) {
+ // showError('管理员未设置聊天链接');
+ // return;
+ // }
+ // url = defaultUrl;
+ // }
window.open(url, '_blank');
};
diff --git a/web/src/helpers/data.js b/web/src/helpers/data.js
index 93380b41..4cd7a641 100644
--- a/web/src/helpers/data.js
+++ b/web/src/helpers/data.js
@@ -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,
diff --git a/web/src/pages/Setting/Operation/SettingsChats.js b/web/src/pages/Setting/Operation/SettingsChats.js
new file mode 100644
index 00000000..c6c9a770
--- /dev/null
+++ b/web/src/pages/Setting/Operation/SettingsChats.js
@@ -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 (
+