mirror of https://github.com/halo-dev/halo-admin
refactor: install page. (#296)
* refactor: install page. * refactor: install page. * refactor: install page. * refactor: install page.pull/300/head
parent
3799afcdd3
commit
acbbb19347
|
@ -1351,9 +1351,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"core-js": {
|
||||
"version": "3.8.2",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.2.tgz",
|
||||
"integrity": "sha512-FfApuSRgrR6G5s58casCBd9M2k+4ikuu4wbW6pJyYU7bd9zvFc9qf7vr5xmrZOhT9nn+8uwlH1oRR9jTnFoA3A=="
|
||||
"version": "3.9.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.9.0.tgz",
|
||||
"integrity": "sha512-PyFBJaLq93FlyYdsndE5VaueA9K5cNB7CGzeCj191YYLhkQM0gdZR2SKihM70oF0wdqKSKClv/tEBOpoRmdOVQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -3113,9 +3113,9 @@
|
|||
}
|
||||
},
|
||||
"ant-design-vue": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-1.7.2.tgz",
|
||||
"integrity": "sha512-iVskTSG62OSiptyGQkvyhoeLlLMiqKtAOTcWZ7MmsMrj38h0TCpGtqSYS4/fwq4yYgyzloYSteBo8U8TrV99RA==",
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-1.7.3.tgz",
|
||||
"integrity": "sha512-OuJBZmpcy32OvdvP7iW1EqdqU6l/dta1zcQ/U0fep7EGksPviVK7ssifI5QMZFQDDsti0dYQhCEOZWUG0Y/xxQ==",
|
||||
"requires": {
|
||||
"@ant-design/icons": "^2.1.1",
|
||||
"@ant-design/icons-vue": "^2.0.0",
|
||||
|
@ -5382,7 +5382,7 @@
|
|||
},
|
||||
"component-classes": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npm.taobao.org/component-classes/download/component-classes-1.2.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/component-classes/-/component-classes-1.2.6.tgz",
|
||||
"integrity": "sha1-xkI5TDYYpNiwuJGe/Mu9kw5c1pE=",
|
||||
"requires": {
|
||||
"component-indexof": "0.0.3"
|
||||
|
@ -5396,7 +5396,7 @@
|
|||
},
|
||||
"component-indexof": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npm.taobao.org/component-indexof/download/component-indexof-0.0.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/component-indexof/-/component-indexof-0.0.3.tgz",
|
||||
"integrity": "sha1-EdCRMSI5648yyPJa6csAL/6NPCQ="
|
||||
},
|
||||
"compressible": {
|
||||
|
@ -6519,7 +6519,7 @@
|
|||
},
|
||||
"dom-closest": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npm.taobao.org/dom-closest/download/dom-closest-0.2.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/dom-closest/-/dom-closest-0.2.0.tgz",
|
||||
"integrity": "sha1-69n5HRvyLo1vR3h2u80+yQIWwM8=",
|
||||
"requires": {
|
||||
"dom-matches": ">=1.0.1"
|
||||
|
@ -6542,7 +6542,7 @@
|
|||
},
|
||||
"dom-matches": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npm.taobao.org/dom-matches/download/dom-matches-2.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/dom-matches/-/dom-matches-2.0.0.tgz",
|
||||
"integrity": "sha1-0nKLQWqHUzmA6wibhI0lPPI6dYw="
|
||||
},
|
||||
"dom-scroll-into-view": {
|
||||
|
@ -7844,6 +7844,11 @@
|
|||
"resolved": "https://registry.npmjs.org/filepond/-/filepond-4.25.1.tgz",
|
||||
"integrity": "sha512-8UPPTzfpHZRUtJl3dEcGMLYOygg8taJZpYTv1WaEkvzeI+X0JX9+agMJ+5Lu1EKtdt9dGq/9Gud+EnNRBaGl1A=="
|
||||
},
|
||||
"filepond-plugin-file-validate-type": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/filepond-plugin-file-validate-type/-/filepond-plugin-file-validate-type-1.2.5.tgz",
|
||||
"integrity": "sha512-SsdYD6N+PDnetrPrBHfl13ZC9jRv5BuGdai5cORfANhuE/N32OwU/IclCNQ4qlpIa88hzqBg9dj6IINkiW+4HA=="
|
||||
},
|
||||
"filepond-plugin-image-preview": {
|
||||
"version": "4.6.4",
|
||||
"resolved": "https://registry.npmjs.org/filepond-plugin-image-preview/-/filepond-plugin-image-preview-4.6.4.tgz",
|
||||
|
@ -9135,7 +9140,7 @@
|
|||
},
|
||||
"intersperse": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npm.taobao.org/intersperse/download/intersperse-1.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/intersperse/-/intersperse-1.0.0.tgz",
|
||||
"integrity": "sha1-8lYfsc/vn1J3zDNHoiiGtDUaUYE="
|
||||
},
|
||||
"invariant": {
|
||||
|
@ -10444,7 +10449,7 @@
|
|||
},
|
||||
"json2mq": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npm.taobao.org/json2mq/download/json2mq-0.2.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz",
|
||||
"integrity": "sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=",
|
||||
"requires": {
|
||||
"string-convert": "^0.2.0"
|
||||
|
@ -14935,7 +14940,7 @@
|
|||
},
|
||||
"string-convert": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npm.taobao.org/string-convert/download/string-convert-0.2.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz",
|
||||
"integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c="
|
||||
},
|
||||
"string-length": {
|
||||
|
|
|
@ -20,11 +20,12 @@
|
|||
"test:unit": "vue-cli-service test:unit"
|
||||
},
|
||||
"dependencies": {
|
||||
"ant-design-vue": "^1.7.2",
|
||||
"ant-design-vue": "^1.7.3",
|
||||
"axios": "^0.21.1",
|
||||
"dayjs": "^1.10.4",
|
||||
"enquire.js": "^2.1.6",
|
||||
"filepond": "^4.25.1",
|
||||
"filepond-plugin-file-validate-type": "^1.2.5",
|
||||
"filepond-plugin-image-preview": "^4.6.4",
|
||||
"flv.js": "^1.5.0",
|
||||
"halo-editor": "^2.8.2",
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
@click="handleClick"
|
||||
:icon="computedIcon"
|
||||
:loading="loading"
|
||||
:size="size"
|
||||
:block="block"
|
||||
>{{ computedText }}</a-button>
|
||||
</template>
|
||||
<script>
|
||||
|
@ -18,6 +20,14 @@ export default {
|
|||
type: String,
|
||||
default: null,
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'default',
|
||||
},
|
||||
block: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
:name="name"
|
||||
:allow-multiple="multiple"
|
||||
:allowRevert="false"
|
||||
:accepted-file-types="accept"
|
||||
:accepted-file-types="accepts"
|
||||
:maxParallelUploads="maxParallelUploads"
|
||||
:allowImagePreview="allowImagePreview"
|
||||
:maxFiles="maxFiles"
|
||||
|
@ -16,6 +16,8 @@
|
|||
labelFileProcessingError="上传错误"
|
||||
labelTapToCancel="点击取消"
|
||||
labelTapToRetry="点击重试"
|
||||
labelFileTypeNotAllowed="不支持当前文件格式"
|
||||
fileValidateTypeLabelExpectedTypes="请选择 {allTypes} 格式的文件"
|
||||
:files="fileList"
|
||||
:server="server"
|
||||
@init="handleFilePondInit"
|
||||
|
@ -33,49 +35,52 @@ import 'filepond/dist/filepond.min.css'
|
|||
// Plugins
|
||||
import FilePondPluginImagePreview from 'filepond-plugin-image-preview'
|
||||
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css'
|
||||
import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type'
|
||||
|
||||
// Create component and regist plugins
|
||||
const FilePond = vueFilePond(FilePondPluginImagePreview)
|
||||
const FilePond = vueFilePond(FilePondPluginImagePreview, FilePondPluginFileValidateType)
|
||||
export default {
|
||||
name: 'FilePondUpload',
|
||||
components: {
|
||||
FilePond
|
||||
FilePond,
|
||||
},
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'file'
|
||||
default: 'file',
|
||||
},
|
||||
filed: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: ''
|
||||
default: '',
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
accept: {
|
||||
type: String,
|
||||
accepts: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: ''
|
||||
default: () => {
|
||||
return []
|
||||
},
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '点击选择文件或将文件拖拽到此处'
|
||||
default: '点击选择文件或将文件拖拽到此处',
|
||||
},
|
||||
uploadHandler: {
|
||||
type: Function,
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
loadOptions: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true
|
||||
}
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['options']),
|
||||
|
@ -96,7 +101,7 @@ export default {
|
|||
return this.options.attachment_upload_max_files
|
||||
}
|
||||
return 1
|
||||
}
|
||||
},
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
|
@ -134,11 +139,11 @@ export default {
|
|||
abort()
|
||||
this.$log.debug('Upload operation aborted by the user')
|
||||
source.cancel('Upload operation canceled by the user.')
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
fileList: []
|
||||
fileList: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -147,7 +152,7 @@ export default {
|
|||
},
|
||||
handleClearFileList() {
|
||||
this.$refs.pond.removeFiles()
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -74,6 +74,20 @@
|
|||
animation-name: fadeInUp;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.fadeIn {
|
||||
animation-name: fadeIn;
|
||||
}
|
||||
|
||||
.animated {
|
||||
-webkit-animation-duration: 1s;
|
||||
animation-duration: 1s;
|
||||
|
|
|
@ -10,31 +10,31 @@
|
|||
padding: 18px 28px 28px 28px;
|
||||
box-shadow: -4px 7px 46px 2px rgba(0, 0, 0, 0.1);
|
||||
|
||||
.halo-logo {
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
|
||||
span {
|
||||
vertical-align: text-bottom;
|
||||
font-size: 38px;
|
||||
display: inline-block;
|
||||
font-weight: 600;
|
||||
color: #1790fe;
|
||||
background-image: linear-gradient(-20deg, #6e45e2 0%, #88d3ce 100%);
|
||||
-webkit-text-fill-color: transparent;
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
|
||||
small {
|
||||
margin-left: 5px;
|
||||
font-size: 35%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tip {
|
||||
cursor: pointer;
|
||||
margin-left: 0.5rem;
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.halo-logo {
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
|
||||
span {
|
||||
vertical-align: text-bottom;
|
||||
font-size: 38px;
|
||||
display: inline-block;
|
||||
font-weight: 600;
|
||||
color: #1790fe;
|
||||
background-image: linear-gradient(-20deg, #6e45e2 0%, #88d3ce 100%);
|
||||
-webkit-text-fill-color: transparent;
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
|
||||
small {
|
||||
margin-left: 5px;
|
||||
font-size: 35%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@
|
|||
<FilePondUpload
|
||||
ref="upload"
|
||||
name="file"
|
||||
accept="application/zip"
|
||||
:accepts="['application/zip']"
|
||||
label="点击选择主题包或将主题包拖拽到此处<br>仅支持 ZIP 格式的文件"
|
||||
:uploadHandler="installModal.local.uploadHandler"
|
||||
@success="handleUploadSucceed"
|
||||
|
@ -223,7 +223,7 @@
|
|||
<FilePondUpload
|
||||
ref="updateByupload"
|
||||
name="file"
|
||||
accept="application/zip"
|
||||
:accepts="['application/zip']"
|
||||
label="点击选择主题更新包或将主题更新包拖拽到此处<br>仅支持 ZIP 格式的文件"
|
||||
:uploadHandler="localUpdateModel.uploadHandler"
|
||||
:filed="localUpdateModel.selected.id"
|
||||
|
|
|
@ -7,41 +7,56 @@
|
|||
class="h-screen"
|
||||
>
|
||||
<a-col
|
||||
:xl="8"
|
||||
:md="12"
|
||||
:xxl="8"
|
||||
:xl="12"
|
||||
:lg="16"
|
||||
:md="20"
|
||||
:sm="20"
|
||||
:xs="24"
|
||||
:xs="23"
|
||||
>
|
||||
<div class="card-container">
|
||||
<div class="card-container animated fadeIn">
|
||||
<a-card
|
||||
:bordered="false"
|
||||
title="Halo 安装向导"
|
||||
style="box-shadow: 0px 10px 20px 0px rgba(236, 236, 236, 0.86);"
|
||||
style="box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;"
|
||||
>
|
||||
|
||||
<a-steps :current="stepCurrent">
|
||||
<a-step title="博主信息">
|
||||
</a-step>
|
||||
<a-step title="博客信息">
|
||||
</a-step>
|
||||
<a-step title="数据导入">
|
||||
</a-step>
|
||||
</a-steps>
|
||||
<a-divider dashed />
|
||||
<div class="halo-logo">
|
||||
<span>Halo
|
||||
<small>安装向导</small>
|
||||
</span>
|
||||
</div>
|
||||
<a-alert
|
||||
:message="`欢迎使用 Halo,您正在安装的是 Halo ${VERSION}。`"
|
||||
type="success"
|
||||
show-icon
|
||||
/>
|
||||
<!-- Blogger info -->
|
||||
<div class="mt-5 mb-5">
|
||||
<a-radio-group v-model="installationMode">
|
||||
<a-radio-button value="new">
|
||||
全新安装
|
||||
</a-radio-button>
|
||||
<a-radio-button value="import">
|
||||
数据导入
|
||||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
<a-form-model
|
||||
ref="generalForm"
|
||||
:model="installation"
|
||||
:rules="generalRules"
|
||||
class="installationForm animated fadeIn"
|
||||
ref="installationForm"
|
||||
:model="form.model"
|
||||
:rules="form.rules"
|
||||
layout="horizontal"
|
||||
v-show="stepCurrent == 0"
|
||||
v-show="isInstallMode"
|
||||
>
|
||||
<a-form-model-item
|
||||
class="animated fadeInUp"
|
||||
prop="username"
|
||||
<a-divider
|
||||
orientation="left"
|
||||
dashed
|
||||
>
|
||||
管理员信息
|
||||
</a-divider>
|
||||
<a-form-model-item prop="username">
|
||||
<a-input
|
||||
v-model="installation.username"
|
||||
v-model="form.model.username"
|
||||
placeholder="用户名"
|
||||
>
|
||||
<a-icon
|
||||
|
@ -51,29 +66,21 @@
|
|||
/>
|
||||
</a-input>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item
|
||||
class="animated fadeInUp"
|
||||
:style="{'animation-delay': '0.1s'}"
|
||||
prop="nickname"
|
||||
>
|
||||
<a-form-model-item prop="username">
|
||||
<a-input
|
||||
v-model="installation.nickname"
|
||||
v-model="form.model.nickname"
|
||||
placeholder="用户昵称"
|
||||
>
|
||||
<a-icon
|
||||
slot="prefix"
|
||||
type="smile"
|
||||
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.2s'}"
|
||||
prop="email"
|
||||
>
|
||||
<a-form-model-item prop="email">
|
||||
<a-input
|
||||
v-model="installation.email"
|
||||
v-model="form.model.email"
|
||||
placeholder="用户邮箱"
|
||||
>
|
||||
<a-icon
|
||||
|
@ -83,15 +90,11 @@
|
|||
/>
|
||||
</a-input>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item
|
||||
class="animated fadeInUp"
|
||||
:style="{'animation-delay': '0.3s'}"
|
||||
prop="password"
|
||||
>
|
||||
<a-form-model-item prop="password">
|
||||
<a-input
|
||||
v-model="installation.password"
|
||||
v-model="form.model.password"
|
||||
type="password"
|
||||
placeholder="用户密码(8-100位)"
|
||||
placeholder="登录密码(8-100位)"
|
||||
>
|
||||
<a-icon
|
||||
slot="prefix"
|
||||
|
@ -100,15 +103,11 @@
|
|||
/>
|
||||
</a-input>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item
|
||||
class="animated fadeInUp"
|
||||
:style="{'animation-delay': '0.4s'}"
|
||||
prop="confirmPassword"
|
||||
>
|
||||
<a-form-model-item prop="confirmPassword">
|
||||
<a-input
|
||||
v-model="installation.confirmPassword"
|
||||
v-model="form.model.confirmPassword"
|
||||
type="password"
|
||||
placeholder="确认密码"
|
||||
placeholder="确认登录密码"
|
||||
>
|
||||
<a-icon
|
||||
slot="prefix"
|
||||
|
@ -117,23 +116,15 @@
|
|||
/>
|
||||
</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-divider
|
||||
orientation="left"
|
||||
dashed
|
||||
>
|
||||
站点信息
|
||||
</a-divider>
|
||||
<a-form-model-item prop="url">
|
||||
<a-input
|
||||
v-model="installation.url"
|
||||
v-model="form.model.url"
|
||||
placeholder="博客地址"
|
||||
>
|
||||
<a-icon
|
||||
|
@ -143,13 +134,9 @@
|
|||
/>
|
||||
</a-input>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item
|
||||
class="animated fadeInUp"
|
||||
:style="{'animation-delay': '0.2s'}"
|
||||
prop="title"
|
||||
>
|
||||
<a-form-model-item prop="title">
|
||||
<a-input
|
||||
v-model="installation.title"
|
||||
v-model="form.model.title"
|
||||
placeholder="博客标题"
|
||||
>
|
||||
<a-icon
|
||||
|
@ -162,50 +149,51 @@
|
|||
</a-form-model>
|
||||
|
||||
<!-- Data migration -->
|
||||
<div v-show="stepCurrent == 2">
|
||||
<a-alert
|
||||
style="margin-bottom: 1rem"
|
||||
message="如果有数据导入需求,请点击并选择之前导出的文件。需要注意的是,并不是所有数据都会导入,该初始化表单的数据会覆盖你导入的数据。"
|
||||
type="info"
|
||||
/>
|
||||
<div
|
||||
class="animated fadeIn"
|
||||
v-show="isImportMode"
|
||||
>
|
||||
<FilePondUpload
|
||||
ref="upload"
|
||||
name="file"
|
||||
accept="application/json"
|
||||
label="拖拽或点击选择数据文件,请确认是否为 Halo 后台导出的文件。"
|
||||
:accepts="['application/json']"
|
||||
label="拖拽或点击选择数据文件<br>请确认是否为 Halo 后台导出的文件。"
|
||||
:multiple="false"
|
||||
:uploadHandler="handleMigrationUpload"
|
||||
:uploadHandler="onImportUpload"
|
||||
: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"
|
||||
<div class="mt-8">
|
||||
<ReactiveButton
|
||||
v-if="isInstallMode"
|
||||
icon="check"
|
||||
type="primary"
|
||||
icon="upload"
|
||||
block
|
||||
size="large"
|
||||
@click="handleInstall"
|
||||
:loading="installing"
|
||||
>安装</a-button>
|
||||
</a-row>
|
||||
@callback="handleInstallCallback"
|
||||
:loading="form.installing"
|
||||
:errored="form.installErrored"
|
||||
text="安装"
|
||||
loadedText="安装成功"
|
||||
erroredText="安装失败"
|
||||
></ReactiveButton>
|
||||
<ReactiveButton
|
||||
v-if="isImportMode"
|
||||
icon="import"
|
||||
type="primary"
|
||||
block
|
||||
size="large"
|
||||
@click="handleImport"
|
||||
@callback="handleImportCallback"
|
||||
:loading="form.importing"
|
||||
:errored="form.importErrored"
|
||||
text="导入"
|
||||
loadedText="导入成功"
|
||||
erroredText="导入失败"
|
||||
></ReactiveButton>
|
||||
</div>
|
||||
</a-card>
|
||||
</div>
|
||||
</a-col>
|
||||
|
@ -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' })
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
::v-deep .installationForm {
|
||||
.ant-divider {
|
||||
.ant-divider-inner-text {
|
||||
padding-left: 0;
|
||||
}
|
||||
&::before {
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</style>
|
||||
|
|
|
@ -103,7 +103,7 @@
|
|||
<FilePondUpload
|
||||
ref="upload"
|
||||
name="file"
|
||||
accept="text/markdown"
|
||||
:accepts="['text/markdown']"
|
||||
label="拖拽或点击选择 Markdown 文件到此处"
|
||||
:uploadHandler="uploadHandler"
|
||||
></FilePondUpload>
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
Loading…
Reference in New Issue