Commit add3b05d by CaIon

chore: reformat code

parent 7c547cbc
...@@ -13,7 +13,7 @@ import ( ...@@ -13,7 +13,7 @@ import (
// TODO: when a new api is enabled, check the pricing here // TODO: when a new api is enabled, check the pricing here
// 1 === $0.002 / 1K tokens // 1 === $0.002 / 1K tokens
// 1 === ¥0.014 / 1k tokens // 1 === ¥0.014 / 1k tokens
var ModelRatio = map[string]float64{ var DefaultModelRatio = map[string]float64{
//"midjourney": 50, //"midjourney": 50,
"gpt-4-gizmo-*": 15, "gpt-4-gizmo-*": 15,
"gpt-4": 15, "gpt-4": 15,
...@@ -115,6 +115,7 @@ var DefaultModelPrice = map[string]float64{ ...@@ -115,6 +115,7 @@ var DefaultModelPrice = map[string]float64{
} }
var ModelPrice = map[string]float64{} var ModelPrice = map[string]float64{}
var ModelRatio = map[string]float64{}
func ModelPrice2JSONString() string { func ModelPrice2JSONString() string {
if len(ModelPrice) == 0 { if len(ModelPrice) == 0 {
...@@ -150,6 +151,9 @@ func GetModelPrice(name string, printErr bool) float64 { ...@@ -150,6 +151,9 @@ func GetModelPrice(name string, printErr bool) float64 {
} }
func ModelRatio2JSONString() string { func ModelRatio2JSONString() string {
if len(ModelRatio) == 0 {
ModelRatio = DefaultModelRatio
}
jsonBytes, err := json.Marshal(ModelRatio) jsonBytes, err := json.Marshal(ModelRatio)
if err != nil { if err != nil {
SysError("error marshalling model ratio: " + err.Error()) SysError("error marshalling model ratio: " + err.Error())
...@@ -163,6 +167,9 @@ func UpdateModelRatioByJSONString(jsonStr string) error { ...@@ -163,6 +167,9 @@ func UpdateModelRatioByJSONString(jsonStr string) error {
} }
func GetModelRatio(name string) float64 { func GetModelRatio(name string) float64 {
if len(ModelRatio) == 0 {
ModelRatio = DefaultModelRatio
}
if strings.HasPrefix(name, "gpt-4-gizmo") { if strings.HasPrefix(name, "gpt-4-gizmo") {
name = "gpt-4-gizmo-*" name = "gpt-4-gizmo-*"
} }
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"prettier": "^2.7.1", "prettier": "2.8.8",
"typescript": "4.4.2" "typescript": "4.4.2"
}, },
"prettier": { "prettier": {
......
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { getFooterHTML, getSystemName } from '../helpers'; import { getFooterHTML, getSystemName } from '../helpers';
import {Layout} from "@douyinfe/semi-ui"; import { Layout } from '@douyinfe/semi-ui';
const Footer = () => { const Footer = () => {
const systemName = getSystemName(); const systemName = getSystemName();
...@@ -29,30 +29,30 @@ const Footer = () => { ...@@ -29,30 +29,30 @@ const Footer = () => {
return ( return (
<Layout> <Layout>
<Layout.Content style={{textAlign: 'center'}}> <Layout.Content style={{ textAlign: 'center' }}>
{footer ? ( {footer ? (
<div <div
className='custom-footer' className="custom-footer"
dangerouslySetInnerHTML={{ __html: footer }} dangerouslySetInnerHTML={{ __html: footer }}
></div> ></div>
) : ( ) : (
<div className='custom-footer'> <div className="custom-footer">
<a <a
href='https://github.com/Calcium-Ion/new-api' href="https://github.com/Calcium-Ion/new-api"
target='_blank' target="_blank" rel="noreferrer"
> >
New API {process.env.REACT_APP_VERSION}{' '} New API {process.env.REACT_APP_VERSION}{' '}
</a> </a>
{' '} {' '}
<a href='https://github.com/Calcium-Ion' target='_blank'> <a href="https://github.com/Calcium-Ion" target="_blank" rel="noreferrer">
Calcium-Ion Calcium-Ion
</a>{' '} </a>{' '}
开发,基于{' '} 开发,基于{' '}
<a href='https://github.com/songquanpeng/one-api' target='_blank'> <a href="https://github.com/songquanpeng/one-api" target="_blank" rel="noreferrer">
One API v0.5.4 One API v0.5.4
</a>{' '} </a>{' '}
,本项目根据{' '} ,本项目根据{' '}
<a href='https://opensource.org/licenses/mit-license.php'> <a href="https://opensource.org/licenses/mit-license.php">
MIT 许可证 MIT 许可证
</a>{' '} </a>{' '}
授权 授权
......
...@@ -49,7 +49,7 @@ const GitHubOAuth = () => { ...@@ -49,7 +49,7 @@ const GitHubOAuth = () => {
return ( return (
<Segment style={{ minHeight: '300px' }}> <Segment style={{ minHeight: '300px' }}>
<Dimmer active inverted> <Dimmer active inverted>
<Loader size='large'>{prompt}</Loader> <Loader size="large">{prompt}</Loader>
</Dimmer> </Dimmer>
</Segment> </Segment>
); );
......
import React from 'react'; import React from 'react';
import { Segment, Dimmer, Loader } from 'semantic-ui-react'; import { Dimmer, Loader, Segment } from 'semantic-ui-react';
const Loading = ({ prompt: name = 'page' }) => { const Loading = ({ prompt: name = 'page' }) => {
return ( return (
......
import React, { useEffect, useRef, useState } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import { Col, Row , Form, Button, Banner } from '@douyinfe/semi-ui'; import { Banner, Button, Col, Form, Row } from '@douyinfe/semi-ui';
import { API, showError, showSuccess } from '../helpers'; import { API, showError, showSuccess } from '../helpers';
import { marked } from 'marked'; import { marked } from 'marked';
...@@ -57,8 +57,8 @@ const OtherSetting = () => { ...@@ -57,8 +57,8 @@ const OtherSetting = () => {
await updateOption('Notice', inputs.Notice); await updateOption('Notice', inputs.Notice);
showSuccess('公告已更新'); showSuccess('公告已更新');
} catch (error) { } catch (error) {
console.error("公告更新失败", error); console.error('公告更新失败', error);
showError("公告更新失败") showError('公告更新失败');
} finally { } finally {
setLoadingInput((loadingInput) => ({ ...loadingInput, Notice: false })); setLoadingInput((loadingInput) => ({ ...loadingInput, Notice: false }));
} }
...@@ -72,8 +72,8 @@ const OtherSetting = () => { ...@@ -72,8 +72,8 @@ const OtherSetting = () => {
await updateOption('SystemName', inputs.SystemName); await updateOption('SystemName', inputs.SystemName);
showSuccess('系统名称已更新'); showSuccess('系统名称已更新');
} catch (error) { } catch (error) {
console.error("系统名称更新失败", error); console.error('系统名称更新失败', error);
showError("系统名称更新失败") showError('系统名称更新失败');
} finally { } finally {
setLoadingInput((loadingInput) => ({ ...loadingInput, SystemName: false })); setLoadingInput((loadingInput) => ({ ...loadingInput, SystemName: false }));
} }
...@@ -86,8 +86,8 @@ const OtherSetting = () => { ...@@ -86,8 +86,8 @@ const OtherSetting = () => {
await updateOption('Logo', inputs.Logo); await updateOption('Logo', inputs.Logo);
showSuccess('Logo 已更新'); showSuccess('Logo 已更新');
} catch (error) { } catch (error) {
console.error("Logo 更新失败", error); console.error('Logo 更新失败', error);
showError("Logo 更新失败") showError('Logo 更新失败');
} finally { } finally {
setLoadingInput((loadingInput) => ({ ...loadingInput, Logo: false })); setLoadingInput((loadingInput) => ({ ...loadingInput, Logo: false }));
} }
...@@ -99,8 +99,8 @@ const OtherSetting = () => { ...@@ -99,8 +99,8 @@ const OtherSetting = () => {
await updateOption(key, inputs[key]); await updateOption(key, inputs[key]);
showSuccess('首页内容已更新'); showSuccess('首页内容已更新');
} catch (error) { } catch (error) {
console.error("首页内容更新失败", error); console.error('首页内容更新失败', error);
showError("首页内容更新失败") showError('首页内容更新失败');
} finally { } finally {
setLoadingInput((loadingInput) => ({ ...loadingInput, HomePageContent: false })); setLoadingInput((loadingInput) => ({ ...loadingInput, HomePageContent: false }));
} }
...@@ -112,8 +112,8 @@ const OtherSetting = () => { ...@@ -112,8 +112,8 @@ const OtherSetting = () => {
await updateOption('About', inputs.About); await updateOption('About', inputs.About);
showSuccess('关于内容已更新'); showSuccess('关于内容已更新');
} catch (error) { } catch (error) {
console.error("关于内容更新失败", error); console.error('关于内容更新失败', error);
showError("关于内容更新失败"); showError('关于内容更新失败');
} finally { } finally {
setLoadingInput((loadingInput) => ({ ...loadingInput, About: false })); setLoadingInput((loadingInput) => ({ ...loadingInput, About: false }));
} }
...@@ -125,16 +125,14 @@ const OtherSetting = () => { ...@@ -125,16 +125,14 @@ const OtherSetting = () => {
await updateOption('Footer', inputs.Footer); await updateOption('Footer', inputs.Footer);
showSuccess('页脚内容已更新'); showSuccess('页脚内容已更新');
} catch (error) { } catch (error) {
console.error("页脚内容更新失败", error); console.error('页脚内容更新失败', error);
showError("页脚内容更新失败"); showError('页脚内容更新失败');
} finally { } finally {
setLoadingInput((loadingInput) => ({ ...loadingInput, Footer: false })); setLoadingInput((loadingInput) => ({ ...loadingInput, Footer: false }));
} }
}; };
const openGitHubRelease = () => { const openGitHubRelease = () => {
window.location = window.location =
'https://github.com/songquanpeng/one-api/releases/latest'; 'https://github.com/songquanpeng/one-api/releases/latest';
...@@ -173,16 +171,17 @@ const OtherSetting = () => { ...@@ -173,16 +171,17 @@ const OtherSetting = () => {
} }
}; };
useEffect( () => { useEffect(() => {
getOptions(); getOptions();
}, []); }, []);
return ( return (
<Row > <Row>
<Col span={24}> <Col span={24}>
{/* 通用设置 */} {/* 通用设置 */}
<Form values={inputs} getFormApi={formAPI => formAPISettingGeneral.current = formAPI} style={{marginBottom: 15}}> <Form values={inputs} getFormApi={formAPI => formAPISettingGeneral.current = formAPI}
style={{ marginBottom: 15 }}>
<Form.Section text={'通用设置'}> <Form.Section text={'通用设置'}>
<Form.TextArea <Form.TextArea
label={'公告'} label={'公告'}
...@@ -191,26 +190,27 @@ const OtherSetting = () => { ...@@ -191,26 +190,27 @@ const OtherSetting = () => {
onChange={handleInputChange} onChange={handleInputChange}
style={{ fontFamily: 'JetBrains Mono, Consolas' }} style={{ fontFamily: 'JetBrains Mono, Consolas' }}
autosize={{ minRows: 6, maxRows: 12 }} autosize={{ minRows: 6, maxRows: 12 }}
/> />
<Button onClick={submitNotice} loading={loadingInput['Notice']}>设置公告</Button> <Button onClick={submitNotice} loading={loadingInput['Notice']}>设置公告</Button>
</Form.Section> </Form.Section>
</Form> </Form>
{/* 个性化设置 */} {/* 个性化设置 */}
<Form values={inputs} getFormApi={formAPI => formAPIPersonalization.current = formAPI} style={{marginBottom: 15}}> <Form values={inputs} getFormApi={formAPI => formAPIPersonalization.current = formAPI}
style={{ marginBottom: 15 }}>
<Form.Section text={'个性化设置'}> <Form.Section text={'个性化设置'}>
<Form.Input <Form.Input
label={'系统名称'} label={'系统名称'}
placeholder={'在此输入系统名称'} placeholder={'在此输入系统名称'}
field={'SystemName'} field={'SystemName'}
onChange={handleInputChange} onChange={handleInputChange}
/> />
<Button onClick={submitSystemName} loading={loadingInput['SystemName']}>设置系统名称</Button> <Button onClick={submitSystemName} loading={loadingInput['SystemName']}>设置系统名称</Button>
<Form.Input <Form.Input
label={'Logo 图片地址'} label={'Logo 图片地址'}
placeholder={'在此输入 Logo 图片地址'} placeholder={'在此输入 Logo 图片地址'}
field={'Logo'} field={'Logo'}
onChange={handleInputChange} onChange={handleInputChange}
/> />
<Button onClick={submitLogo} loading={loadingInput['Logo']}>设置 Logo</Button> <Button onClick={submitLogo} loading={loadingInput['Logo']}>设置 Logo</Button>
<Form.TextArea <Form.TextArea
label={'首页内容'} label={'首页内容'}
...@@ -219,8 +219,9 @@ const OtherSetting = () => { ...@@ -219,8 +219,9 @@ const OtherSetting = () => {
onChange={handleInputChange} onChange={handleInputChange}
style={{ fontFamily: 'JetBrains Mono, Consolas' }} style={{ fontFamily: 'JetBrains Mono, Consolas' }}
autosize={{ minRows: 6, maxRows: 12 }} autosize={{ minRows: 6, maxRows: 12 }}
/> />
<Button onClick={() => submitOption('HomePageContent')} loading={loadingInput['HomePageContent']}>设置首页内容</Button> <Button onClick={() => submitOption('HomePageContent')}
loading={loadingInput['HomePageContent']}>设置首页内容</Button>
<Form.TextArea <Form.TextArea
label={'关于'} label={'关于'}
placeholder={'在此输入新的关于内容,支持 Markdown & HTML 代码。如果输入的是一个链接,则会使用该链接作为 iframe 的 src 属性,这允许你设置任意网页作为关于页面。'} placeholder={'在此输入新的关于内容,支持 Markdown & HTML 代码。如果输入的是一个链接,则会使用该链接作为 iframe 的 src 属性,这允许你设置任意网页作为关于页面。'}
...@@ -228,7 +229,7 @@ const OtherSetting = () => { ...@@ -228,7 +229,7 @@ const OtherSetting = () => {
onChange={handleInputChange} onChange={handleInputChange}
style={{ fontFamily: 'JetBrains Mono, Consolas' }} style={{ fontFamily: 'JetBrains Mono, Consolas' }}
autosize={{ minRows: 6, maxRows: 12 }} autosize={{ minRows: 6, maxRows: 12 }}
/> />
<Button onClick={submitAbout} loading={loadingInput['About']}>设置关于</Button> <Button onClick={submitAbout} loading={loadingInput['About']}>设置关于</Button>
{/* */} {/* */}
<Banner <Banner
...@@ -236,14 +237,14 @@ const OtherSetting = () => { ...@@ -236,14 +237,14 @@ const OtherSetting = () => {
type="info" type="info"
description="移除 One API 的版权标识必须首先获得授权,项目维护需要花费大量精力,如果本项目对你有意义,请主动支持本项目。" description="移除 One API 的版权标识必须首先获得授权,项目维护需要花费大量精力,如果本项目对你有意义,请主动支持本项目。"
closeIcon={null} closeIcon={null}
style={{ marginTop: 15 }} style={{ marginTop: 15 }}
/> />
<Form.Input <Form.Input
label={'页脚'} label={'页脚'}
placeholder={'在此输入新的页脚,留空则使用默认页脚,支持 HTML 代码'} placeholder={'在此输入新的页脚,留空则使用默认页脚,支持 HTML 代码'}
field={'Footer'} field={'Footer'}
onChange={handleInputChange} onChange={handleInputChange}
/> />
<Button onClick={submitFooter} loading={loadingInput['Footer']}>设置页脚</Button> <Button onClick={submitFooter} loading={loadingInput['Footer']}>设置页脚</Button>
</Form.Section> </Form.Section>
</Form> </Form>
...@@ -270,7 +271,7 @@ const OtherSetting = () => { ...@@ -270,7 +271,7 @@ const OtherSetting = () => {
{/* />*/} {/* />*/}
{/* </Modal.Actions>*/} {/* </Modal.Actions>*/}
{/*</Modal>*/} {/*</Modal>*/}
</Row> </Row>
); );
}; };
......
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Button, Form, Grid, Header, Image, Segment } from 'semantic-ui-react'; import { Button, Form, Grid, Header, Image, Segment } from 'semantic-ui-react';
import { API, copy, showError, showInfo, showNotice, showSuccess } from '../helpers'; import { API, copy, showError, showNotice } from '../helpers';
import { useSearchParams } from 'react-router-dom'; import { useSearchParams } from 'react-router-dom';
const PasswordResetConfirm = () => { const PasswordResetConfirm = () => {
const [inputs, setInputs] = useState({ const [inputs, setInputs] = useState({
email: '', email: '',
token: '', token: ''
}); });
const { email, token } = inputs; const { email, token } = inputs;
...@@ -23,7 +23,7 @@ const PasswordResetConfirm = () => { ...@@ -23,7 +23,7 @@ const PasswordResetConfirm = () => {
let email = searchParams.get('email'); let email = searchParams.get('email');
setInputs({ setInputs({
token, token,
email, email
}); });
}, []); }, []);
...@@ -37,7 +37,7 @@ const PasswordResetConfirm = () => { ...@@ -37,7 +37,7 @@ const PasswordResetConfirm = () => {
setDisableButton(false); setDisableButton(false);
setCountdown(30); setCountdown(30);
} }
return () => clearInterval(countdownInterval); return () => clearInterval(countdownInterval);
}, [disableButton, countdown]); }, [disableButton, countdown]);
async function handleSubmit(e) { async function handleSubmit(e) {
...@@ -46,7 +46,7 @@ const PasswordResetConfirm = () => { ...@@ -46,7 +46,7 @@ const PasswordResetConfirm = () => {
setLoading(true); setLoading(true);
const res = await API.post(`/api/user/reset`, { const res = await API.post(`/api/user/reset`, {
email, email,
token, token
}); });
const { success, message } = res.data; const { success, message } = res.data;
if (success) { if (success) {
...@@ -59,44 +59,44 @@ const PasswordResetConfirm = () => { ...@@ -59,44 +59,44 @@ const PasswordResetConfirm = () => {
} }
setLoading(false); setLoading(false);
} }
return ( return (
<Grid textAlign='center' style={{ marginTop: '48px' }}> <Grid textAlign="center" style={{ marginTop: '48px' }}>
<Grid.Column style={{ maxWidth: 450 }}> <Grid.Column style={{ maxWidth: 450 }}>
<Header as='h2' color='' textAlign='center'> <Header as="h2" color="" textAlign="center">
<Image src='/logo.png' /> 密码重置确认 <Image src="/logo.png" /> 密码重置确认
</Header> </Header>
<Form size='large'> <Form size="large">
<Segment> <Segment>
<Form.Input <Form.Input
fluid fluid
icon='mail' icon="mail"
iconPosition='left' iconPosition="left"
placeholder='邮箱地址' placeholder="邮箱地址"
name='email' name="email"
value={email} value={email}
readOnly readOnly
/> />
{newPassword && ( {newPassword && (
<Form.Input <Form.Input
fluid fluid
icon='lock' icon="lock"
iconPosition='left' iconPosition="left"
placeholder='新密码' placeholder="新密码"
name='newPassword' name="newPassword"
value={newPassword} value={newPassword}
readOnly readOnly
onClick={(e) => { onClick={(e) => {
e.target.select(); e.target.select();
navigator.clipboard.writeText(newPassword); navigator.clipboard.writeText(newPassword);
showNotice(`密码已复制到剪贴板:${newPassword}`); showNotice(`密码已复制到剪贴板:${newPassword}`);
}} }}
/> />
)} )}
<Button <Button
color='green' color="green"
fluid fluid
size='large' size="large"
onClick={handleSubmit} onClick={handleSubmit}
loading={loading} loading={loading}
disabled={disableButton} disabled={disableButton}
...@@ -107,7 +107,7 @@ const PasswordResetConfirm = () => { ...@@ -107,7 +107,7 @@ const PasswordResetConfirm = () => {
</Form> </Form>
</Grid.Column> </Grid.Column>
</Grid> </Grid>
); );
}; };
export default PasswordResetConfirm; export default PasswordResetConfirm;
...@@ -56,19 +56,19 @@ const PasswordResetForm = () => { ...@@ -56,19 +56,19 @@ const PasswordResetForm = () => {
} }
return ( return (
<Grid textAlign='center' style={{ marginTop: '48px' }}> <Grid textAlign="center" style={{ marginTop: '48px' }}>
<Grid.Column style={{ maxWidth: 450 }}> <Grid.Column style={{ maxWidth: 450 }}>
<Header as='h2' color='' textAlign='center'> <Header as="h2" color="" textAlign="center">
<Image src='/logo.png' /> 密码重置 <Image src="/logo.png" /> 密码重置
</Header> </Header>
<Form size='large'> <Form size="large">
<Segment> <Segment>
<Form.Input <Form.Input
fluid fluid
icon='mail' icon="mail"
iconPosition='left' iconPosition="left"
placeholder='邮箱地址' placeholder="邮箱地址"
name='email' name="email"
value={email} value={email}
onChange={handleChange} onChange={handleChange}
/> />
...@@ -83,9 +83,9 @@ const PasswordResetForm = () => { ...@@ -83,9 +83,9 @@ const PasswordResetForm = () => {
<></> <></>
)} )}
<Button <Button
color='green' color="green"
fluid fluid
size='large' size="large"
onClick={handleSubmit} onClick={handleSubmit}
loading={loading} loading={loading}
disabled={disableButton} disabled={disableButton}
......
...@@ -5,7 +5,7 @@ import { history } from '../helpers'; ...@@ -5,7 +5,7 @@ import { history } from '../helpers';
function PrivateRoute({ children }) { function PrivateRoute({ children }) {
if (!localStorage.getItem('user')) { if (!localStorage.getItem('user')) {
return <Navigate to='/login' state={{ from: history.location }} />; return <Navigate to="/login" state={{ from: history.location }} />;
} }
return children; return children;
} }
......
...@@ -98,49 +98,49 @@ const RegisterForm = () => { ...@@ -98,49 +98,49 @@ const RegisterForm = () => {
}; };
return ( return (
<Grid textAlign='center' style={{ marginTop: '48px' }}> <Grid textAlign="center" style={{ marginTop: '48px' }}>
<Grid.Column style={{ maxWidth: 450 }}> <Grid.Column style={{ maxWidth: 450 }}>
<Header as='h2' color='' textAlign='center'> <Header as="h2" color="" textAlign="center">
<Image src={logo} /> 新用户注 <Image src={logo} /> 新用户注
</Header> </Header>
<Form size='large'> <Form size="large">
<Segment> <Segment>
<Form.Input <Form.Input
fluid fluid
icon='user' icon="user"
iconPosition='left' iconPosition="left"
placeholder='输入用户名,最长 12 位' placeholder="输入用户名,最长 12 位"
onChange={handleChange} onChange={handleChange}
name='username' name="username"
/> />
<Form.Input <Form.Input
fluid fluid
icon='lock' icon="lock"
iconPosition='left' iconPosition="left"
placeholder='输入密码,最短 8 位,最长 20 位' placeholder="输入密码,最短 8 位,最长 20 位"
onChange={handleChange} onChange={handleChange}
name='password' name="password"
type='password' type="password"
/> />
<Form.Input <Form.Input
fluid fluid
icon='lock' icon="lock"
iconPosition='left' iconPosition="left"
placeholder='输入密码,最短 8 位,最长 20 位' placeholder="输入密码,最短 8 位,最长 20 位"
onChange={handleChange} onChange={handleChange}
name='password2' name="password2"
type='password' type="password"
/> />
{showEmailVerification ? ( {showEmailVerification ? (
<> <>
<Form.Input <Form.Input
fluid fluid
icon='mail' icon="mail"
iconPosition='left' iconPosition="left"
placeholder='输入邮箱地址' placeholder="输入邮箱地址"
onChange={handleChange} onChange={handleChange}
name='email' name="email"
type='email' type="email"
action={ action={
<Button onClick={sendVerificationCode} disabled={loading}> <Button onClick={sendVerificationCode} disabled={loading}>
获取验证码 获取验证码
...@@ -149,11 +149,11 @@ const RegisterForm = () => { ...@@ -149,11 +149,11 @@ const RegisterForm = () => {
/> />
<Form.Input <Form.Input
fluid fluid
icon='lock' icon="lock"
iconPosition='left' iconPosition="left"
placeholder='输入验证码' placeholder="输入验证码"
onChange={handleChange} onChange={handleChange}
name='verification_code' name="verification_code"
/> />
</> </>
) : ( ) : (
...@@ -170,9 +170,9 @@ const RegisterForm = () => { ...@@ -170,9 +170,9 @@ const RegisterForm = () => {
<></> <></>
)} )}
<Button <Button
color='green' color="green"
fluid fluid
size='large' size="large"
onClick={handleSubmit} onClick={handleSubmit}
loading={loading} loading={loading}
> >
...@@ -182,7 +182,7 @@ const RegisterForm = () => { ...@@ -182,7 +182,7 @@ const RegisterForm = () => {
</Form> </Form>
<Message> <Message>
已有账户? 已有账户?
<Link to='/login' className='btn btn-link'> <Link to="/login" className="btn btn-link">
点击登录 点击登录
</Link> </Link>
</Message> </Message>
......
...@@ -3,14 +3,14 @@ import { Icon } from '@douyinfe/semi-ui'; ...@@ -3,14 +3,14 @@ import { Icon } from '@douyinfe/semi-ui';
const WeChatIcon = () => { const WeChatIcon = () => {
function CustomIcon() { function CustomIcon() {
return <svg t='1709714447384' className='icon' viewBox='0 0 1024 1024' version='1.1' return <svg t="1709714447384" className="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns='http://www.w3.org/2000/svg' p-id='5091' width='16' height='16'> xmlns="http://www.w3.org/2000/svg" p-id="5091" width="16" height="16">
<path <path
d='M690.1 377.4c5.9 0 11.8 0.2 17.6 0.5-24.4-128.7-158.3-227.1-319.9-227.1C209 150.8 64 271.4 64 420.2c0 81.1 43.6 154.2 111.9 203.6 5.5 3.9 9.1 10.3 9.1 17.6 0 2.4-0.5 4.6-1.1 6.9-5.5 20.3-14.2 52.8-14.6 54.3-0.7 2.6-1.7 5.2-1.7 7.9 0 5.9 4.8 10.8 10.8 10.8 2.3 0 4.2-0.9 6.2-2l70.9-40.9c5.3-3.1 11-5 17.2-5 3.2 0 6.4 0.5 9.5 1.4 33.1 9.5 68.8 14.8 105.7 14.8 6 0 11.9-0.1 17.8-0.4-7.1-21-10.9-43.1-10.9-66 0-135.8 132.2-245.8 295.3-245.8z m-194.3-86.5c23.8 0 43.2 19.3 43.2 43.1s-19.3 43.1-43.2 43.1c-23.8 0-43.2-19.3-43.2-43.1s19.4-43.1 43.2-43.1z m-215.9 86.2c-23.8 0-43.2-19.3-43.2-43.1s19.3-43.1 43.2-43.1 43.2 19.3 43.2 43.1-19.4 43.1-43.2 43.1z' d="M690.1 377.4c5.9 0 11.8 0.2 17.6 0.5-24.4-128.7-158.3-227.1-319.9-227.1C209 150.8 64 271.4 64 420.2c0 81.1 43.6 154.2 111.9 203.6 5.5 3.9 9.1 10.3 9.1 17.6 0 2.4-0.5 4.6-1.1 6.9-5.5 20.3-14.2 52.8-14.6 54.3-0.7 2.6-1.7 5.2-1.7 7.9 0 5.9 4.8 10.8 10.8 10.8 2.3 0 4.2-0.9 6.2-2l70.9-40.9c5.3-3.1 11-5 17.2-5 3.2 0 6.4 0.5 9.5 1.4 33.1 9.5 68.8 14.8 105.7 14.8 6 0 11.9-0.1 17.8-0.4-7.1-21-10.9-43.1-10.9-66 0-135.8 132.2-245.8 295.3-245.8z m-194.3-86.5c23.8 0 43.2 19.3 43.2 43.1s-19.3 43.1-43.2 43.1c-23.8 0-43.2-19.3-43.2-43.1s19.4-43.1 43.2-43.1z m-215.9 86.2c-23.8 0-43.2-19.3-43.2-43.1s19.3-43.1 43.2-43.1 43.2 19.3 43.2 43.1-19.4 43.1-43.2 43.1z"
p-id='5092'></path> p-id="5092"></path>
<path <path
d='M866.7 792.7c56.9-41.2 93.2-102 93.2-169.7 0-124-120.8-224.5-269.9-224.5-149 0-269.9 100.5-269.9 224.5S540.9 847.5 690 847.5c30.8 0 60.6-4.4 88.1-12.3 2.6-0.8 5.2-1.2 7.9-1.2 5.2 0 9.9 1.6 14.3 4.1l59.1 34c1.7 1 3.3 1.7 5.2 1.7 2.4 0 4.7-0.9 6.4-2.6 1.7-1.7 2.6-4 2.6-6.4 0-2.2-0.9-4.4-1.4-6.6-0.3-1.2-7.6-28.3-12.2-45.3-0.5-1.9-0.9-3.8-0.9-5.7 0.1-5.9 3.1-11.2 7.6-14.5zM600.2 587.2c-19.9 0-36-16.1-36-35.9 0-19.8 16.1-35.9 36-35.9s36 16.1 36 35.9c0 19.8-16.2 35.9-36 35.9z m179.9 0c-19.9 0-36-16.1-36-35.9 0-19.8 16.1-35.9 36-35.9s36 16.1 36 35.9c-0.1 19.8-16.2 35.9-36 35.9z' d="M866.7 792.7c56.9-41.2 93.2-102 93.2-169.7 0-124-120.8-224.5-269.9-224.5-149 0-269.9 100.5-269.9 224.5S540.9 847.5 690 847.5c30.8 0 60.6-4.4 88.1-12.3 2.6-0.8 5.2-1.2 7.9-1.2 5.2 0 9.9 1.6 14.3 4.1l59.1 34c1.7 1 3.3 1.7 5.2 1.7 2.4 0 4.7-0.9 6.4-2.6 1.7-1.7 2.6-4 2.6-6.4 0-2.2-0.9-4.4-1.4-6.6-0.3-1.2-7.6-28.3-12.2-45.3-0.5-1.9-0.9-3.8-0.9-5.7 0.1-5.9 3.1-11.2 7.6-14.5zM600.2 587.2c-19.9 0-36-16.1-36-35.9 0-19.8 16.1-35.9 36-35.9s36 16.1 36 35.9c0 19.8-16.2 35.9-36 35.9z m179.9 0c-19.9 0-36-16.1-36-35.9 0-19.8 16.1-35.9 36-35.9s36 16.1 36 35.9c-0.1 19.8-16.2 35.9-36 35.9z"
p-id='5093'></path> p-id="5093"></path>
</svg>; </svg>;
} }
......
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { useParams, useNavigate } from 'react-router-dom'; import { useNavigate, useParams } from 'react-router-dom';
import {API, downloadTextAsFile, isMobile, showError, showSuccess} from '../../helpers'; import { API, downloadTextAsFile, isMobile, showError, showSuccess } from '../../helpers';
import { renderQuota, renderQuotaWithPrompt } from '../../helpers/render'; import { renderQuotaWithPrompt } from '../../helpers/render';
import {SideSheet, Space, Spin, Button, Input, Typography, AutoComplete, Modal} from "@douyinfe/semi-ui"; import { AutoComplete, Button, Input, Modal, SideSheet, Space, Spin, Typography } from '@douyinfe/semi-ui';
import Title from "@douyinfe/semi-ui/lib/es/typography/title"; import Title from '@douyinfe/semi-ui/lib/es/typography/title';
import {Divider} from "semantic-ui-react"; import { Divider } from 'semantic-ui-react';
const EditRedemption = (props) => { const EditRedemption = (props) => {
const isEdit = props.editingRedemption.id !== undefined; const isEdit = props.editingRedemption.id !== undefined;
const [loading, setLoading] = useState(isEdit); const [loading, setLoading] = useState(isEdit);
const params = useParams(); const params = useParams();
const navigate = useNavigate() const navigate = useNavigate();
const originInputs = { const originInputs = {
name: '', name: '',
quota: 100000, quota: 100000,
...@@ -22,8 +22,8 @@ const EditRedemption = (props) => { ...@@ -22,8 +22,8 @@ const EditRedemption = (props) => {
const handleCancel = () => { const handleCancel = () => {
props.handleClose(); props.handleClose();
} };
const handleInputChange = (name, value) => { const handleInputChange = (name, value) => {
setInputs((inputs) => ({ ...inputs, [name]: value })); setInputs((inputs) => ({ ...inputs, [name]: value }));
}; };
...@@ -43,9 +43,9 @@ const EditRedemption = (props) => { ...@@ -43,9 +43,9 @@ const EditRedemption = (props) => {
useEffect(() => { useEffect(() => {
if (isEdit) { if (isEdit) {
loadRedemption().then( loadRedemption().then(
() => { () => {
// console.log(inputs); // console.log(inputs);
} }
); );
} else { } else {
setInputs(originInputs); setInputs(originInputs);
...@@ -82,21 +82,21 @@ const EditRedemption = (props) => { ...@@ -82,21 +82,21 @@ const EditRedemption = (props) => {
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`);
Modal.confirm({ Modal.confirm({
title: '兑换码创建成功', title: '兑换码创建成功',
content: ( content: (
<div> <div>
<p>兑换码创建成功,是否下载兑换码?</p> <p>兑换码创建成功,是否下载兑换码?</p>
<p>兑换码将以文本文件的形式下载,文件名为兑换码的名称。</p> <p>兑换码将以文本文件的形式下载,文件名为兑换码的名称。</p>
</div> </div>
), ),
onOk: () => { onOk: () => {
downloadTextAsFile(text, `${inputs.name}.txt`); downloadTextAsFile(text, `${inputs.name}.txt`);
} }
}); });
} }
...@@ -106,71 +106,71 @@ const EditRedemption = (props) => { ...@@ -106,71 +106,71 @@ const EditRedemption = (props) => {
return ( return (
<> <>
<SideSheet <SideSheet
placement={isEdit ? 'right' : 'left'} placement={isEdit ? 'right' : 'left'}
title={<Title level={3}>{isEdit ? '更新兑换码信息' : '创建新的兑换码'}</Title>} title={<Title level={3}>{isEdit ? '更新兑换码信息' : '创建新的兑换码'}</Title>}
headerStyle={{borderBottom: '1px solid var(--semi-color-border)'}} headerStyle={{ borderBottom: '1px solid var(--semi-color-border)' }}
bodyStyle={{borderBottom: '1px solid var(--semi-color-border)'}} bodyStyle={{ borderBottom: '1px solid var(--semi-color-border)' }}
visible={props.visiable} visible={props.visiable}
footer={ footer={
<div style={{display: 'flex', justifyContent: 'flex-end'}}> <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
<Space> <Space>
<Button theme='solid' size={'large'} onClick={submit}>提交</Button> <Button theme="solid" size={'large'} onClick={submit}>提交</Button>
<Button theme='solid' size={'large'} type={'tertiary'} onClick={handleCancel}>取消</Button> <Button theme="solid" size={'large'} type={'tertiary'} onClick={handleCancel}>取消</Button>
</Space> </Space>
</div> </div>
} }
closeIcon={null} closeIcon={null}
onCancel={() => handleCancel()} onCancel={() => handleCancel()}
width={isMobile() ? '100%' : 600} width={isMobile() ? '100%' : 600}
> >
<Spin spinning={loading}> <Spin spinning={loading}>
<Input <Input
style={{ marginTop: 20 }} style={{ marginTop: 20 }}
label='名称' label="名称"
name='name' name="name"
placeholder={'请输入名称'} placeholder={'请输入名称'}
onChange={value => handleInputChange('name', value)} onChange={value => handleInputChange('name', value)}
value={name} value={name}
autoComplete='new-password' autoComplete="new-password"
required={!isEdit} required={!isEdit}
/> />
<Divider/> <Divider />
<div style={{ marginTop: 20 }}> <div style={{ marginTop: 20 }}>
<Typography.Text>{`额度${renderQuotaWithPrompt(quota)}`}</Typography.Text> <Typography.Text>{`额度${renderQuotaWithPrompt(quota)}`}</Typography.Text>
</div> </div>
<AutoComplete <AutoComplete
style={{ marginTop: 8 }} style={{ marginTop: 8 }}
name='quota' name="quota"
placeholder={'请输入额度'} placeholder={'请输入额度'}
onChange={(value) => handleInputChange('quota', value)} onChange={(value) => handleInputChange('quota', value)}
value={quota} value={quota}
autoComplete='new-password' autoComplete="new-password"
type='number' type="number"
position={'bottom'} position={'bottom'}
data={[ data={[
{value: 500000, label: '1$'}, { value: 500000, label: '1$' },
{value: 5000000, label: '10$'}, { value: 5000000, label: '10$' },
{value: 25000000, label: '50$'}, { value: 25000000, label: '50$' },
{value: 50000000, label: '100$'}, { value: 50000000, label: '100$' },
{value: 250000000, label: '500$'}, { value: 250000000, label: '500$' },
{value: 500000000, label: '1000$'}, { value: 500000000, label: '1000$' }
]} ]}
/> />
{ {
!isEdit && <> !isEdit && <>
<Divider/> <Divider />
<Typography.Text>生成数量</Typography.Text> <Typography.Text>生成数量</Typography.Text>
<Input <Input
style={{ marginTop: 8 }} style={{ marginTop: 8 }}
label='生成数量' label="生成数量"
name='count' name="count"
placeholder={'请输入生成数量'} placeholder={'请输入生成数量'}
onChange={value => handleInputChange('count', value)} onChange={value => handleInputChange('count', value)}
value={count} value={count}
autoComplete='new-password' autoComplete="new-password"
type='number' type="number"
/> />
</> </>
} }
</Spin> </Spin>
</SideSheet> </SideSheet>
......
import React, {useState} from 'react'; import React, { useState } from 'react';
import {API, isMobile, showError, showSuccess} from '../../helpers'; import { API, isMobile, showError, showSuccess } from '../../helpers';
import Title from "@douyinfe/semi-ui/lib/es/typography/title"; import Title from '@douyinfe/semi-ui/lib/es/typography/title';
import {Button, SideSheet, Space, Input, Spin} from "@douyinfe/semi-ui"; import { Button, Input, SideSheet, Space, Spin } from '@douyinfe/semi-ui';
const AddUser = (props) => { const AddUser = (props) => {
const originInputs = { const originInputs = {
username: '', username: '',
display_name: '', display_name: '',
password: '', password: ''
}; };
const [inputs, setInputs] = useState(originInputs); const [inputs, setInputs] = useState(originInputs);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const {username, display_name, password} = inputs; const { username, display_name, password } = inputs;
const handleInputChange = (name, value) => { const handleInputChange = (name, value) => {
setInputs((inputs) => ({...inputs, [name]: value})); setInputs((inputs) => ({ ...inputs, [name]: value }));
}; };
const submit = async () => { const submit = async () => {
setLoading(true); setLoading(true);
if (inputs.username === '' || inputs.password === '') return; if (inputs.username === '' || inputs.password === '') return;
const res = await API.post(`/api/user/`, inputs); const res = await API.post(`/api/user/`, inputs);
const {success, message} = res.data; const { success, message } = res.data;
if (success) { if (success) {
showSuccess('用户账户创建成功!'); showSuccess('用户账户创建成功!');
setInputs(originInputs); setInputs(originInputs);
props.refresh(); props.refresh();
props.handleClose(); props.handleClose();
} else { } else {
showError(message); showError(message);
}
setLoading(false);
};
const handleCancel = () => {
props.handleClose();
} }
setLoading(false);
};
return ( const handleCancel = () => {
<> props.handleClose();
<SideSheet };
placement={'left'}
title={<Title level={3}>{'添加用户'}</Title>} return (
headerStyle={{borderBottom: '1px solid var(--semi-color-border)'}} <>
bodyStyle={{borderBottom: '1px solid var(--semi-color-border)'}} <SideSheet
visible={props.visible} placement={'left'}
footer={ title={<Title level={3}>{'添加用户'}</Title>}
<div style={{display: 'flex', justifyContent: 'flex-end'}}> headerStyle={{ borderBottom: '1px solid var(--semi-color-border)' }}
<Space> bodyStyle={{ borderBottom: '1px solid var(--semi-color-border)' }}
<Button theme='solid' size={'large'} onClick={submit}>提交</Button> visible={props.visible}
<Button theme='solid' size={'large'} type={'tertiary'} onClick={handleCancel}>取消</Button> footer={
</Space> <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
</div> <Space>
} <Button theme="solid" size={'large'} onClick={submit}>提交</Button>
closeIcon={null} <Button theme="solid" size={'large'} type={'tertiary'} onClick={handleCancel}>取消</Button>
onCancel={() => handleCancel()} </Space>
width={isMobile() ? '100%' : 600} </div>
> }
<Spin spinning={loading}> closeIcon={null}
<Input onCancel={() => handleCancel()}
style={{marginTop: 20}} width={isMobile() ? '100%' : 600}
label="用户名" >
name="username" <Spin spinning={loading}>
addonBefore={'用户名'} <Input
placeholder={'请输入用户名'} style={{ marginTop: 20 }}
onChange={value => handleInputChange('username', value)} label="用户名"
value={username} name="username"
autoComplete="off" addonBefore={'用户名'}
/> placeholder={'请输入用户名'}
<Input onChange={value => handleInputChange('username', value)}
style={{marginTop: 20}} value={username}
addonBefore={'显示名'} autoComplete="off"
label="显示名称" />
name="display_name" <Input
autoComplete="off" style={{ marginTop: 20 }}
placeholder={'请输入显示名称'} addonBefore={'显示名'}
onChange={value => handleInputChange('display_name', value)} label="显示名称"
value={display_name} name="display_name"
/> autoComplete="off"
<Input placeholder={'请输入显示名称'}
style={{marginTop: 20}} onChange={value => handleInputChange('display_name', value)}
label="密 码" value={display_name}
name="password" />
type={'password'} <Input
addonBefore={'密码'} style={{ marginTop: 20 }}
placeholder={'请输入密码'} label="密 码"
onChange={value => handleInputChange('password', value)} name="password"
value={password} type={'password'}
autoComplete="off" addonBefore={'密码'}
/> placeholder={'请输入密码'}
</Spin> onChange={value => handleInputChange('password', value)}
</SideSheet> value={password}
</> autoComplete="off"
); />
</Spin>
</SideSheet>
</>
);
}; };
export default AddUser; export default AddUser;
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { useParams, useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { API, isMobile, showError, showSuccess } from '../../helpers'; import { API, isMobile, showError, showSuccess } from '../../helpers';
import { renderQuota, renderQuotaWithPrompt } from '../../helpers/render'; import { renderQuotaWithPrompt } from '../../helpers/render';
import Title from "@douyinfe/semi-ui/lib/es/typography/title"; import Title from '@douyinfe/semi-ui/lib/es/typography/title';
import { SideSheet, Space, Button, Spin, Input, Typography, Select, Divider } from "@douyinfe/semi-ui"; import { Button, Divider, Input, Select, SideSheet, Space, Spin, Typography } from '@douyinfe/semi-ui';
const EditUser = (props) => { const EditUser = (props) => {
const userId = props.editingUser.id; const userId = props.editingUser.id;
...@@ -29,7 +29,7 @@ const EditUser = (props) => { ...@@ -29,7 +29,7 @@ const EditUser = (props) => {
let res = await API.get(`/api/group/`); let res = await API.get(`/api/group/`);
setGroupOptions(res.data.data.map((group) => ({ setGroupOptions(res.data.data.map((group) => ({
label: group, label: group,
value: group, value: group
}))); })));
} catch (error) { } catch (error) {
showError(error.message); showError(error.message);
...@@ -38,7 +38,7 @@ const EditUser = (props) => { ...@@ -38,7 +38,7 @@ const EditUser = (props) => {
const navigate = useNavigate(); const navigate = useNavigate();
const handleCancel = () => { const handleCancel = () => {
props.handleClose(); props.handleClose();
} };
const loadUser = async () => { const loadUser = async () => {
setLoading(true); setLoading(true);
let res = undefined; let res = undefined;
...@@ -98,8 +98,8 @@ const EditUser = (props) => { ...@@ -98,8 +98,8 @@ const EditUser = (props) => {
footer={ footer={
<div style={{ display: 'flex', justifyContent: 'flex-end' }}> <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
<Space> <Space>
<Button theme='solid' size={'large'} onClick={submit}>提交</Button> <Button theme="solid" size={'large'} onClick={submit}>提交</Button>
<Button theme='solid' size={'large'} type={'tertiary'} onClick={handleCancel}>取消</Button> <Button theme="solid" size={'large'} type={'tertiary'} onClick={handleCancel}>取消</Button>
</Space> </Space>
</div> </div>
} }
...@@ -112,35 +112,35 @@ const EditUser = (props) => { ...@@ -112,35 +112,35 @@ const EditUser = (props) => {
<Typography.Text>用户名</Typography.Text> <Typography.Text>用户名</Typography.Text>
</div> </div>
<Input <Input
label='用户名' label="用户名"
name='username' name="username"
placeholder={'请输入新的用户名'} placeholder={'请输入新的用户名'}
onChange={value => handleInputChange('username', value)} onChange={value => handleInputChange('username', value)}
value={username} value={username}
autoComplete='new-password' autoComplete="new-password"
/> />
<div style={{ marginTop: 20 }}> <div style={{ marginTop: 20 }}>
<Typography.Text>密码</Typography.Text> <Typography.Text>密码</Typography.Text>
</div> </div>
<Input <Input
label='密码' label="密码"
name='password' name="password"
type={'password'} type={'password'}
placeholder={'请输入新的密码,最短 8 位'} placeholder={'请输入新的密码,最短 8 位'}
onChange={value => handleInputChange('password', value)} onChange={value => handleInputChange('password', value)}
value={password} value={password}
autoComplete='new-password' autoComplete="new-password"
/> />
<div style={{ marginTop: 20 }}> <div style={{ marginTop: 20 }}>
<Typography.Text>显示名称</Typography.Text> <Typography.Text>显示名称</Typography.Text>
</div> </div>
<Input <Input
label='显示名称' label="显示名称"
name='display_name' name="display_name"
placeholder={'请输入新的显示名称'} placeholder={'请输入新的显示名称'}
onChange={value => handleInputChange('display_name', value)} onChange={value => handleInputChange('display_name', value)}
value={display_name} value={display_name}
autoComplete='new-password' autoComplete="new-password"
/> />
{ {
userId && <> userId && <>
...@@ -149,7 +149,7 @@ const EditUser = (props) => { ...@@ -149,7 +149,7 @@ const EditUser = (props) => {
</div> </div>
<Select <Select
placeholder={'请选择分组'} placeholder={'请选择分组'}
name='group' name="group"
fluid fluid
search search
selection selection
...@@ -157,19 +157,19 @@ const EditUser = (props) => { ...@@ -157,19 +157,19 @@ const EditUser = (props) => {
additionLabel={'请在系统设置页面编辑分组倍率以添加新的分组:'} additionLabel={'请在系统设置页面编辑分组倍率以添加新的分组:'}
onChange={value => handleInputChange('group', value)} onChange={value => handleInputChange('group', value)}
value={inputs.group} value={inputs.group}
autoComplete='new-password' autoComplete="new-password"
optionList={groupOptions} optionList={groupOptions}
/> />
<div style={{ marginTop: 20 }}> <div style={{ marginTop: 20 }}>
<Typography.Text>{`剩余额度${renderQuotaWithPrompt(quota)}`}</Typography.Text> <Typography.Text>{`剩余额度${renderQuotaWithPrompt(quota)}`}</Typography.Text>
</div> </div>
<Input <Input
name='quota' name="quota"
placeholder={'请输入新的剩余额度'} placeholder={'请输入新的剩余额度'}
onChange={value => handleInputChange('quota', value)} onChange={value => handleInputChange('quota', value)}
value={quota} value={quota}
type={'number'} type={'number'}
autoComplete='new-password' autoComplete="new-password"
/> />
</> </>
} }
...@@ -178,37 +178,37 @@ const EditUser = (props) => { ...@@ -178,37 +178,37 @@ const EditUser = (props) => {
<Typography.Text>已绑定的 GitHub 账户</Typography.Text> <Typography.Text>已绑定的 GitHub 账户</Typography.Text>
</div> </div>
<Input <Input
name='github_id' name="github_id"
value={github_id} value={github_id}
autoComplete='new-password' autoComplete="new-password"
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改' placeholder="此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改"
readonly readonly
/> />
<div style={{ marginTop: 20 }}> <div style={{ marginTop: 20 }}>
<Typography.Text>已绑定的微信账户</Typography.Text> <Typography.Text>已绑定的微信账户</Typography.Text>
</div> </div>
<Input <Input
name='wechat_id' name="wechat_id"
value={wechat_id} value={wechat_id}
autoComplete='new-password' autoComplete="new-password"
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改' placeholder="此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改"
readonly readonly
/> />
<Input <Input
name='telegram_id' name="telegram_id"
value={telegram_id} value={telegram_id}
autoComplete='new-password' autoComplete="new-password"
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改' placeholder="此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改"
readonly readonly
/> />
<div style={{ marginTop: 20 }}> <div style={{ marginTop: 20 }}>
<Typography.Text>已绑定的邮箱账户</Typography.Text> <Typography.Text>已绑定的邮箱账户</Typography.Text>
</div> </div>
<Input <Input
name='email' name="email"
value={email} value={email}
autoComplete='new-password' autoComplete="new-password"
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改' placeholder="此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改"
readonly readonly
/> />
</Spin> </Spin>
......
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