|
|
@@ -23,6 +23,7 @@ import {
|
|
|
} from '@douyinfe/semi-ui';
|
|
|
import Title from '@douyinfe/semi-ui/lib/es/typography/title';
|
|
|
import { Divider } from 'semantic-ui-react';
|
|
|
+import { useTranslation } from 'react-i18next';
|
|
|
|
|
|
const EditToken = (props) => {
|
|
|
const [isEdit, setIsEdit] = useState(false);
|
|
|
@@ -52,6 +53,7 @@ const EditToken = (props) => {
|
|
|
const [models, setModels] = useState([]);
|
|
|
const [groups, setGroups] = useState([]);
|
|
|
const navigate = useNavigate();
|
|
|
+ const { t } = useTranslation();
|
|
|
const handleInputChange = (name, value) => {
|
|
|
setInputs((inputs) => ({ ...inputs, [name]: value }));
|
|
|
};
|
|
|
@@ -87,7 +89,7 @@ const EditToken = (props) => {
|
|
|
}));
|
|
|
setModels(localModelOptions);
|
|
|
} else {
|
|
|
- showError(message);
|
|
|
+ showError(t(message));
|
|
|
}
|
|
|
};
|
|
|
|
|
|
@@ -95,15 +97,13 @@ const EditToken = (props) => {
|
|
|
let res = await API.get(`/api/user/self/groups`);
|
|
|
const { success, message, data } = res.data;
|
|
|
if (success) {
|
|
|
- // return data is a map, key is group name, value is group description
|
|
|
- // label is group description, value is group name
|
|
|
- let localGroupOptions = Object.keys(data).map((group) => ({
|
|
|
- label: data[group],
|
|
|
- value: group,
|
|
|
- }));
|
|
|
- setGroups(localGroupOptions);
|
|
|
+ let localGroupOptions = Object.keys(data).map((group) => ({
|
|
|
+ label: data[group],
|
|
|
+ value: group,
|
|
|
+ }));
|
|
|
+ setGroups(localGroupOptions);
|
|
|
} else {
|
|
|
- showError(message);
|
|
|
+ showError(t(message));
|
|
|
}
|
|
|
};
|
|
|
|
|
|
@@ -176,7 +176,7 @@ const EditToken = (props) => {
|
|
|
if (localInputs.expired_time !== -1) {
|
|
|
let time = Date.parse(localInputs.expired_time);
|
|
|
if (isNaN(time)) {
|
|
|
- showError('过期时间格式错误!');
|
|
|
+ showError(t('过期时间格式错误!'));
|
|
|
setLoading(false);
|
|
|
return;
|
|
|
}
|
|
|
@@ -189,11 +189,11 @@ const EditToken = (props) => {
|
|
|
});
|
|
|
const { success, message } = res.data;
|
|
|
if (success) {
|
|
|
- showSuccess('令牌更新成功!');
|
|
|
+ showSuccess(t('令牌更新成功!'));
|
|
|
props.refresh();
|
|
|
props.handleClose();
|
|
|
} else {
|
|
|
- showError(message);
|
|
|
+ showError(t(message));
|
|
|
}
|
|
|
} else {
|
|
|
// 处理新增多个令牌的情况
|
|
|
@@ -209,7 +209,7 @@ const EditToken = (props) => {
|
|
|
if (localInputs.expired_time !== -1) {
|
|
|
let time = Date.parse(localInputs.expired_time);
|
|
|
if (isNaN(time)) {
|
|
|
- showError('过期时间格式错误!');
|
|
|
+ showError(t('过期时间格式错误!'));
|
|
|
setLoading(false);
|
|
|
break;
|
|
|
}
|
|
|
@@ -222,14 +222,14 @@ const EditToken = (props) => {
|
|
|
if (success) {
|
|
|
successCount++;
|
|
|
} else {
|
|
|
- showError(message);
|
|
|
+ showError(t(message));
|
|
|
break; // 如果创建失败,终止循环
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (successCount > 0) {
|
|
|
showSuccess(
|
|
|
- `${successCount}个令牌创建成功,请在列表页面点击复制获取令牌!`,
|
|
|
+ t('令牌创建成功,请在列表页面点击复制获取令牌!')
|
|
|
);
|
|
|
props.refresh();
|
|
|
props.handleClose();
|
|
|
@@ -245,7 +245,7 @@ const EditToken = (props) => {
|
|
|
<SideSheet
|
|
|
placement={isEdit ? 'right' : 'left'}
|
|
|
title={
|
|
|
- <Title level={3}>{isEdit ? '更新令牌信息' : '创建新的令牌'}</Title>
|
|
|
+ <Title level={3}>{isEdit ? t('更新令牌信息') : t('创建新的令牌')}</Title>
|
|
|
}
|
|
|
headerStyle={{ borderBottom: '1px solid var(--semi-color-border)' }}
|
|
|
bodyStyle={{ borderBottom: '1px solid var(--semi-color-border)' }}
|
|
|
@@ -254,7 +254,7 @@ const EditToken = (props) => {
|
|
|
<div style={{ display: 'flex', justifyContent: 'flex-end' }}>
|
|
|
<Space>
|
|
|
<Button theme='solid' size={'large'} onClick={submit}>
|
|
|
- 提交
|
|
|
+ {t('提交')}
|
|
|
</Button>
|
|
|
<Button
|
|
|
theme='solid'
|
|
|
@@ -262,7 +262,7 @@ const EditToken = (props) => {
|
|
|
type={'tertiary'}
|
|
|
onClick={handleCancel}
|
|
|
>
|
|
|
- 取消
|
|
|
+ {t('取消')}
|
|
|
</Button>
|
|
|
</Space>
|
|
|
</div>
|
|
|
@@ -274,9 +274,9 @@ const EditToken = (props) => {
|
|
|
<Spin spinning={loading}>
|
|
|
<Input
|
|
|
style={{ marginTop: 20 }}
|
|
|
- label='名称'
|
|
|
+ label={t('名称')}
|
|
|
name='name'
|
|
|
- placeholder={'请输入名称'}
|
|
|
+ placeholder={t('请输入名称')}
|
|
|
onChange={(value) => handleInputChange('name', value)}
|
|
|
value={name}
|
|
|
autoComplete='new-password'
|
|
|
@@ -284,9 +284,9 @@ const EditToken = (props) => {
|
|
|
/>
|
|
|
<Divider />
|
|
|
<DatePicker
|
|
|
- label='过期时间'
|
|
|
+ label={t('过期时间')}
|
|
|
name='expired_time'
|
|
|
- placeholder={'请选择过期时间'}
|
|
|
+ placeholder={t('请选择过期时间')}
|
|
|
onChange={(value) => handleInputChange('expired_time', value)}
|
|
|
value={expired_time}
|
|
|
autoComplete='new-password'
|
|
|
@@ -300,7 +300,7 @@ const EditToken = (props) => {
|
|
|
setExpiredTime(0, 0, 0, 0);
|
|
|
}}
|
|
|
>
|
|
|
- 永不过期
|
|
|
+ {t('永不过期')}
|
|
|
</Button>
|
|
|
<Button
|
|
|
type={'tertiary'}
|
|
|
@@ -308,7 +308,7 @@ const EditToken = (props) => {
|
|
|
setExpiredTime(0, 0, 1, 0);
|
|
|
}}
|
|
|
>
|
|
|
- 一小时
|
|
|
+ {t('一小时')}
|
|
|
</Button>
|
|
|
<Button
|
|
|
type={'tertiary'}
|
|
|
@@ -316,7 +316,7 @@ const EditToken = (props) => {
|
|
|
setExpiredTime(1, 0, 0, 0);
|
|
|
}}
|
|
|
>
|
|
|
- 一个月
|
|
|
+ {t('一个月')}
|
|
|
</Button>
|
|
|
<Button
|
|
|
type={'tertiary'}
|
|
|
@@ -324,7 +324,7 @@ const EditToken = (props) => {
|
|
|
setExpiredTime(0, 1, 0, 0);
|
|
|
}}
|
|
|
>
|
|
|
- 一天
|
|
|
+ {t('一天')}
|
|
|
</Button>
|
|
|
</Space>
|
|
|
</div>
|
|
|
@@ -332,17 +332,15 @@ const EditToken = (props) => {
|
|
|
<Divider />
|
|
|
<Banner
|
|
|
type={'warning'}
|
|
|
- description={
|
|
|
- '注意,令牌的额度仅用于限制令牌本身的最大额度使用量,实际的使用受到账户的剩余额度限制。'
|
|
|
- }
|
|
|
+ description={t('注意,令牌的额度仅用于限制令牌本身的最大额度使用量,实际的使用受到账户的剩余额度限制。')}
|
|
|
></Banner>
|
|
|
<div style={{ marginTop: 20 }}>
|
|
|
- <Typography.Text>{`额度${renderQuotaWithPrompt(remain_quota)}`}</Typography.Text>
|
|
|
+ <Typography.Text>{`${t('额度')}${renderQuotaWithPrompt(remain_quota)}`}</Typography.Text>
|
|
|
</div>
|
|
|
<AutoComplete
|
|
|
style={{ marginTop: 8 }}
|
|
|
name='remain_quota'
|
|
|
- placeholder={'请输入额度'}
|
|
|
+ placeholder={t('请输入额度')}
|
|
|
onChange={(value) => handleInputChange('remain_quota', value)}
|
|
|
value={remain_quota}
|
|
|
autoComplete='new-password'
|
|
|
@@ -362,22 +360,22 @@ const EditToken = (props) => {
|
|
|
{!isEdit && (
|
|
|
<>
|
|
|
<div style={{ marginTop: 20 }}>
|
|
|
- <Typography.Text>新建数量</Typography.Text>
|
|
|
+ <Typography.Text>{t('新建数量')}</Typography.Text>
|
|
|
</div>
|
|
|
<AutoComplete
|
|
|
style={{ marginTop: 8 }}
|
|
|
- label='数量'
|
|
|
- placeholder={'请选择或输入创建令牌的数量'}
|
|
|
+ label={t('数量')}
|
|
|
+ placeholder={t('请选择或输入创建令牌的数量')}
|
|
|
onChange={(value) => handleTokenCountChange(value)}
|
|
|
onSelect={(value) => handleTokenCountChange(value)}
|
|
|
value={tokenCount.toString()}
|
|
|
autoComplete='off'
|
|
|
type='number'
|
|
|
data={[
|
|
|
- { value: 10, label: '10个' },
|
|
|
- { value: 20, label: '20个' },
|
|
|
- { value: 30, label: '30个' },
|
|
|
- { value: 100, label: '100个' },
|
|
|
+ { value: 10, label: t('10个') },
|
|
|
+ { value: 20, label: t('20个') },
|
|
|
+ { value: 30, label: t('30个') },
|
|
|
+ { value: 100, label: t('100个') },
|
|
|
]}
|
|
|
disabled={unlimited_quota}
|
|
|
/>
|
|
|
@@ -392,17 +390,17 @@ const EditToken = (props) => {
|
|
|
setUnlimitedQuota();
|
|
|
}}
|
|
|
>
|
|
|
- {unlimited_quota ? '取消无限额度' : '设为无限额度'}
|
|
|
+ {unlimited_quota ? t('取消���限额度') : t('设为无限额度')}
|
|
|
</Button>
|
|
|
</div>
|
|
|
<Divider />
|
|
|
<div style={{ marginTop: 10 }}>
|
|
|
- <Typography.Text>IP白名单(请勿过度信任此功能)</Typography.Text>
|
|
|
+ <Typography.Text>{t('IP白名单(请勿过度信任此功能)')}</Typography.Text>
|
|
|
</div>
|
|
|
<TextArea
|
|
|
- label='IP白名单'
|
|
|
+ label={t('IP白名单')}
|
|
|
name='allow_ips'
|
|
|
- placeholder={'允许的IP,一行一个'}
|
|
|
+ placeholder={t('允许的IP,一行一个')}
|
|
|
onChange={(value) => {
|
|
|
handleInputChange('allow_ips', value);
|
|
|
}}
|
|
|
@@ -417,16 +415,15 @@ const EditToken = (props) => {
|
|
|
onChange={(e) =>
|
|
|
handleInputChange('model_limits_enabled', e.target.checked)
|
|
|
}
|
|
|
- ></Checkbox>
|
|
|
- <Typography.Text>
|
|
|
- 启用模型限制(非必要,不建议启用)
|
|
|
- </Typography.Text>
|
|
|
+ >
|
|
|
+ {t('启用模型限制(非必要,不建议启用)')}
|
|
|
+ </Checkbox>
|
|
|
</Space>
|
|
|
</div>
|
|
|
|
|
|
<Select
|
|
|
style={{ marginTop: 8 }}
|
|
|
- placeholder={'请选择该渠道所支持的模型'}
|
|
|
+ placeholder={t('请选择该渠道所支持的模型')}
|
|
|
name='models'
|
|
|
required
|
|
|
multiple
|
|
|
@@ -440,12 +437,12 @@ const EditToken = (props) => {
|
|
|
disabled={!model_limits_enabled}
|
|
|
/>
|
|
|
<div style={{ marginTop: 10 }}>
|
|
|
- <Typography.Text>令牌分组,默认为用户的分组</Typography.Text>
|
|
|
+ <Typography.Text>{t('令牌分组,默认为用户的分组')}</Typography.Text>
|
|
|
</div>
|
|
|
{groups.length > 0 ?
|
|
|
<Select
|
|
|
style={{ marginTop: 8 }}
|
|
|
- placeholder={'令牌分组,默认为用户的分组'}
|
|
|
+ placeholder={t('令牌分组,默认为用户的分组')}
|
|
|
name='gruop'
|
|
|
required
|
|
|
selection
|
|
|
@@ -458,7 +455,7 @@ const EditToken = (props) => {
|
|
|
/>:
|
|
|
<Select
|
|
|
style={{ marginTop: 8 }}
|
|
|
- placeholder={'管理员未设置用户可选分组'}
|
|
|
+ placeholder={t('管理员未设置用户可选分组')}
|
|
|
name='gruop'
|
|
|
disabled={true}
|
|
|
/>
|