mirror of
https://github.com/linux-do/new-api.git
synced 2025-11-13 01:23:41 +08:00
merge upstream
Signed-off-by: wozulong <>
This commit is contained in:
1
web/.prettierrc.mjs
Normal file
1
web/.prettierrc.mjs
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require("@so1ve/prettier-config");
|
||||
@@ -1 +0,0 @@
|
||||
module.exports = require("@so1ve/prettier-config");
|
||||
@@ -471,10 +471,10 @@ const LogsTable = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const refresh = async (localLogType) => {
|
||||
const refresh = async () => {
|
||||
// setLoading(true);
|
||||
setActivePage(1);
|
||||
await loadLogs(0, pageSize, localLogType);
|
||||
await loadLogs(0, pageSize, logType);
|
||||
};
|
||||
|
||||
const copyText = async (text) => {
|
||||
@@ -637,7 +637,7 @@ const LogsTable = () => {
|
||||
style={{ width: 120 }}
|
||||
onChange={(value) => {
|
||||
setLogType(parseInt(value));
|
||||
refresh(parseInt(value)).then();
|
||||
loadLogs(0, pageSize, parseInt(value));
|
||||
}}
|
||||
>
|
||||
<Select.Option value='0'>全部</Select.Option>
|
||||
|
||||
@@ -8,39 +8,41 @@ export function renderText(text, limit) {
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render group tags based on the input group string
|
||||
* @param {string} group - The input group string
|
||||
* @returns {JSX.Element} - The rendered group tags
|
||||
*/
|
||||
export function renderGroup(group) {
|
||||
if (group === '') {
|
||||
return <Tag size='large'>default</Tag>;
|
||||
return (
|
||||
<Tag size='large' key='default'>
|
||||
unknown
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
let groups = group.split(',');
|
||||
groups.sort();
|
||||
|
||||
const tagColors = {
|
||||
vip: 'yellow',
|
||||
pro: 'yellow',
|
||||
svip: 'red',
|
||||
premium: 'red',
|
||||
};
|
||||
|
||||
const groups = group.split(',').sort();
|
||||
|
||||
return (
|
||||
<>
|
||||
{groups.map((group) => {
|
||||
if (group === 'vip' || group === 'pro') {
|
||||
return (
|
||||
<Tag size='large' color='yellow'>
|
||||
{group}
|
||||
</Tag>
|
||||
);
|
||||
} else if (group === 'svip' || group === 'premium') {
|
||||
return (
|
||||
<Tag size='large' color='red'>
|
||||
{group}
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
if (group === 'default') {
|
||||
return <Tag size='large'>{group}</Tag>;
|
||||
} else {
|
||||
return (
|
||||
<Tag size='large' color={stringToColor(group)}>
|
||||
{group}
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</>
|
||||
<span key={group}>
|
||||
{groups.map((group) => (
|
||||
<Tag
|
||||
size='large'
|
||||
color={tagColors[group] || stringToColor(group)}
|
||||
key={group}
|
||||
>
|
||||
{group}
|
||||
</Tag>
|
||||
))}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -99,12 +101,29 @@ export function getQuotaPerUnit() {
|
||||
return quotaPerUnit;
|
||||
}
|
||||
|
||||
export function renderUnitWithQuota(quota) {
|
||||
let quotaPerUnit = localStorage.getItem('quota_per_unit');
|
||||
quotaPerUnit = parseFloat(quotaPerUnit);
|
||||
quota = parseFloat(quota);
|
||||
return quotaPerUnit * quota;
|
||||
}
|
||||
|
||||
export function getQuotaWithUnit(quota, digits = 6) {
|
||||
let quotaPerUnit = localStorage.getItem('quota_per_unit');
|
||||
quotaPerUnit = parseFloat(quotaPerUnit);
|
||||
return (quota / quotaPerUnit).toFixed(digits);
|
||||
}
|
||||
|
||||
export function renderQuotaWithAmount(amount) {
|
||||
let displayInCurrency = localStorage.getItem('display_in_currency');
|
||||
displayInCurrency = displayInCurrency === 'true';
|
||||
if (displayInCurrency) {
|
||||
return '$' + amount;
|
||||
} else {
|
||||
return renderUnitWithQuota(amount);
|
||||
}
|
||||
}
|
||||
|
||||
export function renderQuota(quota, digits = 2) {
|
||||
let quotaPerUnit = localStorage.getItem('quota_per_unit');
|
||||
let displayInCurrency = localStorage.getItem('display_in_currency');
|
||||
|
||||
@@ -63,6 +63,7 @@ const EditChannel = (props) => {
|
||||
model_mapping: '',
|
||||
models: [],
|
||||
auto_ban: 1,
|
||||
test_model: '',
|
||||
groups: ['default'],
|
||||
};
|
||||
const [batch, setBatch] = useState(false);
|
||||
@@ -669,6 +670,17 @@ const EditChannel = (props) => {
|
||||
}}
|
||||
value={inputs.openai_organization}
|
||||
/>
|
||||
<div style={{ marginTop: 10 }}>
|
||||
<Typography.Text strong>默认测试模型:</Typography.Text>
|
||||
</div>
|
||||
<Input
|
||||
name='test_model'
|
||||
placeholder='不填则为模型列表第一个'
|
||||
onChange={(value) => {
|
||||
handleInputChange('test_model', value);
|
||||
}}
|
||||
value={inputs.test_model}
|
||||
/>
|
||||
<div style={{ marginTop: 10, display: 'flex' }}>
|
||||
<Space>
|
||||
<Checkbox
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Layout, TabPane, Tabs } from '@douyinfe/semi-ui';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
|
||||
import SystemSetting from '../../components/SystemSetting';
|
||||
import { isRoot } from '../../helpers';
|
||||
import OtherSetting from '../../components/OtherSetting';
|
||||
import PersonalSetting from '../../components/PersonalSetting';
|
||||
import OperationSetting from '../../components/OperationSetting';
|
||||
import { Layout, TabPane, Tabs } from '@douyinfe/semi-ui';
|
||||
|
||||
const Setting = () => {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const [tabActiveKey, setTabActiveKey] = useState('1');
|
||||
let panes = [
|
||||
{
|
||||
tab: '个人设置',
|
||||
content: <PersonalSetting />,
|
||||
itemKey: '1',
|
||||
itemKey: 'personal',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -19,28 +23,44 @@ const Setting = () => {
|
||||
panes.push({
|
||||
tab: '运营设置',
|
||||
content: <OperationSetting />,
|
||||
itemKey: '2',
|
||||
itemKey: 'operation',
|
||||
});
|
||||
panes.push({
|
||||
tab: '系统设置',
|
||||
content: <SystemSetting />,
|
||||
itemKey: '3',
|
||||
itemKey: 'system',
|
||||
});
|
||||
panes.push({
|
||||
tab: '其他设置',
|
||||
content: <OtherSetting />,
|
||||
itemKey: '4',
|
||||
itemKey: 'other',
|
||||
});
|
||||
}
|
||||
|
||||
const onChangeTab = (key) => {
|
||||
setTabActiveKey(key);
|
||||
navigate(`?tab=${key}`);
|
||||
};
|
||||
useEffect(() => {
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
const tab = searchParams.get('tab');
|
||||
if (tab) {
|
||||
setTabActiveKey(tab);
|
||||
} else {
|
||||
onChangeTab('personal');
|
||||
}
|
||||
}, [location.search]);
|
||||
return (
|
||||
<div>
|
||||
<Layout>
|
||||
<Layout.Content>
|
||||
<Tabs type='line' defaultActiveKey='1'>
|
||||
<Tabs
|
||||
type='line'
|
||||
activeKey={tabActiveKey}
|
||||
onChange={(key) => onChangeTab(key)}
|
||||
>
|
||||
{panes.map((pane) => (
|
||||
<TabPane itemKey={pane.itemKey} tab={pane.tab} key={pane.itemKey}>
|
||||
{pane.content}
|
||||
{tabActiveKey === pane.itemKey && pane.content}
|
||||
</TabPane>
|
||||
))}
|
||||
</Tabs>
|
||||
|
||||
Reference in New Issue
Block a user