pref: code optimization again. (halo-dev/console#215)

pull/3445/head
Ryan Wang 2020-07-14 16:51:40 +08:00 committed by GitHub
parent 363422a50a
commit 23768f1d18
46 changed files with 720 additions and 558 deletions

View File

@ -7,6 +7,7 @@
:visible="visible" :visible="visible"
destroyOnClose destroyOnClose
@close="onClose" @close="onClose"
:afterVisibleChange="handleAfterVisibleChanged"
> >
<a-row <a-row
type="flex" type="flex"
@ -51,6 +52,7 @@
:total="pagination.total" :total="pagination.total"
:defaultPageSize="pagination.size" :defaultPageSize="pagination.size"
@change="handlePaginationChange" @change="handlePaginationChange"
showLessItems
></a-pagination> ></a-pagination>
</div> </div>
<a-divider class="divider-transparent" /> <a-divider class="divider-transparent" />
@ -136,13 +138,6 @@ export default {
uploadHandler: attachmentApi.upload uploadHandler: attachmentApi.upload
} }
}, },
watch: {
visible: function(newValue, oldValue) {
if (newValue) {
this.handleListAttachments()
}
}
},
methods: { methods: {
handleShowUploadModal() { handleShowUploadModal() {
this.uploadVisible = true this.uploadVisible = true
@ -182,6 +177,11 @@ export default {
this.$refs.upload.handleClearFileList() this.$refs.upload.handleClearFileList()
this.handlePaginationChange(1, this.pagination.size) this.handlePaginationChange(1, this.pagination.size)
}, },
handleAfterVisibleChanged(visible) {
if (visible) {
this.handleListAttachments()
}
},
handleJudgeMediaType(attachment) { handleJudgeMediaType(attachment) {
var mediaType = attachment.mediaType var mediaType = attachment.mediaType
// //

View File

@ -7,7 +7,7 @@
<a-layout-header <a-layout-header
v-if="visible" v-if="visible"
:class="[fixedHeader && 'ant-header-fixedHeader', sidebarOpened ? 'ant-header-side-opened' : 'ant-header-side-closed', ]" :class="[fixedHeader && 'ant-header-fixedHeader', sidebarOpened ? 'ant-header-side-opened' : 'ant-header-side-closed', ]"
class="p-0" style="padding:0"
> >
<div <div
v-if="mode === 'sidemenu'" v-if="mode === 'sidemenu'"

View File

@ -30,12 +30,12 @@ export default {
...mapGetters(['options']) ...mapGetters(['options'])
}, },
methods: { methods: {
...mapActions(['loadOptions']), ...mapActions(['refreshOptionsCache']),
onLogoClick() { onLogoClick() {
this.clickCount++ this.clickCount++
if (this.clickCount === 10) { if (this.clickCount === 10) {
optionApi.save(this.optionsToCreate).then(response => { optionApi.save(this.optionsToCreate).then(response => {
this.loadOptions() this.refreshOptionsCache()
this.$message.success(`开发者选项已启用!`) this.$message.success(`开发者选项已启用!`)
this.clickCount = 0 this.clickCount = 0
this.$router.push({ name: 'ToolList' }) this.$router.push({ name: 'ToolList' })

View File

@ -156,15 +156,6 @@ export default {
<style lang="less"> <style lang="less">
@import url('../components/global.less'); @import url('../components/global.less');
/*
* The following styles are auto-applied to elements with
* transition="page-transition" when their visibility is toggled
* by Vue.js.
*
* You can easily play with the page transition by editing
* these styles.
*/
.page-transition-enter { .page-transition-enter {
opacity: 0; opacity: 0;
} }

View File

@ -21,7 +21,7 @@ router.beforeEach((to, from, next) => {
// TODO Get installation status // TODO Get installation status
if (!store.getters.options) { if (!store.getters.options) {
store.dispatch('loadOptions').then() store.dispatch('refreshOptionsCache').then()
} }
next() next()

View File

@ -26,7 +26,7 @@ const option = {
} }
}, },
actions: { actions: {
loadOptions({ refreshOptionsCache({
commit commit
}) { }) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {

View File

@ -26,7 +26,7 @@ const user = {
} }
}, },
actions: { actions: {
loadUser({ refreshUserCache({
commit commit
}) { }) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {

View File

@ -170,6 +170,7 @@
showSizeChanger showSizeChanger
@change="handlePaginationChange" @change="handlePaginationChange"
@showSizeChange="handlePaginationChange" @showSizeChange="handlePaginationChange"
showLessItems
/> />
</div> </div>
<a-modal <a-modal

View File

@ -7,6 +7,7 @@
:visible="visible" :visible="visible"
destroyOnClose destroyOnClose
@close="onClose" @close="onClose"
:afterVisibleChange="handleAfterVisibleChanged"
> >
<a-row <a-row
type="flex" type="flex"
@ -52,6 +53,7 @@
:total="pagination.total" :total="pagination.total"
:defaultPageSize="pagination.size" :defaultPageSize="pagination.size"
@change="handlePaginationChange" @change="handlePaginationChange"
showLessItems
></a-pagination> ></a-pagination>
</div> </div>
@ -59,7 +61,7 @@
v-model="detailVisible" v-model="detailVisible"
v-if="selectedAttachment" v-if="selectedAttachment"
:attachment="selectedAttachment" :attachment="selectedAttachment"
@delete="loadAttachments" @delete="handleListAttachments"
/> />
<a-divider class="divider-transparent" /> <a-divider class="divider-transparent" />
<div class="bottom-control"> <div class="bottom-control">
@ -139,13 +141,6 @@ export default {
}) })
} }
}, },
watch: {
visible(value) {
if (value) {
this.loadAttachments()
}
}
},
methods: { methods: {
handleShowDetailDrawer(attachment) { handleShowDetailDrawer(attachment) {
this.selectedAttachment = attachment this.selectedAttachment = attachment
@ -193,7 +188,7 @@ export default {
}) })
return false return false
}, },
loadAttachments() { handleListAttachments() {
this.loading = true this.loading = true
this.queryParam.page = this.pagination.page - 1 this.queryParam.page = this.pagination.page - 1
this.queryParam.size = this.pagination.size this.queryParam.size = this.pagination.size
@ -216,12 +211,17 @@ export default {
handlePaginationChange(page, pageSize) { handlePaginationChange(page, pageSize) {
this.pagination.page = page this.pagination.page = page
this.pagination.size = pageSize this.pagination.size = pageSize
this.loadAttachments() this.handleListAttachments()
}, },
onUploadClose() { onUploadClose() {
this.$refs.upload.handleClearFileList() this.$refs.upload.handleClearFileList()
this.handlePaginationChange(1, this.pagination.size) this.handlePaginationChange(1, this.pagination.size)
}, },
handleAfterVisibleChanged(visible) {
if (visible) {
this.handleListAttachments()
}
},
handleJudgeMediaType(attachment) { handleJudgeMediaType(attachment) {
var mediaType = attachment.mediaType var mediaType = attachment.mediaType
// //

View File

@ -388,6 +388,7 @@
showSizeChanger showSizeChanger
@showSizeChange="handlePaginationChange" @showSizeChange="handlePaginationChange"
@change="handlePaginationChange" @change="handlePaginationChange"
showLessItems
/> />
</div> </div>
</div> </div>

View File

@ -6,6 +6,7 @@
:visible="visible" :visible="visible"
destroyOnClose destroyOnClose
@close="onClose" @close="onClose"
:afterVisibleChange="handleAfterVisibleChanged"
> >
<a-row <a-row
type="flex" type="flex"
@ -49,6 +50,7 @@
:total="pagination.total" :total="pagination.total"
:defaultPageSize="pagination.size" :defaultPageSize="pagination.size"
@change="handlePaginationChange" @change="handlePaginationChange"
showLessItems
></a-pagination> ></a-pagination>
</div> </div>
<a-divider class="divider-transparent" /> <a-divider class="divider-transparent" />
@ -168,15 +170,6 @@ export default {
default: 0 default: 0
} }
}, },
watch: {
visible(newValue, oldValue) {
this.$log.debug('old value', oldValue)
this.$log.debug('new value', newValue)
if (newValue) {
this.handleListComments()
}
}
},
methods: { methods: {
handleListComments() { handleListComments() {
this.loading = true this.loading = true
@ -268,6 +261,11 @@ export default {
sort: '' sort: ''
} }
this.$emit('close', false) this.$emit('close', false)
},
handleAfterVisibleChanged(visible) {
if (visible) {
this.handleListComments()
}
} }
} }
} }

View File

@ -7,6 +7,7 @@
:visible="visible" :visible="visible"
destroyOnClose destroyOnClose
@close="onClose" @close="onClose"
:afterVisibleChange="handleAfterVisibleChanged"
> >
<a-row <a-row
type="flex" type="flex"
@ -42,6 +43,7 @@
showSizeChanger showSizeChanger
@showSizeChange="handlePaginationChange" @showSizeChange="handlePaginationChange"
@change="handlePaginationChange" @change="handlePaginationChange"
showLessItems
/> />
</div> </div>
</a-col> </a-col>
@ -100,13 +102,6 @@ export default {
}) })
} }
}, },
watch: {
visible(value) {
if (value) {
this.handleListLogs()
}
}
},
methods: { methods: {
handleListLogs() { handleListLogs() {
this.loading = true this.loading = true
@ -143,6 +138,11 @@ export default {
}, },
onClose() { onClose() {
this.$emit('close', false) this.$emit('close', false)
},
handleAfterVisibleChanged(visible) {
if (visible) {
this.handleListLogs()
}
} }
} }
} }

View File

@ -345,7 +345,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
_this.form.saving = false _this.form.saving = false
}, 200) }, 400)
_this.handleListMenus() _this.handleListMenus()
_this.handleListTeams() _this.handleListTeams()
}) })
@ -359,7 +359,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
_this.form.saving = false _this.form.saving = false
}, 200) }, 400)
_this.handleListMenus() _this.handleListMenus()
_this.handleListTeams() _this.handleListTeams()
}) })

View File

@ -192,7 +192,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.saving = false this.saving = false
}, 200) }, 400)
}) })
} }
} }

View File

@ -421,7 +421,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.fetchButtonLoading = false this.fetchButtonLoading = false
}, 200) }, 400)
}) })
}, },
handleBranchFetching() { handleBranchFetching() {

View File

@ -7,6 +7,7 @@
destroyOnClose destroyOnClose
@close="onClose" @close="onClose"
:visible="visible" :visible="visible"
:afterVisibleChange="handleAfterVisibleChanged"
> >
<a-row <a-row
:gutter="12" :gutter="12"
@ -56,11 +57,13 @@
style="padding-bottom: 50px;" style="padding-bottom: 50px;"
> >
<a-spin :spinning="settingLoading"> <a-spin :spinning="settingLoading">
<div class="card-container"> <div
class="card-container"
v-if="themeConfigurations.length>0"
>
<a-tabs <a-tabs
type="card" type="card"
defaultActiveKey="0" defaultActiveKey="0"
v-if="themeConfigurations.length>0"
> >
<a-tab-pane <a-tab-pane
v-for="(group, index) in themeConfigurations" v-for="(group, index) in themeConfigurations"
@ -159,12 +162,11 @@
</a-form> </a-form>
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
<a-alert
message="当前主题暂无设置选项"
banner
v-if="themeConfigurations.length <=0 && !settingLoading"
/>
</div> </div>
<a-empty
v-if="themeConfigurations.length <=0 && !settingLoading"
description="当前主题暂无设置选项"
/>
</a-spin> </a-spin>
</a-col> </a-col>
@ -245,7 +247,7 @@ export default {
attachmentDrawerVisible: false, attachmentDrawerVisible: false,
themeConfigurations: [], themeConfigurations: [],
themeSettings: [], themeSettings: [],
settingLoading: false, settingLoading: true,
selectedField: '', selectedField: '',
wrapperCol: { wrapperCol: {
xl: { span: 12 }, xl: { span: 12 },
@ -275,13 +277,6 @@ export default {
default: false default: false
} }
}, },
watch: {
visible(value) {
if (value) {
this.handleFetchConfiguration()
}
}
},
computed: { computed: {
...mapGetters(['options']), ...mapGetters(['options']),
author() { author() {
@ -324,7 +319,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.saving = false this.saving = false
}, 200) }, 400)
}) })
}, },
onClose() { onClose() {
@ -339,6 +334,15 @@ export default {
// this.themeSettings[this.selectedField] = encodeURI(data.path) // this.themeSettings[this.selectedField] = encodeURI(data.path)
this.attachmentDrawerVisible = false this.attachmentDrawerVisible = false
}, },
handleAfterVisibleChanged(visible) {
if (visible) {
this.handleFetchConfiguration()
} else {
this.themeConfigurations = []
this.themeSettings = []
this.settingLoading = true
}
},
toggleViewMode() { toggleViewMode() {
this.viewMode = !this.viewMode this.viewMode = !this.viewMode
if (this.viewMode) { if (this.viewMode) {

View File

@ -368,7 +368,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
_this.form.saving = false _this.form.saving = false
}, 200) }, 400)
_this.handleListCategories() _this.handleListCategories()
}) })
} else { } else {
@ -381,7 +381,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
_this.form.saving = false _this.form.saving = false
}, 200) }, 400)
_this.handleListCategories() _this.handleListCategories()
}) })
} }

View File

@ -196,7 +196,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.draftSaving = false this.draftSaving = false
}, 200) }, 400)
}) })
} else { } else {
postApi postApi
@ -209,7 +209,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.draftSaving = false this.draftSaving = false
}, 200) }, 400)
}) })
} }
} else { } else {
@ -246,7 +246,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.previewSaving = false this.previewSaving = false
}, 200) }, 400)
}) })
}) })
} else { } else {
@ -262,7 +262,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.previewSaving = false this.previewSaving = false
}, 200) }, 400)
}) })
}) })
} }

View File

@ -478,6 +478,7 @@
showSizeChanger showSizeChanger
@showSizeChange="handlePaginationChange" @showSizeChange="handlePaginationChange"
@change="handlePaginationChange" @change="handlePaginationChange"
showLessItems
/> />
</div> </div>
</div> </div>
@ -719,6 +720,7 @@ export default {
this.queryParam.status = null this.queryParam.status = null
this.handleClearRowKeys() this.handleClearRowKeys()
this.handlePaginationChange(1, this.pagination.size) this.handlePaginationChange(1, this.pagination.size)
this.handleListCategories()
}, },
handleQuery() { handleQuery() {
this.handleClearRowKeys() this.handleClearRowKeys()

View File

@ -205,7 +205,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
_this.form.saving = false _this.form.saving = false
}, 200) }, 400)
_this.handleListTags() _this.handleListTags()
}) })
} else { } else {
@ -218,7 +218,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
_this.form.saving = false _this.form.saving = false
}, 200) }, 400)
_this.handleListTags() _this.handleListTags()
}) })
} }

View File

@ -7,6 +7,7 @@
destroyOnClose destroyOnClose
@close="onClose" @close="onClose"
:visible="visible" :visible="visible"
:afterVisibleChange="handleAfterVisibleChanged"
> >
<div class="post-setting-drawer-content"> <div class="post-setting-drawer-content">
<div class="mb-4"> <div class="mb-4">
@ -384,13 +385,6 @@ export default {
}, },
selectedMetas(val) { selectedMetas(val) {
this.$emit('onRefreshPostMetas', val) this.$emit('onRefreshPostMetas', val)
},
visible: function(newValue, oldValue) {
if (newValue) {
this.handleListCategories()
this.handleListPresetMetasField()
this.handleListCustomTpls()
}
} }
}, },
computed: { computed: {
@ -409,6 +403,13 @@ export default {
...mapGetters(['options']) ...mapGetters(['options'])
}, },
methods: { methods: {
handleAfterVisibleChanged(visible) {
if (visible) {
this.handleListCategories()
this.handleListPresetMetasField()
this.handleListCustomTpls()
}
},
handleListCategories() { handleListCategories() {
categoryApi.listAll().then(response => { categoryApi.listAll().then(response => {
this.categories = response.data.data this.categories = response.data.data
@ -506,7 +507,7 @@ export default {
setTimeout(() => { setTimeout(() => {
this.saving = false this.saving = false
this.draftSaving = false this.draftSaving = false
}, 200) }, 400)
}) })
} else { } else {
// Create the post // Create the post
@ -529,7 +530,7 @@ export default {
setTimeout(() => { setTimeout(() => {
this.saving = false this.saving = false
this.draftSaving = false this.draftSaving = false
}, 200) }, 400)
}) })
} }
}, },

View File

@ -186,7 +186,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.draftSaving = false this.draftSaving = false
}, 200) }, 400)
}) })
} else { } else {
sheetApi sheetApi
@ -199,7 +199,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.draftSaving = false this.draftSaving = false
}, 200) }, 400)
}) })
} }
} else { } else {
@ -234,7 +234,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.previewSaving = false this.previewSaving = false
}, 200) }, 400)
}) })
}) })
} else { } else {
@ -249,7 +249,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.previewSaving = false this.previewSaving = false
}, 200) }, 400)
}) })
}) })
} }

View File

@ -314,6 +314,7 @@
showSizeChanger showSizeChanger
@showSizeChange="handlePaginationChange" @showSizeChange="handlePaginationChange"
@change="handlePaginationChange" @change="handlePaginationChange"
showLessItems
/> />
</div> </div>
<SheetSettingDrawer <SheetSettingDrawer

View File

@ -7,6 +7,7 @@
destroyOnClose destroyOnClose
@close="onClose" @close="onClose"
:visible="visible" :visible="visible"
:afterVisibleChange="handleAfterVisibleChanged"
> >
<div class="post-setting-drawer-content"> <div class="post-setting-drawer-content">
<div class="mb-4"> <div class="mb-4">
@ -264,12 +265,6 @@ export default {
}, },
selectedMetas(val) { selectedMetas(val) {
this.$emit('onRefreshSheetMetas', val) this.$emit('onRefreshSheetMetas', val)
},
visible: function(newValue, oldValue) {
if (newValue) {
this.handleListCustomTpls()
this.handleListPresetMetasField()
}
} }
}, },
computed: { computed: {
@ -286,6 +281,12 @@ export default {
...mapGetters(['options']) ...mapGetters(['options'])
}, },
methods: { methods: {
handleAfterVisibleChanged(visible) {
if (visible) {
this.handleListCustomTpls()
this.handleListPresetMetasField()
}
},
handleListPresetMetasField() { handleListPresetMetasField() {
if (this.metas.length <= 0) { if (this.metas.length <= 0) {
themeApi.getActivatedTheme().then(response => { themeApi.getActivatedTheme().then(response => {
@ -359,7 +360,7 @@ export default {
setTimeout(() => { setTimeout(() => {
this.saving = false this.saving = false
this.draftSaving = false this.draftSaving = false
}, 200) }, 400)
}) })
} else { } else {
sheetApi sheetApi
@ -381,7 +382,7 @@ export default {
setTimeout(() => { setTimeout(() => {
this.saving = false this.saving = false
this.draftSaving = false this.draftSaving = false
}, 200) }, 400)
}) })
} }
}, },

View File

@ -147,6 +147,7 @@
showSizeChanger showSizeChanger
@showSizeChange="handlePaginationChange" @showSizeChange="handlePaginationChange"
@change="handlePaginationChange" @change="handlePaginationChange"
showLessItems
/> />
</div> </div>
</a-list> </a-list>
@ -184,9 +185,9 @@
<a-input v-model="options.journals_title" /> <a-input v-model="options.journals_title" />
</a-form-item> </a-form-item>
<a-form-item label="每页显示条数:"> <a-form-item label="每页显示条数:">
<a-input <a-input-number
type="number"
v-model="options.journals_page_size" v-model="options.journals_page_size"
style="width:100%"
/> />
</a-form-item> </a-form-item>
</a-form> </a-form>
@ -293,7 +294,7 @@ export default {
...mapGetters(['user']) ...mapGetters(['user'])
}, },
methods: { methods: {
...mapActions(['loadOptions']), ...mapActions(['refreshOptionsCache']),
hanldeListJournals() { hanldeListJournals() {
this.listLoading = true this.listLoading = true
this.queryParam.page = this.pagination.page - 1 this.queryParam.page = this.pagination.page - 1
@ -402,7 +403,7 @@ export default {
}) })
.finally(() => { .finally(() => {
this.hanldeListOptions() this.hanldeListOptions()
this.loadOptions() this.refreshOptionsCache()
}) })
} }
} }

View File

@ -337,7 +337,7 @@ export default {
this.handleListOptions() this.handleListOptions()
}, },
methods: { methods: {
...mapActions(['loadOptions']), ...mapActions(['refreshOptionsCache']),
handleListLinks() { handleListLinks() {
this.table.loading = true this.table.loading = true
linkApi linkApi
@ -392,7 +392,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
_this.form.saving = false _this.form.saving = false
}, 200) }, 400)
_this.handleListLinks() _this.handleListLinks()
_this.handleListLinkTeams() _this.handleListLinkTeams()
}) })
@ -406,7 +406,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
_this.form.saving = false _this.form.saving = false
}, 200) }, 400)
_this.handleListLinks() _this.handleListLinks()
_this.handleListLinkTeams() _this.handleListLinkTeams()
}) })
@ -423,7 +423,7 @@ export default {
}) })
.finally(() => { .finally(() => {
this.handleListOptions() this.handleListOptions()
this.loadOptions() this.refreshOptionsCache()
}) })
} }
} }

View File

@ -109,6 +109,7 @@
showSizeChanger showSizeChanger
@change="handlePaginationChange" @change="handlePaginationChange"
@showSizeChange="handlePaginationChange" @showSizeChange="handlePaginationChange"
showLessItems
/> />
</div> </div>
<div style="position: fixed;bottom: 30px;right: 30px;"> <div style="position: fixed;bottom: 30px;right: 30px;">
@ -140,9 +141,9 @@
<a-input v-model="options.photos_title" /> <a-input v-model="options.photos_title" />
</a-form-item> </a-form-item>
<a-form-item label="每页显示条数:"> <a-form-item label="每页显示条数:">
<a-input <a-input-number
type="number"
v-model="options.photos_page_size" v-model="options.photos_page_size"
style="width:100%"
/> />
</a-form-item> </a-form-item>
</a-form> </a-form>
@ -353,7 +354,7 @@ export default {
this.hanldeListOptions() this.hanldeListOptions()
}, },
methods: { methods: {
...mapActions(['loadOptions']), ...mapActions(['refreshOptionsCache']),
hanldeListPhotos() { hanldeListPhotos() {
this.listLoading = true this.listLoading = true
this.queryParam.page = this.pagination.page - 1 this.queryParam.page = this.pagination.page - 1
@ -463,7 +464,7 @@ export default {
}) })
.finally(() => { .finally(() => {
this.hanldeListOptions() this.hanldeListOptions()
this.loadOptions() this.refreshOptionsCache()
}) })
} }
} }

View File

@ -317,7 +317,7 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.installing = false this.installing = false
}, 200) }, 400)
}) })
}, },
handleInstall() { handleInstall() {

View File

@ -16,6 +16,7 @@
:options="options" :options="options"
@onChange="onOptionsChange" @onChange="onOptionsChange"
@onSave="onSaveOptions" @onSave="onSaveOptions"
:saving="saving"
/> />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="seo"> <a-tab-pane key="seo">
@ -26,6 +27,7 @@
:options="options" :options="options"
@onChange="onOptionsChange" @onChange="onOptionsChange"
@onSave="onSaveOptions" @onSave="onSaveOptions"
:saving="saving"
/> />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="post"> <a-tab-pane key="post">
@ -36,6 +38,7 @@
:options="options" :options="options"
@onChange="onOptionsChange" @onChange="onOptionsChange"
@onSave="onSaveOptions" @onSave="onSaveOptions"
:saving="saving"
/> />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="comment"> <a-tab-pane key="comment">
@ -46,6 +49,7 @@
:options="options" :options="options"
@onChange="onOptionsChange" @onChange="onOptionsChange"
@onSave="onSaveOptions" @onSave="onSaveOptions"
:saving="saving"
/> />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="attachment"> <a-tab-pane key="attachment">
@ -56,6 +60,7 @@
:options="options" :options="options"
@onChange="onOptionsChange" @onChange="onOptionsChange"
@onSave="onSaveOptions" @onSave="onSaveOptions"
:saving="saving"
/> />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="smtp"> <a-tab-pane key="smtp">
@ -66,6 +71,7 @@
:options="options" :options="options"
@onChange="onOptionsChange" @onChange="onOptionsChange"
@onSave="onSaveOptions" @onSave="onSaveOptions"
:saving="saving"
/> />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="other"> <a-tab-pane key="other">
@ -76,6 +82,7 @@
:options="options" :options="options"
@onChange="onOptionsChange" @onChange="onOptionsChange"
@onSave="onSaveOptions" @onSave="onSaveOptions"
:saving="saving"
/> />
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
@ -93,6 +100,7 @@
:options="options" :options="options"
@onChange="onOptionsChange" @onChange="onOptionsChange"
@onSave="onSaveOptions" @onSave="onSaveOptions"
:saving="saving"
/> />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="api"> <a-tab-pane key="api">
@ -103,6 +111,7 @@
:options="options" :options="options"
@onChange="onOptionsChange" @onChange="onOptionsChange"
@onSave="onSaveOptions" @onSave="onSaveOptions"
:saving="saving"
/> />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="advanced-other"> <a-tab-pane key="advanced-other">
@ -113,6 +122,7 @@
:options="options" :options="options"
@onChange="onOptionsChange" @onChange="onOptionsChange"
@onSave="onSaveOptions" @onSave="onSaveOptions"
:saving="saving"
/> />
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
@ -166,14 +176,15 @@ export default {
data() { data() {
return { return {
options: {}, options: {},
advancedOptions: false advancedOptions: false,
saving: false
} }
}, },
created() { created() {
this.hanldeListOptions() this.hanldeListOptions()
}, },
methods: { methods: {
...mapActions(['loadUser', 'loadOptions']), ...mapActions(['refreshUserCache', 'refreshOptionsCache']),
hanldeListOptions() { hanldeListOptions() {
optionApi.listAll().then(response => { optionApi.listAll().then(response => {
this.options = response.data.data this.options = response.data.data
@ -183,15 +194,19 @@ export default {
this.options = val this.options = val
}, },
onSaveOptions() { onSaveOptions() {
this.saving = true
optionApi optionApi
.save(this.options) .save(this.options)
.then(response => { .then(response => {
this.$message.success('保存成功!') this.$message.success('保存成功!')
}) })
.finally(() => { .finally(() => {
setTimeout(() => {
this.saving = false
}, 400)
this.hanldeListOptions() this.hanldeListOptions()
this.loadOptions() this.refreshOptionsCache()
this.loadUser() this.refreshUserCache()
}) })
} }
} }

View File

@ -6,6 +6,7 @@
:visible="visible" :visible="visible"
destroyOnClose destroyOnClose
@close="onClose" @close="onClose"
:afterVisibleChange="handleAfterVisibleChanged"
> >
<a-row <a-row
type="flex" type="flex"
@ -33,8 +34,8 @@
type="link" type="link"
style="color: red" style="color: red"
icon="delete" icon="delete"
:loading="deleting" :loading="backup.deleting"
@click="handleBackupDeleteClick(backup.filename)" @click="handleBackupDeleteClick(backup)"
>删除</a-button> >删除</a-button>
<a-list-item-meta> <a-list-item-meta>
<a <a
@ -81,7 +82,6 @@ export default {
return { return {
backuping: false, backuping: false,
loading: false, loading: false,
deleting: false,
backups: [] backups: []
} }
}, },
@ -96,14 +96,12 @@ export default {
default: true default: true
} }
}, },
watch: { methods: {
visible: function(newValue, oldValue) { handleAfterVisibleChanged(visible) {
if (newValue) { if (visible) {
this.handleListBackups() this.handleListBackups()
} }
} },
},
methods: {
handleListBackups() { handleListBackups() {
this.loading = true this.loading = true
backupApi backupApi
@ -127,21 +125,21 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.backuping = false this.backuping = false
}, 200) }, 400)
this.handleListBackups() this.handleListBackups()
}) })
}, },
handleBackupDeleteClick(filename) { handleBackupDeleteClick(backup) {
this.deleting = true backup.deleting = true
backupApi backupApi
.deleteWorkDirBackup(filename) .deleteWorkDirBackup(backup.filename)
.then(response => { .then(response => {
this.$message.success('删除成功!') this.$message.success('删除成功!')
}) })
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.deleting = false backup.deleting = false
}, 200) }, 400)
this.handleListBackups() this.handleListBackups()
}) })
}, },

View File

@ -6,6 +6,7 @@
:visible="visible" :visible="visible"
destroyOnClose destroyOnClose
@close="onClose" @close="onClose"
:afterVisibleChange="handleAfterVisibleChanged"
> >
<a-row <a-row
type="flex" type="flex"
@ -33,8 +34,8 @@
type="link" type="link"
style="color: red" style="color: red"
icon="delete" icon="delete"
:loading="deleting" :loading="file.deleting"
@click="handleFileDeleteClick(file.filename)" @click="handleFileDeleteClick(file)"
>删除</a-button> >删除</a-button>
<a-list-item-meta> <a-list-item-meta>
<a <a
@ -81,7 +82,6 @@ export default {
return { return {
backuping: false, backuping: false,
loading: false, loading: false,
deleting: false,
files: [] files: []
} }
}, },
@ -96,14 +96,12 @@ export default {
default: true default: true
} }
}, },
watch: { methods: {
visible: function(newValue, oldValue) { handleAfterVisibleChanged(visible) {
if (newValue) { if (visible) {
this.handleListBackups() this.handleListBackups()
} }
} },
},
methods: {
handleListBackups() { handleListBackups() {
this.loading = true this.loading = true
backupApi backupApi
@ -127,21 +125,21 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.backuping = false this.backuping = false
}, 200) }, 400)
this.handleListBackups() this.handleListBackups()
}) })
}, },
handleFileDeleteClick(filename) { handleFileDeleteClick(file) {
this.deleting = true file.deleting = true
backupApi backupApi
.deleteExportedData(filename) .deleteExportedData(file.filename)
.then(response => { .then(response => {
this.$message.success('删除成功!') this.$message.success('删除成功!')
}) })
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.deleting = false file.deleting = false
}, 200) }, 400)
this.handleListBackups() this.handleListBackups()
}) })
}, },

View File

@ -127,6 +127,7 @@
showSizeChanger showSizeChanger
@showSizeChange="handlePaginationChange" @showSizeChange="handlePaginationChange"
@change="handlePaginationChange" @change="handlePaginationChange"
showLessItems
/> />
</div> </div>
</div> </div>
@ -245,7 +246,7 @@ export default {
this.hanldeListOptions() this.hanldeListOptions()
}, },
methods: { methods: {
...mapActions(['loadOptions']), ...mapActions(['refreshOptionsCache']),
hanldeListOptions() { hanldeListOptions() {
this.loading = true this.loading = true
this.queryParam.page = this.pagination.page - 1 this.queryParam.page = this.pagination.page - 1
@ -274,7 +275,7 @@ export default {
}) })
.finally(() => { .finally(() => {
this.hanldeListOptions() this.hanldeListOptions()
this.loadOptions() this.refreshOptionsCache()
}) })
}, },
handleEditOption(option) { handleEditOption(option) {
@ -321,7 +322,7 @@ export default {
}) })
.finally(() => { .finally(() => {
this.hanldeListOptions() this.hanldeListOptions()
this.loadOptions() this.refreshOptionsCache()
}) })
} else { } else {
this.optionToStage.type = this.optionType.CUSTOM.value this.optionToStage.type = this.optionType.CUSTOM.value
@ -334,7 +335,7 @@ export default {
}) })
.finally(() => { .finally(() => {
this.hanldeListOptions() this.hanldeListOptions()
this.loadOptions() this.refreshOptionsCache()
}) })
} }
} }

View File

@ -34,7 +34,7 @@ export default {
this.loadFormOptions() this.loadFormOptions()
}, },
methods: { methods: {
...mapActions(['loadOptions']), ...mapActions(['refreshOptionsCache']),
loadFormOptions() { loadFormOptions() {
optionApi.listAll().then(response => { optionApi.listAll().then(response => {
this.options = response.data.data this.options = response.data.data
@ -43,7 +43,7 @@ export default {
handleSaveOptions() { handleSaveOptions() {
optionApi.save(this.options).then(response => { optionApi.save(this.options).then(response => {
this.loadFormOptions() this.loadFormOptions()
this.loadOptions() this.refreshOptionsCache()
this.$message.success('保存成功!') this.$message.success('保存成功!')
if (!this.options.developer_mode) { if (!this.options.developer_mode) {
this.$router.push({ name: 'ToolList' }) this.$router.push({ name: 'ToolList' })

View File

@ -1,22 +1,26 @@
<template> <template>
<div> <div>
<a-form <a-form-model
ref="advancedOptionsForm"
:model="options"
:rules="rules"
layout="vertical" layout="vertical"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
> >
<a-form-item <a-form-model-item
label="全局绝对路径:" label="全局绝对路径:"
help="* 对网站上面的所有页面路径、本地附件路径、以及主题中的静态资源路径有效。" help="* 对网站上面的所有页面路径、本地附件路径、以及主题中的静态资源路径有效。"
> >
<a-switch v-model="options.global_absolute_path_enabled" /> <a-switch v-model="options.global_absolute_path_enabled" />
</a-form-item> </a-form-model-item>
<a-form-item> <a-form-model-item>
<a-button <a-button
type="primary" type="primary"
@click="handleSaveOptions" @click="handleSaveOptions"
:loading="saving"
>保存</a-button> >保存</a-button>
</a-form-item> </a-form-model-item>
</a-form> </a-form-model>
</div> </div>
</template> </template>
<script> <script>
@ -26,6 +30,10 @@ export default {
options: { options: {
type: Object, type: Object,
required: true required: true
},
saving: {
type: Boolean,
default: false
} }
}, },
data() { data() {
@ -35,7 +43,8 @@ export default {
lg: { span: 8 }, lg: { span: 8 },
sm: { span: 12 }, sm: { span: 12 },
xs: { span: 24 } xs: { span: 24 }
} },
rules: {}
} }
}, },
watch: { watch: {
@ -45,7 +54,12 @@ export default {
}, },
methods: { methods: {
handleSaveOptions() { handleSaveOptions() {
this.$emit('onSave') const _this = this
_this.$refs.advancedOptionsForm.validate(valid => {
if (valid) {
this.$emit('onSave')
}
})
} }
} }
} }

View File

@ -1,25 +1,29 @@
<template> <template>
<div> <div>
<a-form <a-form-model
ref="apiOptionsForm"
:model="options"
:rules="rules"
layout="vertical" layout="vertical"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
> >
<a-form-item label="API 服务:"> <a-form-model-item label="API 服务:">
<a-switch v-model="options.api_enabled" /> <a-switch v-model="options.api_enabled" />
</a-form-item> </a-form-model-item>
<a-form-item label="Access key"> <a-form-model-item label="Access key">
<a-input-password <a-input-password
v-model="options.api_access_key" v-model="options.api_access_key"
autocomplete="new-password" autocomplete="new-password"
/> />
</a-form-item> </a-form-model-item>
<a-form-item> <a-form-model-item>
<a-button <a-button
type="primary" type="primary"
@click="handleSaveOptions" @click="handleSaveOptions"
:loading="saving"
>保存</a-button> >保存</a-button>
</a-form-item> </a-form-model-item>
</a-form> </a-form-model>
</div> </div>
</template> </template>
<script> <script>
@ -29,6 +33,10 @@ export default {
options: { options: {
type: Object, type: Object,
required: true required: true
},
saving: {
type: Boolean,
default: false
} }
}, },
data() { data() {
@ -38,7 +46,8 @@ export default {
lg: { span: 8 }, lg: { span: 8 },
sm: { span: 12 }, sm: { span: 12 },
xs: { span: 24 } xs: { span: 24 }
} },
rules: {}
} }
}, },
watch: { watch: {
@ -58,7 +67,12 @@ export default {
return return
} }
} }
this.$emit('onSave') const _this = this
_this.$refs.apiOptionsForm.validate(valid => {
if (valid) {
this.$emit('onSave')
}
})
} }
} }
} }

View File

@ -1,25 +1,28 @@
<template> <template>
<div> <div>
<a-form <a-form-model
ref="attachmentOptionsForm"
:model="options"
:rules="rules"
layout="vertical" layout="vertical"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
> >
<a-form-item label="上传图片时预览:"> <a-form-model-item label="上传图片时预览:">
<a-switch v-model="options.attachment_upload_image_preview_enable" /> <a-switch v-model="options.attachment_upload_image_preview_enable" />
</a-form-item> </a-form-model-item>
<a-form-item label="最大上传文件数:"> <a-form-model-item label="最大上传文件数:">
<a-input <a-input-number
type="number"
v-model="options.attachment_upload_max_files" v-model="options.attachment_upload_max_files"
style="width:100%"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="同时上传文件数:"> <a-form-model-item label="同时上传文件数:">
<a-input <a-input-number
type="number"
v-model="options.attachment_upload_max_parallel_uploads" v-model="options.attachment_upload_max_parallel_uploads"
style="width:100%"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="存储位置:"> <a-form-model-item label="存储位置:">
<a-select v-model="options.attachment_type"> <a-select v-model="options.attachment_type">
<a-select-option <a-select-option
v-for="item in Object.keys(attachmentType)" v-for="item in Object.keys(attachmentType)"
@ -27,355 +30,356 @@
:value="item" :value="item"
>{{ attachmentType[item].text }}</a-select-option> >{{ attachmentType[item].text }}</a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-model-item>
<div <div
id="smmsForm" id="smmsForm"
v-show="options.attachment_type === 'SMMS'" v-show="options.attachment_type === 'SMMS'"
> >
<a-form-item label="Secret Token"> <a-form-model-item label="Secret Token">
<a-input-password <a-input-password
v-model="options.smms_api_secret_token" v-model="options.smms_api_secret_token"
placeholder="需要到 sm.ms 官网注册后获取" placeholder="需要到 sm.ms 官网注册后获取"
autocomplete="new-password" autocomplete="new-password"
/> />
</a-form-item> </a-form-model-item>
</div> </div>
<div <div
id="upOssForm" id="upOssForm"
v-show="options.attachment_type === 'UPOSS'" v-show="options.attachment_type === 'UPOSS'"
> >
<a-form-item label="绑定域名协议:"> <a-form-model-item label="绑定域名协议:">
<a-select v-model="options.oss_upyun_domain_protocol"> <a-select v-model="options.oss_upyun_domain_protocol">
<a-select-option value="https://">HTTPS</a-select-option> <a-select-option value="https://">HTTPS</a-select-option>
<a-select-option value="http://">HTTP</a-select-option> <a-select-option value="http://">HTTP</a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-model-item>
<a-form-item label="绑定域名:"> <a-form-model-item label="绑定域名:">
<a-input <a-input
v-model="options.oss_upyun_domain" v-model="options.oss_upyun_domain"
placeholder="无需再加上 http:// 或者 https://" placeholder="无需再加上 http:// 或者 https://"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="空间名称:"> <a-form-model-item label="空间名称:">
<a-input v-model="options.oss_upyun_bucket" /> <a-input v-model="options.oss_upyun_bucket" />
</a-form-item> </a-form-model-item>
<a-form-item label="操作员名称:"> <a-form-model-item label="操作员名称:">
<a-input v-model="options.oss_upyun_operator" /> <a-input v-model="options.oss_upyun_operator" />
</a-form-item> </a-form-model-item>
<a-form-item label="操作员密码:"> <a-form-model-item label="操作员密码:">
<a-input-password <a-input-password
v-model="options.oss_upyun_password" v-model="options.oss_upyun_password"
autocomplete="new-password" autocomplete="new-password"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="文件目录:"> <a-form-model-item label="文件目录:">
<a-input v-model="options.oss_upyun_source" /> <a-input v-model="options.oss_upyun_source" />
</a-form-item> </a-form-model-item>
<a-form-item label="图片处理策略:"> <a-form-model-item label="图片处理策略:">
<a-input <a-input
v-model="options.oss_upyun_style_rule" v-model="options.oss_upyun_style_rule"
placeholder="间隔标识符+图片处理版本名称" placeholder="间隔标识符+图片处理版本名称"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="缩略图处理策略:"> <a-form-model-item label="缩略图处理策略:">
<a-input <a-input
v-model="options.oss_upyun_thumbnail_style_rule" v-model="options.oss_upyun_thumbnail_style_rule"
placeholder="间隔标识符+图片处理版本名称,一般为后台展示所用" placeholder="间隔标识符+图片处理版本名称,一般为后台展示所用"
/> />
</a-form-item> </a-form-model-item>
</div> </div>
<div <div
id="qiniuOssForm" id="qiniuOssForm"
v-show="options.attachment_type === 'QINIUOSS'" v-show="options.attachment_type === 'QINIUOSS'"
> >
<a-form-item label="绑定域名协议:"> <a-form-model-item label="绑定域名协议:">
<a-select v-model="options.oss_qiniu_domain_protocol"> <a-select v-model="options.oss_qiniu_domain_protocol">
<a-select-option value="https://">HTTPS</a-select-option> <a-select-option value="https://">HTTPS</a-select-option>
<a-select-option value="http://">HTTP</a-select-option> <a-select-option value="http://">HTTP</a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-model-item>
<a-form-item label="绑定域名:"> <a-form-model-item label="绑定域名:">
<a-input <a-input
v-model="options.oss_qiniu_domain" v-model="options.oss_qiniu_domain"
placeholder="无需再加上 http:// 或者 https://" placeholder="无需再加上 http:// 或者 https://"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="区域:"> <a-form-model-item label="区域:">
<a-auto-complete <a-auto-complete
:dataSource="qiniuOssZones" :dataSource="qiniuOssZones"
v-model="options.oss_qiniu_zone" v-model="options.oss_qiniu_zone"
allowClear allowClear
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="Access Key"> <a-form-model-item label="Access Key">
<a-input-password <a-input-password
v-model="options.oss_qiniu_access_key" v-model="options.oss_qiniu_access_key"
autocomplete="new-password" autocomplete="new-password"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="Secret Key"> <a-form-model-item label="Secret Key">
<a-input-password <a-input-password
v-model="options.oss_qiniu_secret_key" v-model="options.oss_qiniu_secret_key"
autocomplete="new-password" autocomplete="new-password"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="文件目录:"> <a-form-model-item label="文件目录:">
<a-input <a-input
v-model="options.oss_qiniu_source" v-model="options.oss_qiniu_source"
placeholder="不填写则上传到根目录" placeholder="不填写则上传到根目录"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="Bucket"> <a-form-model-item label="Bucket">
<a-input <a-input
v-model="options.oss_qiniu_bucket" v-model="options.oss_qiniu_bucket"
placeholder="存储空间名称" placeholder="存储空间名称"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="图片处理策略:"> <a-form-model-item label="图片处理策略:">
<a-input <a-input
v-model="options.oss_qiniu_style_rule" v-model="options.oss_qiniu_style_rule"
placeholder="样式分隔符+图片处理样式名称" placeholder="样式分隔符+图片处理样式名称"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="缩略图处理策略:"> <a-form-model-item label="缩略图处理策略:">
<a-input <a-input
v-model="options.oss_qiniu_thumbnail_style_rule" v-model="options.oss_qiniu_thumbnail_style_rule"
placeholder="样式分隔符+图片处理样式名称,一般为后台展示所用" placeholder="样式分隔符+图片处理样式名称,一般为后台展示所用"
/> />
</a-form-item> </a-form-model-item>
</div> </div>
<div <div
id="aliOssForm" id="aliOssForm"
v-show="options.attachment_type === 'ALIOSS'" v-show="options.attachment_type === 'ALIOSS'"
> >
<a-form-item label="绑定域名协议:"> <a-form-model-item label="绑定域名协议:">
<a-select v-model="options.oss_ali_domain_protocol"> <a-select v-model="options.oss_ali_domain_protocol">
<a-select-option value="https://">HTTPS</a-select-option> <a-select-option value="https://">HTTPS</a-select-option>
<a-select-option value="http://">HTTP</a-select-option> <a-select-option value="http://">HTTP</a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-model-item>
<a-form-item label="绑定域名:"> <a-form-model-item label="绑定域名:">
<a-input <a-input
v-model="options.oss_ali_domain" v-model="options.oss_ali_domain"
placeholder="如不填写,路径根域名将为 Bucket + EndPoint" placeholder="如不填写,路径根域名将为 Bucket + EndPoint"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="Bucket"> <a-form-model-item label="Bucket">
<a-input <a-input
v-model="options.oss_ali_bucket_name" v-model="options.oss_ali_bucket_name"
placeholder="存储空间名称" placeholder="存储空间名称"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="EndPoint地域节点"> <a-form-model-item label="EndPoint地域节点">
<a-input v-model="options.oss_ali_endpoint" /> <a-input v-model="options.oss_ali_endpoint" />
</a-form-item> </a-form-model-item>
<a-form-item label="Access Key"> <a-form-model-item label="Access Key">
<a-input-password <a-input-password
v-model="options.oss_ali_access_key" v-model="options.oss_ali_access_key"
autocomplete="new-password" autocomplete="new-password"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="Access Secret"> <a-form-model-item label="Access Secret">
<a-input-password <a-input-password
v-model="options.oss_ali_access_secret" v-model="options.oss_ali_access_secret"
autocomplete="new-password" autocomplete="new-password"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="文件目录:"> <a-form-model-item label="文件目录:">
<a-input <a-input
v-model="options.oss_ali_source" v-model="options.oss_ali_source"
placeholder="不填写则上传到根目录" placeholder="不填写则上传到根目录"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="图片处理策略:"> <a-form-model-item label="图片处理策略:">
<a-input <a-input
v-model="options.oss_ali_style_rule" v-model="options.oss_ali_style_rule"
placeholder="请到阿里云控制台的图片处理获取" placeholder="请到阿里云控制台的图片处理获取"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="缩略图处理策略:"> <a-form-model-item label="缩略图处理策略:">
<a-input <a-input
v-model="options.oss_ali_thumbnail_style_rule" v-model="options.oss_ali_thumbnail_style_rule"
placeholder="请到阿里云控制台的图片处理获取,一般为后台展示所用" placeholder="请到阿里云控制台的图片处理获取,一般为后台展示所用"
/> />
</a-form-item> </a-form-model-item>
</div> </div>
<div <div
id="baiduBosForm" id="baiduBosForm"
v-show="options.attachment_type === 'BAIDUBOS'" v-show="options.attachment_type === 'BAIDUBOS'"
> >
<a-form-item label="绑定域名协议:"> <a-form-model-item label="绑定域名协议:">
<a-select v-model="options.bos_baidu_domain_protocol"> <a-select v-model="options.bos_baidu_domain_protocol">
<a-select-option value="https://">HTTPS</a-select-option> <a-select-option value="https://">HTTPS</a-select-option>
<a-select-option value="http://">HTTP</a-select-option> <a-select-option value="http://">HTTP</a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-model-item>
<a-form-item label="绑定域名:"> <a-form-model-item label="绑定域名:">
<a-input <a-input
v-model="options.bos_baidu_domain" v-model="options.bos_baidu_domain"
placeholder="如不填写,路径根域名将为 Bucket + EndPoint" placeholder="如不填写,路径根域名将为 Bucket + EndPoint"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="Bucket"> <a-form-model-item label="Bucket">
<a-input <a-input
v-model="options.bos_baidu_bucket_name" v-model="options.bos_baidu_bucket_name"
placeholder="存储空间名称" placeholder="存储空间名称"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="EndPoint地域节点"> <a-form-model-item label="EndPoint地域节点">
<a-input v-model="options.bos_baidu_endpoint" /> <a-input v-model="options.bos_baidu_endpoint" />
</a-form-item> </a-form-model-item>
<a-form-item label="Access Key"> <a-form-model-item label="Access Key">
<a-input-password <a-input-password
v-model="options.bos_baidu_access_key" v-model="options.bos_baidu_access_key"
autocomplete="new-password" autocomplete="new-password"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="Secret Key"> <a-form-model-item label="Secret Key">
<a-input-password <a-input-password
v-model="options.bos_baidu_secret_key" v-model="options.bos_baidu_secret_key"
autocomplete="new-password" autocomplete="new-password"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="图片处理策略:"> <a-form-model-item label="图片处理策略:">
<a-input <a-input
v-model="options.bos_baidu_style_rule" v-model="options.bos_baidu_style_rule"
placeholder="请到百度云控制台的图片处理获取" placeholder="请到百度云控制台的图片处理获取"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="缩略图处理策略:"> <a-form-model-item label="缩略图处理策略:">
<a-input <a-input
v-model="options.bos_baidu_thumbnail_style_rule" v-model="options.bos_baidu_thumbnail_style_rule"
placeholder="请到百度云控制台的图片处理获取,一般为后台展示所用" placeholder="请到百度云控制台的图片处理获取,一般为后台展示所用"
/> />
</a-form-item> </a-form-model-item>
</div> </div>
<div <div
id="tencentCosForm" id="tencentCosForm"
v-show="options.attachment_type === 'TENCENTCOS'" v-show="options.attachment_type === 'TENCENTCOS'"
> >
<a-form-item label="绑定域名协议:"> <a-form-model-item label="绑定域名协议:">
<a-select v-model="options.cos_tencent_domain_protocol"> <a-select v-model="options.cos_tencent_domain_protocol">
<a-select-option value="https://">HTTPS</a-select-option> <a-select-option value="https://">HTTPS</a-select-option>
<a-select-option value="http://">HTTP</a-select-option> <a-select-option value="http://">HTTP</a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-model-item>
<a-form-item label="绑定域名:"> <a-form-model-item label="绑定域名:">
<a-input <a-input
v-model="options.cos_tencent_domain" v-model="options.cos_tencent_domain"
placeholder="如不填写,路径根域名将为 Bucket + 区域地址" placeholder="如不填写,路径根域名将为 Bucket + 区域地址"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="Bucket"> <a-form-model-item label="Bucket">
<a-input <a-input
v-model="options.cos_tencent_bucket_name" v-model="options.cos_tencent_bucket_name"
placeholder="存储桶名称" placeholder="存储桶名称"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="区域:"> <a-form-model-item label="区域:">
<a-auto-complete <a-auto-complete
:dataSource="tencentCosRegions" :dataSource="tencentCosRegions"
v-model="options.cos_tencent_region" v-model="options.cos_tencent_region"
allowClear allowClear
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="Secret Id"> <a-form-model-item label="Secret Id">
<a-input-password <a-input-password
v-model="options.cos_tencent_secret_id" v-model="options.cos_tencent_secret_id"
autocomplete="new-password" autocomplete="new-password"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="Secret Key"> <a-form-model-item label="Secret Key">
<a-input-password <a-input-password
v-model="options.cos_tencent_secret_key" v-model="options.cos_tencent_secret_key"
autocomplete="new-password" autocomplete="new-password"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="文件目录:"> <a-form-model-item label="文件目录:">
<a-input <a-input
v-model="options.cos_tencent_source" v-model="options.cos_tencent_source"
placeholder="不填写则上传到根目录" placeholder="不填写则上传到根目录"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="图片处理策略:"> <a-form-model-item label="图片处理策略:">
<a-input <a-input
v-model="options.cos_tencent_style_rule" v-model="options.cos_tencent_style_rule"
placeholder="请到腾讯云控制台的图片处理获取" placeholder="请到腾讯云控制台的图片处理获取"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="缩略图处理策略:"> <a-form-model-item label="缩略图处理策略:">
<a-input <a-input
v-model="options.cos_tencent_thumbnail_style_rule" v-model="options.cos_tencent_thumbnail_style_rule"
placeholder="请到腾讯云控制台的图片处理获取,一般为后台展示所用" placeholder="请到腾讯云控制台的图片处理获取,一般为后台展示所用"
/> />
</a-form-item> </a-form-model-item>
</div> </div>
<div <div
id="huaweiObsForm" id="huaweiObsForm"
v-show="options.attachment_type === 'HUAWEIOBS'" v-show="options.attachment_type === 'HUAWEIOBS'"
> >
<a-form-item label="绑定域名协议:"> <a-form-model-item label="绑定域名协议:">
<a-select v-model="options.obs_huawei_domain_protocol"> <a-select v-model="options.obs_huawei_domain_protocol">
<a-select-option value="https://">HTTPS</a-select-option> <a-select-option value="https://">HTTPS</a-select-option>
<a-select-option value="http://">HTTP</a-select-option> <a-select-option value="http://">HTTP</a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-model-item>
<a-form-item label="绑定域名:"> <a-form-model-item label="绑定域名:">
<a-input <a-input
v-model="options.obs_huawei_domain" v-model="options.obs_huawei_domain"
placeholder="如不填写,路径根域名将为 Bucket + EndPoint" placeholder="如不填写,路径根域名将为 Bucket + EndPoint"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="Bucket桶名称"> <a-form-model-item label="Bucket桶名称">
<a-input <a-input
v-model="options.obs_huawei_bucket_name" v-model="options.obs_huawei_bucket_name"
placeholder="桶名称" placeholder="桶名称"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="EndPoint终端节点"> <a-form-model-item label="EndPoint终端节点">
<a-input <a-input
v-model="options.obs_huawei_endpoint" v-model="options.obs_huawei_endpoint"
placeholder="Endpoint" placeholder="Endpoint"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="Access Key"> <a-form-model-item label="Access Key">
<a-input-password <a-input-password
v-model="options.obs_huawei_access_key" v-model="options.obs_huawei_access_key"
autocomplete="new-password" autocomplete="new-password"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="Access Secret"> <a-form-model-item label="Access Secret">
<a-input-password <a-input-password
v-model="options.obs_huawei_access_secret" v-model="options.obs_huawei_access_secret"
autocomplete="new-password" autocomplete="new-password"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="文件目录:"> <a-form-model-item label="文件目录:">
<a-input <a-input
v-model="options.obs_huawei_source" v-model="options.obs_huawei_source"
placeholder="不填写则上传到根目录" placeholder="不填写则上传到根目录"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="图片处理策略:"> <a-form-model-item label="图片处理策略:">
<a-input <a-input
v-model="options.obs_huawei_style_rule" v-model="options.obs_huawei_style_rule"
placeholder="请到华为云控制台的图片处理创建" placeholder="请到华为云控制台的图片处理创建"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="缩略图处理策略:"> <a-form-model-item label="缩略图处理策略:">
<a-input <a-input
v-model="options.obs_huawei_thumbnail_style_rule" v-model="options.obs_huawei_thumbnail_style_rule"
placeholder="请到华为云控制台的图片处理获取,一般为后台展示所用" placeholder="请到华为云控制台的图片处理获取,一般为后台展示所用"
/> />
</a-form-item> </a-form-model-item>
</div> </div>
<a-form-item> <a-form-model-item>
<a-button <a-button
type="primary" type="primary"
@click="handleSaveOptions" @click="handleSaveOptions"
:loading="saving"
>保存</a-button> >保存</a-button>
</a-form-item> </a-form-model-item>
</a-form> </a-form-model>
</div> </div>
</template> </template>
<script> <script>
@ -438,6 +442,10 @@ export default {
options: { options: {
type: Object, type: Object,
required: true required: true
},
saving: {
type: Boolean,
default: false
} }
}, },
data() { data() {
@ -450,7 +458,8 @@ export default {
xs: { span: 24 } xs: { span: 24 }
}, },
tencentCosRegions, tencentCosRegions,
qiniuOssZones qiniuOssZones,
rules: {}
} }
}, },
watch: { watch: {
@ -659,7 +668,12 @@ export default {
} }
break break
} }
this.$emit('onSave') const _this = this
_this.$refs.attachmentOptionsForm.validate(valid => {
if (valid) {
this.$emit('onSave')
}
})
} }
} }
} }

View File

@ -1,10 +1,13 @@
<template> <template>
<div> <div>
<a-form <a-form-model
ref="commentOptionsForm"
:model="options"
:rules="rules"
layout="vertical" layout="vertical"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
> >
<a-form-item label="评论者头像:"> <a-form-model-item label="评论者头像:">
<a-select v-model="options.comment_gravatar_default"> <a-select v-model="options.comment_gravatar_default">
<a-select-option value="mm">默认</a-select-option> <a-select-option value="mm">默认</a-select-option>
<a-select-option value="identicon">抽象几何图形</a-select-option> <a-select-option value="identicon">抽象几何图形</a-select-option>
@ -14,40 +17,40 @@
<a-select-option value="robohash">机器人</a-select-option> <a-select-option value="robohash">机器人</a-select-option>
<a-select-option value="blank">不显示头像</a-select-option> <a-select-option value="blank">不显示头像</a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-model-item>
<a-form-item label="评论审核后才显示:"> <a-form-model-item label="评论审核后才显示:">
<a-switch v-model="options.comment_new_need_check" /> <a-switch v-model="options.comment_new_need_check" />
</a-form-item> </a-form-model-item>
<a-form-item label="新评论通知:"> <a-form-model-item label="新评论通知:">
<a-switch v-model="options.comment_new_notice" /> <a-switch v-model="options.comment_new_notice" />
</a-form-item> </a-form-model-item>
<a-form-item label="评论回复通知对方:"> <a-form-model-item label="评论回复通知对方:">
<a-switch v-model="options.comment_reply_notice" /> <a-switch v-model="options.comment_reply_notice" />
</a-form-item> </a-form-model-item>
<a-form-item <a-form-model-item
label="API 评论开关:" label="API 评论开关:"
help="* 关闭之后将无法进行评论" help="* 关闭之后将无法进行评论"
> >
<a-switch v-model="options.comment_api_enabled" /> <a-switch v-model="options.comment_api_enabled" />
</a-form-item> </a-form-model-item>
<a-form-item label="评论模块 JS"> <a-form-model-item label="评论模块 JS">
<a-input <a-input
type="textarea" type="textarea"
:autoSize="{ minRows: 2 }" :autoSize="{ minRows: 2 }"
v-model="options.comment_internal_plugin_js" v-model="options.comment_internal_plugin_js"
placeholder="该设置仅对内置的评论模块有效" placeholder="该设置仅对内置的评论模块有效"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="每页显示条数: "> <a-form-model-item label="每页显示条数: ">
<a-input <a-input-number
type="number"
v-model="options.comment_page_size" v-model="options.comment_page_size"
style="width:100%"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="占位提示:"> <a-form-model-item label="占位提示:">
<a-input v-model="options.comment_content_placeholder" /> <a-input v-model="options.comment_content_placeholder" />
</a-form-item> </a-form-model-item>
<!-- <a-form-item <!-- <a-form-model-item
label="自定义样式:" label="自定义样式:"
> >
@ -56,14 +59,15 @@
:autoSize="{ minRows: 5 }" :autoSize="{ minRows: 5 }"
v-model="options.comment_custom_style" v-model="options.comment_custom_style"
/> />
</a-form-item> --> </a-form-model-item> -->
<a-form-item> <a-form-model-item>
<a-button <a-button
type="primary" type="primary"
@click="handleSaveOptions" @click="handleSaveOptions"
:loading="saving"
>保存</a-button> >保存</a-button>
</a-form-item> </a-form-model-item>
</a-form> </a-form-model>
</div> </div>
</template> </template>
<script> <script>
@ -73,6 +77,10 @@ export default {
options: { options: {
type: Object, type: Object,
required: true required: true
},
saving: {
type: Boolean,
default: false
} }
}, },
data() { data() {
@ -82,7 +90,8 @@ export default {
lg: { span: 8 }, lg: { span: 8 },
sm: { span: 12 }, sm: { span: 12 },
xs: { span: 24 } xs: { span: 24 }
} },
rules: {}
} }
}, },
watch: { watch: {
@ -102,7 +111,12 @@ export default {
return return
} }
} }
this.$emit('onSave') const _this = this
_this.$refs.commentOptionsForm.validate(valid => {
if (valid) {
this.$emit('onSave')
}
})
} }
} }
} }

View File

@ -1,65 +1,79 @@
<template> <template>
<div> <div>
<a-form <a-form-model
ref="generalOptionsForm"
:model="options"
:rules="rules"
layout="vertical" layout="vertical"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
> >
<a-form-item label="博客标题:"> <a-form-model-item
label="博客标题:"
prop="blog_title"
>
<a-input v-model="options.blog_title" /> <a-input v-model="options.blog_title" />
</a-form-item> </a-form-model-item>
<a-form-item label="博客地址:"> <a-form-model-item
label="博客地址:"
prop="blog_url"
>
<a-input <a-input
v-model="options.blog_url" v-model="options.blog_url"
placeholder="如https://halo.run" placeholder="如https://halo.run"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="Logo"> <a-form-model-item
label="Logo"
prop="blog_logo"
>
<a-input v-model="options.blog_logo"> <a-input v-model="options.blog_logo">
<a <a
href="javascript:void(0);" href="javascript:void(0);"
slot="addonAfter" slot="addonAfter"
@click="logoDrawerVisible = true" @click="handleShowLogoSelector"
> >
<a-icon type="picture" /> <a-icon type="picture" />
</a> </a>
</a-input> </a-input>
</a-form-item> </a-form-model-item>
<a-form-item label="Favicon"> <a-form-model-item
label="Favicon"
prop="blog_favicon"
>
<a-input v-model="options.blog_favicon"> <a-input v-model="options.blog_favicon">
<a <a
href="javascript:void(0);" href="javascript:void(0);"
slot="addonAfter" slot="addonAfter"
@click="faviconDrawerVisible = true" @click="handleShowFaviconSelector"
> >
<a-icon type="picture" /> <a-icon type="picture" />
</a> </a>
</a-input> </a-input>
</a-form-item> </a-form-model-item>
<a-form-item label="页脚信息:"> <a-form-model-item
label="页脚信息:"
prop="blog_footer_info"
>
<a-input <a-input
type="textarea" type="textarea"
:autoSize="{ minRows: 5 }" :autoSize="{ minRows: 5 }"
v-model="options.blog_footer_info" v-model="options.blog_footer_info"
placeholder="支持 HTML 格式的文本" placeholder="支持 HTML 格式的文本"
/> />
</a-form-item> </a-form-model-item>
<a-form-item> <a-form-model-item>
<a-button <a-button
type="primary" type="primary"
@click="handleSaveOptions" @click="handleSaveOptions"
:loading="saving"
>保存</a-button> >保存</a-button>
</a-form-item> </a-form-model-item>
</a-form> </a-form-model>
<AttachmentSelectDrawer <AttachmentSelectDrawer
v-model="logoDrawerVisible" v-model="attachmentSelector.visible"
@listenToSelect="handleSelectLogo" @listenToSelect="handleSelectAttachment"
title="选择 Logo" :title="attachmentSelectorTitle"
/>
<AttachmentSelectDrawer
v-model="faviconDrawerVisible"
@listenToSelect="handleSelectFavicon"
title="选择 Favicon"
/> />
</div> </div>
</template> </template>
@ -71,6 +85,10 @@ export default {
options: { options: {
type: Object, type: Object,
required: true required: true
},
saving: {
type: Boolean,
default: false
} }
}, },
data() { data() {
@ -81,24 +99,49 @@ export default {
sm: { span: 12 }, sm: { span: 12 },
xs: { span: 24 } xs: { span: 24 }
}, },
logoDrawerVisible: false, attachmentSelector: {
faviconDrawerVisible: false visible: false,
field: ''
},
rules: {
blog_title: [
{ required: true, message: '* 博客标题不能为空', trigger: ['change', 'blur'] },
{ max: 1023, message: '* 字符数不能超过 1023', trigger: ['change', 'blur'] }
],
blog_url: [
{ required: true, message: '* 博客地址不能为空', trigger: ['change', 'blur'] },
{ max: 1023, message: '* 字符数不能超过 1023', trigger: ['change', 'blur'] }
],
blog_logo: [
{ type: 'url', message: '* 链接格式不正确', trigger: ['change', 'blur'] },
{ max: 1023, message: '* 字符数不能超过 1023', trigger: ['change', 'blur'] }
],
blog_favicon: [
{ type: 'url', message: '* 链接格式不正确', trigger: ['change', 'blur'] },
{ max: 1023, message: '* 字符数不能超过 1023', trigger: ['change', 'blur'] }
],
blog_footer_info: [{ max: 1023, message: '* 字符数不能超过 1023', trigger: ['change', 'blur'] }]
}
}
},
computed: {
attachmentSelectorTitle() {
if (this.attachmentSelector.field === 'blog_logo') {
return '选择 Logo'
} else if (this.attachmentSelector.field === 'blog_favicon') {
return '选择 Favicon'
}
return ''
} }
}, },
destroyed: function() { destroyed: function() {
if (this.faviconDrawerVisible) { if (this.attachmentSelector.visible) {
this.faviconDrawerVisible = false this.attachmentSelector.visible = false
}
if (this.logoDrawerVisible) {
this.logoDrawerVisible = false
} }
}, },
beforeRouteLeave(to, from, next) { beforeRouteLeave(to, from, next) {
if (this.faviconDrawerVisible) { if (this.attachmentSelector.visible) {
this.faviconDrawerVisible = false this.attachmentSelector.visible = false
}
if (this.logoDrawerVisible) {
this.logoDrawerVisible = false
} }
next() next()
}, },
@ -109,30 +152,24 @@ export default {
}, },
methods: { methods: {
handleSaveOptions() { handleSaveOptions() {
if (!this.options.blog_title) { const _this = this
this.$notification['error']({ _this.$refs.generalOptionsForm.validate(valid => {
message: '提示', if (valid) {
description: '博客标题不能为空!' this.$emit('onSave')
}) }
return })
}
if (!this.options.blog_url) {
this.$notification['error']({
message: '提示',
description: '博客地址不能为空!'
})
return
}
this.$emit('onSave')
}, },
handleSelectLogo(data) { handleShowLogoSelector() {
this.$set(this.options, 'blog_logo', encodeURI(data.path)) this.attachmentSelector.field = 'blog_logo'
this.logoDrawerVisible = false this.attachmentSelector.visible = true
}, },
handleSelectFavicon(data) { handleShowFaviconSelector() {
this.$set(this.options, 'blog_favicon', encodeURI(data.path)) this.attachmentSelector.field = 'blog_favicon'
this.faviconDrawerVisible = false this.attachmentSelector.visible = true
},
handleSelectAttachment(attachment) {
this.$set(this.options, this.attachmentSelector.field, encodeURI(attachment.path))
this.attachmentSelector.visible = false
} }
} }
} }

View File

@ -1,34 +1,37 @@
<template> <template>
<div> <div>
<a-form <a-form-model
ref="otherOptionsForm"
:model="options"
:rules="rules"
layout="vertical" layout="vertical"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
> >
<a-form-item label="自定义全局 head"> <a-form-model-item label="自定义全局 head">
<a-input <a-input
type="textarea" type="textarea"
:autoSize="{ minRows: 5 }" :autoSize="{ minRows: 5 }"
v-model="options.blog_custom_head" v-model="options.blog_custom_head"
placeholder="放置于每个页面的 <head></head> 标签中" placeholder="放置于每个页面的 <head></head> 标签中"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="自定义内容页 head"> <a-form-model-item label="自定义内容页 head">
<a-input <a-input
type="textarea" type="textarea"
:autoSize="{ minRows: 5 }" :autoSize="{ minRows: 5 }"
v-model="options.blog_custom_content_head" v-model="options.blog_custom_content_head"
placeholder="仅放置于内容页面的 <head></head> 标签中" placeholder="仅放置于内容页面的 <head></head> 标签中"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="统计代码:"> <a-form-model-item label="统计代码:">
<a-input <a-input
type="textarea" type="textarea"
:autoSize="{ minRows: 5 }" :autoSize="{ minRows: 5 }"
v-model="options.blog_statistics_code" v-model="options.blog_statistics_code"
placeholder="第三方网站统计的代码Google Analytics、百度统计、CNZZ 等" placeholder="第三方网站统计的代码Google Analytics、百度统计、CNZZ 等"
/> />
</a-form-item> </a-form-model-item>
<!-- <a-form-item <!-- <a-form-model-item
label="黑名单 IP" label="黑名单 IP"
> >
@ -38,14 +41,15 @@
v-model="options.blog_ip_blacklist" v-model="options.blog_ip_blacklist"
placeholder="多个 IP 地址换行隔开" placeholder="多个 IP 地址换行隔开"
/> />
</a-form-item> --> </a-form-model-item> -->
<a-form-item> <a-form-model-item>
<a-button <a-button
type="primary" type="primary"
@click="handleSaveOptions" @click="handleSaveOptions"
:loading="saving"
>保存</a-button> >保存</a-button>
</a-form-item> </a-form-model-item>
</a-form> </a-form-model>
</div> </div>
</template> </template>
<script> <script>
@ -55,6 +59,10 @@ export default {
options: { options: {
type: Object, type: Object,
required: true required: true
},
saving: {
type: Boolean,
default: false
} }
}, },
data() { data() {
@ -64,7 +72,8 @@ export default {
lg: { span: 8 }, lg: { span: 8 },
sm: { span: 12 }, sm: { span: 12 },
xs: { span: 24 } xs: { span: 24 }
} },
rules: {}
} }
}, },
watch: { watch: {
@ -74,7 +83,12 @@ export default {
}, },
methods: { methods: {
handleSaveOptions() { handleSaveOptions() {
this.$emit('onSave') const _this = this
_this.$refs.otherOptionsForm.validate(valid => {
if (valid) {
this.$emit('onSave')
}
})
} }
} }
} }

View File

@ -1,10 +1,13 @@
<template> <template>
<div> <div>
<a-form <a-form-model
ref="permalinkOptionsForm"
:model="options"
:rules="rules"
layout="vertical" layout="vertical"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
> >
<a-form-item label="文章固定链接类型:"> <a-form-model-item label="文章固定链接类型:">
<template slot="help"> <template slot="help">
<span v-if="options.post_permalink_type === 'DEFAULT'">{{ options.blog_url }}/{{ options.archives_prefix }}/${slug}{{ options.path_suffix }}</span> <span v-if="options.post_permalink_type === 'DEFAULT'">{{ options.blog_url }}/{{ options.archives_prefix }}/${slug}{{ options.path_suffix }}</span>
<span v-else-if="options.post_permalink_type === 'DATE'">{{ options.blog_url }}{{ new Date() | moment_post_date }}${slug}{{ options.path_suffix }}</span> <span v-else-if="options.post_permalink_type === 'DATE'">{{ options.blog_url }}{{ new Date() | moment_post_date }}${slug}{{ options.path_suffix }}</span>
@ -18,62 +21,63 @@
:value="item" :value="item"
>{{ permalinkType[item].text }}</a-select-option> >{{ permalinkType[item].text }}</a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-model-item>
<a-form-item label="自定义页面前缀:"> <a-form-model-item label="自定义页面前缀:">
<template slot="help"> <template slot="help">
<span>{{ options.blog_url }}/{{ options.sheet_prefix }}/${slug}{{ options.path_suffix }}</span> <span>{{ options.blog_url }}/{{ options.sheet_prefix }}/${slug}{{ options.path_suffix }}</span>
</template> </template>
<a-input v-model="options.sheet_prefix" /> <a-input v-model="options.sheet_prefix" />
</a-form-item> </a-form-model-item>
<a-form-item label="友情链接页面前缀:"> <a-form-model-item label="友情链接页面前缀:">
<template slot="help"> <template slot="help">
<span>{{ options.blog_url }}/{{ options.links_prefix }}{{ options.path_suffix }}</span> <span>{{ options.blog_url }}/{{ options.links_prefix }}{{ options.path_suffix }}</span>
</template> </template>
<a-input v-model="options.links_prefix" /> <a-input v-model="options.links_prefix" />
</a-form-item> </a-form-model-item>
<a-form-item label="图库页面前缀:"> <a-form-model-item label="图库页面前缀:">
<template slot="help"> <template slot="help">
<span>{{ options.blog_url }}/{{ options.photos_prefix }}{{ options.path_suffix }}</span> <span>{{ options.blog_url }}/{{ options.photos_prefix }}{{ options.path_suffix }}</span>
</template> </template>
<a-input v-model="options.photos_prefix" /> <a-input v-model="options.photos_prefix" />
</a-form-item> </a-form-model-item>
<a-form-item label="日志页面前缀:"> <a-form-model-item label="日志页面前缀:">
<template slot="help"> <template slot="help">
<span>{{ options.blog_url }}/{{ options.journals_prefix }}{{ options.path_suffix }}</span> <span>{{ options.blog_url }}/{{ options.journals_prefix }}{{ options.path_suffix }}</span>
</template> </template>
<a-input v-model="options.journals_prefix" /> <a-input v-model="options.journals_prefix" />
</a-form-item> </a-form-model-item>
<a-form-item label="归档前缀:"> <a-form-model-item label="归档前缀:">
<template slot="help"> <template slot="help">
<span>{{ options.blog_url }}/{{ options.archives_prefix }}{{ options.path_suffix }}</span> <span>{{ options.blog_url }}/{{ options.archives_prefix }}{{ options.path_suffix }}</span>
</template> </template>
<a-input v-model="options.archives_prefix" /> <a-input v-model="options.archives_prefix" />
</a-form-item> </a-form-model-item>
<a-form-item label="分类前缀:"> <a-form-model-item label="分类前缀:">
<template slot="help"> <template slot="help">
<span>{{ options.blog_url }}/{{ options.categories_prefix }}/${slug}{{ options.path_suffix }}</span> <span>{{ options.blog_url }}/{{ options.categories_prefix }}/${slug}{{ options.path_suffix }}</span>
</template> </template>
<a-input v-model="options.categories_prefix" /> <a-input v-model="options.categories_prefix" />
</a-form-item> </a-form-model-item>
<a-form-item label="标签前缀:"> <a-form-model-item label="标签前缀:">
<template slot="help"> <template slot="help">
<span>{{ options.blog_url }}/{{ options.tags_prefix }}/${slug}{{ options.path_suffix }}</span> <span>{{ options.blog_url }}/{{ options.tags_prefix }}/${slug}{{ options.path_suffix }}</span>
</template> </template>
<a-input v-model="options.tags_prefix" /> <a-input v-model="options.tags_prefix" />
</a-form-item> </a-form-model-item>
<a-form-item label="路径后缀:"> <a-form-model-item label="路径后缀:">
<template slot="help"> <template slot="help">
<span>* 格式为<code>.${suffix}</code>仅对内建路径有效</span> <span>* 格式为<code>.${suffix}</code>仅对内建路径有效</span>
</template> </template>
<a-input v-model="options.path_suffix" /> <a-input v-model="options.path_suffix" />
</a-form-item> </a-form-model-item>
<a-form-item> <a-form-model-item>
<a-button <a-button
type="primary" type="primary"
@click="handleSaveOptions" @click="handleSaveOptions"
:loading="saving"
>保存</a-button> >保存</a-button>
</a-form-item> </a-form-model-item>
</a-form> </a-form-model>
</div> </div>
</template> </template>
<script> <script>
@ -84,6 +88,10 @@ export default {
options: { options: {
type: Object, type: Object,
required: true required: true
},
saving: {
type: Boolean,
default: false
} }
}, },
data() { data() {
@ -94,7 +102,8 @@ export default {
lg: { span: 8 }, lg: { span: 8 },
sm: { span: 12 }, sm: { span: 12 },
xs: { span: 24 } xs: { span: 24 }
} },
rules: {}
} }
}, },
watch: { watch: {
@ -104,7 +113,12 @@ export default {
}, },
methods: { methods: {
handleSaveOptions() { handleSaveOptions() {
this.$emit('onSave') const _this = this
_this.$refs.permalinkOptionsForm.validate(valid => {
if (valid) {
this.$emit('onSave')
}
})
} }
} }
} }

View File

@ -1,59 +1,63 @@
<template> <template>
<div> <div>
<a-form <a-form-model
ref="postOptionsForm"
:model="options"
:rules="rules"
layout="vertical" layout="vertical"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
> >
<!-- <a-form-item label="默认编辑器:"> <!-- <a-form-model-item label="默认编辑器:">
<a-select v-model="options.default_editor"> <a-select v-model="options.default_editor">
<a-select-option value="MARKDOWN">Markdown 编辑器</a-select-option> <a-select-option value="MARKDOWN">Markdown 编辑器</a-select-option>
<a-select-option value="RICHTEXT">富文本编辑器</a-select-option> <a-select-option value="RICHTEXT">富文本编辑器</a-select-option>
</a-select> </a-select>
</a-form-item> --> </a-form-model-item> -->
<a-form-item label="首页文章排序:"> <a-form-model-item label="首页文章排序:">
<a-select v-model="options.post_index_sort"> <a-select v-model="options.post_index_sort">
<a-select-option value="createTime">创建时间</a-select-option> <a-select-option value="createTime">创建时间</a-select-option>
<a-select-option value="editTime">最后编辑时间</a-select-option> <a-select-option value="editTime">最后编辑时间</a-select-option>
<a-select-option value="visits">点击量</a-select-option> <a-select-option value="visits">点击量</a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-model-item>
<a-form-item label="首页每页条数:"> <a-form-model-item label="首页每页条数:">
<a-input <a-input-number
type="number"
v-model="options.post_index_page_size" v-model="options.post_index_page_size"
style="width:100%"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="归档每页条数:"> <a-form-model-item label="归档每页条数:">
<a-input <a-input-number
type="number"
v-model="options.post_archives_page_size" v-model="options.post_archives_page_size"
style="width:100%"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="RSS 内容类型:"> <a-form-model-item label="RSS 内容类型:">
<a-select v-model="options.rss_content_type"> <a-select v-model="options.rss_content_type">
<a-select-option value="full">全文</a-select-option> <a-select-option value="full">全文</a-select-option>
<a-select-option value="summary">摘要</a-select-option> <a-select-option value="summary">摘要</a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-model-item>
<a-form-item label="RSS 内容条数:"> <a-form-model-item label="RSS 内容条数:">
<a-input <a-input-number
type="number"
v-model="options.rss_page_size" v-model="options.rss_page_size"
style="width:100%"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="文章摘要字数:"> <a-form-model-item label="文章摘要字数:">
<a-input <a-input-number
type="number"
v-model="options.post_summary_length" v-model="options.post_summary_length"
style="width:100%"
/> />
</a-form-item> </a-form-model-item>
<a-form-item> <a-form-model-item>
<a-button <a-button
type="primary" type="primary"
@click="handleSaveOptions" @click="handleSaveOptions"
:loading="saving"
>保存</a-button> >保存</a-button>
</a-form-item> </a-form-model-item>
</a-form> </a-form-model>
</div> </div>
</template> </template>
<script> <script>
@ -63,6 +67,10 @@ export default {
options: { options: {
type: Object, type: Object,
required: true required: true
},
saving: {
type: Boolean,
default: false
} }
}, },
data() { data() {
@ -72,7 +80,8 @@ export default {
lg: { span: 8 }, lg: { span: 8 },
sm: { span: 12 }, sm: { span: 12 },
xs: { span: 24 } xs: { span: 24 }
} },
rules: {}
} }
}, },
watch: { watch: {
@ -82,7 +91,12 @@ export default {
}, },
methods: { methods: {
handleSaveOptions() { handleSaveOptions() {
this.$emit('onSave') const _this = this
_this.$refs.postOptionsForm.validate(valid => {
if (valid) {
this.$emit('onSave')
}
})
} }
} }
} }

View File

@ -1,32 +1,45 @@
<template> <template>
<div> <div>
<a-form <a-form-model
ref="seoOptionsForm"
:model="options"
:rules="rules"
layout="vertical" layout="vertical"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
> >
<a-form-item label="屏蔽搜索引擎:"> <a-form-model-item
label="屏蔽搜索引擎:"
prop="seo_spider_disabled"
>
<a-switch v-model="options.seo_spider_disabled" /> <a-switch v-model="options.seo_spider_disabled" />
</a-form-item> </a-form-model-item>
<a-form-item label="关键词:"> <a-form-model-item
label="关键词:"
prop="seo_keywords"
>
<a-input <a-input
v-model="options.seo_keywords" v-model="options.seo_keywords"
placeholder="多个关键词以英文状态下的逗号隔开" placeholder="多个关键词以英文状态下的逗号隔开"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="博客描述:"> <a-form-model-item
label="博客描述:"
prop="seo_description"
>
<a-input <a-input
type="textarea" type="textarea"
:autoSize="{ minRows: 5 }" :autoSize="{ minRows: 5 }"
v-model="options.seo_description" v-model="options.seo_description"
/> />
</a-form-item> </a-form-model-item>
<a-form-item> <a-form-model-item>
<a-button <a-button
type="primary" type="primary"
@click="handleSaveOptions" @click="handleSaveOptions"
:loading="saving"
>保存</a-button> >保存</a-button>
</a-form-item> </a-form-model-item>
</a-form> </a-form-model>
</div> </div>
</template> </template>
<script> <script>
@ -36,6 +49,10 @@ export default {
options: { options: {
type: Object, type: Object,
required: true required: true
},
saving: {
type: Boolean,
default: false
} }
}, },
data() { data() {
@ -45,6 +62,10 @@ export default {
lg: { span: 8 }, lg: { span: 8 },
sm: { span: 12 }, sm: { span: 12 },
xs: { span: 24 } xs: { span: 24 }
},
rules: {
seo_keywords: [{ max: 1023, message: '* 字符数不能超过 1023', trigger: ['change', 'blur'] }],
seo_description: [{ max: 1023, message: '* 字符数不能超过 1023', trigger: ['change', 'blur'] }]
} }
} }
}, },
@ -55,7 +76,12 @@ export default {
}, },
methods: { methods: {
handleSaveOptions() { handleSaveOptions() {
this.$emit('onSave') const _this = this
_this.$refs.seoOptionsForm.validate(valid => {
if (valid) {
this.$emit('onSave')
}
})
} }
} }
} }

View File

@ -5,71 +5,76 @@
tab="发信设置" tab="发信设置"
key="smtpoptions" key="smtpoptions"
> >
<a-form <a-form-model
ref="smtpOptionsForm"
:model="options"
:rules="rules"
layout="vertical" layout="vertical"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
> >
<a-form-item label="是否启用:"> <a-form-model-item label="是否启用:">
<a-switch v-model="options.email_enabled" /> <a-switch v-model="options.email_enabled" />
</a-form-item> </a-form-model-item>
<a-form-item label="SMTP 地址:"> <a-form-model-item label="SMTP 地址:">
<a-input v-model="options.email_host" /> <a-input v-model="options.email_host" />
</a-form-item> </a-form-model-item>
<a-form-item label="发送协议:"> <a-form-model-item label="发送协议:">
<a-input v-model="options.email_protocol" /> <a-input v-model="options.email_protocol" />
</a-form-item> </a-form-model-item>
<a-form-item label="SSL 端口:"> <a-form-model-item label="SSL 端口:">
<a-input v-model="options.email_ssl_port" /> <a-input v-model="options.email_ssl_port" />
</a-form-item> </a-form-model-item>
<a-form-item label="邮箱账号:"> <a-form-model-item label="邮箱账号:">
<a-input v-model="options.email_username" /> <a-input v-model="options.email_username" />
</a-form-item> </a-form-model-item>
<a-form-item label="邮箱密码:"> <a-form-model-item label="邮箱密码:">
<a-input-password <a-input-password
v-model="options.email_password" v-model="options.email_password"
placeholder="部分邮箱可能是授权码" placeholder="部分邮箱可能是授权码"
autocomplete="new-password" autocomplete="new-password"
/> />
</a-form-item> </a-form-model-item>
<a-form-item label="发件人:"> <a-form-model-item label="发件人:">
<a-input v-model="options.email_from_name" /> <a-input v-model="options.email_from_name" />
</a-form-item> </a-form-model-item>
<a-form-item> <a-form-model-item>
<a-button <a-button
type="primary" type="primary"
@click="handleSaveOptions" @click="handleSaveOptions"
:loading="saving"
>保存</a-button> >保存</a-button>
</a-form-item> </a-form-model-item>
</a-form> </a-form-model>
</a-tab-pane> </a-tab-pane>
<a-tab-pane <a-tab-pane
tab="发送测试" tab="发送测试"
key="smtptest" key="smtptest"
> >
<a-form <a-form-model
layout="vertical" layout="vertical"
:wrapperCol="wrapperCol" :wrapperCol="wrapperCol"
> >
<a-form-item label="收件人:"> <a-form-model-item label="收件人:">
<a-input v-model="mailParam.to" /> <a-input v-model="mailParam.to" />
</a-form-item> </a-form-model-item>
<a-form-item label="主题:"> <a-form-model-item label="主题:">
<a-input v-model="mailParam.subject" /> <a-input v-model="mailParam.subject" />
</a-form-item> </a-form-model-item>
<a-form-item label="内容:"> <a-form-model-item label="内容:">
<a-input <a-input
type="textarea" type="textarea"
:autoSize="{ minRows: 5 }" :autoSize="{ minRows: 5 }"
v-model="mailParam.content" v-model="mailParam.content"
/> />
</a-form-item> </a-form-model-item>
<a-form-item> <a-form-model-item>
<a-button <a-button
type="primary" type="primary"
@click="handleTestMailClick" @click="handleTestMailClick"
:loading="sending"
>发送</a-button> >发送</a-button>
</a-form-item> </a-form-model-item>
</a-form> </a-form-model>
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
</div> </div>
@ -82,6 +87,10 @@ export default {
options: { options: {
type: Object, type: Object,
required: true required: true
},
saving: {
type: Boolean,
default: false
} }
}, },
data() { data() {
@ -92,7 +101,9 @@ export default {
sm: { span: 12 }, sm: { span: 12 },
xs: { span: 24 } xs: { span: 24 }
}, },
mailParam: {} mailParam: {},
sending: false,
rules: {}
} }
}, },
watch: { watch: {
@ -147,7 +158,12 @@ export default {
return return
} }
} }
this.$emit('onSave') const _this = this
_this.$refs.smtpOptionsForm.validate(valid => {
if (valid) {
this.$emit('onSave')
}
})
}, },
handleTestMailClick() { handleTestMailClick() {
if (!this.mailParam.to) { if (!this.mailParam.to) {
@ -171,9 +187,17 @@ export default {
}) })
return return
} }
mailApi.testMail(this.mailParam).then(response => { this.sending = true
this.$message.info(response.data.message) mailApi
}) .testMail(this.mailParam)
.then(response => {
this.$message.info(response.data.message)
})
.finally(() => {
setTimeout(() => {
this.sending = false
}, 400)
})
} }
} }
} }

View File

@ -88,7 +88,7 @@ export default {
this.loadFormOptions() this.loadFormOptions()
}, },
methods: { methods: {
...mapActions(['loadOptions']), ...mapActions(['refreshOptionsCache']),
loadFormOptions() { loadFormOptions() {
optionApi.listAll().then(response => { optionApi.listAll().then(response => {
this.options = response.data.data this.options = response.data.data
@ -97,7 +97,7 @@ export default {
handleSaveOptions() { handleSaveOptions() {
optionApi.save(this.options).then(response => { optionApi.save(this.options).then(response => {
this.loadFormOptions() this.loadFormOptions()
this.loadOptions() this.refreshOptionsCache()
this.$message.success('保存成功!') this.$message.success('保存成功!')
}) })
} }

View File

@ -218,7 +218,7 @@ export default {
} }
}, },
methods: { methods: {
...mapActions(['login', 'loadUser', 'loadOptions']), ...mapActions(['login', 'refreshUserCache', 'refreshOptionsCache']),
...mapMutations({ ...mapMutations({
setApiUrl: 'SET_API_URL', setApiUrl: 'SET_API_URL',
restoreApiUrl: 'RESTORE_API_URL' restoreApiUrl: 'RESTORE_API_URL'
@ -277,13 +277,13 @@ export default {
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.landing = false this.landing = false
}, 200) }, 400)
}) })
}, },
loginSuccess() { loginSuccess() {
// Cache the user info // Cache the user info
this.loadUser() this.refreshUserCache()
this.loadOptions() this.refreshOptionsCache()
if (this.$route.query.redirect) { if (this.$route.query.redirect) {
this.$router.replace(this.$route.query.redirect) this.$router.replace(this.$route.query.redirect)
} else { } else {

View File

@ -10,41 +10,50 @@
:bordered="false" :bordered="false"
:bodyStyle="{ padding: '16px' }" :bodyStyle="{ padding: '16px' }"
> >
<div class="profile-center-avatarHolder"> <div class="text-center mb-6">
<a-tooltip <a-tooltip
placement="right" placement="right"
:trigger="['hover']" :trigger="['hover']"
title="点击可修改头像" title="点击可修改头像"
> >
<template slot="title"> <a-avatar
<span>prompt text</span> :size="104"
</template> :src="user.avatar || '//cn.gravatar.com/avatar/?s=256&d=mm'"
<div class="avatar"> @click="attachmentDrawerVisible = true"
<img class="cursor-pointer"
:src="user.avatar || '//cn.gravatar.com/avatar/?s=256&d=mm'" />
@click="attachmentDrawerVisible = true"
>
</div>
</a-tooltip> </a-tooltip>
<div class="username">{{ user.nickname }}</div> <div
<div class="bio">{{ user.description }}</div> class="text-xl leading-5 font-medium mt-4 mb-1"
style="color: rgba(0, 0, 0, 0.85);"
>{{ user.nickname }}</div>
<div>{{ user.description }}</div>
</div> </div>
<div class="profile-center-detail"> <div>
<p> <p class="mb-3">
<a-icon type="link" /><a <a-icon
type="link"
class="mr-3"
/><a
:href="options.blog_url" :href="options.blog_url"
target="method" target="method"
>{{ options.blog_url }}</a> >{{ options.blog_url }}</a>
</p> </p>
<p> <p class="mb-3">
<a-icon type="mail" />{{ user.email }} <a-icon
type="mail"
class="mr-3"
/>{{ user.email }}
</p> </p>
<p> <p class="mb-3">
<a-icon type="calendar" />{{ statistics.establishDays || 0 }} <a-icon
type="calendar"
class="mr-3"
/>{{ statistics.establishDays || 0 }}
</p> </p>
</div> </div>
<a-divider /> <a-divider />
<div class="general-profile"> <div>
<a-list <a-list
:loading="statisticsLoading" :loading="statisticsLoading"
itemLayout="horizontal" itemLayout="horizontal"
@ -456,49 +465,3 @@ export default {
} }
} }
</script> </script>
<style lang="less" scoped>
.profile-center-avatarHolder {
text-align: center;
margin-bottom: 24px;
& > .avatar {
margin: 0 auto;
width: 104px;
height: 104px;
margin-bottom: 20px;
border-radius: 50%;
overflow: hidden;
cursor: pointer;
img {
height: 100%;
width: 100%;
}
}
.username {
color: rgba(0, 0, 0, 0.85);
font-size: 20px;
line-height: 28px;
font-weight: 500;
margin-bottom: 4px;
}
}
.profile-center-detail {
p {
margin-bottom: 8px;
padding-left: 26px;
position: relative;
}
i {
position: absolute;
height: 14px;
width: 14px;
left: 0;
top: 4px;
}
}
</style>