halo/src/views/system/Installation.vue

345 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div>
<a-row
type="flex"
justify="center"
align="middle"
class="h-screen"
>
<a-col
:xl="8"
:md="12"
:sm="20"
:xs="24"
>
<div class="card-container">
<a-card
:bordered="false"
title="Halo 安装向导"
style="box-shadow: 0px 10px 20px 0px rgba(236, 236, 236, 0.86);"
>
<a-steps :current="stepCurrent">
<a-step title="博主信息">
</a-step>
<a-step title="博客信息">
</a-step>
<a-step title="数据导入">
</a-step>
</a-steps>
<a-divider dashed />
<!-- Blogger info -->
<a-form-model
ref="generalForm"
:model="installation"
:rules="generalRules"
layout="horizontal"
v-show="stepCurrent == 0"
>
<a-form-model-item
class="animated fadeInUp"
prop="username"
>
<a-input
v-model="installation.username"
placeholder="用户名"
>
<a-icon
slot="prefix"
type="user"
style="color: rgba(0,0,0,.25)"
/>
</a-input>
</a-form-model-item>
<a-form-model-item
class="animated fadeInUp"
:style="{'animation-delay': '0.1s'}"
prop="nickname"
>
<a-input
v-model="installation.nickname"
placeholder="用户昵称"
>
<a-icon
slot="prefix"
type="smile"
style="color: rgba(0,0,0,.25)"
/>
</a-input>
</a-form-model-item>
<a-form-model-item
class="animated fadeInUp"
:style="{'animation-delay': '0.2s'}"
prop="email"
>
<a-input
v-model="installation.email"
placeholder="用户邮箱"
>
<a-icon
slot="prefix"
type="mail"
style="color: rgba(0,0,0,.25)"
/>
</a-input>
</a-form-model-item>
<a-form-model-item
class="animated fadeInUp"
:style="{'animation-delay': '0.3s'}"
prop="password"
>
<a-input
v-model="installation.password"
type="password"
placeholder="用户密码8-100位"
>
<a-icon
slot="prefix"
type="lock"
style="color: rgba(0,0,0,.25)"
/>
</a-input>
</a-form-model-item>
<a-form-model-item
class="animated fadeInUp"
:style="{'animation-delay': '0.4s'}"
prop="confirmPassword"
>
<a-input
v-model="installation.confirmPassword"
type="password"
placeholder="确认密码"
>
<a-icon
slot="prefix"
type="lock"
style="color: rgba(0,0,0,.25)"
/>
</a-input>
</a-form-model-item>
</a-form-model>
<!-- Blog info -->
<a-form-model
layout="horizontal"
v-show="stepCurrent == 1"
ref="blogForm"
:model="installation"
:rules="blogRules"
>
<a-form-model-item
class="animated fadeInUp"
prop="url"
>
<a-input
v-model="installation.url"
placeholder="博客地址"
>
<a-icon
slot="prefix"
type="link"
style="color: rgba(0,0,0,.25)"
/>
</a-input>
</a-form-model-item>
<a-form-model-item
class="animated fadeInUp"
:style="{'animation-delay': '0.2s'}"
prop="title"
>
<a-input
v-model="installation.title"
placeholder="博客标题"
>
<a-icon
slot="prefix"
type="book"
style="color: rgba(0,0,0,.25)"
/>
</a-input>
</a-form-model-item>
</a-form-model>
<!-- Data migration -->
<div v-show="stepCurrent == 2">
<a-alert
style="margin-bottom: 1rem"
message="如果有数据导入需求,请点击并选择之前导出的文件。需要注意的是,并不是所有数据都会导入,该初始化表单的数据会覆盖你导入的数据。"
type="info"
/>
<FilePondUpload
ref="upload"
name="file"
accept="application/json"
label="拖拽或点击选择数据文件,请确认是否为 Halo 后台导出的文件。"
:multiple="false"
:uploadHandler="handleMigrationUpload"
:loadOptions="false"
></FilePondUpload>
</div>
<a-row
class="install-action"
type="flex"
justify="space-between"
style="margin-top: 1rem;"
>
<div>
<a-button
class="previus-button"
v-if="stepCurrent != 0"
@click="stepCurrent--"
style="margin-right: 1rem;"
>上一步</a-button>
<a-button
type="primary"
v-if="stepCurrent != 2"
@click="handleNextStep"
>下一步</a-button>
</div>
<a-button
v-if="stepCurrent == 2"
type="primary"
icon="upload"
@click="handleInstall"
:loading="installing"
>安装</a-button>
</a-row>
</a-card>
</div>
</a-col>
</a-row>
</div>
</template>
<script>
import adminApi from '@/api/admin'
import migrateApi from '@/api/migrate'
import { mapActions } from 'vuex'
export default {
data() {
const confirmPasswordValidate = (rule, value, callback) => {
if (value !== this.installation.password) {
callback(new Error('确认密码与所输入的密码不一致'))
} else {
callback()
}
}
return {
installation: {},
stepCurrent: 0,
migrationData: null,
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'] }]
}
}
},
beforeMount() {
this.handleVerifyIsInstall()
this.$set(this.installation, 'url', window.location.protocol + '//' + window.location.host)
},
methods: {
...mapActions(['installCleanToken']),
async handleVerifyIsInstall() {
await adminApi.isInstalled().then((response) => {
if (response.data.data) {
this.$router.push({ name: 'Login' })
}
})
},
handleNextStep() {
if (this.stepCurrent === 0) {
this.$refs.generalForm.validate((valid) => {
if (valid) {
this.stepCurrent++
} else {
return false
}
})
} else if (this.stepCurrent === 1) {
this.$refs.blogForm.validate((valid) => {
if (valid) {
this.stepCurrent++
} else {
return false
}
})
}
},
handleMigrationUpload(data) {
this.$log.debug('Selected data', data)
this.migrationData = data
return new Promise((resolve, reject) => {
this.$log.debug('Handle uploading')
resolve()
})
},
install() {
this.installCleanToken(this.installation)
.then((response) => {
this.$log.debug('Installation response', response)
this.$message.success('安装成功!')
setTimeout(() => {
this.$router.push({ name: 'Login' })
}, 200)
})
.finally(() => {
setTimeout(() => {
this.installing = false
}, 400)
})
},
handleInstall() {
this.installing = true
if (this.migrationData) {
const hide = this.$message.loading('数据导入中...', 0)
migrateApi
.migrate(this.migrationData)
.then((response) => {
this.$log.debug('Migrated successfullly')
this.$message.success('数据导入成功!')
this.install()
})
.finally(() => {
hide()
})
} else {
this.install()
}
}
}
}
</script>