mirror of
https://github.com/songquanpeng/one-api.git
synced 2025-11-12 03:13:41 +08:00
Initial commit
This commit is contained in:
47
web/src/pages/About/index.js
Normal file
47
web/src/pages/About/index.js
Normal file
@@ -0,0 +1,47 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Header, Segment } from 'semantic-ui-react';
|
||||
import { API, showError } from '../../helpers';
|
||||
import { marked } from 'marked';
|
||||
|
||||
const About = () => {
|
||||
const [about, setAbout] = useState('');
|
||||
|
||||
const displayAbout = async () => {
|
||||
const res = await API.get('/api/about');
|
||||
const { success, message, data } = res.data;
|
||||
if (success) {
|
||||
let HTMLAbout = marked.parse(data);
|
||||
localStorage.setItem('about', HTMLAbout);
|
||||
setAbout(HTMLAbout);
|
||||
} else {
|
||||
showError(message);
|
||||
setAbout('加载关于内容失败...');
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
displayAbout().then();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Segment>
|
||||
{
|
||||
about === '' ? <>
|
||||
<Header as='h3'>关于</Header>
|
||||
<p>可在设置页面设置关于内容,支持 HTML & Markdown</p>
|
||||
项目仓库地址:
|
||||
<a href="https://github.com/songquanpeng/gin-template">
|
||||
https://github.com/songquanpeng/gin-template
|
||||
</a>
|
||||
</> : <>
|
||||
<div dangerouslySetInnerHTML={{ __html: about}}></div>
|
||||
</>
|
||||
}
|
||||
</Segment>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
export default About;
|
||||
14
web/src/pages/File/index.js
Normal file
14
web/src/pages/File/index.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
import { Header, Segment } from 'semantic-ui-react';
|
||||
import FilesTable from '../../components/FilesTable';
|
||||
|
||||
const File = () => (
|
||||
<>
|
||||
<Segment>
|
||||
<Header as='h3'>管理文件</Header>
|
||||
<FilesTable />
|
||||
</Segment>
|
||||
</>
|
||||
);
|
||||
|
||||
export default File;
|
||||
78
web/src/pages/Home/index.js
Normal file
78
web/src/pages/Home/index.js
Normal file
@@ -0,0 +1,78 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { Grid, Header, Placeholder, Segment } from 'semantic-ui-react';
|
||||
import { API, showError, showNotice } from '../../helpers';
|
||||
|
||||
const Home = () => {
|
||||
const displayNotice = async () => {
|
||||
const res = await API.get('/api/notice');
|
||||
const { success, message, data } = res.data;
|
||||
if (success) {
|
||||
let oldNotice = localStorage.getItem('notice');
|
||||
if (data !== oldNotice && data !== '') {
|
||||
showNotice(data);
|
||||
localStorage.setItem('notice', data);
|
||||
}
|
||||
} else {
|
||||
showError(message);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
displayNotice().then();
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
<Segment>
|
||||
<Header as="h3">示例标题</Header>
|
||||
<Grid columns={3} stackable>
|
||||
<Grid.Column>
|
||||
<Segment raised>
|
||||
<Placeholder>
|
||||
<Placeholder.Header image>
|
||||
<Placeholder.Line />
|
||||
<Placeholder.Line />
|
||||
</Placeholder.Header>
|
||||
<Placeholder.Paragraph>
|
||||
<Placeholder.Line length="medium" />
|
||||
<Placeholder.Line length="short" />
|
||||
</Placeholder.Paragraph>
|
||||
</Placeholder>
|
||||
</Segment>
|
||||
</Grid.Column>
|
||||
|
||||
<Grid.Column>
|
||||
<Segment raised>
|
||||
<Placeholder>
|
||||
<Placeholder.Header image>
|
||||
<Placeholder.Line />
|
||||
<Placeholder.Line />
|
||||
</Placeholder.Header>
|
||||
<Placeholder.Paragraph>
|
||||
<Placeholder.Line length="medium" />
|
||||
<Placeholder.Line length="short" />
|
||||
</Placeholder.Paragraph>
|
||||
</Placeholder>
|
||||
</Segment>
|
||||
</Grid.Column>
|
||||
|
||||
<Grid.Column>
|
||||
<Segment raised>
|
||||
<Placeholder>
|
||||
<Placeholder.Header image>
|
||||
<Placeholder.Line />
|
||||
<Placeholder.Line />
|
||||
</Placeholder.Header>
|
||||
<Placeholder.Paragraph>
|
||||
<Placeholder.Line length="medium" />
|
||||
<Placeholder.Line length="short" />
|
||||
</Placeholder.Paragraph>
|
||||
</Placeholder>
|
||||
</Segment>
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Segment>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Home;
|
||||
20
web/src/pages/NotFound/index.js
Normal file
20
web/src/pages/NotFound/index.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import { Segment, Header } from 'semantic-ui-react';
|
||||
|
||||
const NotFound = () => (
|
||||
<>
|
||||
<Header
|
||||
block
|
||||
as="h4"
|
||||
content="404"
|
||||
attached="top"
|
||||
icon="info"
|
||||
className="small-icon"
|
||||
/>
|
||||
<Segment attached="bottom">
|
||||
未找到所请求的页面
|
||||
</Segment>
|
||||
</>
|
||||
);
|
||||
|
||||
export default NotFound;
|
||||
46
web/src/pages/Setting/index.js
Normal file
46
web/src/pages/Setting/index.js
Normal file
@@ -0,0 +1,46 @@
|
||||
import React from 'react';
|
||||
import { Segment, Tab } from 'semantic-ui-react';
|
||||
import SystemSetting from '../../components/SystemSetting';
|
||||
import { isRoot } from '../../helpers';
|
||||
import OtherSetting from '../../components/OtherSetting';
|
||||
import PersonalSetting from '../../components/PersonalSetting';
|
||||
|
||||
const Setting = () => {
|
||||
let panes = [
|
||||
{
|
||||
menuItem: '个人设置',
|
||||
render: () => (
|
||||
<Tab.Pane attached={false}>
|
||||
<PersonalSetting />
|
||||
</Tab.Pane>
|
||||
)
|
||||
}
|
||||
];
|
||||
|
||||
if (isRoot()) {
|
||||
panes.push({
|
||||
menuItem: '系统设置',
|
||||
render: () => (
|
||||
<Tab.Pane attached={false}>
|
||||
<SystemSetting />
|
||||
</Tab.Pane>
|
||||
)
|
||||
});
|
||||
panes.push({
|
||||
menuItem: '其他设置',
|
||||
render: () => (
|
||||
<Tab.Pane attached={false}>
|
||||
<OtherSetting />
|
||||
</Tab.Pane>
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<Segment>
|
||||
<Tab menu={{ secondary: true, pointing: true }} panes={panes} />
|
||||
</Segment>
|
||||
);
|
||||
};
|
||||
|
||||
export default Setting;
|
||||
77
web/src/pages/User/AddUser.js
Normal file
77
web/src/pages/User/AddUser.js
Normal file
@@ -0,0 +1,77 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Button, Form, Header, Segment } from 'semantic-ui-react';
|
||||
import { API, showError, showSuccess } from '../../helpers';
|
||||
|
||||
const AddUser = () => {
|
||||
const originInputs = {
|
||||
username: '',
|
||||
display_name: '',
|
||||
password: '',
|
||||
};
|
||||
const [inputs, setInputs] = useState(originInputs);
|
||||
const { username, display_name, password } = inputs;
|
||||
|
||||
const handleInputChange = (e, { name, value }) => {
|
||||
setInputs((inputs) => ({ ...inputs, [name]: value }));
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
if (inputs.username === '' || inputs.password === '') return;
|
||||
const res = await API.post(`/api/user/`, inputs);
|
||||
const { success, message } = res.data;
|
||||
if (success) {
|
||||
showSuccess('用户账户创建成功!');
|
||||
setInputs(originInputs);
|
||||
} else {
|
||||
showError(message);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Segment>
|
||||
<Header as="h3">创建新用户账户</Header>
|
||||
<Form autoComplete="off">
|
||||
<Form.Field>
|
||||
<Form.Input
|
||||
label="用户名"
|
||||
name="username"
|
||||
placeholder={'请输入用户名'}
|
||||
onChange={handleInputChange}
|
||||
value={username}
|
||||
autoComplete="off"
|
||||
required
|
||||
/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Form.Input
|
||||
label="显示名称"
|
||||
name="display_name"
|
||||
placeholder={'请输入显示名称'}
|
||||
onChange={handleInputChange}
|
||||
value={display_name}
|
||||
autoComplete="off"
|
||||
/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Form.Input
|
||||
label="密码"
|
||||
name="password"
|
||||
type={'password'}
|
||||
placeholder={'请输入密码'}
|
||||
onChange={handleInputChange}
|
||||
value={password}
|
||||
autoComplete="off"
|
||||
required
|
||||
/>
|
||||
</Form.Field>
|
||||
<Button type={'submit'} onClick={submit}>
|
||||
提交
|
||||
</Button>
|
||||
</Form>
|
||||
</Segment>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddUser;
|
||||
132
web/src/pages/User/EditUser.js
Normal file
132
web/src/pages/User/EditUser.js
Normal file
@@ -0,0 +1,132 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Button, Form, Header, Segment } from 'semantic-ui-react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { API, showError, showSuccess } from '../../helpers';
|
||||
|
||||
const EditUser = () => {
|
||||
const params = useParams();
|
||||
const userId = params.id;
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [inputs, setInputs] = useState({
|
||||
username: '',
|
||||
display_name: '',
|
||||
password: '',
|
||||
github_id: '',
|
||||
wechat_id: '',
|
||||
email: '',
|
||||
});
|
||||
const { username, display_name, password, github_id, wechat_id, email } =
|
||||
inputs;
|
||||
const handleInputChange = (e, { name, value }) => {
|
||||
setInputs((inputs) => ({ ...inputs, [name]: value }));
|
||||
};
|
||||
|
||||
const loadUser = async () => {
|
||||
let res = undefined;
|
||||
if (userId) {
|
||||
res = await API.get(`/api/user/${userId}`);
|
||||
} else {
|
||||
res = await API.get(`/api/user/self`);
|
||||
}
|
||||
const { success, message, data } = res.data;
|
||||
if (success) {
|
||||
data.password = '';
|
||||
setInputs(data);
|
||||
} else {
|
||||
showError(message);
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
useEffect(() => {
|
||||
loadUser().then();
|
||||
}, []);
|
||||
|
||||
const submit = async () => {
|
||||
let res = undefined;
|
||||
if (userId) {
|
||||
res = await API.put(`/api/user/`, { ...inputs, id: parseInt(userId) });
|
||||
} else {
|
||||
res = await API.put(`/api/user/self`, inputs);
|
||||
}
|
||||
const { success, message } = res.data;
|
||||
if (success) {
|
||||
showSuccess('用户信息更新成功!');
|
||||
} else {
|
||||
showError(message);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Segment loading={loading}>
|
||||
<Header as='h3'>更新用户信息</Header>
|
||||
<Form autoComplete='off'>
|
||||
<Form.Field>
|
||||
<Form.Input
|
||||
label='用户名'
|
||||
name='username'
|
||||
placeholder={'请输入新的用户名'}
|
||||
onChange={handleInputChange}
|
||||
value={username}
|
||||
autoComplete='off'
|
||||
/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Form.Input
|
||||
label='密码'
|
||||
name='password'
|
||||
type={'password'}
|
||||
placeholder={'请输入新的密码'}
|
||||
onChange={handleInputChange}
|
||||
value={password}
|
||||
autoComplete='off'
|
||||
/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Form.Input
|
||||
label='显示名称'
|
||||
name='display_name'
|
||||
placeholder={'请输入新的显示名称'}
|
||||
onChange={handleInputChange}
|
||||
value={display_name}
|
||||
autoComplete='off'
|
||||
/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Form.Input
|
||||
label='已绑定的 GitHub 账户'
|
||||
name='github_id'
|
||||
value={github_id}
|
||||
autoComplete='off'
|
||||
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改'
|
||||
readOnly
|
||||
/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Form.Input
|
||||
label='已绑定的微信账户'
|
||||
name='wechat_id'
|
||||
value={wechat_id}
|
||||
autoComplete='off'
|
||||
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改'
|
||||
readOnly
|
||||
/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Form.Input
|
||||
label='已绑定的邮箱账户'
|
||||
name='email'
|
||||
value={email}
|
||||
autoComplete='off'
|
||||
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改'
|
||||
readOnly
|
||||
/>
|
||||
</Form.Field>
|
||||
<Button onClick={submit}>提交</Button>
|
||||
</Form>
|
||||
</Segment>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default EditUser;
|
||||
14
web/src/pages/User/index.js
Normal file
14
web/src/pages/User/index.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
import { Segment, Header } from 'semantic-ui-react';
|
||||
import UsersTable from '../../components/UsersTable';
|
||||
|
||||
const User = () => (
|
||||
<>
|
||||
<Segment>
|
||||
<Header as='h3'>管理用户</Header>
|
||||
<UsersTable/>
|
||||
</Segment>
|
||||
</>
|
||||
);
|
||||
|
||||
export default User;
|
||||
Reference in New Issue
Block a user