+
-
-
-
-
-
-
-
-
-
-
+
+ Halo
+ 安装向导
+
+
+
+
+
+
+ 全新安装
+
+
+ 数据导入
+
+
+
-
+ 管理员信息
+
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
+ 站点信息
+
+
-
+
-
-
+
-
-
-
+ 安装
-
+ @callback="handleInstallCallback"
+ :loading="form.installing"
+ :errored="form.installErrored"
+ text="安装"
+ loadedText="安装成功"
+ erroredText="安装失败"
+ >
+
+
@@ -221,124 +209,149 @@ import { mapActions } from 'vuex'
export default {
data() {
const confirmPasswordValidate = (rule, value, callback) => {
- if (value !== this.installation.password) {
+ if (value !== this.form.model.password) {
callback(new Error('确认密码与所输入的密码不一致'))
} else {
callback()
}
}
return {
- installation: {},
- stepCurrent: 0,
- migrationData: null,
- installing: false,
+ installationMode: 'new', // new or import
+ form: {
+ model: {},
+ rules: {
+ 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'] },
+ ],
+ url: [{ required: true, message: '* 博客地址不能为空', trigger: ['change'] }],
+ title: [{ required: true, message: '* 博客标题不能为空', trigger: ['change'] }],
+ },
+ installing: false,
+ installErrored: 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'] }
- ]
+ importing: false,
+ importErrored: false,
+ importData: null,
},
- 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)
+ this.$set(this.form.model, 'url', window.location.protocol + '//' + window.location.host)
+ },
+ computed: {
+ isInstallMode() {
+ return this.installationMode === 'new'
+ },
+ isImportMode() {
+ return this.installationMode === 'import'
+ },
},
methods: {
...mapActions(['installCleanToken']),
async handleVerifyIsInstall() {
- await adminApi.isInstalled().then((response) => {
- if (response.data.data) {
- this.$router.push({ name: 'Login' })
+ const response = await adminApi.isInstalled()
+ if (response.data.data) {
+ this.$router.push({ name: 'Login' })
+ }
+ },
+ handleInstall() {
+ this.$refs.installationForm.validate((valid) => {
+ if (valid) {
+ this.form.installing = true
+ this.installCleanToken(this.form.model)
+ .then((response) => {
+ this.$log.debug('Installation response', response)
+ })
+ .catch(() => {
+ this.form.installErrored = true
+ })
+ .finally(() => {
+ setTimeout(() => {
+ this.form.installing = false
+ }, 400)
+ })
}
})
},
- 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
- }
- })
+ handleInstallCallback() {
+ if (this.form.installErrored) {
+ this.form.installErrored = false
+ } else {
+ this.$message.success('安装成功!')
+ this.$router.push({ name: 'Login' })
}
},
- handleMigrationUpload(data) {
+ onImportUpload(data) {
this.$log.debug('Selected data', data)
- this.migrationData = data
+ this.form.importData = data
return new Promise((resolve, reject) => {
this.$log.debug('Handle uploading')
resolve()
})
},
- install() {
- this.installCleanToken(this.installation)
+ handleImport() {
+ if (!this.form.importData) {
+ this.$message.warning('请先上传数据文件!')
+ return
+ }
+ this.form.importing = true
+ migrateApi
+ .migrate(this.form.importData)
.then((response) => {
- this.$log.debug('Installation response', response)
- this.$message.success('安装成功!')
- setTimeout(() => {
- this.$router.push({ name: 'Login' })
- }, 200)
+ this.$log.debug('Migrated successfullly')
+ })
+ .catch(() => {
+ this.form.importErrored = true
})
.finally(() => {
setTimeout(() => {
- this.installing = false
+ this.form.importing = 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()
- })
+ handleImportCallback() {
+ if (this.form.importErrored) {
+ this.form.importErrored = false
} else {
- this.install()
+ this.$message.success('导入成功!')
+ this.$router.push({ name: 'Login' })
}
+ },
+ },
+}
+
+
diff --git a/src/views/system/ToolList.vue b/src/views/system/ToolList.vue
index 982ea77e..0fd0600a 100644
--- a/src/views/system/ToolList.vue
+++ b/src/views/system/ToolList.vue
@@ -103,7 +103,7 @@
diff --git a/src/views/user/Login.vue b/src/views/user/Login.vue
index 18592f78..6520c23e 100644
--- a/src/views/user/Login.vue
+++ b/src/views/user/Login.vue
@@ -97,19 +97,19 @@ import { mapActions, mapGetters, mapMutations } from 'vuex'
import LoginForm from '@/components/Login/LoginForm'
export default {
components: {
- LoginForm
+ LoginForm,
},
data() {
return {
resetPasswordButtonVisible: false,
apiForm: {
apiUrl: window.location.host,
- visible: false
- }
+ visible: false,
+ },
}
},
computed: {
- ...mapGetters({ defaultApiUrl: 'apiUrl' })
+ ...mapGetters({ defaultApiUrl: 'apiUrl' }),
},
beforeMount() {
const _this = this
@@ -124,14 +124,13 @@ export default {
...mapActions(['refreshUserCache', 'refreshOptionsCache']),
...mapMutations({
setApiUrl: 'SET_API_URL',
- restoreApiUrl: 'RESTORE_API_URL'
+ restoreApiUrl: 'RESTORE_API_URL',
}),
- handleVerifyIsInstall() {
- adminApi.isInstalled().then((response) => {
- if (!response.data.data) {
- this.$router.push({ name: 'Install' })
- }
- })
+ async handleVerifyIsInstall() {
+ const response = await adminApi.isInstalled()
+ if (!response.data.data) {
+ this.$router.push({ name: 'Install' })
+ }
},
onLoginSucceed() {
// Refresh the user info
@@ -156,7 +155,7 @@ export default {
if (this.apiForm.visible) {
this.apiForm.apiUrl = this.defaultApiUrl
}
- }
- }
+ },
+ },
}