mirror of https://github.com/halo-dev/halo-admin
feat: add validate for installation. (#169)
parent
c165cf8f56
commit
d3e2bda04f
File diff suppressed because it is too large
Load Diff
19
package.json
19
package.json
|
@ -9,11 +9,12 @@
|
||||||
"test:unit": "vue-cli-service test:unit"
|
"test:unit": "vue-cli-service test:unit"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ant-design-vue": "^1.5.2",
|
"ant-design-vue": "^1.5.5",
|
||||||
"axios": "^0.19.2",
|
"axios": "^0.19.2",
|
||||||
"enquire.js": "^2.1.6",
|
"enquire.js": "^2.1.6",
|
||||||
"filepond": "^4.13.0",
|
"filepond": "^4.13.0",
|
||||||
"filepond-plugin-image-preview": "^4.6.1",
|
"filepond-plugin-image-preview": "^4.6.1",
|
||||||
|
"flv.js": "^1.5.0",
|
||||||
"halo-editor": "^2.8.2",
|
"halo-editor": "^2.8.2",
|
||||||
"marked": "^1.0.0",
|
"marked": "^1.0.0",
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
|
@ -27,8 +28,7 @@
|
||||||
"vue-ls": "^3.2.1",
|
"vue-ls": "^3.2.1",
|
||||||
"vue-router": "^3.1.6",
|
"vue-router": "^3.1.6",
|
||||||
"vuejs-logger": "^1.5.3",
|
"vuejs-logger": "^1.5.3",
|
||||||
"vuex": "^3.1.1",
|
"vuex": "^3.1.1"
|
||||||
"flv.js": "^1.5.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/polyfill": "^7.4.4",
|
"@babel/polyfill": "^7.4.4",
|
||||||
|
@ -46,8 +46,10 @@
|
||||||
"eslint-plugin-html": "^6.0.2",
|
"eslint-plugin-html": "^6.0.2",
|
||||||
"eslint-plugin-vue": "^6.2.2",
|
"eslint-plugin-vue": "^6.2.2",
|
||||||
"generate-asset-webpack-plugin": "^0.3.0",
|
"generate-asset-webpack-plugin": "^0.3.0",
|
||||||
|
"husky": "^4.2.5",
|
||||||
"less": "^3.10.0",
|
"less": "^3.10.0",
|
||||||
"less-loader": "^5.0.0",
|
"less-loader": "^5.0.0",
|
||||||
|
"lint-staged": "^10.2.2",
|
||||||
"vue-svg-component-runtime": "^1.0.1",
|
"vue-svg-component-runtime": "^1.0.1",
|
||||||
"vue-svg-icon-loader": "^2.1.1",
|
"vue-svg-icon-loader": "^2.1.1",
|
||||||
"vue-template-compiler": "^2.6.11"
|
"vue-template-compiler": "^2.6.11"
|
||||||
|
@ -117,6 +119,17 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"husky": {
|
||||||
|
"hooks": {
|
||||||
|
"pre-commit": "lint-staged"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"src/**/*.{js,vue}": [
|
||||||
|
"eslint --fix",
|
||||||
|
"git add"
|
||||||
|
]
|
||||||
|
},
|
||||||
"postcss": {
|
"postcss": {
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"autoprefixer": {}
|
"autoprefixer": {}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import {
|
||||||
Divider,
|
Divider,
|
||||||
Dropdown,
|
Dropdown,
|
||||||
Form,
|
Form,
|
||||||
|
FormModel,
|
||||||
Icon,
|
Icon,
|
||||||
Input,
|
Input,
|
||||||
InputNumber,
|
InputNumber,
|
||||||
|
@ -67,6 +68,7 @@ Vue.use(Divider)
|
||||||
Vue.use(Drawer)
|
Vue.use(Drawer)
|
||||||
Vue.use(Dropdown)
|
Vue.use(Dropdown)
|
||||||
Vue.use(Form)
|
Vue.use(Form)
|
||||||
|
Vue.use(FormModel)
|
||||||
Vue.use(Icon)
|
Vue.use(Icon)
|
||||||
Vue.use(Input)
|
Vue.use(Input)
|
||||||
Vue.use(InputNumber)
|
Vue.use(InputNumber)
|
||||||
|
|
|
@ -29,19 +29,20 @@
|
||||||
</a-steps>
|
</a-steps>
|
||||||
<a-divider dashed />
|
<a-divider dashed />
|
||||||
<!-- Blogger info -->
|
<!-- Blogger info -->
|
||||||
<a-form
|
<a-form-model
|
||||||
|
ref="generalForm"
|
||||||
|
:model="installation"
|
||||||
|
:rules="generalRules"
|
||||||
layout="horizontal"
|
layout="horizontal"
|
||||||
v-show="stepCurrent == 0"
|
v-show="stepCurrent == 0"
|
||||||
:form="bloggerForm"
|
|
||||||
>
|
>
|
||||||
<a-form-item class="animated fadeInUp">
|
<a-form-model-item
|
||||||
|
class="animated fadeInUp"
|
||||||
|
prop="username"
|
||||||
|
>
|
||||||
<a-input
|
<a-input
|
||||||
v-model="installation.username"
|
v-model="installation.username"
|
||||||
placeholder="用户名"
|
placeholder="用户名"
|
||||||
v-decorator="[
|
|
||||||
'username',
|
|
||||||
{rules: [{ required: true, message: '请输入用户名' }]}
|
|
||||||
]"
|
|
||||||
>
|
>
|
||||||
<a-icon
|
<a-icon
|
||||||
slot="prefix"
|
slot="prefix"
|
||||||
|
@ -49,10 +50,11 @@
|
||||||
style="color: rgba(0,0,0,.25)"
|
style="color: rgba(0,0,0,.25)"
|
||||||
/>
|
/>
|
||||||
</a-input>
|
</a-input>
|
||||||
</a-form-item>
|
</a-form-model-item>
|
||||||
<a-form-item
|
<a-form-model-item
|
||||||
class="animated fadeInUp"
|
class="animated fadeInUp"
|
||||||
:style="{'animation-delay': '0.1s'}"
|
:style="{'animation-delay': '0.1s'}"
|
||||||
|
prop="nickname"
|
||||||
>
|
>
|
||||||
<a-input
|
<a-input
|
||||||
v-model="installation.nickname"
|
v-model="installation.nickname"
|
||||||
|
@ -64,18 +66,15 @@
|
||||||
style="color: rgba(0,0,0,.25)"
|
style="color: rgba(0,0,0,.25)"
|
||||||
/>
|
/>
|
||||||
</a-input>
|
</a-input>
|
||||||
</a-form-item>
|
</a-form-model-item>
|
||||||
<a-form-item
|
<a-form-model-item
|
||||||
class="animated fadeInUp"
|
class="animated fadeInUp"
|
||||||
:style="{'animation-delay': '0.2s'}"
|
:style="{'animation-delay': '0.2s'}"
|
||||||
|
prop="email"
|
||||||
>
|
>
|
||||||
<a-input
|
<a-input
|
||||||
v-model="installation.email"
|
v-model="installation.email"
|
||||||
placeholder="用户邮箱"
|
placeholder="用户邮箱"
|
||||||
v-decorator="[
|
|
||||||
'email',
|
|
||||||
{rules: [{ required: true, message: '请输入邮箱' }]}
|
|
||||||
]"
|
|
||||||
>
|
>
|
||||||
<a-icon
|
<a-icon
|
||||||
slot="prefix"
|
slot="prefix"
|
||||||
|
@ -83,19 +82,16 @@
|
||||||
style="color: rgba(0,0,0,.25)"
|
style="color: rgba(0,0,0,.25)"
|
||||||
/>
|
/>
|
||||||
</a-input>
|
</a-input>
|
||||||
</a-form-item>
|
</a-form-model-item>
|
||||||
<a-form-item
|
<a-form-model-item
|
||||||
class="animated fadeInUp"
|
class="animated fadeInUp"
|
||||||
:style="{'animation-delay': '0.3s'}"
|
:style="{'animation-delay': '0.3s'}"
|
||||||
|
prop="password"
|
||||||
>
|
>
|
||||||
<a-input
|
<a-input
|
||||||
v-model="installation.password"
|
v-model="installation.password"
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="用户密码(8-100位)"
|
placeholder="用户密码(8-100位)"
|
||||||
v-decorator="[
|
|
||||||
'password',
|
|
||||||
{rules: [{ required: true, message: '请输入密码(8-100位)' },{ validator: handleValidatePassword }]}
|
|
||||||
]"
|
|
||||||
>
|
>
|
||||||
<a-icon
|
<a-icon
|
||||||
slot="prefix"
|
slot="prefix"
|
||||||
|
@ -103,19 +99,16 @@
|
||||||
style="color: rgba(0,0,0,.25)"
|
style="color: rgba(0,0,0,.25)"
|
||||||
/>
|
/>
|
||||||
</a-input>
|
</a-input>
|
||||||
</a-form-item>
|
</a-form-model-item>
|
||||||
<a-form-item
|
<a-form-model-item
|
||||||
class="animated fadeInUp"
|
class="animated fadeInUp"
|
||||||
:style="{'animation-delay': '0.4s'}"
|
:style="{'animation-delay': '0.4s'}"
|
||||||
|
prop="confirmPassword"
|
||||||
>
|
>
|
||||||
<a-input
|
<a-input
|
||||||
v-model="installation.confirmPassword"
|
v-model="installation.confirmPassword"
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="确认密码"
|
placeholder="确认密码"
|
||||||
v-decorator="[
|
|
||||||
'confirmPassword',
|
|
||||||
{rules: [{ required: true, message: '请输入确认密码' },{ validator: handleValidateConfirmPassword }]}
|
|
||||||
]"
|
|
||||||
>
|
>
|
||||||
<a-icon
|
<a-icon
|
||||||
slot="prefix"
|
slot="prefix"
|
||||||
|
@ -123,16 +116,22 @@
|
||||||
style="color: rgba(0,0,0,.25)"
|
style="color: rgba(0,0,0,.25)"
|
||||||
/>
|
/>
|
||||||
</a-input>
|
</a-input>
|
||||||
</a-form-item>
|
</a-form-model-item>
|
||||||
</a-form>
|
</a-form-model>
|
||||||
|
|
||||||
<!-- Blog info -->
|
<!-- Blog info -->
|
||||||
|
|
||||||
<a-form
|
<a-form-model
|
||||||
layout="horizontal"
|
layout="horizontal"
|
||||||
v-show="stepCurrent == 1"
|
v-show="stepCurrent == 1"
|
||||||
|
ref="blogForm"
|
||||||
|
:model="installation"
|
||||||
|
:rules="blogRules"
|
||||||
|
>
|
||||||
|
<a-form-model-item
|
||||||
|
class="animated fadeInUp"
|
||||||
|
prop="url"
|
||||||
>
|
>
|
||||||
<a-form-item class="animated fadeInUp">
|
|
||||||
<a-input
|
<a-input
|
||||||
v-model="installation.url"
|
v-model="installation.url"
|
||||||
placeholder="博客地址"
|
placeholder="博客地址"
|
||||||
|
@ -143,10 +142,11 @@
|
||||||
style="color: rgba(0,0,0,.25)"
|
style="color: rgba(0,0,0,.25)"
|
||||||
/>
|
/>
|
||||||
</a-input>
|
</a-input>
|
||||||
</a-form-item>
|
</a-form-model-item>
|
||||||
<a-form-item
|
<a-form-model-item
|
||||||
class="animated fadeInUp"
|
class="animated fadeInUp"
|
||||||
:style="{'animation-delay': '0.2s'}"
|
:style="{'animation-delay': '0.2s'}"
|
||||||
|
prop="title"
|
||||||
>
|
>
|
||||||
<a-input
|
<a-input
|
||||||
v-model="installation.title"
|
v-model="installation.title"
|
||||||
|
@ -158,8 +158,8 @@
|
||||||
style="color: rgba(0,0,0,.25)"
|
style="color: rgba(0,0,0,.25)"
|
||||||
/>
|
/>
|
||||||
</a-input>
|
</a-input>
|
||||||
</a-form-item>
|
</a-form-model-item>
|
||||||
</a-form>
|
</a-form-model>
|
||||||
|
|
||||||
<!-- Data migration -->
|
<!-- Data migration -->
|
||||||
<div v-show="stepCurrent == 2">
|
<div v-show="stepCurrent == 2">
|
||||||
|
@ -219,12 +219,102 @@ import migrateApi from '@/api/migrate'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
|
const confirmPasswordValidate = (rule, value, callback) => {
|
||||||
|
if (value !== this.installation.password) {
|
||||||
|
callback(new Error('确认密码与所输入的密码不一致'))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
installation: {},
|
installation: {},
|
||||||
stepCurrent: 0,
|
stepCurrent: 0,
|
||||||
migrationData: null,
|
migrationData: null,
|
||||||
bloggerForm: this.$form.createForm(this),
|
installing: false,
|
||||||
installing: false
|
|
||||||
|
generalRules: {
|
||||||
|
username: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '用户名不能为空',
|
||||||
|
trigger: 'change'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
max: 50,
|
||||||
|
message: '用户名的字符长度不能超过 50',
|
||||||
|
trigger: 'change'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
nickname: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '用户昵称不能为空',
|
||||||
|
trigger: 'change'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
max: 255,
|
||||||
|
message: '用户昵称的字符长度不能超过 255',
|
||||||
|
trigger: 'change'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
email: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '电子邮件地址不能为空',
|
||||||
|
trigger: 'change'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
max: 127,
|
||||||
|
message: '电子邮件地址的字符长度不能超过 127',
|
||||||
|
trigger: 'change'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: /\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}/g,
|
||||||
|
message: '电子邮件地址的格式不正确',
|
||||||
|
trigger: 'change'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
password: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '密码不能为空',
|
||||||
|
trigger: 'change'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
min: 8,
|
||||||
|
max: 100,
|
||||||
|
message: '密码的字符长度必须在 8 - 100 之间',
|
||||||
|
trigger: 'change'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
confirmPassword: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '确认密码不能为空',
|
||||||
|
trigger: 'change'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
validator: confirmPasswordValidate,
|
||||||
|
trigger: 'change'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
blogRules: {
|
||||||
|
url: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '博客地址不能为空',
|
||||||
|
trigger: 'change'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '博客标题不能为空',
|
||||||
|
trigger: 'change'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -232,37 +322,31 @@ export default {
|
||||||
this.$set(this.installation, 'url', window.location.protocol + '//' + window.location.host)
|
this.$set(this.installation, 'url', window.location.protocol + '//' + window.location.host)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleValidateConfirmPassword(rule, value, callback) {
|
async verifyIsInstall() {
|
||||||
if (this.installation.confirmPassword && this.installation.password !== this.installation.confirmPassword) {
|
await adminApi.isInstalled().then(response => {
|
||||||
// eslint-disable-next-line standard/no-callback-literal
|
|
||||||
callback('确认密码和密码不匹配')
|
|
||||||
}
|
|
||||||
callback()
|
|
||||||
},
|
|
||||||
handleValidatePassword(rule, value, callback) {
|
|
||||||
if (this.installation.password.length < 8) {
|
|
||||||
// eslint-disable-next-line standard/no-callback-literal
|
|
||||||
callback('密码不能低于 8 位')
|
|
||||||
}
|
|
||||||
callback()
|
|
||||||
},
|
|
||||||
verifyIsInstall() {
|
|
||||||
adminApi.isInstalled().then(response => {
|
|
||||||
if (response.data.data) {
|
if (response.data.data) {
|
||||||
this.$router.push({ name: 'Login' })
|
this.$router.push({ name: 'Login' })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleNextStep(e) {
|
handleNextStep() {
|
||||||
e.preventDefault()
|
if (this.stepCurrent === 0) {
|
||||||
this.bloggerForm.validateFields((error, values) => {
|
this.$refs.generalForm.validate(valid => {
|
||||||
this.$log.debug('error', error)
|
if (valid) {
|
||||||
this.$log.debug('Received values of form: ', values)
|
|
||||||
if (error != null) {
|
|
||||||
} else {
|
|
||||||
this.stepCurrent++
|
this.stepCurrent++
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
} else if (this.stepCurrent === 1) {
|
||||||
|
this.$refs.blogForm.validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
this.stepCurrent++
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
handleMigrationUpload(data) {
|
handleMigrationUpload(data) {
|
||||||
this.$log.debug('Selected data', data)
|
this.$log.debug('Selected data', data)
|
||||||
|
@ -287,16 +371,6 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleInstall() {
|
handleInstall() {
|
||||||
const password = this.installation.password
|
|
||||||
const confirmPassword = this.installation.confirmPassword
|
|
||||||
|
|
||||||
this.$log.debug('Password', password)
|
|
||||||
this.$log.debug('Confirm password', confirmPassword)
|
|
||||||
|
|
||||||
if (password !== confirmPassword) {
|
|
||||||
this.$message.error('确认密码和密码不匹配')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.installing = true
|
this.installing = true
|
||||||
if (this.migrationData) {
|
if (this.migrationData) {
|
||||||
const hide = this.$message.loading('数据导入中...', 0)
|
const hide = this.$message.loading('数据导入中...', 0)
|
||||||
|
|
Loading…
Reference in New Issue