初始化项目

This commit is contained in:
whyour
2021-03-14 22:06:27 +08:00
commit f1f8ece8a2
41 changed files with 3017 additions and 0 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

+81
View File
@@ -0,0 +1,81 @@
import {
FormOutlined,
FieldTimeOutlined,
DiffOutlined,
SettingOutlined,
CodeOutlined,
FolderOutlined,
LockOutlined,
RadiusSettingOutlined,
} from '@ant-design/icons';
import logo from '@/assets/logo.png';
export default {
route: {
routes: [
{
name: 'login',
path: '/login',
hideInMenu: true,
component: '@/pages/login/index',
},
{
path: '/cookie',
name: 'Cookie管理',
icon: <RadiusSettingOutlined />,
component: '@/pages/cookie/index',
},
{
path: '/config',
name: '配置文件',
icon: <SettingOutlined />,
component: '@/pages/config/index',
},
{
path: '/diy',
name: '自定义脚本',
icon: <FormOutlined />,
component: '@/pages/diy/index',
},
{
path: '/crontab',
name: '定时任务',
icon: <FieldTimeOutlined />,
component: '@/pages/crontab/index',
},
{
path: '/diff',
name: '对比工具',
icon: <DiffOutlined />,
component: '@/pages/diff/index',
},
{
path: '/code',
name: '互助码',
icon: <CodeOutlined />,
component: '@/pages/code/index',
},
{
path: '/log',
name: '日志',
icon: <FolderOutlined />,
component: '@/pages/log/index',
},
{
path: '/password',
name: '修改密码',
icon: <LockOutlined />,
component: '@/pages/password/index',
},
],
},
location: {
pathname: '/',
},
fixSiderbar: true,
navTheme: 'light',
primaryColor: '#1890ff',
contentWidth: 'Fixed',
splitMenus: false,
logo: logo,
} as any;
+23
View File
@@ -0,0 +1,23 @@
body {
height: 100%;
overflow-y: hidden;
background-color: rgb(248, 248, 248);
}
@import '~codemirror/lib/codemirror.css';
@import '~codemirror/theme/dracula.css';
.code-mirror-wrapper .CodeMirror {
position: absolute;
height: calc(100% - 24px);
width: 100%;
}
.ant-pro-grid-content.wide {
max-width: unset;
height: calc(100vh - 72px);
overflow: auto;
.ant-pro-page-container-children-content{
overflow: auto;
}
}
+54
View File
@@ -0,0 +1,54 @@
import React, { useEffect, useState } from 'react';
import { Button, Descriptions, Result, Avatar, Space, Statistic } from 'antd';
import { LikeOutlined, UserOutlined } from '@ant-design/icons';
import ProLayout, {
PageContainer,
PageLoading,
SettingDrawer,
} from '@ant-design/pro-layout';
import defaultProps from './defaultProps';
import { Link, history } from 'umi';
import config from '@/utils/config';
import 'codemirror/mode/shell/shell.js'
import './index.less';
export default function (props: any) {
useEffect(() => {
const isAuth = localStorage.getItem(config.authKey);
if (!isAuth) {
history.push('/login');
}
}, []);
useEffect(() => {
if (props.location.pathname === '/') {
history.push('/config');
}
}, [props.location.pathname]);
if (props.location.pathname === '/login') {
return props.children;
}
return (
<ProLayout
selectedKeys={[props.location.pathname]}
title="控制面板"
menuItemRender={(menuItemProps: any, defaultDom) => {
if (
menuItemProps.isUrl ||
!menuItemProps.path ||
location.pathname === menuItemProps.path
) {
return defaultDom;
}
return <Link to={menuItemProps.path}>{defaultDom}</Link>;
}}
// rightContentRender={() => (
// <div>
// <Avatar shape="square" size="small" icon={<UserOutlined />} />
// </div>
// )}
{...defaultProps}
>
{props.children}
</ProLayout>
);
}
View File
+93
View File
@@ -0,0 +1,93 @@
import React, { PureComponent, Fragment, useState, useEffect } from 'react';
import { Button, notification, Modal } from 'antd';
import config from '@/utils/config';
import { PageContainer } from '@ant-design/pro-layout';
import { Controlled as CodeMirror } from 'react-codemirror2';
import { request } from '@/utils/http';
const Crontab = () => {
const [width, setWdith] = useState('100%');
const [marginLeft, setMarginLeft] = useState(0);
const [marginTop, setMarginTop] = useState(-72);
const [value, setValue] = useState('');
const [loading, setLoading] = useState(true);
const getConfig = () => {
setLoading(true);
request.get(`${config.apiPrefix}config/shareCode`).then((data) => {
setValue(data);
}).finally(() => setLoading(false));
};
const updateConfig = () => {
request
.post(`${config.apiPrefix}save`, {
data: { content: value, name: 'diy.sh' },
})
.then((data) => {
notification.success({
message: data.msg,
});
});
};
useEffect(() => {
if (document.body.clientWidth < 768) {
setWdith('auto');
setMarginLeft(0);
setMarginTop(0);
} else {
setWdith('100%');
setMarginLeft(0);
setMarginTop(-72);
}
getConfig();
}, []);
return (
<PageContainer
className="code-mirror-wrapper"
title="互助码"
loading={loading}
extra={[
<Button key="1" type="primary" onClick={updateConfig}>
</Button>,
]}
header={{
style: {
padding: '4px 16px 4px 15px',
position: 'sticky',
top: 0,
left: 0,
zIndex: 20,
marginTop,
width,
marginLeft,
},
}}
style={{
height: '100vh',
}}
>
<CodeMirror
value={value}
options={{
lineNumbers: true,
lineWrapping: true,
styleActiveLine: true,
matchBrackets: true,
mode: 'shell',
theme: 'dracula',
readOnly: 'nocursor',
}}
onBeforeChange={(editor, data, value) => {
setValue(value);
}}
onChange={(editor, data, value) => {}}
/>
</PageContainer>
);
};
export default Crontab;
View File
+148
View File
@@ -0,0 +1,148 @@
import React, { PureComponent, Fragment, useState, useEffect } from 'react';
import { Button, notification, Modal } from 'antd';
import config from '@/utils/config';
import { PageContainer } from '@ant-design/pro-layout';
import { Controlled as CodeMirror } from 'react-codemirror2';
import { request } from '@/utils/http';
import QRCode from 'qrcode.react';
const Config = () => {
const [width, setWdith] = useState('100%');
const [marginLeft, setMarginLeft] = useState(0);
const [marginTop, setMarginTop] = useState(-72);
const [value, setValue] = useState('');
const [loading, setLoading] = useState(true);
const getConfig = () => {
setLoading(true);
request.get(`${config.apiPrefix}config/config`).then((data) => {
setValue(data);
}).finally(() => setLoading(false));
};
const updateConfig = () => {
request
.post(`${config.apiPrefix}save`, {
data: { content: value, name: 'config.sh' },
})
.then((data) => {
notification.success({
message: data.msg,
});
});
};
function sleep(time: number) {
return new Promise((resolve) => setTimeout(resolve, time));
}
const showQrCode = () => {
request.get(`${config.apiPrefix}qrcode`).then(async (data) => {
const modal = Modal.info({
title: '二维码',
content: (
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
marginLeft: -38,
}}
>
<QRCode
style={{
width: 200,
height: 200,
marginBottom: 10,
marginTop: 20,
}}
value={data.qrcode}
/>
</div>
),
});
getCookie(modal);
});
};
const getCookie = async (modal: { destroy: () => void }) => {
for (let i = 0; i < 50; i++) {
const result = await request.get(`${config.apiPrefix}cookie`);
console.log(i, result);
if (result && result.cookie) {
notification.success({
message: 'Cookie获取成功',
});
modal.destroy();
Modal.success({
title: '获取Cookie成功',
content: <div>{result.cookie}</div>,
});
break;
}
await sleep(2000);
}
};
useEffect(() => {
if (document.body.clientWidth < 768) {
setWdith('auto');
setMarginLeft(0);
setMarginTop(0);
} else {
setWdith('100%');
setMarginLeft(0);
setMarginTop(-72);
}
getConfig();
}, []);
return (
<PageContainer
className="code-mirror-wrapper"
title="config.sh"
loading={loading}
extra={[
<Button key="1" type="primary" onClick={updateConfig}>
</Button>,
<Button key="2" type="primary" onClick={showQrCode}>
Cookie
</Button>,
]}
header={{
style: {
padding: '4px 16px 4px 15px',
position: 'sticky',
top: 0,
left: 0,
zIndex: 20,
marginTop,
width,
marginLeft,
},
}}
style={{
height: '100vh',
}}
>
<CodeMirror
value={value}
options={{
lineNumbers: true,
lineWrapping: true,
styleActiveLine: true,
matchBrackets: true,
mode: 'shell',
theme: 'dracula',
}}
onBeforeChange={(editor, data, value) => {
setValue(value);
}}
onChange={(editor, data, value) => {}}
/>
</PageContainer>
);
};
export default Config;
View File
+190
View File
@@ -0,0 +1,190 @@
import React, { PureComponent, Fragment, useState, useEffect } from 'react';
import { Button, notification, Modal, Table, Tag, Space } from 'antd';
import config from '@/utils/config';
import { PageContainer } from '@ant-design/pro-layout';
import { request } from '@/utils/http';
import QRCode from 'qrcode.react';
const columns = [
{
title: '用户名',
dataIndex: 'pin',
key: 'pin',
},
{
title: '昵称',
dataIndex: 'nickname',
key: 'nickname',
},
{
title: '值',
dataIndex: 'cookie',
key: 'cookie',
},
{
title: '状态',
key: 'status',
dataIndex: 'status',
render: (text: string, record: any) => (
<Tag color="success">success</Tag>
),
},
{
title: '操作',
key: 'action',
render: (text: string, record: any) => (
<Space size="middle">
<a>Invite {record.name}</a>
<a>Delete</a>
</Space>
),
},
];
const data = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
tags: ['nice', 'developer'],
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
tags: ['loser'],
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
tags: ['cool', 'teacher'],
},
];
const Config = () => {
const [width, setWdith] = useState('100%');
const [marginLeft, setMarginLeft] = useState(0);
const [marginTop, setMarginTop] = useState(-72);
const [value, setValue] = useState('');
const [loading, setLoading] = useState(true);
const getConfig = () => {
setLoading(true);
request.get(`${config.apiPrefix}config/config`).then((data) => {
setValue(data);
}).finally(() => setLoading(false));
};
const updateConfig = () => {
request
.post(`${config.apiPrefix}save`, {
data: { content: value, name: 'config.sh' },
})
.then((data) => {
notification.success({
message: data.msg,
});
});
};
function sleep(time: number) {
return new Promise((resolve) => setTimeout(resolve, time));
}
const showQrCode = () => {
request.get(`${config.apiPrefix}qrcode`).then(async (data) => {
const modal = Modal.info({
title: '二维码',
content: (
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
marginLeft: -38,
}}
>
<QRCode
style={{
width: 200,
height: 200,
marginBottom: 10,
marginTop: 20,
}}
value={data.qrcode}
/>
</div>
),
});
getCookie(modal);
});
};
const getCookie = async (modal: { destroy: () => void }) => {
for (let i = 0; i < 50; i++) {
const result = await request.get(`${config.apiPrefix}cookie`);
console.log(i, result);
if (result && result.cookie) {
notification.success({
message: 'Cookie获取成功',
});
modal.destroy();
Modal.success({
title: '获取Cookie成功',
content: <div>{result.cookie}</div>,
});
break;
}
await sleep(2000);
}
};
useEffect(() => {
if (document.body.clientWidth < 768) {
setWdith('auto');
setMarginLeft(0);
setMarginTop(0);
} else {
setWdith('100%');
setMarginLeft(0);
setMarginTop(-72);
}
getConfig();
}, []);
return (
<PageContainer
className="code-mirror-wrapper"
title="Cookie管理"
loading={loading}
extra={[
<Button key="2" type="primary" onClick={showQrCode}>
Cookie
</Button>,
]}
header={{
style: {
padding: '4px 16px 4px 15px',
position: 'sticky',
top: 0,
left: 0,
zIndex: 20,
marginTop,
width,
marginLeft,
},
}}
style={{
height: '100vh',
}}
>
<Table columns={columns} pagination={{hideOnSinglePage: true}} dataSource={data} />
</PageContainer>
);
};
export default Config;
View File
+92
View File
@@ -0,0 +1,92 @@
import React, { PureComponent, Fragment, useState, useEffect } from 'react';
import { Button, notification, Modal } from 'antd';
import config from '@/utils/config';
import { PageContainer } from '@ant-design/pro-layout';
import { Controlled as CodeMirror } from 'react-codemirror2';
import { request } from '@/utils/http';
const Crontab = () => {
const [width, setWdith] = useState('100%');
const [marginLeft, setMarginLeft] = useState(0);
const [marginTop, setMarginTop] = useState(-72);
const [value, setValue] = useState('');
const [loading, setLoading] = useState(true);
const getConfig = () => {
setLoading(true);
request.get(`${config.apiPrefix}config/crontab`).then((data) => {
setValue(data);
}).finally(() => setLoading(false));
};
const updateConfig = () => {
request
.post(`${config.apiPrefix}save`, {
data: { content: value, name: 'crontab.list' },
})
.then((data) => {
notification.success({
message: data.msg,
});
});
};
useEffect(() => {
if (document.body.clientWidth < 768) {
setWdith('auto');
setMarginLeft(0);
setMarginTop(0);
} else {
setWdith('100%');
setMarginLeft(0);
setMarginTop(-72);
}
getConfig();
}, []);
return (
<PageContainer
className="code-mirror-wrapper"
title="crontab.list"
loading={loading}
extra={[
<Button key="1" type="primary" onClick={updateConfig}>
</Button>,
]}
header={{
style: {
padding: '4px 16px 4px 15px',
position: 'sticky',
top: 0,
left: 0,
zIndex: 20,
marginTop,
width,
marginLeft,
},
}}
style={{
height: '100vh',
}}
>
<CodeMirror
value={value}
options={{
lineNumbers: true,
lineWrapping: true,
styleActiveLine: true,
matchBrackets: true,
mode: 'shell',
theme: 'dracula',
}}
onBeforeChange={(editor, data, value) => {
setValue(value);
}}
onChange={(editor, data, value) => {}}
/>
</PageContainer>
);
};
export default Crontab;
+12
View File
@@ -0,0 +1,12 @@
.d2h-files-diff {
height: calc(100vh - 130px);
overflow: auto;
}
.d2h-code-side-linenumber {
position: relative;
}
.d2h-code-side-line {
padding: 0 0.5em;
}
+93
View File
@@ -0,0 +1,93 @@
import React, { PureComponent, Fragment, useState, useEffect } from 'react';
import { Button, notification, Modal } from 'antd';
import config from '@/utils/config';
import { PageContainer } from '@ant-design/pro-layout';
import { request } from '@/utils/http';
import ReactDiffViewer from 'react-diff-viewer';
import './index.less';
const Crontab = () => {
const [width, setWdith] = useState('100%');
const [marginLeft, setMarginLeft] = useState(0);
const [marginTop, setMarginTop] = useState(-72);
const [value, setValue] = useState('');
const [sample, setSample] = useState('');
const [loading, setLoading] = useState(true);
const getConfig = () => {
request.get(`${config.apiPrefix}config/config`).then((data) => {
setValue(data);
});
};
const getSample = () => {
setLoading(true);
request.get(`${config.apiPrefix}config/sample`).then((data) => {
setSample(data);
}).finally(() => setLoading(false));
};
useEffect(() => {
if (document.body.clientWidth < 768) {
setWdith('auto');
setMarginLeft(0);
setMarginTop(0);
} else {
setWdith('100%');
setMarginLeft(0);
setMarginTop(-72);
}
getConfig();
getSample();
}, []);
return (
<PageContainer
className="code-mirror-wrapper"
title="对比工具"
loading={loading}
header={{
style: {
padding: '4px 16px 4px 15px',
position: 'sticky',
top: 0,
left: 0,
zIndex: 20,
marginTop,
width,
marginLeft,
},
}}
style={{
height: '100vh',
}}
>
<ReactDiffViewer
styles={{ diffRemoved: {
overflowX: 'auto',
maxWidth: 300,
},
diffAdded: {
overflowX: 'auto',
maxWidth: 300,
},line: {
wordBreak: 'break-word',
}, }}
oldValue={value}
newValue={sample}
splitView={true}
leftTitle="config.sh"
rightTitle="config.sh.sample"
disableWordDiff={true}
/>
{/* <CodeDiff
style={{ height: 'calc(100vh - 72px)', overflowY: 'auto' }}
outputFormat="side-by-side"
oldStr={value}
newStr={sample}
/> */}
</PageContainer>
);
};
export default Crontab;
View File
+92
View File
@@ -0,0 +1,92 @@
import React, { PureComponent, Fragment, useState, useEffect } from 'react';
import { Button, notification, Modal } from 'antd';
import config from '@/utils/config';
import { PageContainer } from '@ant-design/pro-layout';
import { Controlled as CodeMirror } from 'react-codemirror2';
import { request } from '@/utils/http';
const Crontab = () => {
const [width, setWdith] = useState('100%');
const [marginLeft, setMarginLeft] = useState(0);
const [marginTop, setMarginTop] = useState(-72);
const [value, setValue] = useState('');
const [loading, setLoading] = useState(true);
const getConfig = () => {
setLoading(true);
request.get(`${config.apiPrefix}config/diy`).then((data) => {
setValue(data);
}).finally(() => setLoading(false));
};
const updateConfig = () => {
request
.post(`${config.apiPrefix}save`, {
data: { content: value, name: 'diy.sh' },
})
.then((data) => {
notification.success({
message: data.msg,
});
});
};
useEffect(() => {
if (document.body.clientWidth < 768) {
setWdith('auto');
setMarginLeft(0);
setMarginTop(0);
} else {
setWdith('100%');
setMarginLeft(0);
setMarginTop(-72);
}
getConfig();
}, []);
return (
<PageContainer
className="code-mirror-wrapper"
title="diy.sh"
loading={loading}
extra={[
<Button key="1" type="primary" onClick={updateConfig}>
</Button>,
]}
header={{
style: {
padding: '4px 16px 4px 15px',
position: 'sticky',
top: 0,
left: 0,
zIndex: 20,
marginTop,
width,
marginLeft,
},
}}
style={{
height: '100vh',
}}
>
<CodeMirror
value={value}
options={{
lineNumbers: true,
lineWrapping: true,
styleActiveLine: true,
matchBrackets: true,
mode: 'shell',
theme: 'dracula',
}}
onBeforeChange={(editor, data, value) => {
setValue(value);
}}
onChange={(editor, data, value) => {}}
/>
</PageContainer>
);
};
export default Crontab;
View File
+112
View File
@@ -0,0 +1,112 @@
import React, { PureComponent, Fragment, useState, useEffect } from 'react';
import { Button, notification, Modal, TreeSelect } from 'antd';
import config from '@/utils/config';
import { PageContainer } from '@ant-design/pro-layout';
import { Controlled as CodeMirror } from 'react-codemirror2';
import { request } from '@/utils/http';
const Log = () => {
const [width, setWdith] = useState('100%');
const [marginLeft, setMarginLeft] = useState(0);
const [marginTop, setMarginTop] = useState(-72);
const [title, setTitle] = useState('log');
const [value, setValue] = useState('请选择日志文件');
const [select, setSelect] = useState();
const [data, setData] = useState();
const [loading, setLoading] = useState(false);
const getConfig = () => {
request.get(`${config.apiPrefix}logs`).then((data) => {
setData(formatData(data.dirs) as any);
});
};
const formatData = (tree: any[]) => {
return tree.map(x => {
x.title = x.dirName;
x.value = x.dirName;
x.disabled = true;
x.children = x.files.map((y: string) => ({ title: y, key: y, value: y, parent: x.dirName }));
return x;
})
}
const getLog = (node: any) => {
setLoading(true);
request.get(`${config.apiPrefix}logs/${node.parent}/${node.value}`).then((data) => {
setValue(data);
}).finally(() => setLoading(false));
};
const onSelect = (value: any, node: any) => {
setSelect(value);
setTitle(node.parent);
getLog(node);
};
useEffect(() => {
if (document.body.clientWidth < 768) {
setWdith('auto');
setMarginLeft(0);
setMarginTop(0);
} else {
setWdith('100%');
setMarginLeft(0);
setMarginTop(-72);
}
getConfig();
}, []);
return (
<PageContainer
className="code-mirror-wrapper"
title={title}
loading={loading}
extra={[
<TreeSelect
style={{ width: 280 }}
value={select}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={data}
placeholder="请选择日志文件"
showSearch
key="title"
onSelect={onSelect}
/>
]}
header={{
style: {
padding: '4px 16px 4px 15px',
position: 'sticky',
top: 0,
left: 0,
zIndex: 20,
marginTop,
width,
marginLeft,
},
}}
style={{
height: '100vh',
}}
>
<CodeMirror
value={value}
options={{
lineNumbers: true,
lineWrapping: true,
styleActiveLine: true,
matchBrackets: true,
mode: 'shell',
theme: 'dracula',
readOnly: 'nocursor',
}}
onBeforeChange={(editor, data, value) => {
setValue(value);
}}
onChange={(editor, data, value) => {}}
/>
</PageContainer>
);
};
export default Log;
+58
View File
@@ -0,0 +1,58 @@
.form {
position: absolute;
top: 45%;
left: 50%;
margin: -160px 0 0 -160px;
width: 320px;
height: 320px;
padding: 36px;
box-shadow: 0 0 100px rgba(0, 0, 0, 0.08);
button {
width: 100%;
}
p {
color: rgb(204, 204, 204);
text-align: center;
margin-top: 16px;
font-size: 12px;
display: flex;
justify-content: space-between;
}
}
.logo {
text-align: center;
cursor: pointer;
margin-bottom: 24px;
display: flex;
justify-content: center;
align-items: center;
img {
width: 40px;
margin-right: 8px;
}
span {
vertical-align: text-bottom;
font-size: 16px;
text-transform: uppercase;
display: inline-block;
font-weight: 700;
// color: @primary-color;
// .text-gradient();
}
}
.ant-spin-container,
.ant-spin-nested-loading {
height: 100%;
}
.footer {
position: absolute;
width: 100%;
bottom: 0;
}
+73
View File
@@ -0,0 +1,73 @@
import React, { Fragment, useEffect } from 'react';
import { Button, Row, Input, Form, notification } from 'antd';
import config from '@/utils/config';
import { history } from 'umi';
import styles from './index.less';
import { request } from '@/utils/http';
const FormItem = Form.Item;
const Login = () => {
const handleOk = (values: any) => {
request
.post(`${config.apiPrefix}auth`, {
data: {
username: values.username,
password: values.password,
},
})
.then((data) => {
if (data.err == 0) {
localStorage.setItem(config.authKey, 'true');
history.push('/cookie');
} else {
notification.open({
message: data.msg,
});
}
})
.catch(function (error) {
console.log(error);
});
};
useEffect(() => {
const isAuth = localStorage.getItem(config.authKey);
if (isAuth) {
history.push('/cookie');
}
}, [])
return (
<Fragment>
<div className={styles.form}>
<div className={styles.logo}>
<span>{config.siteName}</span>
</div>
<Form onFinish={handleOk}>
<FormItem
name="username"
rules={[{ required: true, message: '请输入用户名' }]}
hasFeedback
>
<Input placeholder="用户名" autoFocus/>
</FormItem>
<FormItem
name="password"
rules={[{ required: true, message: '请输入密码' }]}
hasFeedback
>
<Input type="password" placeholder="密码" />
</FormItem>
<Row>
<Button type="primary" htmlType="submit">
Sign in
</Button>
</Row>
</Form>
</div>
</Fragment>
);
};
export default Login;
View File
+84
View File
@@ -0,0 +1,84 @@
import React, { PureComponent, Fragment, useState, useEffect } from 'react';
import { Button, notification, Input, Form } from 'antd';
import config from '@/utils/config';
import { PageContainer } from '@ant-design/pro-layout';
import { Controlled as CodeMirror } from 'react-codemirror2';
import { request } from '@/utils/http';
const Password = () => {
const [width, setWdith] = useState('100%');
const [marginLeft, setMarginLeft] = useState(0);
const [marginTop, setMarginTop] = useState(-72);
const [value, setValue] = useState('');
const [loading, setLoading] = useState(true);
const handleOk = (values: any) => {
request
.post(`${config.apiPrefix}auth?t=${Date.now()}`, {
data: {
username: values.username,
password: values.password,
},
})
.then((data) => {
if (data.err == 0) {
localStorage.setItem(config.authKey, 'true');
} else {
notification.open({
message: data.msg,
});
}
})
.catch(function (error) {
console.log(error);
});
};
useEffect(() => {
if (document.body.clientWidth < 768) {
setWdith('auto');
setMarginLeft(0);
setMarginTop(0);
} else {
setWdith('100%');
setMarginLeft(0);
setMarginTop(-72);
}
}, []);
return (
<PageContainer
className="code-mirror-wrapper"
title="修改密码"
header={{
style: {
padding: '4px 16px 4px 15px',
position: 'sticky',
top: 0,
left: 0,
zIndex: 20,
marginTop,
width,
marginLeft,
},
}}
style={{
height: '100vh',
}}
>
<Form onFinish={handleOk} style={{ padding: 20, background: '#fff', height: 'calc(100vh - 96px)' }}>
<Form.Item name="username" rules={[{ required: true, message: '请输入用户名' }]} hasFeedback style={{width:300}}>
<Input placeholder="用户名" autoFocus/>
</Form.Item>
<Form.Item name="password" rules={[{ required: true, message: '请输入密码' }]} hasFeedback style={{width:300}}>
<Input type="password" placeholder="密码" />
</Form.Item>
<Button type="primary" htmlType="submit">
</Button>
</Form>
</PageContainer>
);
};
export default Password;
+37
View File
@@ -0,0 +1,37 @@
export default {
siteName: '京东羊毛脚本控制面板',
apiPrefix: '/api/',
authKey: 'whyour',
/* Layout configuration, specify which layout to use for route. */
layouts: [
{
name: 'primary',
include: [/.*/],
exclude: [/(\/(en|zh))*\/login/],
},
],
/* I18n configuration, `languages` and `defaultLanguage` are required currently. */
i18n: {
/* Countrys flags: https://www.flaticon.com/packs/countrys-flags */
languages: [
{
key: 'pt-br',
title: 'Português',
flag: '/portugal.svg',
},
{
key: 'en',
title: 'English',
flag: '/america.svg',
},
{
key: 'zh',
title: '中文',
flag: '/china.svg',
},
],
defaultLanguage: 'en',
},
};
+29
View File
@@ -0,0 +1,29 @@
import { extend } from 'umi-request';
import { history } from 'umi';
const time = Date.now();
const errorHandler = function (error: any) {
if (error.response) {
console.log(error.response)
} else {
console.log(error.message);
}
throw error; // 如果throw. 错误将继续抛出.
// return {some: 'data'};
};
const _request = extend({ timeout: 5000, params: { t: time }, errorHandler });
_request.interceptors.response.use(async response => {
const res = await response.clone().text()
if (res === '请先登录!') {
setTimeout(() => {
localStorage.removeItem('whyour');
history.push('/login');
});
}
return response;
})
export const request = _request;