halo/src/views/sheet/components/SheetSettingDrawer.vue

445 lines
13 KiB
Vue

<template>
<a-drawer
title="页面设置"
:width="isMobile()?'100%':'480'"
placement="right"
closable
destroyOnClose
@close="onClose"
:visible="visible"
:afterVisibleChange="handleAfterVisibleChanged"
>
<div class="post-setting-drawer-content">
<div class="mb-4">
<h3 class="post-setting-drawer-title">基本设置</h3>
<div class="post-setting-drawer-item">
<a-form layout="vertical">
<a-form-item
label="页面标题:"
v-if="needTitle"
>
<a-input v-model="selectedSheet.title" />
</a-form-item>
<a-form-item
label="页面别名:"
:help="fullPath"
>
<a-input v-model="selectedSheet.slug" />
</a-form-item>
<a-form-item label="发表时间:">
<a-date-picker
showTime
:defaultValue="pickerDefaultValue"
format="YYYY-MM-DD HH:mm:ss"
placeholder="选择页面发表时间"
@change="onSheetDateChange"
@ok="onSheetDateOk"
/>
</a-form-item>
<a-form-item label="开启评论:">
<a-radio-group
v-model="selectedSheet.disallowComment"
:defaultValue="false"
>
<a-radio :value="false">开启</a-radio>
<a-radio :value="true">关闭</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item
label="自定义模板:"
v-if="customTpls.length>0"
>
<a-select
v-model="selectedSheet.template"
:loading="customTplsLoading"
>
<a-select-option
key=""
value=""
>无</a-select-option>
<a-select-option
v-for="tpl in customTpls"
:key="tpl"
:value="tpl"
>{{ tpl }}</a-select-option>
</a-select>
</a-form-item>
</a-form>
</div>
</div>
<a-divider />
<div class="mb-4">
<h3 class="post-setting-drawer-title">摘要</h3>
<div class="post-setting-drawer-item">
<a-form layout="vertical">
<a-form-item>
<a-input
type="textarea"
:autoSize="{ minRows: 5 }"
v-model="selectedSheet.summary"
placeholder="不填写则会自动生成"
/>
</a-form-item>
</a-form>
</div>
</div>
<a-divider />
<div class="mb-4">
<h3 class="post-setting-drawer-title">封面图</h3>
<div class="post-setting-drawer-item">
<div class="sheet-thumb">
<img
class="img"
:src="selectedSheet.thumbnail || '/images/placeholder.jpg'"
@click="thumbDrawerVisible = true"
>
<a-form layout="vertial">
<a-form-item>
<a-input
v-model="selectedSheet.thumbnail"
placeholder="点击封面图选择图片,或者输入外部链接"
></a-input>
</a-form-item>
</a-form>
<a-button
class="sheet-thumb-remove"
type="dashed"
@click="selectedSheet.thumbnail = null"
>移除</a-button>
</div>
</div>
</div>
<a-divider class="divider-transparent" />
</div>
<AttachmentSelectDrawer
v-model="thumbDrawerVisible"
@listenToSelect="handleSelectSheetThumb"
:drawerWidth="480"
/>
<a-drawer
title="高级设置"
:width="isMobile()?'100%':'480'"
placement="right"
closable
destroyOnClose
@close="advancedVisible = false"
:visible="advancedVisible"
>
<div class="post-setting-drawer-content">
<div class="mb-4">
<h3 class="post-setting-drawer-title">SEO 设置</h3>
<div class="post-setting-drawer-item">
<a-form layout="vertical">
<a-form-item label="自定义关键词:">
<a-input
v-model="selectedSheet.metaKeywords"
placeholder="多个关键词以英文逗号隔开"
/>
</a-form-item>
<a-form-item label="自定义描述:">
<a-input
type="textarea"
:autoSize="{ minRows: 5 }"
v-model="selectedSheet.metaDescription"
placeholder="如不填写,会从页面中自动截取"
/>
</a-form-item>
</a-form>
</div>
</div>
<a-divider />
<div class="mb-4">
<h3 class="post-setting-drawer-title">元数据</h3>
<a-form layout="vertical">
<a-form-item
v-for="(meta, index) in selectedMetas"
:key="index"
:prop="'meta.' + index + '.value'"
>
<a-row :gutter="5">
<a-col :span="12">
<a-input v-model="meta.key"><i slot="addonBefore">K</i></a-input>
</a-col>
<a-col :span="12">
<a-input v-model="meta.value">
<i slot="addonBefore">V</i>
<a
href="javascript:void(0);"
slot="addonAfter"
@click.prevent="handleRemoveSheetMeta(meta)"
>
<a-icon type="close" />
</a>
</a-input>
</a-col>
</a-row>
</a-form-item>
<a-form-item>
<a-button
type="dashed"
@click="handleInsertSheetMeta()"
>新增</a-button>
</a-form-item>
</a-form>
</div>
<a-divider class="divider-transparent" />
</div>
</a-drawer>
<div class="bottom-control">
<a-button
class="mr-2"
type="dashed"
@click="advancedVisible = true"
>高级</a-button>
<ReactiveButton
type="danger"
v-if="saveDraftButton"
class="mr-2"
@click="handleDraftClick"
@callback="handleSavedCallback"
:loading="draftSaving"
:errored="draftSavedErrored"
text="保存草稿"
loadedText="保存成功"
erroredText="保存失败"
></ReactiveButton>
<ReactiveButton
@click="handlePublishClick"
@callback="handleSavedCallback"
:loading="saving"
:errored="savedErrored"
:text="`${selectedSheet.id?'保存':'发布'}`"
:loadedText="`${selectedSheet.id?'保存':'发布'}成功`"
:erroredText="`${selectedSheet.id?'保存':'发布'}失败`"
></ReactiveButton>
</div>
</a-drawer>
</template>
<script>
// libs
import { mixin, mixinDevice } from '@/utils/mixin.js'
import moment from 'moment'
import { mapGetters } from 'vuex'
import pinyin from 'tiny-pinyin'
// apis
import themeApi from '@/api/theme'
import sheetApi from '@/api/sheet'
export default {
name: 'SheetSettingDrawer',
mixins: [mixin, mixinDevice],
data() {
return {
thumbDrawerVisible: false,
advancedVisible: false,
customTplsLoading: false,
selectedSheet: this.sheet,
customTpls: [],
saving: false,
savedErrored: false,
draftSaving: false,
draftSavedErrored: false
}
},
props: {
sheet: {
type: Object,
required: true
},
metas: {
type: Array,
required: true
},
needTitle: {
type: Boolean,
required: false,
default: false
},
saveDraftButton: {
type: Boolean,
required: false,
default: true
},
visible: {
type: Boolean,
required: false,
default: true
}
},
watch: {
sheet(val) {
this.selectedSheet = val
},
selectedSheet(val) {
this.$emit('onRefreshSheet', val)
},
selectedMetas(val) {
this.$emit('onRefreshSheetMetas', val)
}
},
computed: {
...mapGetters(['options']),
selectedMetas() {
return this.metas
},
pickerDefaultValue() {
if (this.selectedSheet.createTime) {
var date = new Date(this.selectedSheet.createTime)
return moment(date, 'YYYY-MM-DD HH:mm:ss')
}
return moment(new Date(), 'YYYY-MM-DD HH:mm:ss')
},
fullPath() {
const blogUrl = this.options.blog_url
const sheetPrefix = this.options.sheet_prefix
const pathSuffix = this.options.path_suffix ? this.options.path_suffix : ''
return `${blogUrl}/${sheetPrefix}/${this.selectedSheet.slug ? this.selectedSheet.slug : '{slug}'}${pathSuffix}`
}
},
methods: {
handleAfterVisibleChanged(visible) {
if (visible) {
this.handleListCustomTpls()
this.handleListPresetMetasField()
this.handleSetPinyinSlug()
}
},
handleListPresetMetasField() {
if (this.metas.length <= 0) {
themeApi.getActivatedTheme().then(response => {
const fields = response.data.data.sheetMetaField
if (fields && fields.length > 0) {
for (let i = 0, len = fields.length; i < len; i++) {
this.selectedMetas.push({
value: '',
key: fields[i]
})
}
}
})
}
},
handleListCustomTpls() {
this.customTplsLoading = true
themeApi
.customSheetTpls()
.then(response => {
this.customTpls = response.data.data
})
.finally(() => {
setTimeout(() => {
this.customTplsLoading = false
}, 200)
})
},
handleSelectSheetThumb(data) {
this.selectedSheet.thumbnail = encodeURI(data.path)
this.thumbDrawerVisible = false
},
handlePublishClick() {
this.selectedSheet.status = 'PUBLISHED'
this.createOrUpdateSheet()
},
handleDraftClick() {
this.selectedSheet.status = 'DRAFT'
this.createOrUpdateSheet()
},
createOrUpdateSheet() {
if (!this.selectedSheet.title) {
this.$notification['error']({
message: '提示',
description: '页面标题不能为空!'
})
return
}
this.selectedSheet.metas = this.selectedMetas
if (this.selectedSheet.status === 'DRAFT') {
this.draftSaving = true
} else {
this.saving = true
}
if (this.selectedSheet.id) {
sheetApi
.update(this.selectedSheet.id, this.selectedSheet, false)
.catch(() => {
if (this.selectedSheet.status === 'DRAFT') {
this.draftSavedErrored = true
} else {
this.savedErrored = true
}
})
.finally(() => {
setTimeout(() => {
this.saving = false
this.draftSaving = false
}, 400)
})
} else {
sheetApi
.create(this.selectedSheet, false)
.catch(() => {
if (this.selectedSheet.status === 'DRAFT') {
this.draftSavedErrored = true
} else {
this.savedErrored = true
}
})
.then(response => {
this.selectedSheet = response.data.data
})
.finally(() => {
setTimeout(() => {
this.saving = false
this.draftSaving = false
}, 400)
})
}
},
handleSavedCallback() {
if (this.draftSavedErrored || this.savedErrored) {
this.draftSavedErrored = false
this.savedErrored = false
} else {
this.$emit('onSaved', true)
this.$router.push({ name: 'SheetList', query: { activeKey: 'custom' } })
}
},
onClose() {
this.$emit('close', false)
},
onSheetDateChange(value, dateString) {
this.selectedSheet.createTime = value.valueOf()
},
onSheetDateOk(value) {
this.selectedSheet.createTime = value.valueOf()
},
handleRemoveSheetMeta(item) {
var index = this.selectedMetas.indexOf(item)
if (index !== -1) {
this.selectedMetas.splice(index, 1)
}
},
handleInsertSheetMeta() {
this.selectedMetas.push({
value: '',
key: ''
})
},
handleSetPinyinSlug() {
if (this.selectedSheet.title && !this.selectedSheet.id) {
if (pinyin.isSupported()) {
this.$set(this.selectedSheet, 'slug', pinyin.convertToPinyin(this.selectedSheet.title, '-', true))
}
}
}
}
}
</script>