mirror of https://github.com/halo-dev/halo
refactor: options page. (halo-dev/console#89)
* refactor: options page. * fix: option api.pull/3445/head
parent
70538d7caf
commit
8308c66dc1
|
@ -4,16 +4,21 @@ const baseUrl = '/api/admin/options'
|
|||
|
||||
const optionApi = {}
|
||||
|
||||
optionApi.listAll = keys => {
|
||||
optionApi.listAll = () => {
|
||||
return service({
|
||||
url: `${baseUrl}/map_view`,
|
||||
params: {
|
||||
key: keys
|
||||
},
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
optionApi.listAllByKeys = keys => {
|
||||
return service({
|
||||
url: `${baseUrl}/map_view/keys`,
|
||||
data: keys,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
optionApi.query = params => {
|
||||
return service({
|
||||
url: `${baseUrl}/list_view`,
|
||||
|
|
|
@ -175,8 +175,8 @@ export const asyncRouterMap = [
|
|||
},
|
||||
{
|
||||
path: '/system/options',
|
||||
name: 'OptionForm',
|
||||
component: () => import('@/views/system/OptionForm'),
|
||||
name: 'SystemOptions',
|
||||
component: () => import('@/views/system/SystemOptions'),
|
||||
meta: { title: '博客设置', hiddenHeaderContent: false }
|
||||
},
|
||||
{
|
||||
|
|
|
@ -31,7 +31,7 @@ const option = {
|
|||
}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
optionApi
|
||||
.listAll(keys)
|
||||
.listAllByKeys(keys)
|
||||
.then(response => {
|
||||
commit('SET_OPTIONS', response.data.data)
|
||||
resolve(response)
|
||||
|
|
|
@ -97,7 +97,7 @@
|
|||
</template>
|
||||
<a-tag
|
||||
color="blue"
|
||||
style="margin-bottom: 8px"
|
||||
style="margin-bottom: 8px;cursor:pointer;"
|
||||
@click="handleEditTag(tag)"
|
||||
>{{ tag.name }}</a-tag>
|
||||
</a-tooltip>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,198 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-row>
|
||||
<a-col :span="24">
|
||||
<div class="card-container">
|
||||
<a-tabs
|
||||
type="card"
|
||||
class="general"
|
||||
v-if="!advancedOptions"
|
||||
>
|
||||
<a-tab-pane key="general">
|
||||
<span slot="tab">
|
||||
<a-icon type="tool" />常规设置
|
||||
</span>
|
||||
<GeneralTab
|
||||
:options="options"
|
||||
@onChange="onOptionsChange"
|
||||
@onSave="onSaveOptions"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="seo">
|
||||
<span slot="tab">
|
||||
<a-icon type="global" />SEO 设置
|
||||
</span>
|
||||
<SeoTab
|
||||
:options="options"
|
||||
@onChange="onOptionsChange"
|
||||
@onSave="onSaveOptions"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="post">
|
||||
<span slot="tab">
|
||||
<a-icon type="form" />文章设置
|
||||
</span>
|
||||
<PostTab
|
||||
:options="options"
|
||||
@onChange="onOptionsChange"
|
||||
@onSave="onSaveOptions"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="comment">
|
||||
<span slot="tab">
|
||||
<a-icon type="message" />评论设置
|
||||
</span>
|
||||
<CommentTab
|
||||
:options="options"
|
||||
@onChange="onOptionsChange"
|
||||
@onSave="onSaveOptions"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="attachment">
|
||||
<span slot="tab">
|
||||
<a-icon type="picture" />附件设置
|
||||
</span>
|
||||
<AttachmentTab
|
||||
:options="options"
|
||||
@onChange="onOptionsChange"
|
||||
@onSave="onSaveOptions"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="smtp">
|
||||
<span slot="tab">
|
||||
<a-icon type="mail" />SMTP 服务
|
||||
</span>
|
||||
<SmtpTab
|
||||
:options="options"
|
||||
@onChange="onOptionsChange"
|
||||
@onSave="onSaveOptions"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="other">
|
||||
<span slot="tab">
|
||||
<a-icon type="align-left" />其他设置
|
||||
</span>
|
||||
<OtherTab
|
||||
:options="options"
|
||||
@onChange="onOptionsChange"
|
||||
@onSave="onSaveOptions"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
|
||||
<a-tabs
|
||||
type="card"
|
||||
class="advanced"
|
||||
v-else
|
||||
>
|
||||
<a-tab-pane key="permalink">
|
||||
<span slot="tab">
|
||||
<a-icon type="link" />固定链接
|
||||
</span>
|
||||
<PermalinkTab
|
||||
:options="options"
|
||||
@onChange="onOptionsChange"
|
||||
@onSave="onSaveOptions"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="api">
|
||||
<span slot="tab">
|
||||
<a-icon type="api" />API 设置
|
||||
</span>
|
||||
<ApiTab
|
||||
:options="options"
|
||||
@onChange="onOptionsChange"
|
||||
@onSave="onSaveOptions"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="advanced-other">
|
||||
<span slot="tab">
|
||||
<a-icon type="align-left" />其他设置
|
||||
</span>
|
||||
<AdvancedOtherTab
|
||||
:options="options"
|
||||
@onChange="onOptionsChange"
|
||||
@onSave="onSaveOptions"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<div style="position: fixed;bottom: 30px;right: 30px;">
|
||||
<a-tooltip placement="top">
|
||||
<template slot="title">
|
||||
<span>{{ advancedOptions?'基础选项':'高级选项' }}</span>
|
||||
</template>
|
||||
<a-button
|
||||
type="primary"
|
||||
shape="circle"
|
||||
:icon="`${advancedOptions?'setting':'thunderbolt'}`"
|
||||
size="large"
|
||||
@click="handleAdvancedOptions()"
|
||||
></a-button>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import GeneralTab from './optiontabs/GeneralTab'
|
||||
import SeoTab from './optiontabs/SeoTab'
|
||||
import PostTab from './optiontabs/PostTab'
|
||||
import CommentTab from './optiontabs/CommentTab'
|
||||
import AttachmentTab from './optiontabs/AttachmentTab'
|
||||
import SmtpTab from './optiontabs/SmtpTab'
|
||||
import OtherTab from './optiontabs/OtherTab'
|
||||
import PermalinkTab from './optiontabs/PermalinkTab'
|
||||
import ApiTab from './optiontabs/ApiTab'
|
||||
import AdvancedOtherTab from './optiontabs/AdvancedOtherTab'
|
||||
import optionApi from '@/api/option'
|
||||
|
||||
import { mapActions } from 'vuex'
|
||||
export default {
|
||||
components: {
|
||||
GeneralTab,
|
||||
SeoTab,
|
||||
PostTab,
|
||||
CommentTab,
|
||||
AttachmentTab,
|
||||
SmtpTab,
|
||||
OtherTab,
|
||||
PermalinkTab,
|
||||
ApiTab,
|
||||
AdvancedOtherTab
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
options: {},
|
||||
advancedOptions: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadFormOptions()
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['loadUser', 'loadOptions']),
|
||||
handleAdvancedOptions() {
|
||||
this.advancedOptions = !this.advancedOptions
|
||||
},
|
||||
loadFormOptions() {
|
||||
optionApi.listAll().then(response => {
|
||||
this.options = response.data.data
|
||||
})
|
||||
},
|
||||
onOptionsChange(val) {
|
||||
this.options = val
|
||||
},
|
||||
onSaveOptions() {
|
||||
optionApi.save(this.options).then(response => {
|
||||
this.loadFormOptions()
|
||||
this.loadOptions()
|
||||
this.loadUser()
|
||||
this.$message.success('保存成功!')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,52 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-form
|
||||
layout="vertical"
|
||||
:wrapperCol="wrapperCol"
|
||||
>
|
||||
<a-form-item
|
||||
label="全局绝对路径:"
|
||||
help="* 对网站上面的所有页面路径、本地附件路径、以及主题中的静态资源路径有效。"
|
||||
>
|
||||
<a-switch v-model="options.global_absolute_path_enabled" />
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="handleSaveOptions"
|
||||
>保存</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'AdvancedOtherTab',
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
wrapperCol: {
|
||||
xl: { span: 8 },
|
||||
lg: { span: 8 },
|
||||
sm: { span: 12 },
|
||||
xs: { span: 24 }
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
options(val) {
|
||||
this.$emit('onChange', val)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSaveOptions() {
|
||||
this.$emit('onSave')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,65 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-form
|
||||
layout="vertical"
|
||||
:wrapperCol="wrapperCol"
|
||||
>
|
||||
<a-form-item label="API 服务:">
|
||||
<a-switch v-model="options.api_enabled" />
|
||||
</a-form-item>
|
||||
<a-form-item label="Access key:">
|
||||
<a-input-password
|
||||
v-model="options.api_access_key"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="handleSaveOptions"
|
||||
>保存</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'ApiTab',
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
wrapperCol: {
|
||||
xl: { span: 8 },
|
||||
lg: { span: 8 },
|
||||
sm: { span: 12 },
|
||||
xs: { span: 24 }
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
options(val) {
|
||||
this.$emit('onChange', val)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSaveOptions() {
|
||||
// API 配置验证
|
||||
if (this.options.api_enabled) {
|
||||
if (!this.options.api_access_key) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: 'Access key 不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
this.$emit('onSave')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,577 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-form
|
||||
layout="vertical"
|
||||
:wrapperCol="wrapperCol"
|
||||
>
|
||||
<a-form-item label="上传图片时预览:">
|
||||
<a-switch v-model="options.attachment_upload_image_preview_enable" />
|
||||
</a-form-item>
|
||||
<a-form-item label="最大上传文件数:">
|
||||
<a-input
|
||||
type="number"
|
||||
v-model="options.attachment_upload_max_files"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="同时上传文件数:">
|
||||
<a-input
|
||||
type="number"
|
||||
v-model="options.attachment_upload_max_parallel_uploads"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="存储位置:">
|
||||
<a-select v-model="options.attachment_type">
|
||||
<a-select-option
|
||||
v-for="item in Object.keys(attachmentType)"
|
||||
:key="item"
|
||||
:value="item"
|
||||
>{{ attachmentType[item].text }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<div
|
||||
id="smmsForm"
|
||||
v-show="options.attachment_type === 'SMMS'"
|
||||
>
|
||||
<a-form-item label="Secret Token:">
|
||||
<a-input-password
|
||||
v-model="options.smms_api_secret_token"
|
||||
placeholder="需要到 sm.ms 官网注册后获取"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div
|
||||
id="upOssForm"
|
||||
v-show="options.attachment_type === 'UPOSS'"
|
||||
>
|
||||
<a-form-item label="绑定域名协议:">
|
||||
<a-select v-model="options.oss_upyun_domain_protocol">
|
||||
<a-select-option value="https://">HTTPS</a-select-option>
|
||||
<a-select-option value="http://">HTTP</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="绑定域名:">
|
||||
<a-input
|
||||
v-model="options.oss_upyun_domain"
|
||||
placeholder="无需再加上 http:// 或者 https://"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="空间名称:">
|
||||
<a-input v-model="options.oss_upyun_bucket" />
|
||||
</a-form-item>
|
||||
<a-form-item label="操作员名称:">
|
||||
<a-input v-model="options.oss_upyun_operator" />
|
||||
</a-form-item>
|
||||
<a-form-item label="操作员密码:">
|
||||
<a-input-password
|
||||
v-model="options.oss_upyun_password"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="文件目录:">
|
||||
<a-input v-model="options.oss_upyun_source" />
|
||||
</a-form-item>
|
||||
<a-form-item label="图片处理策略:">
|
||||
<a-input
|
||||
v-model="options.oss_upyun_style_rule"
|
||||
placeholder="间隔标识符+图片处理版本名称"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="缩略图处理策略:">
|
||||
<a-input
|
||||
v-model="options.oss_upyun_thumbnail_style_rule"
|
||||
placeholder="间隔标识符+图片处理版本名称,一般为后台展示所用"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div
|
||||
id="qiniuOssForm"
|
||||
v-show="options.attachment_type === 'QINIUOSS'"
|
||||
>
|
||||
<a-form-item label="绑定域名协议:">
|
||||
<a-select v-model="options.oss_qiniu_domain_protocol">
|
||||
<a-select-option value="https://">HTTPS</a-select-option>
|
||||
<a-select-option value="http://">HTTP</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="绑定域名:">
|
||||
<a-input
|
||||
v-model="options.oss_qiniu_domain"
|
||||
placeholder="无需再加上 http:// 或者 https://"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="区域:">
|
||||
<a-auto-complete
|
||||
:dataSource="qiniuOssZones"
|
||||
v-model="options.oss_qiniu_zone"
|
||||
allowClear
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="Access Key:">
|
||||
<a-input-password
|
||||
v-model="options.oss_qiniu_access_key"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="Secret Key:">
|
||||
<a-input-password
|
||||
v-model="options.oss_qiniu_secret_key"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="文件目录:">
|
||||
<a-input
|
||||
v-model="options.oss_qiniu_source"
|
||||
placeholder="不填写则上传到根目录"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="Bucket:">
|
||||
<a-input
|
||||
v-model="options.oss_qiniu_bucket"
|
||||
placeholder="存储空间名称"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="图片处理策略:">
|
||||
<a-input
|
||||
v-model="options.oss_qiniu_style_rule"
|
||||
placeholder="样式分隔符+图片处理样式名称"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="缩略图处理策略:">
|
||||
<a-input
|
||||
v-model="options.oss_qiniu_thumbnail_style_rule"
|
||||
placeholder="样式分隔符+图片处理样式名称,一般为后台展示所用"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div
|
||||
id="aliOssForm"
|
||||
v-show="options.attachment_type === 'ALIOSS'"
|
||||
>
|
||||
<a-form-item label="绑定域名协议:">
|
||||
<a-select v-model="options.oss_ali_domain_protocol">
|
||||
<a-select-option value="https://">HTTPS</a-select-option>
|
||||
<a-select-option value="http://">HTTP</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="绑定域名:">
|
||||
<a-input
|
||||
v-model="options.oss_ali_domain"
|
||||
placeholder="如不填写,路径根域名将为 Bucket + EndPoint"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="Bucket:">
|
||||
<a-input
|
||||
v-model="options.oss_ali_bucket_name"
|
||||
placeholder="存储空间名称"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="EndPoint(地域节点):">
|
||||
<a-input v-model="options.oss_ali_endpoint" />
|
||||
</a-form-item>
|
||||
<a-form-item label="Access Key:">
|
||||
<a-input-password
|
||||
v-model="options.oss_ali_access_key"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="Access Secret:">
|
||||
<a-input-password
|
||||
v-model="options.oss_ali_access_secret"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="文件目录:">
|
||||
<a-input
|
||||
v-model="options.oss_ali_source"
|
||||
placeholder="不填写则上传到根目录"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="图片处理策略:">
|
||||
<a-input
|
||||
v-model="options.oss_ali_style_rule"
|
||||
placeholder="请到阿里云控制台的图片处理获取"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="缩略图处理策略:">
|
||||
<a-input
|
||||
v-model="options.oss_ali_thumbnail_style_rule"
|
||||
placeholder="请到阿里云控制台的图片处理获取,一般为后台展示所用"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div
|
||||
id="baiduBosForm"
|
||||
v-show="options.attachment_type === 'BAIDUBOS'"
|
||||
>
|
||||
<a-form-item label="绑定域名协议:">
|
||||
<a-select v-model="options.bos_baidu_domain_protocol">
|
||||
<a-select-option value="https://">HTTPS</a-select-option>
|
||||
<a-select-option value="http://">HTTP</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="绑定域名:">
|
||||
<a-input
|
||||
v-model="options.bos_baidu_domain"
|
||||
placeholder="如不填写,路径根域名将为 Bucket + EndPoint"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="Bucket:">
|
||||
<a-input
|
||||
v-model="options.bos_baidu_bucket_name"
|
||||
placeholder="存储空间名称"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="EndPoint(地域节点):">
|
||||
<a-input v-model="options.bos_baidu_endpoint" />
|
||||
</a-form-item>
|
||||
<a-form-item label="Access Key:">
|
||||
<a-input-password
|
||||
v-model="options.bos_baidu_access_key"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="Secret Key:">
|
||||
<a-input-password
|
||||
v-model="options.bos_baidu_secret_key"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="图片处理策略:">
|
||||
<a-input
|
||||
v-model="options.bos_baidu_style_rule"
|
||||
placeholder="请到百度云控制台的图片处理获取"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="缩略图处理策略:">
|
||||
<a-input
|
||||
v-model="options.bos_baidu_thumbnail_style_rule"
|
||||
placeholder="请到百度云控制台的图片处理获取,一般为后台展示所用"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div
|
||||
id="tencentCosForm"
|
||||
v-show="options.attachment_type === 'TENCENTCOS'"
|
||||
>
|
||||
<a-form-item label="绑定域名协议:">
|
||||
<a-select v-model="options.cos_tencent_domain_protocol">
|
||||
<a-select-option value="https://">HTTPS</a-select-option>
|
||||
<a-select-option value="http://">HTTP</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="绑定域名:">
|
||||
<a-input
|
||||
v-model="options.cos_tencent_domain"
|
||||
placeholder="如不填写,路径根域名将为 Bucket + 区域地址"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="Bucket:">
|
||||
<a-input
|
||||
v-model="options.cos_tencent_bucket_name"
|
||||
placeholder="存储桶名称"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="区域:">
|
||||
<a-auto-complete
|
||||
:dataSource="tencentCosRegions"
|
||||
v-model="options.cos_tencent_region"
|
||||
allowClear
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="Secret Id:">
|
||||
<a-input-password
|
||||
v-model="options.cos_tencent_secret_id"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="Secret Key:">
|
||||
<a-input-password
|
||||
v-model="options.cos_tencent_secret_key"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="文件目录:">
|
||||
<a-input
|
||||
v-model="options.cos_tencent_source"
|
||||
placeholder="不填写则上传到根目录"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="图片处理策略:">
|
||||
<a-input
|
||||
v-model="options.cos_tencent_style_rule"
|
||||
placeholder="请到腾讯云控制台的图片处理获取"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="缩略图处理策略:">
|
||||
<a-input
|
||||
v-model="options.cos_tencent_thumbnail_style_rule"
|
||||
placeholder="请到腾讯云控制台的图片处理获取,一般为后台展示所用"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<a-form-item>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="handleSaveOptions"
|
||||
>保存</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import attachmentApi from '@/api/attachment'
|
||||
const tencentCosRegions = [
|
||||
{
|
||||
text: '北京一区',
|
||||
value: 'ap-beijing-1'
|
||||
},
|
||||
{
|
||||
text: '北京',
|
||||
value: 'ap-beijing'
|
||||
},
|
||||
{
|
||||
text: '上海(华东)',
|
||||
value: 'ap-shanghai'
|
||||
},
|
||||
{
|
||||
text: '广州(华南)',
|
||||
value: 'ap-guangzhou'
|
||||
},
|
||||
{
|
||||
text: '成都(西南)',
|
||||
value: 'ap-chengdu'
|
||||
},
|
||||
{
|
||||
text: '重庆',
|
||||
value: 'ap-chongqing'
|
||||
}
|
||||
]
|
||||
const qiniuOssZones = [
|
||||
{
|
||||
text: '自动选择',
|
||||
value: 'auto'
|
||||
},
|
||||
{
|
||||
text: '华东',
|
||||
value: 'z0'
|
||||
},
|
||||
{
|
||||
text: '华北',
|
||||
value: 'z1'
|
||||
},
|
||||
{
|
||||
text: '华南',
|
||||
value: 'z2'
|
||||
},
|
||||
{
|
||||
text: '北美',
|
||||
value: 'na0'
|
||||
},
|
||||
{
|
||||
text: '东南亚',
|
||||
value: 'as0'
|
||||
}
|
||||
]
|
||||
export default {
|
||||
name: 'AttachmentTab',
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
attachmentType: attachmentApi.type,
|
||||
wrapperCol: {
|
||||
xl: { span: 8 },
|
||||
lg: { span: 8 },
|
||||
sm: { span: 12 },
|
||||
xs: { span: 24 }
|
||||
},
|
||||
tencentCosRegions,
|
||||
qiniuOssZones
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
options(val) {
|
||||
this.$emit('onChange', val)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSaveOptions() {
|
||||
// 附件配置验证
|
||||
switch (this.options.attachment_type) {
|
||||
case 'SMMS':
|
||||
if (!this.options.smms_api_secret_token) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: 'Secret Token 不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
break
|
||||
case 'UPOSS':
|
||||
if (!this.options.oss_upyun_domain) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: '绑定域名不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.oss_upyun_bucket) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: '空间名称不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.oss_upyun_operator) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: '操作员名称不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.oss_upyun_password) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: '操作员密码不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.oss_upyun_source) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: '文件目录不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
break
|
||||
case 'QINIUOSS':
|
||||
if (!this.options.oss_qiniu_domain) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: '绑定域名不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.oss_qiniu_access_key) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: 'Access Key 不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.oss_qiniu_secret_key) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: 'Secret Key 不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.oss_qiniu_bucket) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: 'Bucket 不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
break
|
||||
case 'ALIOSS':
|
||||
if (!this.options.oss_ali_bucket_name) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: 'Bucket 不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.oss_ali_endpoint) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: 'EndPoint(地域节点) 不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.oss_ali_access_key) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: 'Access Key 不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.oss_ali_access_secret) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: 'Access Secret 不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
break
|
||||
case 'BAIDUBOS':
|
||||
if (!this.options.bos_baidu_bucket_name) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: 'Bucket 不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.bos_baidu_endpoint) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: 'EndPoint(地域节点) 不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.bos_baidu_access_key) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: 'Access Key 不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.bos_baidu_secret_key) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: 'Secret Key 不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
break
|
||||
case 'TENCENTCOS':
|
||||
if (!this.options.cos_tencent_bucket_name) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: 'Bucket 不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.cos_tencent_region) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: '区域不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.cos_tencent_secret_id) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: 'Secret Id 不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.cos_tencent_secret_key) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: 'Secret Key 不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
this.$emit('onSave')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,109 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-form
|
||||
layout="vertical"
|
||||
:wrapperCol="wrapperCol"
|
||||
>
|
||||
<a-form-item label="评论者头像:">
|
||||
<a-select v-model="options.comment_gravatar_default">
|
||||
<a-select-option value="mm">默认</a-select-option>
|
||||
<a-select-option value="identicon">抽象几何图形</a-select-option>
|
||||
<a-select-option value="monsterid">小怪物</a-select-option>
|
||||
<a-select-option value="wavatar">Wavatar</a-select-option>
|
||||
<a-select-option value="retro">复古</a-select-option>
|
||||
<a-select-option value="robohash">机器人</a-select-option>
|
||||
<a-select-option value="blank">不显示头像</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="评论审核后才显示:">
|
||||
<a-switch v-model="options.comment_new_need_check" />
|
||||
</a-form-item>
|
||||
<a-form-item label="新评论通知:">
|
||||
<a-switch v-model="options.comment_new_notice" />
|
||||
</a-form-item>
|
||||
<a-form-item label="评论回复通知对方:">
|
||||
<a-switch v-model="options.comment_reply_notice" />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
label="API 评论开关:"
|
||||
help="* 关闭之后将无法进行评论"
|
||||
>
|
||||
<a-switch v-model="options.comment_api_enabled" />
|
||||
</a-form-item>
|
||||
<a-form-item label="评论模块 JS:">
|
||||
<a-input
|
||||
type="textarea"
|
||||
:autoSize="{ minRows: 2 }"
|
||||
v-model="options.comment_internal_plugin_js"
|
||||
placeholder="该设置仅对内置的评论模块有效"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="每页显示条数: ">
|
||||
<a-input
|
||||
type="number"
|
||||
v-model="options.comment_page_size"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="占位提示:">
|
||||
<a-input v-model="options.comment_content_placeholder" />
|
||||
</a-form-item>
|
||||
<!-- <a-form-item
|
||||
label="自定义样式:"
|
||||
|
||||
>
|
||||
<a-input
|
||||
type="textarea"
|
||||
:autoSize="{ minRows: 5 }"
|
||||
v-model="options.comment_custom_style"
|
||||
/>
|
||||
</a-form-item> -->
|
||||
<a-form-item>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="handleSaveOptions"
|
||||
>保存</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'CommentTab',
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
wrapperCol: {
|
||||
xl: { span: 8 },
|
||||
lg: { span: 8 },
|
||||
sm: { span: 12 },
|
||||
xs: { span: 24 }
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
options(val) {
|
||||
this.$emit('onChange', val)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSaveOptions() {
|
||||
// 新评论通知和回复通知验证
|
||||
if (this.options.comment_new_notice || this.options.comment_reply_notice) {
|
||||
if (!this.options.email_enabled) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: '新评论通知或回复通知需要打开和配置 SMTP 服务!'
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
this.$emit('onSave')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,143 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-form
|
||||
layout="vertical"
|
||||
:wrapperCol="wrapperCol"
|
||||
>
|
||||
<a-form-item label="博客标题:">
|
||||
<a-input v-model="options.blog_title" />
|
||||
</a-form-item>
|
||||
<a-form-item label="博客地址:">
|
||||
<a-input
|
||||
v-model="options.blog_url"
|
||||
placeholder="如:https://halo.run"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="Logo:">
|
||||
<a-input v-model="options.blog_logo">
|
||||
<a
|
||||
href="javascript:void(0);"
|
||||
slot="addonAfter"
|
||||
@click="()=>this.logoDrawerVisible = true"
|
||||
>
|
||||
<a-icon type="picture" />
|
||||
</a>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="Favicon:">
|
||||
<a-input v-model="options.blog_favicon">
|
||||
<a
|
||||
href="javascript:void(0);"
|
||||
slot="addonAfter"
|
||||
@click="()=>this.faviconDrawerVisible = true"
|
||||
>
|
||||
<a-icon type="picture" />
|
||||
</a>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="页脚信息:">
|
||||
<a-input
|
||||
type="textarea"
|
||||
:autoSize="{ minRows: 5 }"
|
||||
v-model="options.blog_footer_info"
|
||||
placeholder="支持 HTML 格式的文本"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="handleSaveOptions"
|
||||
>保存</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<AttachmentSelectDrawer
|
||||
v-model="logoDrawerVisible"
|
||||
@listenToSelect="handleSelectLogo"
|
||||
title="选择 Logo"
|
||||
/>
|
||||
<AttachmentSelectDrawer
|
||||
v-model="faviconDrawerVisible"
|
||||
@listenToSelect="handleSelectFavicon"
|
||||
title="选择 Favicon"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AttachmentSelectDrawer from '../../attachment/components/AttachmentSelectDrawer'
|
||||
export default {
|
||||
name: 'GeneralTab',
|
||||
components: {
|
||||
AttachmentSelectDrawer
|
||||
},
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
wrapperCol: {
|
||||
xl: { span: 8 },
|
||||
lg: { span: 8 },
|
||||
sm: { span: 12 },
|
||||
xs: { span: 24 }
|
||||
},
|
||||
logoDrawerVisible: false,
|
||||
faviconDrawerVisible: false
|
||||
}
|
||||
},
|
||||
destroyed: function() {
|
||||
if (this.faviconDrawerVisible) {
|
||||
this.faviconDrawerVisible = false
|
||||
}
|
||||
if (this.logoDrawerVisible) {
|
||||
this.logoDrawerVisible = false
|
||||
}
|
||||
},
|
||||
beforeRouteLeave(to, from, next) {
|
||||
if (this.faviconDrawerVisible) {
|
||||
this.faviconDrawerVisible = false
|
||||
}
|
||||
if (this.logoDrawerVisible) {
|
||||
this.logoDrawerVisible = false
|
||||
}
|
||||
next()
|
||||
},
|
||||
watch: {
|
||||
options(val) {
|
||||
this.$emit('onChange', val)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSaveOptions() {
|
||||
if (!this.options.blog_title) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: '博客标题不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.options.blog_url) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: '博客地址不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$emit('onSave')
|
||||
},
|
||||
handleSelectLogo(data) {
|
||||
this.$set(this.options, 'blog_logo', encodeURI(data.path))
|
||||
this.logoDrawerVisible = false
|
||||
},
|
||||
handleSelectFavicon(data) {
|
||||
this.$set(this.options, 'blog_favicon', encodeURI(data.path))
|
||||
this.faviconDrawerVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,81 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-form
|
||||
layout="vertical"
|
||||
:wrapperCol="wrapperCol"
|
||||
>
|
||||
<a-form-item label="自定义全局 head:">
|
||||
<a-input
|
||||
type="textarea"
|
||||
:autoSize="{ minRows: 5 }"
|
||||
v-model="options.blog_custom_head"
|
||||
placeholder="放置于每个页面的 <head></head> 标签中"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="自定义内容页 head:">
|
||||
<a-input
|
||||
type="textarea"
|
||||
:autoSize="{ minRows: 5 }"
|
||||
v-model="options.blog_custom_content_head"
|
||||
placeholder="仅放置于内容页面的 <head></head> 标签中"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="统计代码:">
|
||||
<a-input
|
||||
type="textarea"
|
||||
:autoSize="{ minRows: 5 }"
|
||||
v-model="options.blog_statistics_code"
|
||||
placeholder="第三方网站统计的代码,如:Google Analytics、百度统计、CNZZ 等"
|
||||
/>
|
||||
</a-form-item>
|
||||
<!-- <a-form-item
|
||||
label="黑名单 IP:"
|
||||
|
||||
>
|
||||
<a-input
|
||||
type="textarea"
|
||||
:autoSize="{ minRows: 5 }"
|
||||
v-model="options.blog_ip_blacklist"
|
||||
placeholder="多个 IP 地址换行隔开"
|
||||
/>
|
||||
</a-form-item> -->
|
||||
<a-form-item>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="handleSaveOptions"
|
||||
>保存</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'OtherTab',
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
wrapperCol: {
|
||||
xl: { span: 8 },
|
||||
lg: { span: 8 },
|
||||
sm: { span: 12 },
|
||||
xs: { span: 24 }
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
options(val) {
|
||||
this.$emit('onChange', val)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSaveOptions() {
|
||||
this.$emit('onSave')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,111 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-form
|
||||
layout="vertical"
|
||||
:wrapperCol="wrapperCol"
|
||||
>
|
||||
<a-form-item label="文章固定链接类型:">
|
||||
<template slot="help">
|
||||
<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 === 'DAY'">{{ options.blog_url }}{{ new Date() | moment_post_day }}${slug}{{ options.path_suffix }}</span>
|
||||
<span v-else-if="options.post_permalink_type === 'ID'">{{ options.blog_url }}/?p=${id}</span>
|
||||
</template>
|
||||
<a-select v-model="options.post_permalink_type">
|
||||
<a-select-option
|
||||
v-for="item in Object.keys(permalinkType)"
|
||||
:key="item"
|
||||
:value="item"
|
||||
>{{ permalinkType[item].text }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="自定义页面前缀:">
|
||||
<template slot="help">
|
||||
<span>{{ options.blog_url }}/{{ options.sheet_prefix }}/${slug}{{ options.path_suffix }}</span>
|
||||
</template>
|
||||
<a-input v-model="options.sheet_prefix" />
|
||||
</a-form-item>
|
||||
<a-form-item label="友情链接页面前缀:">
|
||||
<template slot="help">
|
||||
<span>{{ options.blog_url }}/{{ options.links_prefix }}{{ options.path_suffix }}</span>
|
||||
</template>
|
||||
<a-input v-model="options.links_prefix" />
|
||||
</a-form-item>
|
||||
<a-form-item label="图库页面前缀:">
|
||||
<template slot="help">
|
||||
<span>{{ options.blog_url }}/{{ options.photos_prefix }}{{ options.path_suffix }}</span>
|
||||
</template>
|
||||
<a-input v-model="options.photos_prefix" />
|
||||
</a-form-item>
|
||||
<a-form-item label="日志页面前缀:">
|
||||
<template slot="help">
|
||||
<span>{{ options.blog_url }}/{{ options.journals_prefix }}{{ options.path_suffix }}</span>
|
||||
</template>
|
||||
<a-input v-model="options.journals_prefix" />
|
||||
</a-form-item>
|
||||
<a-form-item label="归档前缀:">
|
||||
<template slot="help">
|
||||
<span>{{ options.blog_url }}/{{ options.archives_prefix }}{{ options.path_suffix }}</span>
|
||||
</template>
|
||||
<a-input v-model="options.archives_prefix" />
|
||||
</a-form-item>
|
||||
<a-form-item label="分类前缀:">
|
||||
<template slot="help">
|
||||
<span>{{ options.blog_url }}/{{ options.categories_prefix }}/${slug}{{ options.path_suffix }}</span>
|
||||
</template>
|
||||
<a-input v-model="options.categories_prefix" />
|
||||
</a-form-item>
|
||||
<a-form-item label="标签前缀:">
|
||||
<template slot="help">
|
||||
<span>{{ options.blog_url }}/{{ options.tags_prefix }}/${slug}{{ options.path_suffix }}</span>
|
||||
</template>
|
||||
<a-input v-model="options.tags_prefix" />
|
||||
</a-form-item>
|
||||
<a-form-item label="路径后缀:">
|
||||
<template slot="help">
|
||||
<span>* 格式为:<code>.${suffix}</code>,仅对内建路径有效</span>
|
||||
</template>
|
||||
<a-input v-model="options.path_suffix" />
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="handleSaveOptions"
|
||||
>保存</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import postApi from '@/api/post'
|
||||
export default {
|
||||
name: 'PermalinkTab',
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
permalinkType: postApi.permalinkType,
|
||||
wrapperCol: {
|
||||
xl: { span: 8 },
|
||||
lg: { span: 8 },
|
||||
sm: { span: 12 },
|
||||
xs: { span: 24 }
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
options(val) {
|
||||
this.$emit('onChange', val)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSaveOptions() {
|
||||
this.$emit('onSave')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,89 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-form
|
||||
layout="vertical"
|
||||
:wrapperCol="wrapperCol"
|
||||
>
|
||||
<a-form-item label="默认编辑器:">
|
||||
<a-select v-model="options.default_editor">
|
||||
<a-select-option value="MARKDOWN">Markdown 编辑器</a-select-option>
|
||||
<a-select-option value="RICHTEXT">富文本编辑器</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="首页文章排序:">
|
||||
<a-select v-model="options.post_index_sort">
|
||||
<a-select-option value="createTime">创建时间</a-select-option>
|
||||
<a-select-option value="editTime">最后编辑时间</a-select-option>
|
||||
<a-select-option value="visits">点击量</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="首页每页条数:">
|
||||
<a-input
|
||||
type="number"
|
||||
v-model="options.post_index_page_size"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="归档每页条数:">
|
||||
<a-input
|
||||
type="number"
|
||||
v-model="options.post_archives_page_size"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="RSS 内容类型:">
|
||||
<a-select v-model="options.rss_content_type">
|
||||
<a-select-option value="full">全文</a-select-option>
|
||||
<a-select-option value="summary">摘要</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="RSS 内容条数:">
|
||||
<a-input
|
||||
type="number"
|
||||
v-model="options.rss_page_size"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="文章摘要字数:">
|
||||
<a-input
|
||||
type="number"
|
||||
v-model="options.post_summary_length"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="handleSaveOptions"
|
||||
>保存</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'PostTab',
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
wrapperCol: {
|
||||
xl: { span: 8 },
|
||||
lg: { span: 8 },
|
||||
sm: { span: 12 },
|
||||
xs: { span: 24 }
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
options(val) {
|
||||
this.$emit('onChange', val)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSaveOptions() {
|
||||
this.$emit('onSave')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,62 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-form
|
||||
layout="vertical"
|
||||
:wrapperCol="wrapperCol"
|
||||
>
|
||||
<a-form-item label="屏蔽搜索引擎:">
|
||||
<a-switch v-model="options.seo_spider_disabled" />
|
||||
</a-form-item>
|
||||
<a-form-item label="关键词:">
|
||||
<a-input
|
||||
v-model="options.seo_keywords"
|
||||
placeholder="多个关键词以英文状态下的逗号隔开"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="博客描述:">
|
||||
<a-input
|
||||
type="textarea"
|
||||
:autoSize="{ minRows: 5 }"
|
||||
v-model="options.seo_description"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="handleSaveOptions"
|
||||
>保存</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'SeoTab',
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
wrapperCol: {
|
||||
xl: { span: 8 },
|
||||
lg: { span: 8 },
|
||||
sm: { span: 12 },
|
||||
xs: { span: 24 }
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
options(val) {
|
||||
this.$emit('onChange', val)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSaveOptions() {
|
||||
this.$emit('onSave')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,180 @@
|
|||
<template>
|
||||
<div class="custom-tab-wrapper">
|
||||
<a-tabs>
|
||||
<a-tab-pane
|
||||
tab="发信设置"
|
||||
key="smtpoptions"
|
||||
>
|
||||
<a-form
|
||||
layout="vertical"
|
||||
:wrapperCol="wrapperCol"
|
||||
>
|
||||
<a-form-item label="是否启用:">
|
||||
<a-switch v-model="options.email_enabled" />
|
||||
</a-form-item>
|
||||
<a-form-item label="SMTP 地址:">
|
||||
<a-input v-model="options.email_host" />
|
||||
</a-form-item>
|
||||
<a-form-item label="发送协议:">
|
||||
<a-input v-model="options.email_protocol" />
|
||||
</a-form-item>
|
||||
<a-form-item label="SSL 端口:">
|
||||
<a-input v-model="options.email_ssl_port" />
|
||||
</a-form-item>
|
||||
<a-form-item label="邮箱账号:">
|
||||
<a-input v-model="options.email_username" />
|
||||
</a-form-item>
|
||||
<a-form-item label="邮箱密码:">
|
||||
<a-input-password
|
||||
v-model="options.email_password"
|
||||
placeholder="部分邮箱可能是授权码"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="发件人:">
|
||||
<a-input v-model="options.email_from_name" />
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="handleSaveOptions"
|
||||
>保存</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane
|
||||
tab="发送测试"
|
||||
key="smtptest"
|
||||
>
|
||||
<a-form
|
||||
layout="vertical"
|
||||
:wrapperCol="wrapperCol"
|
||||
>
|
||||
<a-form-item label="收件人:">
|
||||
<a-input v-model="mailParam.to" />
|
||||
</a-form-item>
|
||||
<a-form-item label="主题:">
|
||||
<a-input v-model="mailParam.subject" />
|
||||
</a-form-item>
|
||||
<a-form-item label="内容:">
|
||||
<a-input
|
||||
type="textarea"
|
||||
:autoSize="{ minRows: 5 }"
|
||||
v-model="mailParam.content"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="handleTestMailClick"
|
||||
>发送</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import mailApi from '@/api/mail'
|
||||
export default {
|
||||
name: 'SmtpTab',
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
wrapperCol: {
|
||||
xl: { span: 8 },
|
||||
lg: { span: 8 },
|
||||
sm: { span: 12 },
|
||||
xs: { span: 24 }
|
||||
},
|
||||
mailParam: {}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
options(val) {
|
||||
this.$emit('onChange', val)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSaveOptions() {
|
||||
// SMTP 配置验证
|
||||
if (this.options.email_enabled) {
|
||||
if (!this.options.email_host) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: 'SMTP 地址不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.email_protocol) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: '发送协议不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.email_ssl_port) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: 'SSL 端口不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.email_username) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: '邮箱账号不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.email_password) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: '邮箱密码不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.options.email_from_name) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: '发件人不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
this.$emit('onSave')
|
||||
},
|
||||
handleTestMailClick() {
|
||||
if (!this.mailParam.to) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: '收件人不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.mailParam.subject) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: '主题不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.mailParam.content) {
|
||||
this.$notification['error']({
|
||||
message: '提示',
|
||||
description: '内容不能为空!'
|
||||
})
|
||||
return
|
||||
}
|
||||
mailApi.testMail(this.mailParam).then(response => {
|
||||
this.$message.info(response.data.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
Loading…
Reference in New Issue