mirror of
https://github.com/whyour/qinglong.git
synced 2025-05-23 14:56:07 +08:00
262 lines
7.2 KiB
TypeScript
262 lines
7.2 KiB
TypeScript
import intl from 'react-intl-universal';
|
|
import React, { Fragment, useEffect, useState } from 'react';
|
|
import {
|
|
Button,
|
|
Row,
|
|
Input,
|
|
Form,
|
|
message,
|
|
Typography,
|
|
Steps,
|
|
Select,
|
|
} from 'antd';
|
|
import config from '@/utils/config';
|
|
import { history } from '@umijs/max';
|
|
import styles from './index.less';
|
|
import { request } from '@/utils/http';
|
|
|
|
const FormItem = Form.Item;
|
|
const { Step } = Steps;
|
|
const { Option } = Select;
|
|
const { Link } = Typography;
|
|
|
|
const Initialization = () => {
|
|
const [loading, setLoading] = useState(false);
|
|
const [current, setCurrent] = React.useState(0);
|
|
const [fields, setFields] = useState<any[]>([]);
|
|
|
|
const next = () => {
|
|
setCurrent(current + 1);
|
|
};
|
|
|
|
const prev = () => {
|
|
setCurrent(current - 1);
|
|
};
|
|
|
|
const submitAccountSetting = (values: any) => {
|
|
setLoading(true);
|
|
request
|
|
.put(`${config.apiPrefix}user/init`, {
|
|
username: values.username,
|
|
password: values.password,
|
|
})
|
|
.then(({ code, data }) => {
|
|
if (code === 200) {
|
|
next();
|
|
}
|
|
})
|
|
.finally(() => setLoading(false));
|
|
};
|
|
|
|
const submitNotification = (values: any) => {
|
|
setLoading(true);
|
|
request
|
|
.put(`${config.apiPrefix}user/notification/init`, values)
|
|
.then(({ code, data }) => {
|
|
if (code === 200) {
|
|
next();
|
|
}
|
|
})
|
|
.finally(() => setLoading(false));
|
|
};
|
|
|
|
const notificationModeChange = (value: string) => {
|
|
const _fields = (config.notificationModeMap as any)[value];
|
|
setFields(_fields || []);
|
|
};
|
|
|
|
useEffect(() => {
|
|
localStorage.removeItem(config.authKey);
|
|
}, []);
|
|
|
|
const steps = [
|
|
{
|
|
title: intl.get('欢迎使用'),
|
|
content: (
|
|
<div className={styles.top} style={{ marginTop: 30 }}>
|
|
<div className={styles.header}>
|
|
<span className={styles.title}>{intl.get('欢迎使用青龙')}</span>
|
|
<span className={styles.desc}>
|
|
{intl.get(
|
|
'支持python3、javascript、shell、typescript 的定时任务管理面板',
|
|
)}
|
|
</span>
|
|
</div>
|
|
<div className={styles.action}>
|
|
<Button
|
|
type="primary"
|
|
onClick={() => {
|
|
next();
|
|
}}
|
|
>
|
|
{intl.get('开始安装')}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
),
|
|
},
|
|
{
|
|
title: intl.get('账户设置'),
|
|
content: (
|
|
<Form onFinish={submitAccountSetting} layout="vertical">
|
|
<Form.Item
|
|
label={intl.get('用户名')}
|
|
name="username"
|
|
rules={[{ required: true }]}
|
|
style={{ maxWidth: 350 }}
|
|
>
|
|
<Input placeholder={intl.get('用户名')} />
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={intl.get('密码')}
|
|
name="password"
|
|
rules={[
|
|
{ required: true },
|
|
{
|
|
pattern: /^(?!admin$).*$/,
|
|
message: intl.get('密码不能为admin'),
|
|
},
|
|
]}
|
|
hasFeedback
|
|
style={{ maxWidth: 350 }}
|
|
>
|
|
<Input type="password" placeholder={intl.get('密码')} />
|
|
</Form.Item>
|
|
<Form.Item
|
|
name="confirm"
|
|
label={intl.get('确认密码')}
|
|
dependencies={['password']}
|
|
hasFeedback
|
|
style={{ maxWidth: 350 }}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
},
|
|
({ getFieldValue }) => ({
|
|
validator(_, value) {
|
|
if (!value || getFieldValue('password') === value) {
|
|
return Promise.resolve();
|
|
}
|
|
return Promise.reject(
|
|
new Error(intl.get('您输入的两个密码不匹配!')),
|
|
);
|
|
},
|
|
}),
|
|
]}
|
|
>
|
|
<Input.Password placeholder={intl.get('确认密码')} />
|
|
</Form.Item>
|
|
<Button type="primary" htmlType="submit" loading={loading}>
|
|
{intl.get('提交')}
|
|
</Button>
|
|
</Form>
|
|
),
|
|
},
|
|
{
|
|
title: intl.get('通知设置'),
|
|
content: (
|
|
<Form onFinish={submitNotification} layout="vertical">
|
|
<Form.Item
|
|
label={intl.get('通知方式')}
|
|
name="type"
|
|
rules={[{ required: true, message: intl.get('请选择通知方式') }]}
|
|
style={{ maxWidth: 350 }}
|
|
>
|
|
<Select
|
|
onChange={notificationModeChange}
|
|
placeholder={intl.get('请选择通知方式')}
|
|
>
|
|
{config.notificationModes
|
|
.filter((x) => x.value !== 'closed')
|
|
.map((x) => (
|
|
<Option key={x.value} value={x.value}>
|
|
{x.label}
|
|
</Option>
|
|
))}
|
|
</Select>
|
|
</Form.Item>
|
|
{fields.map((x) => (
|
|
<Form.Item
|
|
key={x.label}
|
|
label={x.label}
|
|
name={x.label}
|
|
extra={x.tip}
|
|
rules={[{ required: x.required }]}
|
|
style={{ maxWidth: 400 }}
|
|
>
|
|
<Input.TextArea
|
|
autoSize={{ minRows: 1, maxRows: 5 }}
|
|
placeholder={`请输入${x.label}`}
|
|
/>
|
|
</Form.Item>
|
|
))}
|
|
<Button type="primary" htmlType="submit" loading={loading}>
|
|
{intl.get('保存')}
|
|
</Button>
|
|
<Button type="link" htmlType="button" onClick={() => next()}>
|
|
{intl.get('跳过')}
|
|
</Button>
|
|
</Form>
|
|
),
|
|
},
|
|
{
|
|
title: intl.get('完成安装'),
|
|
content: (
|
|
<div className={styles.top} style={{ marginTop: 80 }}>
|
|
<div className={styles.header}>
|
|
<span className={styles.title}>{intl.get('恭喜安装完成!')}</span>
|
|
<Link href="https://github.com/whyour/qinglong" target="_blank">
|
|
Github
|
|
</Link>
|
|
<Link href="https://t.me/jiao_long" target="_blank">
|
|
{intl.get('Telegram频道')}
|
|
</Link>
|
|
</div>
|
|
<div style={{ marginTop: 16 }}>
|
|
<Button
|
|
type="primary"
|
|
onClick={() => {
|
|
window.location.reload();
|
|
}}
|
|
>
|
|
{intl.get('去登录')}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
),
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div className={styles.container}>
|
|
<div className={styles.top}>
|
|
<div className={styles.header}>
|
|
<img
|
|
alt="logo"
|
|
className={styles.logo}
|
|
src="https://qn.whyour.cn/logo.png"
|
|
/>
|
|
<span className={styles.title}>{intl.get('初始化配置')}</span>
|
|
</div>
|
|
</div>
|
|
<div className={styles.main}>
|
|
<Steps
|
|
current={current}
|
|
direction="vertical"
|
|
size="small"
|
|
className={styles['ant-steps']}
|
|
>
|
|
{steps.map((item) => (
|
|
<Step key={item.title} title={item.title} />
|
|
))}
|
|
</Steps>
|
|
<div className={styles['steps-container']}>
|
|
{steps[current].content}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Initialization;
|