mirror of https://gitee.com/answerdev/answer.git
fix: add installation process
This commit is contained in:
parent
847c9a343e
commit
48654aa995
|
@ -18,7 +18,12 @@ module.exports = {
|
|||
const config = configFunction(proxy, allowedHost);
|
||||
config.proxy = {
|
||||
'/answer': {
|
||||
target: 'http://10.0.10.98:2060',
|
||||
target: 'http://10.0.20.88:8080',
|
||||
changeOrigin: true,
|
||||
secure: false,
|
||||
},
|
||||
'/installation': {
|
||||
target: 'http://10.0.20.88:8080',
|
||||
changeOrigin: true,
|
||||
secure: false,
|
||||
},
|
||||
|
|
|
@ -739,6 +739,7 @@
|
|||
"title": "Answer",
|
||||
"next": "Next",
|
||||
"done": "Done",
|
||||
"config_yaml_error": "Can’t create the config.yaml file.",
|
||||
"lang": {
|
||||
"label": "Please choose a language"
|
||||
},
|
||||
|
@ -779,22 +780,42 @@
|
|||
"site_information": "Site Information",
|
||||
"admin_account": "Admin Account",
|
||||
"site_name": {
|
||||
"label": "Site Name"
|
||||
"label": "Site Name",
|
||||
"msg": "Site Name cannot be empty."
|
||||
},
|
||||
"site_url": {
|
||||
"label": "Site URL",
|
||||
"text": "The address of your site.",
|
||||
"msg": {
|
||||
"empty": "Site URL cannot be empty.",
|
||||
"incorrect": "Site URL incorrect format."
|
||||
}
|
||||
},
|
||||
"contact_email": {
|
||||
"label": "Contact Email",
|
||||
"text": "Email address of key contact responsible for this site."
|
||||
"text": "Email address of key contact responsible for this site.",
|
||||
"msg": {
|
||||
"empty": "Contact Email cannot be empty.",
|
||||
"incorrect": "Contact Email incorrect format."
|
||||
}
|
||||
|
||||
},
|
||||
"admin_name": {
|
||||
"label": "Name"
|
||||
"label": "Name",
|
||||
"msg": "Name cannot be empty."
|
||||
},
|
||||
"admin_password": {
|
||||
"label": "Password",
|
||||
"text": "You will need this password to log in. Please store it in a secure location."
|
||||
"text": "You will need this password to log in. Please store it in a secure location.",
|
||||
"msg": "Password cannot be empty."
|
||||
},
|
||||
"admin_email": {
|
||||
"label": "Email",
|
||||
"text": "You will need this email to log in."
|
||||
"text": "You will need this email to log in.",
|
||||
"msg": {
|
||||
"empty": "Email cannot be empty.",
|
||||
"incorrect": "Email incorrect format."
|
||||
}
|
||||
},
|
||||
"ready_title": "Your Answer is Ready!",
|
||||
"ready_description": "If you ever feel like changing more settings, visit <1>admin section</1>; find it in the site menu.",
|
||||
|
|
|
@ -6,8 +6,9 @@ import Progress from '../Progress';
|
|||
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
siteUrl: string;
|
||||
}
|
||||
const Index: FC<Props> = ({ visible }) => {
|
||||
const Index: FC<Props> = ({ visible, siteUrl = '' }) => {
|
||||
const { t } = useTranslation('translation', { keyPrefix: 'install' });
|
||||
|
||||
if (!visible) return null;
|
||||
|
@ -17,14 +18,15 @@ const Index: FC<Props> = ({ visible }) => {
|
|||
<p>
|
||||
<Trans i18nKey="install.ready_description">
|
||||
If you ever feel like changing more settings, visit
|
||||
<a href="/">admin section</a>; find it in the site menu.
|
||||
<a href={`${siteUrl}/users/login`}>admin section</a>; find it in the
|
||||
site menu.
|
||||
</Trans>
|
||||
</p>
|
||||
<p>{t('good_luck')}</p>
|
||||
|
||||
<div className="d-flex align-items-center justify-content-between">
|
||||
<Progress step={5} />
|
||||
<Button>{t('done')}</Button>
|
||||
<Button href={siteUrl}>{t('done')}</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next';
|
|||
|
||||
import type { LangsType, FormValue, FormDataType } from '@/common/interface';
|
||||
import Progress from '../Progress';
|
||||
import { languages } from '@/services';
|
||||
import { getInstallLangOptions } from '@/services';
|
||||
|
||||
interface Props {
|
||||
data: FormValue;
|
||||
|
@ -18,8 +18,15 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
|||
const [langs, setLangs] = useState<LangsType[]>();
|
||||
|
||||
const getLangs = async () => {
|
||||
const res: LangsType[] = await languages();
|
||||
const res: LangsType[] = await getInstallLangOptions();
|
||||
setLangs(res);
|
||||
changeCallback({
|
||||
lang: {
|
||||
value: res[0].value,
|
||||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
|
|
|
@ -18,6 +18,7 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
|||
let bol = true;
|
||||
const {
|
||||
site_name,
|
||||
site_url,
|
||||
contact_email,
|
||||
admin_name,
|
||||
admin_password,
|
||||
|
@ -33,12 +34,40 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
|||
};
|
||||
}
|
||||
|
||||
if (!site_url.value) {
|
||||
bol = false;
|
||||
data.site_url = {
|
||||
value: '',
|
||||
isInvalid: true,
|
||||
errorMsg: t('site_name.msg.empty'),
|
||||
};
|
||||
}
|
||||
const reg = /^(http|https):\/\//g;
|
||||
if (site_url.value && !site_url.value.match(reg)) {
|
||||
bol = false;
|
||||
data.site_url = {
|
||||
value: site_url.value,
|
||||
isInvalid: true,
|
||||
errorMsg: t('site_url.msg.incorrect'),
|
||||
};
|
||||
}
|
||||
|
||||
if (!contact_email.value) {
|
||||
bol = false;
|
||||
data.contact_email = {
|
||||
value: '',
|
||||
isInvalid: true,
|
||||
errorMsg: t('contact_email.msg'),
|
||||
errorMsg: t('contact_email.msg.empty'),
|
||||
};
|
||||
}
|
||||
|
||||
const mailReg = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
|
||||
if (contact_email.value && !contact_email.value.match(mailReg)) {
|
||||
bol = false;
|
||||
data.contact_email = {
|
||||
value: contact_email.value,
|
||||
isInvalid: true,
|
||||
errorMsg: t('contact_email.msg.incorrect'),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -65,7 +94,16 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
|||
data.admin_email = {
|
||||
value: '',
|
||||
isInvalid: true,
|
||||
errorMsg: t('admin_email.msg'),
|
||||
errorMsg: t('admin_email.msg.empty'),
|
||||
};
|
||||
}
|
||||
|
||||
if (admin_email.value && !admin_email.value.match(mailReg)) {
|
||||
bol = false;
|
||||
data.admin_email = {
|
||||
value: '',
|
||||
isInvalid: true,
|
||||
errorMsg: t('admin_email.msg.incorrect'),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -108,6 +146,27 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
|
|||
{data.site_name.errorMsg}
|
||||
</Form.Control.Feedback>
|
||||
</Form.Group>
|
||||
<Form.Group controlId="site_url" className="mb-3">
|
||||
<Form.Label>{t('site_url.label')}</Form.Label>
|
||||
<Form.Control
|
||||
required
|
||||
value={data.site_url.value}
|
||||
isInvalid={data.site_url.isInvalid}
|
||||
onChange={(e) => {
|
||||
changeCallback({
|
||||
site_url: {
|
||||
value: e.target.value,
|
||||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Form.Text>{t('site_url.text')}</Form.Text>
|
||||
<Form.Control.Feedback type="invalid">
|
||||
{data.site_url.errorMsg}
|
||||
</Form.Control.Feedback>
|
||||
</Form.Group>
|
||||
<Form.Group controlId="contact_email" className="mb-3">
|
||||
<Form.Label>{t('contact_email.label')}</Form.Label>
|
||||
<Form.Control
|
||||
|
|
|
@ -6,29 +6,43 @@ import Progress from '../Progress';
|
|||
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
errorMsg;
|
||||
nextCallback: () => void;
|
||||
}
|
||||
|
||||
const Index: FC<Props> = ({ visible, nextCallback }) => {
|
||||
const Index: FC<Props> = ({ visible, errorMsg, nextCallback }) => {
|
||||
const { t } = useTranslation('translation', { keyPrefix: 'install' });
|
||||
|
||||
if (!visible) return null;
|
||||
return (
|
||||
<div>
|
||||
<h5>{t('config_yaml.title')}</h5>
|
||||
<div className="mb-3">{t('config_yaml.label')}</div>
|
||||
<div className="fmt">
|
||||
<p>
|
||||
<Trans
|
||||
i18nKey="install.config_yaml.description"
|
||||
components={{ 1: <code /> }}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
<FormGroup className="mb-3">
|
||||
<Form.Control type="text" as="textarea" rows={5} className="fs-14" />
|
||||
</FormGroup>
|
||||
<div className="mb-3">{t('config_yaml.info')}</div>
|
||||
|
||||
{errorMsg?.msg?.length > 0 ? (
|
||||
<>
|
||||
<div className="fmt">
|
||||
<p>
|
||||
<Trans
|
||||
i18nKey="install.config_yaml.description"
|
||||
components={{ 1: <code /> }}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
<FormGroup className="mb-3">
|
||||
<Form.Control
|
||||
type="text"
|
||||
as="textarea"
|
||||
rows={8}
|
||||
className="fs-14"
|
||||
value={errorMsg?.default_config}
|
||||
/>
|
||||
</FormGroup>
|
||||
<div className="mb-3">{t('config_yaml.info')}</div>
|
||||
</>
|
||||
) : (
|
||||
<div className="mb-3">{t('config_yaml.label')}</div>
|
||||
)}
|
||||
|
||||
<div className="d-flex align-items-center justify-content-between">
|
||||
<Progress step={3} />
|
||||
<Button onClick={nextCallback}>{t('next')}</Button>
|
||||
|
|
|
@ -3,8 +3,13 @@ import { Container, Row, Col, Card, Alert } from 'react-bootstrap';
|
|||
import { useTranslation, Trans } from 'react-i18next';
|
||||
|
||||
import type { FormDataType } from '@/common/interface';
|
||||
import { Storage } from '@/utils';
|
||||
import { PageTitle } from '@/components';
|
||||
import {
|
||||
dbCheck,
|
||||
installInit,
|
||||
installBaseInfo,
|
||||
checkConfigFileExists,
|
||||
} from '@/services';
|
||||
|
||||
import {
|
||||
FirstStep,
|
||||
|
@ -16,8 +21,12 @@ import {
|
|||
|
||||
const Index: FC = () => {
|
||||
const { t } = useTranslation('translation', { keyPrefix: 'install' });
|
||||
const [step, setStep] = useState(1);
|
||||
const [showError] = useState(false);
|
||||
const [step, setStep] = useState(3);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [errorData, setErrorData] = useState<{ [propName: string]: any }>({
|
||||
msg: '',
|
||||
});
|
||||
const [tableExist, setTableExist] = useState(false);
|
||||
|
||||
const [formData, setFormData] = useState<FormDataType>({
|
||||
lang: {
|
||||
|
@ -26,7 +35,7 @@ const Index: FC = () => {
|
|||
errorMsg: '',
|
||||
},
|
||||
db_type: {
|
||||
value: '',
|
||||
value: 'mysql',
|
||||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
|
@ -55,12 +64,16 @@ const Index: FC = () => {
|
|||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
|
||||
site_name: {
|
||||
value: '',
|
||||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
site_url: {
|
||||
value: '',
|
||||
isInvalid: false,
|
||||
errorMsg: '',
|
||||
},
|
||||
contact_email: {
|
||||
value: '',
|
||||
isInvalid: false,
|
||||
|
@ -88,33 +101,107 @@ const Index: FC = () => {
|
|||
setFormData({ ...formData, ...params });
|
||||
};
|
||||
|
||||
const handleStep = () => {
|
||||
const handleErr = (data) => {
|
||||
window.scrollTo(0, 0);
|
||||
setErrorData(data);
|
||||
};
|
||||
|
||||
const handleNext = async () => {
|
||||
setErrorData({
|
||||
msg: '',
|
||||
});
|
||||
setStep((pre) => pre + 1);
|
||||
};
|
||||
|
||||
// const handleSubmit = () => {
|
||||
// const params = {
|
||||
// lang: formData.lang.value,
|
||||
// db_type: formData.db_type.value,
|
||||
// db_username: formData.db_username.value,
|
||||
// db_password: formData.db_password.value,
|
||||
// db_host: formData.db_host.value,
|
||||
// db_name: formData.db_name.value,
|
||||
// db_file: formData.db_file.value,
|
||||
// site_name: formData.site_name.value,
|
||||
// contact_email: formData.contact_email.value,
|
||||
// admin_name: formData.admin_name.value,
|
||||
// admin_password: formData.admin_password.value,
|
||||
// admin_email: formData.admin_email.value,
|
||||
// };
|
||||
const submitDatabaseForm = () => {
|
||||
const params = {
|
||||
lang: formData.lang.value,
|
||||
db_type: formData.db_type.value,
|
||||
db_username: formData.db_username.value,
|
||||
db_password: formData.db_password.value,
|
||||
db_host: formData.db_host.value,
|
||||
db_name: formData.db_name.value,
|
||||
db_file: formData.db_file.value,
|
||||
};
|
||||
dbCheck(params)
|
||||
.then(() => {
|
||||
handleNext();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
handleErr(err);
|
||||
});
|
||||
};
|
||||
|
||||
// console.log(params);
|
||||
// };
|
||||
const checkInstall = () => {
|
||||
installInit()
|
||||
.then(() => {
|
||||
handleNext();
|
||||
})
|
||||
.catch((err) => {
|
||||
handleErr(err);
|
||||
});
|
||||
};
|
||||
|
||||
const submitSiteConfig = () => {
|
||||
const params = {
|
||||
site_name: formData.site_name.value,
|
||||
contact_email: formData.contact_email.value,
|
||||
admin_name: formData.admin_name.value,
|
||||
admin_password: formData.admin_password.value,
|
||||
admin_email: formData.admin_email.value,
|
||||
};
|
||||
installBaseInfo(params)
|
||||
.then(() => {
|
||||
handleNext();
|
||||
})
|
||||
.catch((err) => {
|
||||
handleErr(err);
|
||||
});
|
||||
};
|
||||
|
||||
const handleStep = () => {
|
||||
if (step === 2) {
|
||||
submitDatabaseForm();
|
||||
} else if (step === 3) {
|
||||
checkInstall();
|
||||
} else if (step === 4) {
|
||||
submitSiteConfig();
|
||||
} else {
|
||||
handleNext();
|
||||
}
|
||||
};
|
||||
|
||||
const handleInstallNow = (e) => {
|
||||
e.preventDefault();
|
||||
if (tableExist) {
|
||||
setStep(7);
|
||||
} else {
|
||||
setStep(4);
|
||||
}
|
||||
};
|
||||
|
||||
const configYmlCheck = () => {
|
||||
checkConfigFileExists()
|
||||
.then((res) => {
|
||||
setTableExist(res?.db_table_exist);
|
||||
if (res && res.config_file_exist) {
|
||||
setStep(5);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log('step===', Storage.get('INSTALL_STEP'));
|
||||
configYmlCheck();
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return <div />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="page-wrap2">
|
||||
<PageTitle title={t('install', { keyPrefix: 'page_title' })} />
|
||||
|
@ -124,7 +211,9 @@ const Index: FC = () => {
|
|||
<h2 className="mb-4 text-center">{t('title')}</h2>
|
||||
<Card>
|
||||
<Card.Body>
|
||||
{showError && <Alert variant="danger"> show error msg </Alert>}
|
||||
{errorData?.msg && (
|
||||
<Alert variant="danger">{errorData?.msg}</Alert>
|
||||
)}
|
||||
|
||||
<FirstStep
|
||||
visible={step === 1}
|
||||
|
@ -140,7 +229,11 @@ const Index: FC = () => {
|
|||
nextCallback={handleStep}
|
||||
/>
|
||||
|
||||
<ThirdStep visible={step === 3} nextCallback={handleStep} />
|
||||
<ThirdStep
|
||||
visible={step === 3}
|
||||
nextCallback={handleStep}
|
||||
errorMsg={errorData}
|
||||
/>
|
||||
|
||||
<FourthStep
|
||||
visible={step === 4}
|
||||
|
@ -149,7 +242,7 @@ const Index: FC = () => {
|
|||
nextCallback={handleStep}
|
||||
/>
|
||||
|
||||
<Fifth visible={step === 5} />
|
||||
<Fifth visible={step === 5} siteUrl={formData.site_url.value} />
|
||||
{step === 6 && (
|
||||
<div>
|
||||
<h5>{t('warning')}</h5>
|
||||
|
@ -158,7 +251,10 @@ const Index: FC = () => {
|
|||
The file <code>config.yaml</code> already exists. If you
|
||||
need to reset any of the configuration items in this
|
||||
file, please delete it first. You may try{' '}
|
||||
<a href="/">installing now</a>.
|
||||
<a href="###" onClick={(e) => handleInstallNow(e)}>
|
||||
installing now
|
||||
</a>
|
||||
.
|
||||
</Trans>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
export * from './admin';
|
||||
export * from './common';
|
||||
export * from './client';
|
||||
export * from './install';
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import request from '@/utils/request';
|
||||
|
||||
export const checkConfigFileExists = () => {
|
||||
return request.post('/installation/config-file/check');
|
||||
};
|
||||
|
||||
export const dbCheck = (params) => {
|
||||
return request.post('/installation/db/check', params);
|
||||
};
|
||||
|
||||
export const installInit = () => {
|
||||
return request.post('/installation/init');
|
||||
};
|
||||
|
||||
export const installBaseInfo = (params) => {
|
||||
return request.post('/installation/base-info', params);
|
||||
};
|
||||
|
||||
export const getInstallLangOptions = () => {
|
||||
return request.get('/installation/language/options');
|
||||
};
|
|
@ -73,7 +73,14 @@ class Request {
|
|||
});
|
||||
}
|
||||
|
||||
if (data.type === 'modal') {
|
||||
if (data.err_type === 'alert') {
|
||||
return Promise.reject({
|
||||
msg,
|
||||
...data,
|
||||
});
|
||||
}
|
||||
|
||||
if (data.err_type === 'modal') {
|
||||
// modal error message
|
||||
Modal.confirm({
|
||||
content: msg,
|
||||
|
|
Loading…
Reference in New Issue