398 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="container">
<el-card class="box-card">
<a-affix>
<div class="box-card-header">
<div class="clearfix card-header-back">
<div v-if="!subpage">
<span>外观设置</span>
<el-button round class="card-button" size="mini" type="primary" @click="save()">保存设置</el-button>
</div>
<div v-if="subpage">
<div class="card-header-back">
<span class="header-back-title" @click="backParent">
<i class="el-icon-back"></i>
<span>返回</span>
</span>
</div>
</div>
</div>
</div>
</a-affix>
<el-tabs v-if="!subpage" v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="网站首页" name="1">
<div class="config-itme-label">网站图标:</div>
<upload-image-input v-model="form.siteIco" desc="只支持ico格式" :enable-select="false" :enable-url="false" accept="image/vnd.microsoft.icon"/>
<span class="instruction"><a href="https://tool.lu/favicon/" target="_blank">在线制作ico</a></span>
<div class="config-itme-label">站点名称:</div>
<el-input autosize type="textarea" width="100%" v-model="form.siteName"></el-input>
<span class="instruction">给您的网站取一个响亮的名字。</span>
<div class="config-itme-label">站点地址:</div>
<el-input autosize type="textarea" width="100%" v-model="form.siteUrl"></el-input>
<span class="instruction">在这里填入站点的地址或域名。例如:<a :href="blogUrlExample" target="_blank">{{ blogUrlExample }}</a></span>
<div class="config-itme-label">站点背景大图:</div><upload-image-input v-model="form.backgroundSite"/>
<span class="instruction">在这里填入图片的URL地址, 以在网站首页显示一个背景大图。</span>
<div class="config-itme-label">首页大图内文字:
<el-button round type="text" @click="heartwings">历史记录</el-button>
</div>
<el-input autosize type="textarea" v-model="form.backgroundTextSite"></el-input>
<span class="instruction">显示在博客首页大图内的主要文字。</span>
<div class="config-itme-label">首页大图内描述:</div>
<el-input autosize type="textarea" v-model="form.backgroundDescSite"></el-input>
<span class="instruction">显示在博客首页大图内的次要文字。</span>
</el-tab-pane>
<el-tab-pane label="导航栏" name="2">
<div class="config-itme-label">导航栏顶部 - 网站 Logo:</div>
<el-input autosize type="textarea" width="100%" v-model="form.siteLogo"></el-input>
<span class="instruction">配置网站的 Logo,该选项仅作用于顶部导航条</span>
<div class="config-itme-label">导航栏操作按钮:</div>
<el-input type="textarea" width="100%" v-model="form.operatingButtons" :autosize="{ minRows: 1, maxRows: 6 }"
@input="preview"></el-input>
<span class="instruction">
一个操作按钮包含两个部分:
<a href="https://fontawesome.com/icons?d=gallery" target="_blank">Font-awesome</a>
图标标签和链接,使用':'隔开(标签里的内容为该图标的简述)。
<br>
列如:{{ example }}:https://github.com/jamebal/jmal-cloud-view (建议不超过5项)
</span>
<div>
<el-divider content-position="center">预览</el-divider>
<ul class="navbar-nav side-toolbar-list">
<li v-for="operatingButton in operatingButtons">
<a :href="operatingButton.url" :title="operatingButton.title" target="_blank">
<dl v-html="operatingButton.fontHtml">
{{ operatingButton.fontHtml }}
</dl>
</a>
</li>
</ul>
</div>
</el-tab-pane>
<el-tab-pane label="归档、分类、标签" name="3">
<div class="config-itme-label">页面显示与否:</div>
<el-checkbox-group v-model="form.alonePages">
<el-checkbox label="archives">归档</el-checkbox>
<el-checkbox label="categories">分类</el-checkbox>
<el-checkbox label="tags">标签</el-checkbox>
</el-checkbox-group>
<span class="instruction">选中项会显示在导航栏中</span>
<div class="config-itme-label">归档界面背景大图:</div>
<upload-image-input v-model="form.archiveBackground"/>
<span class="instruction">在这里填入图片的URL地址, 以在归档页面显示一个背景大图。</span>
<div class="config-itme-label">分类界面背景大图:</div>
<upload-image-input v-model="form.categoryBackground"/>
<span class="instruction">在这里填入图片的URL地址, 以在分类页面显示一个背景大图。</span>
<div class="config-itme-label">标签界面背景大图:</div>
<upload-image-input v-model="form.tagBackground"/>
<span class="instruction">在这里填入图片的URL地址, 以在分类页面显示一个背景大图。</span>
</el-tab-pane>
<el-tab-pane label="网站页脚" name="4">
<div class="config-itme-label">版权信息:</div>
<el-input autosize type="textarea" width="100%" v-model="form.copyright"></el-input>
<div class="config-itme-label">备案许可号:</div>
<el-input autosize type="textarea" width="100%" v-model="form.recordPermissionNum"></el-input>
<div class="config-itme-label">网站联网备案号:</div>
<el-input autosize type="textarea" width="100%" v-model="form.networkRecordNumber"></el-input>
<div class="config-itme-label">网站联网备案号文本:</div>
<el-input autosize type="textarea" width="100%" v-model="form.networkRecordNumberStr"></el-input>
<div class="config-itme-label">自定义页脚html:</div>
<el-input :autosize="{ minRows: 2}" type="textarea" width="100%" v-model="form.footerHtml"></el-input>
<div>
<el-divider content-position="center">预览</el-divider>
<footer id="footer" style="font-size: 0.725rem;">
<div v-if="!form.footerHtml">
<div>{{ form.copyright }}</div>
<span>
<a target="_blank" href="https://beian.miit.gov.cn" >{{ form.recordPermissionNum }}</a>
<a target="_blank" :href="'http://www.beian.gov.cn/portal/registerSystemInfo?recordcode='+form.networkRecordNumber" ><img v-if="form.networkRecordNumberStr" src="~@/assets/img/beian.png"/>{{ form.networkRecordNumberStr }}</a>
</span>
</div>
<div ref="previewFooterHtml" v-else v-html="sanitizedHtml" />
</footer>
</div>
</el-tab-pane>
</el-tabs>
<div v-if="subpage" class="list-body">
<table-list
ref="tableList"
:less-client-height="280"
:tableData="dataList"
:loading="heartwingsLoading"
:hasSelection="false"
:tableHeader="tableHeader"
:pagination="pagination"
@pageChange="pageChange"
@sizeChange="pageChange"
@sortChange="sortChange"
></table-list>
</div>
</el-card>
</div>
</template>
<script>
import {getSetting, getHeartwings, updateSetting} from '@/api/setting-api'
import UploadImageInput from "@/components/input/UploadImageInput"
import TableList from "@/components/table/TableList"
export default {
name: 'blogManager',
components: {
UploadImageInput,
TableList
},
data() {
return {
blogUrlExample: `${window.location.protocol}//${window.location.host}/blog`,
subpage: false,
activeName: '1',
example: '<i class="fab fa-github">github</i>',
form: {
siteUrl: '',
backgroundSite: '',
backgroundTextSite: '',
backgroundDescSite: '',
siteIco: '',
siteName: '',
siteLogo: '',
operatingButtons: '',
categoryBackground: '',
archiveBackground: '',
tagBackground: '',
alonePages: [],
copyright: '',
recordPermissionNum: '',
networkRecordNumber: '',
networkRecordNumberStr: '',
footerHtml: ''
},
operatingButtons: [],
dataList: [],
heartwingsLoading: false,
tableHeader: [
{prop: 'heartwings',label: '心语', minWidth: 450},
{prop: 'username',label: '账号', minWidth: 110},
{prop: 'createTime',label: '创建时间', minWidth: 110, sortable: 'custom'},
],
queryCondition: {
sortProp: '',
sortOrder: 'descending'
},
pagination: {
pageIndex: 1,
pageSize: 15,
pageTotal: 0
},
}
},
computed: {
sanitizedHtml() {
return this.form.footerHtml;
}
},
mounted() {
this.getSetting()
if (this.$route.query.tab) {
this.activeName = this.$route.query.tab
}
},
watch: {
sanitizedHtml(newVal) {
this.$nextTick(() => {
this.loadScripts();
});
}
},
methods: {
loadScripts() {
const preview = this.$refs.previewFooterHtml;
const scripts = preview.querySelectorAll('script');
scripts.forEach(script => {
const newScript = document.createElement('script');
if (script.src) {
newScript.src = script.src;
} else {
newScript.innerHTML = script.innerHTML;
}
document.body.appendChild(newScript).parentNode.removeChild(newScript);
});
},
backParent() {
this.subpage = false
},
heartwings() {
this.subpage = true
this.heartwingsLoading = true
this.getHeartwingsList()
},
getHeartwingsList() {
getHeartwings({
page: this.pagination.pageIndex,
pageSize: this.pagination.pageSize,
order: this.queryCondition.sortOrder
}).then((res) => {
this.dataList = res.data
this.heartwingsLoading = false
this.pagination.pageTotal = res.count
}).catch(() => {
this.heartwingsLoading = false
})
},
pageChange(data) {
this.pagination = data.backData;
this.getHeartwingsList()
},
sortChange(data) {
let column = data.backData;
this.queryCondition.sortProp = column.prop
this.queryCondition.sortOrder = column.order
this.getHeartwingsList()
},
handleClick(tab) {
this.$router.push({query: {tab: tab.name}})
},
preview() {
this.operatingButtons = []
if (this.form.operatingButtons) {
this.form.operatingButtons.split(/[\n]/).forEach(button => {
let operatingButton = {}
const splitIndex = button.indexOf(":")
const ihtml = button.substring(0, splitIndex)
// 获取标签里的内容
let regLabel = /[^><]+(?=<\/i>)/img
const title = ihtml.match(regLabel)
operatingButton.title = title ? title[0] : ''
// 去掉标签里的内容
operatingButton.fontHtml = ihtml.replace(regLabel, '')
operatingButton.url = button.substring(splitIndex + 1, button.length)
this.operatingButtons.push(operatingButton)
})
}
},
getSetting() {
getSetting({userId: this.$store.state.user.userId}).then((res) => {
if (res.data) {
this.form = res.data;
this.preview()
}
}).catch(() => {
})
},
save() {
this.form.userId = this.$store.state.user.userId
updateSetting(this.form).then(() => {
this.$message.success("保存成功!")
}).catch(() => {
})
}
}
}
</script>
<style lang="scss" scoped>
@import "src/styles/setting";
@import "src/styles/markdown";
>>> .el-collapse-item__header {
font-size: 16px;
padding-left: 20px;
}
.list-body {
padding-bottom: 15px;
}
>>> .el-card__body {
padding: 0;
}
.box-card-header {
padding: 15px 20px;
border-bottom: 1px solid #EBEEF5;
-webkit-box-sizing: border-box;
box-sizing: border-box;
background: rgba(235, 235, 235, 0.3);
-webkit-backdrop-filter: blur(20px);
backdrop-filter: blur(20px);
}
>>> .el-divider__text {
background-color: #fafafa;
}
.side-toolbar-list {
text-align: center;
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
li {
position: relative;
display: inline-block;
margin: 0 .25rem;
}
li a {
display: inline-block;
height: 2.75rem;
width: 2.75rem;
line-height: 2.75rem;
border-radius: 100%;
font-size: 1rem;
background: #f0f0f0;
color: #333;
vertical-align: middle;
-webkit-transition: 0.3s ease all;
-moz-transition: 0.3s ease all;
-ms-transition: 0.3s ease all;
-o-transition: 0.3s ease all;
transition: 0.3s ease all;
svg {
width: 22px;
height: 22px;
margin-top: 10px;
}
}
li a:hover {
background: #333;
color: #fff;
}
}
>>> .el-tabs__header {
margin: 0;
@media screen and (min-width: 768px) {
.el-tabs__nav {
padding: 0 20px;
}
.el-tabs__active-bar {
left: 20px;
}
}
}
.config-itme-label {
>>> .el-button {
padding: 0 0;
}
}
footer {
margin: 0 auto;
overflow: hidden;
text-align: center;
-webkit-transition: 0.5s ease all;
transition: 0.5s ease all;
border: 1px dashed #dddfe6;
}
footer, footer p {
font-size: .8125rem;
}
</style>