chore: update default theme style

This commit is contained in:
JustSong
2025-01-31 23:10:02 +08:00
parent f2c7c424e9
commit 3d29713268
4 changed files with 333 additions and 293 deletions

View File

@@ -280,8 +280,8 @@ const EditChannel = () => {
{inputs.type === 3 && ( {inputs.type === 3 && (
<> <>
<Message> <Message>
注意<strong>模型部署名称必须和模型名称保持一致</strong> 注意<strong>模型部署名称必须和模型名称保持一致</strong>
One API 会把请求体中的 model 因为 One API 会把请求体中的 model
参数替换为你的部署名称模型名称中的点会被剔除 参数替换为你的部署名称模型名称中的点会被剔除
<a <a
target='_blank' target='_blank'
@@ -686,7 +686,11 @@ const EditChannel = () => {
</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> </Button>
</Form> </Form>

View File

@@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Button, Form, Header, Segment } from 'semantic-ui-react'; import { Button, Form, Card } from 'semantic-ui-react';
import { useParams, useNavigate } from 'react-router-dom'; import { useParams, useNavigate } from 'react-router-dom';
import { API, downloadTextAsFile, showError, showSuccess } from '../../helpers'; import { API, downloadTextAsFile, showError, showSuccess } from '../../helpers';
import { renderQuota, renderQuotaWithPrompt } from '../../helpers/render'; import { renderQuota, renderQuotaWithPrompt } from '../../helpers/render';
@@ -13,7 +13,7 @@ const EditRedemption = () => {
const originInputs = { const originInputs = {
name: '', name: '',
quota: 100000, quota: 100000,
count: 1 count: 1,
}; };
const [inputs, setInputs] = useState(originInputs); const [inputs, setInputs] = useState(originInputs);
const { name, quota, count } = inputs; const { name, quota, count } = inputs;
@@ -49,10 +49,13 @@ const EditRedemption = () => {
localInputs.quota = parseInt(localInputs.quota); localInputs.quota = parseInt(localInputs.quota);
let res; let res;
if (isEdit) { if (isEdit) {
res = await API.put(`/api/redemption/`, { ...localInputs, id: parseInt(redemptionId) }); res = await API.put(`/api/redemption/`, {
...localInputs,
id: parseInt(redemptionId),
});
} else { } else {
res = await API.post(`/api/redemption/`, { res = await API.post(`/api/redemption/`, {
...localInputs ...localInputs,
}); });
} }
const { success, message, data } = res.data; const { success, message, data } = res.data;
@@ -67,61 +70,67 @@ const EditRedemption = () => {
showError(message); showError(message);
} }
if (!isEdit && data) { if (!isEdit && data) {
let text = ""; let text = '';
for (let i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
text += data[i] + "\n"; text += data[i] + '\n';
} }
downloadTextAsFile(text, `${inputs.name}.txt`); downloadTextAsFile(text, `${inputs.name}.txt`);
} }
}; };
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.Input </Card.Header>
label='名称' <Form loading={loading} autoComplete='new-password'>
name='name' <Form.Field>
placeholder={'请输入名称'} <Form.Input
onChange={handleInputChange} label='名称'
value={name} name='name'
autoComplete='new-password' placeholder={'请输入名称'}
required={!isEdit} onChange={handleInputChange}
/> value={name}
</Form.Field> autoComplete='new-password'
<Form.Field> required={!isEdit}
<Form.Input />
label={`额度${renderQuotaWithPrompt(quota)}`} </Form.Field>
name='quota' <Form.Field>
placeholder={'请输入单个兑换码中包含的额度'} <Form.Input
onChange={handleInputChange} label={`额度${renderQuotaWithPrompt(quota)}`}
value={quota} name='quota'
autoComplete='new-password' placeholder={'请输入单个兑换码中包含的额度'}
type='number' onChange={handleInputChange}
/> value={quota}
</Form.Field> autoComplete='new-password'
{ type='number'
!isEdit && <> />
<Form.Field> </Form.Field>
<Form.Input {!isEdit && (
label='生成数量' <>
name='count' <Form.Field>
placeholder={'请输入生成数量'} <Form.Input
onChange={handleInputChange} label='生成数量'
value={count} name='count'
autoComplete='new-password' placeholder={'请输入生成数量'}
type='number' onChange={handleInputChange}
/> value={count}
</Form.Field> autoComplete='new-password'
</> type='number'
} />
<Button positive onClick={submit}>提交</Button> </Form.Field>
<Button onClick={handleCancel}>取消</Button> </>
</Form> )}
</Segment> <Button positive onClick={submit}>
</> 提交
</Button>
<Button onClick={handleCancel}>取消</Button>
</Form>
</Card.Content>
</Card>
</div>
); );
}; };

View File

@@ -1,5 +1,12 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Button, Form, Header, Message, Segment } from 'semantic-ui-react'; import {
Button,
Form,
Header,
Message,
Segment,
Card,
} from 'semantic-ui-react';
import { useNavigate, useParams } from 'react-router-dom'; import { useNavigate, useParams } from 'react-router-dom';
import { import {
API, API,
@@ -130,138 +137,142 @@ const EditToken = () => {
}; };
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.Input </Card.Header>
label='名称' <Form loading={loading} autoComplete='new-password'>
name='name' <Form.Field>
placeholder={'请输入名称'} <Form.Input
onChange={handleInputChange} label='名称'
value={name} name='name'
autoComplete='new-password' placeholder={'请输入名称'}
required={!isEdit} onChange={handleInputChange}
/> value={name}
</Form.Field> autoComplete='new-password'
<Form.Field> required={!isEdit}
<Form.Dropdown />
label='模型范围' </Form.Field>
placeholder={'请选择允许使用的模型,留空则不进行限制'} <Form.Field>
name='models' <Form.Dropdown
fluid label='模型范围'
multiple placeholder={'请选择允许使用的模型,留空则不进行限制'}
search name='models'
onLabelClick={(e, { value }) => { fluid
copy(value).then(); multiple
}} search
selection onLabelClick={(e, { value }) => {
onChange={handleInputChange} copy(value).then();
value={inputs.models} }}
autoComplete='new-password' selection
options={modelOptions} onChange={handleInputChange}
/> value={inputs.models}
</Form.Field> autoComplete='new-password'
<Form.Field> options={modelOptions}
<Form.Input />
label='IP 限制' </Form.Field>
name='subnet' <Form.Field>
placeholder={ <Form.Input
'请输入允许访问的网段例如192.168.0.0/24请使用英文逗号分隔多个网段' label='IP 限制'
} name='subnet'
onChange={handleInputChange} placeholder={
value={inputs.subnet} '请输入允许访问的网段例如192.168.0.0/24请使用英文逗号分隔多个网段'
autoComplete='new-password' }
/> onChange={handleInputChange}
</Form.Field> value={inputs.subnet}
<Form.Field> autoComplete='new-password'
<Form.Input />
label='过期时间' </Form.Field>
name='expired_time' <Form.Field>
placeholder={ <Form.Input
'请输入过期时间,格式为 yyyy-MM-dd HH:mm:ss-1 表示无限制' label='过期时间'
} name='expired_time'
onChange={handleInputChange} placeholder={
value={expired_time} '请输入过期时间,格式为 yyyy-MM-dd HH:mm:ss-1 表示无限制'
autoComplete='new-password' }
type='datetime-local' onChange={handleInputChange}
/> value={expired_time}
</Form.Field> autoComplete='new-password'
<div style={{ lineHeight: '40px' }}> type='datetime-local'
/>
</Form.Field>
<div style={{ lineHeight: '40px' }}>
<Button
type={'button'}
onClick={() => {
setExpiredTime(0, 0, 0, 0);
}}
>
永不过期
</Button>
<Button
type={'button'}
onClick={() => {
setExpiredTime(1, 0, 0, 0);
}}
>
一个月后过期
</Button>
<Button
type={'button'}
onClick={() => {
setExpiredTime(0, 1, 0, 0);
}}
>
一天后过期
</Button>
<Button
type={'button'}
onClick={() => {
setExpiredTime(0, 0, 1, 0);
}}
>
一小时后过期
</Button>
<Button
type={'button'}
onClick={() => {
setExpiredTime(0, 0, 0, 1);
}}
>
一分钟后过期
</Button>
</div>
<Message>
注意令牌的额度仅用于限制令牌本身的最大额度使用量实际的使用受到账户的剩余额度限制
</Message>
<Form.Field>
<Form.Input
label={`额度${renderQuotaWithPrompt(remain_quota)}`}
name='remain_quota'
placeholder={'请输入额度'}
onChange={handleInputChange}
value={remain_quota}
autoComplete='new-password'
type='number'
disabled={unlimited_quota}
/>
</Form.Field>
<Button <Button
type={'button'} type={'button'}
onClick={() => { onClick={() => {
setExpiredTime(0, 0, 0, 0); setUnlimitedQuota();
}} }}
> >
永不过期 {unlimited_quota ? '取消无限额度' : '设为无限额度'}
</Button> </Button>
<Button <Button floated='right' positive onClick={submit}>
type={'button'} 提交
onClick={() => {
setExpiredTime(1, 0, 0, 0);
}}
>
一个月后过期
</Button> </Button>
<Button <Button floated='right' onClick={handleCancel}>
type={'button'} 取消
onClick={() => {
setExpiredTime(0, 1, 0, 0);
}}
>
一天后过期
</Button> </Button>
<Button </Form>
type={'button'} </Card.Content>
onClick={() => { </Card>
setExpiredTime(0, 0, 1, 0); </div>
}}
>
一小时后过期
</Button>
<Button
type={'button'}
onClick={() => {
setExpiredTime(0, 0, 0, 1);
}}
>
一分钟后过期
</Button>
</div>
<Message>
注意令牌的额度仅用于限制令牌本身的最大额度使用量实际的使用受到账户的剩余额度限制
</Message>
<Form.Field>
<Form.Input
label={`额度${renderQuotaWithPrompt(remain_quota)}`}
name='remain_quota'
placeholder={'请输入额度'}
onChange={handleInputChange}
value={remain_quota}
autoComplete='new-password'
type='number'
disabled={unlimited_quota}
/>
</Form.Field>
<Button
type={'button'}
onClick={() => {
setUnlimitedQuota();
}}
>
{unlimited_quota ? '取消无限额度' : '设为无限额度'}
</Button>
<Button floated='right' positive onClick={submit}>
提交
</Button>
<Button floated='right' onClick={handleCancel}>
取消
</Button>
</Form>
</Segment>
</>
); );
}; };

View File

@@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Button, Form, Header, Segment } from 'semantic-ui-react'; import { Button, Form, Card } from 'semantic-ui-react';
import { useParams, useNavigate } from 'react-router-dom'; import { useParams, useNavigate } from 'react-router-dom';
import { API, showError, showSuccess } from '../../helpers'; import { API, showError, showSuccess } from '../../helpers';
import { renderQuota, renderQuotaWithPrompt } from '../../helpers/render'; import { renderQuota, renderQuotaWithPrompt } from '../../helpers/render';
@@ -16,30 +16,40 @@ const EditUser = () => {
wechat_id: '', wechat_id: '',
email: '', email: '',
quota: 0, quota: 0,
group: 'default' group: 'default',
}); });
const [groupOptions, setGroupOptions] = useState([]); const [groupOptions, setGroupOptions] = useState([]);
const { username, display_name, password, github_id, wechat_id, email, quota, group } = const {
inputs; username,
display_name,
password,
github_id,
wechat_id,
email,
quota,
group,
} = inputs;
const handleInputChange = (e, { name, value }) => { const handleInputChange = (e, { name, value }) => {
setInputs((inputs) => ({ ...inputs, [name]: value })); setInputs((inputs) => ({ ...inputs, [name]: value }));
}; };
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);
} }
}; };
const navigate = useNavigate(); const navigate = useNavigate();
const handleCancel = () => { const handleCancel = () => {
navigate("/setting"); navigate('/setting');
} };
const loadUser = async () => { const loadUser = async () => {
let res = undefined; let res = undefined;
if (userId) { if (userId) {
@@ -83,107 +93,113 @@ const EditUser = () => {
}; };
return ( return (
<> <div className='dashboard-container'>
<Segment loading={loading}> <Card fluid className='chart-card'>
<Header as='h3'>更新用户信息</Header> <Card.Content>
<Form autoComplete='new-password'> <Card.Header className='header'>更新用户信息</Card.Header>
<Form.Field> <Form loading={loading} autoComplete='new-password'>
<Form.Input <Form.Field>
label='用户名' <Form.Input
name='username' label='用户名'
placeholder={'请输入新的用户名'} name='username'
onChange={handleInputChange} placeholder={'请输入新的用户名'}
value={username} onChange={handleInputChange}
autoComplete='new-password' value={username}
/> autoComplete='new-password'
</Form.Field> />
<Form.Field> </Form.Field>
<Form.Input <Form.Field>
label='密码' <Form.Input
name='password' label='密码'
type={'password'} name='password'
placeholder={'请输入新的密码,最短 8 位'} type={'password'}
onChange={handleInputChange} placeholder={'请输入新的密码,最短 8 位'}
value={password} onChange={handleInputChange}
autoComplete='new-password' value={password}
/> autoComplete='new-password'
</Form.Field> />
<Form.Field> </Form.Field>
<Form.Input <Form.Field>
label='显示名称' <Form.Input
name='display_name' label='显示名称'
placeholder={'请输入新的显示名称'} name='display_name'
onChange={handleInputChange} placeholder={'请输入新的显示名称'}
value={display_name} onChange={handleInputChange}
autoComplete='new-password' value={display_name}
/> autoComplete='new-password'
</Form.Field> />
{ </Form.Field>
userId && <> {userId && (
<Form.Field> <>
<Form.Dropdown <Form.Field>
label='分组' <Form.Dropdown
placeholder={'请选择分组'} label='分组'
name='group' placeholder={'请选择分组'}
fluid name='group'
search fluid
selection search
allowAdditions selection
additionLabel={'请在系统设置页面编辑分组倍率以添加新的分组:'} allowAdditions
onChange={handleInputChange} additionLabel={
value={inputs.group} '请在系统设置页面编辑分组倍率以添加新的分组:'
autoComplete='new-password' }
options={groupOptions} onChange={handleInputChange}
/> value={inputs.group}
</Form.Field> autoComplete='new-password'
<Form.Field> options={groupOptions}
<Form.Input />
label={`剩余额度${renderQuotaWithPrompt(quota)}`} </Form.Field>
name='quota' <Form.Field>
placeholder={'请输入新的剩余额度'} <Form.Input
onChange={handleInputChange} label={`剩余额度${renderQuotaWithPrompt(quota)}`}
value={quota} name='quota'
type={'number'} placeholder={'请输入新的剩余额度'}
autoComplete='new-password' onChange={handleInputChange}
/> value={quota}
</Form.Field> type={'number'}
</> autoComplete='new-password'
} />
<Form.Field> </Form.Field>
<Form.Input </>
label='已绑定的 GitHub 账户' )}
name='github_id' <Form.Field>
value={github_id} <Form.Input
autoComplete='new-password' label='已绑定的 GitHub 账户'
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改' name='github_id'
readOnly value={github_id}
/> autoComplete='new-password'
</Form.Field> placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改'
<Form.Field> readOnly
<Form.Input />
label='已绑定的微信账户' </Form.Field>
name='wechat_id' <Form.Field>
value={wechat_id} <Form.Input
autoComplete='new-password' label='已绑定的微信账户'
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改' name='wechat_id'
readOnly value={wechat_id}
/> autoComplete='new-password'
</Form.Field> placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改'
<Form.Field> readOnly
<Form.Input />
label='已绑定的邮箱账户' </Form.Field>
name='email' <Form.Field>
value={email} <Form.Input
autoComplete='new-password' label='已绑定的邮箱账户'
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改' name='email'
readOnly value={email}
/> autoComplete='new-password'
</Form.Field> placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改'
<Button onClick={handleCancel}>取消</Button> readOnly
<Button positive onClick={submit}>提交</Button> />
</Form> </Form.Field>
</Segment> <Button onClick={handleCancel}>取消</Button>
</> <Button positive onClick={submit}>
提交
</Button>
</Form>
</Card.Content>
</Card>
</div>
); );
}; };