|
|
|
@ -4,7 +4,7 @@
|
|
|
|
|
<!-- 网站信息 -->
|
|
|
|
|
<div class="card-content1 shadow-box background-opacity">
|
|
|
|
|
<el-avatar style="margin-top: 20px" class="user-avatar" :size="120" :src="currentUser.avatar"></el-avatar>
|
|
|
|
|
<div class="web-name">{{webInfo.webName}}</div>
|
|
|
|
|
<div class="web-name">{{currentUser.username}}</div>
|
|
|
|
|
<div class="web-info">
|
|
|
|
|
<div class="blog-info-box">
|
|
|
|
|
<span>博客</span>
|
|
|
|
@ -23,12 +23,116 @@
|
|
|
|
|
<i class="el-icon-star-off" style="margin-right: 2px"></i>朋友圈
|
|
|
|
|
</a>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div style="display: inline-block;position: absolute;left: 470px;top: 208px; width: fit-content">
|
|
|
|
|
<!-- 写博客按钮 -->
|
|
|
|
|
<button class="write-blog-btn" @click="showEditor = true">
|
|
|
|
|
✍️ 写博客
|
|
|
|
|
✍️ 写个人博客
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
<div style="text-align: center;display: inline-block">
|
|
|
|
|
<button class="publicBlog" @click="showPostEditor = true">✍️ 写公开博客</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<!--公开文章框-->
|
|
|
|
|
<div id="editorPost" v-if="showPostEditor" style="background-color: #efe5fa;padding-bottom: 10px">
|
|
|
|
|
<div>
|
|
|
|
|
<el-tag effect="dark" class="my-tag">
|
|
|
|
|
<svg viewBox="0 0 1024 1024" width="20" height="20" style="vertical-align: -3px;">
|
|
|
|
|
<path d="M0 0h1024v1024H0V0z" fill="#202425" opacity=".01"></path>
|
|
|
|
|
<path
|
|
|
|
|
d="M682.666667 204.8h238.933333a34.133333 34.133333 0 0 1 34.133333 34.133333v648.533334a68.266667 68.266667 0 0 1-68.266666 68.266666h-204.8V204.8z"
|
|
|
|
|
fill="#FFAA44"></path>
|
|
|
|
|
<path
|
|
|
|
|
d="M68.266667 921.6a34.133333 34.133333 0 0 0 34.133333 34.133333h785.066667a68.266667 68.266667 0 0 1-68.266667-68.266666V102.4a34.133333 34.133333 0 0 0-34.133333-34.133333H102.4a34.133333 34.133333 0 0 0-34.133333 34.133333v819.2z"
|
|
|
|
|
fill="#11AA66"></path>
|
|
|
|
|
<path
|
|
|
|
|
d="M238.933333 307.2a34.133333 34.133333 0 0 0 0 68.266667h136.533334a34.133333 34.133333 0 1 0 0-68.266667H238.933333z m0 204.8a34.133333 34.133333 0 1 0 0 68.266667h409.6a34.133333 34.133333 0 1 0 0-68.266667H238.933333z m0 204.8a34.133333 34.133333 0 1 0 0 68.266667h204.8a34.133333 34.133333 0 1 0 0-68.266667H238.933333z"
|
|
|
|
|
fill="#FFFFFF"></path>
|
|
|
|
|
</svg>
|
|
|
|
|
文章信息
|
|
|
|
|
</el-tag>
|
|
|
|
|
<el-form :model="article" :rules="rules" ref="ruleForm" label-width="150px"
|
|
|
|
|
class="demo-ruleForm">
|
|
|
|
|
<el-form-item label="标题" prop="articleTitle">
|
|
|
|
|
<el-input maxlength="30" v-model="article.articleTitle"></el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
<el-form-item label="内容" prop="articleContent">
|
|
|
|
|
<mavon-editor ref="md" @imgAdd="imgAdd" v-model="article.articleContent"/>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
<el-form-item label="是否启用评论" prop="commentStatus">
|
|
|
|
|
<el-tag :type="article.commentStatus === false ? 'danger' : 'success'"
|
|
|
|
|
disable-transitions>
|
|
|
|
|
{{article.commentStatus === false ? '否' : '是'}}
|
|
|
|
|
</el-tag>
|
|
|
|
|
<el-switch v-model="article.commentStatus"></el-switch>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
<el-form-item label="是否推荐" prop="recommendStatus">
|
|
|
|
|
<el-tag :type="article.recommendStatus === false ? 'danger' : 'success'"
|
|
|
|
|
disable-transitions>
|
|
|
|
|
{{article.recommendStatus === false ? '否' : '是'}}
|
|
|
|
|
</el-tag>
|
|
|
|
|
<el-switch v-model="article.recommendStatus"></el-switch>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
<el-form-item label="是否可见" prop="viewStatus">
|
|
|
|
|
<el-tag :type="article.viewStatus === false ? 'danger' : 'success'"
|
|
|
|
|
disable-transitions>
|
|
|
|
|
{{article.viewStatus === false ? '否' : '是'}}
|
|
|
|
|
</el-tag>
|
|
|
|
|
<el-switch v-model="article.viewStatus"></el-switch>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
<el-form-item v-if="article.viewStatus === false" label="不可见时的访问密码" prop="password">
|
|
|
|
|
<el-input maxlength="30" v-model="article.password"></el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
<el-form-item v-if="article.viewStatus === false" label="密码提示" prop="tips">
|
|
|
|
|
<el-input maxlength="60" v-model="article.tips"></el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
<el-form-item label="封面" prop="articleCover">
|
|
|
|
|
<div style="display: flex">
|
|
|
|
|
<el-input v-model="article.articleCover"></el-input>
|
|
|
|
|
<el-image class="table-td-thumb"
|
|
|
|
|
lazy
|
|
|
|
|
style="margin-left: 10px"
|
|
|
|
|
:preview-src-list="[article.articleCover]"
|
|
|
|
|
:src="article.articleCover"
|
|
|
|
|
fit="cover"></el-image>
|
|
|
|
|
</div>
|
|
|
|
|
<uploadPicture :isAdmin="true" :prefix="'articleCover'" style="margin-top: 10px" @addPicture="addArticleCover"
|
|
|
|
|
:maxSize="2"
|
|
|
|
|
:maxNumber="1"></uploadPicture>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="分类" prop="sortId">
|
|
|
|
|
<el-select v-model="article.sortId" placeholder="请选择分类">
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="item in sorts"
|
|
|
|
|
:key="item.id"
|
|
|
|
|
:label="item.sortName"
|
|
|
|
|
:value="item.id">
|
|
|
|
|
</el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="标签" prop="labelId">
|
|
|
|
|
<el-select v-model="article.labelId" placeholder="请选择标签">
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="item in labelsTemp"
|
|
|
|
|
:key="item.id"
|
|
|
|
|
:label="item.labelName"
|
|
|
|
|
:value="item.id">
|
|
|
|
|
</el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
<div class="myCenter" style="margin-bottom: 22px">
|
|
|
|
|
<el-button type="primary" @click="submitForm('ruleForm')">保存</el-button>
|
|
|
|
|
<el-button type="danger" @click="resetForm('ruleForm')">重置所有修改</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- 编辑框 -->
|
|
|
|
|
<div id="editorArea" class="blog-editor" v-if="showEditor">
|
|
|
|
|
<textarea id ="areaTitle" class="blog-editor-title" v-model="blogContentTitle" placeholder="请输入博客标题..."></textarea>
|
|
|
|
@ -94,7 +198,7 @@
|
|
|
|
|
<!-- 推荐博客 -->
|
|
|
|
|
<div class="card-content2-title">
|
|
|
|
|
<i class="el-icon-reading card-content2-icon"></i>
|
|
|
|
|
<span style="font-size: 28px">我的博客</span>
|
|
|
|
|
<span style="font-size: 28px">我的个人博客</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div v-if="!$common.isEmpty(articles)" class="blog-card-container">
|
|
|
|
|
<div v-for="(article, index) in articles.slice().reverse()" :key="index" class="blog-card">
|
|
|
|
@ -132,13 +236,59 @@
|
|
|
|
|
import axios from "axios";
|
|
|
|
|
import * as events from "events";
|
|
|
|
|
import upload from '../utils/ajaxUpload';
|
|
|
|
|
const uploadPicture = () => import( "./common/uploadPicture");
|
|
|
|
|
export default {
|
|
|
|
|
components: {
|
|
|
|
|
uploadPicture
|
|
|
|
|
},
|
|
|
|
|
avatar: {
|
|
|
|
|
type: String
|
|
|
|
|
},
|
|
|
|
|
// 组件的逻辑和配置
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
id: this.$route.query.id,
|
|
|
|
|
article: {
|
|
|
|
|
articleTitle: "",
|
|
|
|
|
articleContent: "",
|
|
|
|
|
commentStatus: true,
|
|
|
|
|
recommendStatus: false,
|
|
|
|
|
viewStatus: true,
|
|
|
|
|
password: "",
|
|
|
|
|
tips: "",
|
|
|
|
|
articleCover: "",
|
|
|
|
|
sortId: null,
|
|
|
|
|
labelId: null
|
|
|
|
|
},
|
|
|
|
|
sorts: [],
|
|
|
|
|
labels: [],
|
|
|
|
|
labelsTemp: [],
|
|
|
|
|
rules: {
|
|
|
|
|
articleTitle: [
|
|
|
|
|
{required: true, message: '请输入标题', trigger: 'change'}
|
|
|
|
|
],
|
|
|
|
|
articleContent: [
|
|
|
|
|
{required: true, message: '请输入内容', trigger: 'change'}
|
|
|
|
|
],
|
|
|
|
|
commentStatus: [
|
|
|
|
|
{required: true, message: '是否启用评论', trigger: 'change'}
|
|
|
|
|
],
|
|
|
|
|
recommendStatus: [
|
|
|
|
|
{required: true, message: '是否推荐', trigger: 'change'}
|
|
|
|
|
],
|
|
|
|
|
viewStatus: [
|
|
|
|
|
{required: true, message: '是否可见', trigger: 'change'}
|
|
|
|
|
],
|
|
|
|
|
articleCover: [
|
|
|
|
|
{required: true, message: '封面', trigger: 'change'}
|
|
|
|
|
],
|
|
|
|
|
sortId: [
|
|
|
|
|
{required: true, message: '分类', trigger: 'change'}
|
|
|
|
|
],
|
|
|
|
|
labelId: [
|
|
|
|
|
{required: true, message: '标签', trigger: 'blur'}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
pagination: {
|
|
|
|
|
current: 1,
|
|
|
|
|
size: 5,
|
|
|
|
@ -150,6 +300,7 @@ export default {
|
|
|
|
|
showAdmireDialog: false,
|
|
|
|
|
articleSearch: "",
|
|
|
|
|
showEditor: false,
|
|
|
|
|
showPostEditor: false,
|
|
|
|
|
showUpdateBtn: false,
|
|
|
|
|
showPublishBtn: true,
|
|
|
|
|
blogContent: "",
|
|
|
|
@ -184,16 +335,192 @@ export default {
|
|
|
|
|
return this.$store.state.sortInfo;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
watch: {
|
|
|
|
|
'article.sortId'(newVal, oldVal) {
|
|
|
|
|
if (oldVal !== null) {
|
|
|
|
|
this.article.labelId = null;
|
|
|
|
|
}
|
|
|
|
|
if (!this.$common.isEmpty(newVal) && !this.$common.isEmpty(this.labels)) {
|
|
|
|
|
this.labelsTemp = this.labels.filter(l => l.sortId === newVal);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
this.getRecommendArticles();
|
|
|
|
|
this.getAdmire();
|
|
|
|
|
this.getUserArticles(); // 调用获取用户文章列表的方法
|
|
|
|
|
this.getUserArticleLabelTotalNum();// 调用获取用户文章的标签种类数的方法
|
|
|
|
|
this.getBlogLabels();//调用获取标签分类的方法
|
|
|
|
|
this.getSortAndLabel();
|
|
|
|
|
console.log('getUserArticleLabelTotalNum is called');
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
imgAdd(pos, file) {
|
|
|
|
|
let suffix = "";
|
|
|
|
|
if (file.name.lastIndexOf('.') !== -1) {
|
|
|
|
|
suffix = file.name.substring(file.name.lastIndexOf('.'));
|
|
|
|
|
}
|
|
|
|
|
let key = "articlePicture" + "/" + this.$store.state.currentAdmin.username.replace(/[^a-zA-Z]/g, '') + this.$store.state.currentAdmin.id + new Date().getTime() + Math.floor(Math.random() * 1000) + suffix;
|
|
|
|
|
|
|
|
|
|
let storeType = localStorage.getItem("defaultStoreType");
|
|
|
|
|
|
|
|
|
|
let fd = new FormData();
|
|
|
|
|
fd.append("file", file);
|
|
|
|
|
fd.append("key", key);
|
|
|
|
|
fd.append("relativePath", key);
|
|
|
|
|
fd.append("type", "articlePicture");
|
|
|
|
|
fd.append("storeType", storeType);
|
|
|
|
|
|
|
|
|
|
if (storeType === "local") {
|
|
|
|
|
this.saveLocal(pos, fd);
|
|
|
|
|
} else if (storeType === "qiniu") {
|
|
|
|
|
this.saveQiniu(pos, fd);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
saveLocal(pos, fd) {
|
|
|
|
|
this.$http.upload(this.$constant.baseURL + "/resource/upload", fd, true)
|
|
|
|
|
.then((res) => {
|
|
|
|
|
if (!this.$common.isEmpty(res.data)) {
|
|
|
|
|
let url = res.data;
|
|
|
|
|
this.$refs.md.$img2Url(pos, url);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: error.message,
|
|
|
|
|
type: "error"
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
saveQiniu(pos, fd) {
|
|
|
|
|
this.$http.get(this.$constant.baseURL + "/qiniu/getUpToken", {key: fd.get("key")}, true)
|
|
|
|
|
.then((res) => {
|
|
|
|
|
if (!this.$common.isEmpty(res.data)) {
|
|
|
|
|
fd.append("token", res.data);
|
|
|
|
|
|
|
|
|
|
this.$http.uploadQiniu(this.$constant.qiniuUrl, fd)
|
|
|
|
|
.then((res) => {
|
|
|
|
|
if (!this.$common.isEmpty(res.key)) {
|
|
|
|
|
let url = this.$constant.qiniuDownload + res.key;
|
|
|
|
|
let file = fd.get("file");
|
|
|
|
|
this.$common.saveResource(this, "articlePicture", url, file.size, file.type, "qiniu", true);
|
|
|
|
|
this.$refs.md.$img2Url(pos, url);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: error.message,
|
|
|
|
|
type: "error"
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: error.message,
|
|
|
|
|
type: "error"
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
addArticleCover(res) {
|
|
|
|
|
this.article.articleCover = res;
|
|
|
|
|
},
|
|
|
|
|
getSortAndLabel() {
|
|
|
|
|
this.$http.get(this.$constant.baseURL + "/webInfo/listSortAndLabel")
|
|
|
|
|
.then((res) => {
|
|
|
|
|
if (!this.$common.isEmpty(res.data)) {
|
|
|
|
|
this.sorts = res.data.sorts;
|
|
|
|
|
this.labels = res.data.labels;
|
|
|
|
|
if (!this.$common.isEmpty(this.id)) {
|
|
|
|
|
this.getArticle();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: error.message,
|
|
|
|
|
type: "error"
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
getArticle() {
|
|
|
|
|
this.$http.get(this.$constant.baseURL + "/admin/article/getArticleById", {id: this.id}, true)
|
|
|
|
|
.then((res) => {
|
|
|
|
|
if (!this.$common.isEmpty(res.data)) {
|
|
|
|
|
this.article = res.data;
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: error.message,
|
|
|
|
|
type: "error"
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
submitForm(formName) {
|
|
|
|
|
if (this.article.viewStatus === false && this.$common.isEmpty(this.article.password)) {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: "文章不可见时必须输入密码!",
|
|
|
|
|
type: "error"
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
this.$refs[formName].validate((valid) => {
|
|
|
|
|
if (valid) {
|
|
|
|
|
if (this.$common.isEmpty(this.id)) {
|
|
|
|
|
this.saveArticle(this.article, "/article/saveArticle")
|
|
|
|
|
} else {
|
|
|
|
|
this.article.id = this.id;
|
|
|
|
|
this.saveArticle(this.article, "/article/updateArticle")
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: "请完善必填项!",
|
|
|
|
|
type: "error"
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
resetForm(formName) {
|
|
|
|
|
this.$refs[formName].resetFields();
|
|
|
|
|
if (!this.$common.isEmpty(this.id)) {
|
|
|
|
|
this.getArticle();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
saveArticle(value, url) {
|
|
|
|
|
this.$confirm('确认保存?', '提示', {
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
type: 'success',
|
|
|
|
|
center: true
|
|
|
|
|
}).then(() => {
|
|
|
|
|
this.$http.post(this.$constant.baseURL + url, value, true)
|
|
|
|
|
.then((res) => {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: "保存成功!",
|
|
|
|
|
type: "success"
|
|
|
|
|
});
|
|
|
|
|
// this.$router.push({path: '/postList'});
|
|
|
|
|
this.showPostEditor = false;
|
|
|
|
|
this.article.articleContent = "";
|
|
|
|
|
this.article.articleCover = "";
|
|
|
|
|
this.article.articleTitle = "";
|
|
|
|
|
this.article.sortId = "";
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: error.message,
|
|
|
|
|
type: "error"
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
this.$message({
|
|
|
|
|
type: 'success',
|
|
|
|
|
message: '已取消保存!'
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
submitUpload() {
|
|
|
|
|
this.$refs.upload.submit();
|
|
|
|
|
},
|
|
|
|
@ -619,17 +946,18 @@ export default {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.write-blog-btn {
|
|
|
|
|
position: absolute;
|
|
|
|
|
left: 470px;
|
|
|
|
|
top: 197px;
|
|
|
|
|
width: 160px;
|
|
|
|
|
height: 63px;
|
|
|
|
|
//position: absolute;
|
|
|
|
|
//left: 470px;
|
|
|
|
|
//top: 197px;
|
|
|
|
|
//width: 160px;
|
|
|
|
|
//height: 63px;
|
|
|
|
|
margin-top: 7px;
|
|
|
|
|
background-color: var(--gradualRed);
|
|
|
|
|
color: #181313;
|
|
|
|
|
border-radius: 20px;
|
|
|
|
|
font-size: 24px;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
display: flex;
|
|
|
|
|
display: inline-block;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
|
|
|
|
cursor: pointer;
|
|
|
|
@ -1085,4 +1413,26 @@ option {
|
|
|
|
|
object-fit: contain;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.publicBlog {
|
|
|
|
|
margin-left: 10px;
|
|
|
|
|
//display: inline-block;
|
|
|
|
|
margin-top: 7px;
|
|
|
|
|
background-color: var(--gradualRed);
|
|
|
|
|
color: #181313;
|
|
|
|
|
border-radius: 20px;
|
|
|
|
|
font-size: 24px;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
display: inline-block;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
transition: all .2s ease-in-out;
|
|
|
|
|
border: 2px solid #1675b4; /* 添加边框 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.publicBlog:hover {
|
|
|
|
|
background-color: #2980b9;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
</style>
|
|
|
|
|