You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

931 lines
24 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="outside">
<!-- 组件的内容 -->
<!-- 网站信息 -->
<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-info">
<div class="blog-info-box">
<span>博客</span>
<span id="totalBlogNum" class="blog-info-num"></span>
</div>
<div class="blog-info-box">
<span>分类</span>
<span id="labelTotalNum" class="blog-info-num"></span>
</div>
<div class="blog-info-box">
<span>访问量</span>
<span class="blog-info-num">{{ webInfo.historyAllCount }}</span>
</div>
</div>
<a class="collection-btn" @click="showTip()">
<i class="el-icon-star-off" style="margin-right: 2px"></i>朋友圈
</a>
</div>
<!-- 写博客按钮 -->
<button class="write-blog-btn" @click="showEditor = true">
写博客
</button>
<!-- 编辑框 -->
<div id="editorArea" class="blog-editor" v-if="showEditor">
<textarea id ="areaTitle" class="blog-editor-title" v-model="blogContentTitle" placeholder="请输入博客标题..."></textarea>
<div class="labelSelect">
<label for="category">选择博客分类:</label>
<select id="category" name="category" v-model="selectedCategoryIndex">
<option v-for="(label, index) in blogLabels" :value="index" :key="index">{{ label }}</option>
</select>
</div>
<textarea id = "areaContent" class="blog-editor-content" v-model="blogContent" placeholder="请输入博客正文..."></textarea>
<span style="font-size: larger">上传封面:</span><input type="file" @change="handleFileChange()" ref="fileInput" class="pictureUpload"/>
<div class="editor-btns">
<button class="cancel-btn" @click="cancelEdit">取消</button>
<button class="publish-btn" @click="saveBlog" v-if="showPublishBtn">发布</button>
<button @click="updateBlog" class="publish-btn" v-if="showUpdateBtn">更新</button>
</div>
</div>
<br/><br/>
<!-- 推荐博客 -->
<div class="card-content2-title">
<i class="el-icon-reading card-content2-icon"></i>
<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">
<div class="blog-card-header">
<div class="author">{{ article.username }}</div>
<div class="title" >{{ article.articleTitle }}</div>
</div>
<div class="blog-card-content" >
{{ article.articleContent }}
</div>
<div class="blog-card-footer">
<div class="label">{{ article.labelName }}</div>
<div class="date"><i class="el-icon-date" style="color: var(--greyFont)"></i>发布于 {{ article.createTime }}</div>
<br/>
<div class="date">最近更新于 {{ article.updateTime }}</div>
<div class="actions">
<div class="delete-icon" @click="deleteArticle(article)">
<img src="../assets/file/delete.png" alt="Delete Icon" width="26px" height="26px">
</div>
<div class="update-icon" @click="updateArticle(article)">
<img src="../assets/file/update.png" alt="Update Icon" width="30px" height="30px">
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
import * as events from "events";
export default {
avatar: {
type: String
},
// 组件的逻辑和配置
data() {
return {
pagination: {
current: 1,
size: 5,
recommendStatus: true
},
currentUser: this.$store.state.currentUser,
recommendArticles: [],
admires: [],
showAdmireDialog: false,
articleSearch: "",
showEditor: false,
showUpdateBtn: false,
showPublishBtn: true,
blogContent: "",
blogContentTitle:"",
blogLabelName: "",
articles: [] , // 存储文章列表
labelTotalNum: 0,
articleCover: "",
articleUp: {
id: 1,
articleTitle: "",
articleContent: "",
userId: 1,
username: "",
sortId: 1,
labelId: 0,
labelName: "研发"
},
file:"",
blogLabels:[],
selectedCategoryIndex: 0, // 默认选中第一个选项
}
},
computed: {
events() {
return events
},
webInfo() {
return this.$store.state.webInfo;
},
sortInfo() {
return this.$store.state.sortInfo;
}
},
created() {
this.getRecommendArticles();
this.getAdmire();
this.getUserArticles(); // 调用获取用户文章列表的方法
this.getUserArticleLabelTotalNum();// 调用获取用户文章的标签种类数的方法
this.getBlogLabels();//调用获取标签分类的方法
console.log('getUserArticleLabelTotalNum is called');
},
methods: {
selectSort(sort) {
this.$emit("selectSort", sort);
},
selectArticle() {
this.$emit("selectArticle", this.articleSearch);
},
showAdmire() {
if (this.$common.isEmpty(this.$store.state.currentUser)) {
this.$message({
message: "请先登录!",
type: "error"
});
return;
}
this.showAdmireDialog = true;
},
getAdmire() {
this.$http.get(this.$constant.baseURL + "/webInfo/getAdmire")
.then((res) => {
if (!this.$common.isEmpty(res.data)) {
this.admires = res.data;
}
})
.catch((error) => {
this.$message({
message: error.message,
type: "error"
});
});
},
getRecommendArticles() {
this.$http.post(this.$constant.baseURL + "/article/listArticle", this.pagination)
.then((res) => {
if (!this.$common.isEmpty(res.data)) {
this.recommendArticles = res.data.records;
}
})
.catch((error) => {
this.$message({
message: error.message,
type: "error"
});
});
},
getUserArticleLabelTotalNum() {
const id = this.$store.state.currentUser.id; // 获取当前用户的ID
this.$http.get(`/admin/article/getUserArticleLabelTotalNum?id=${id}`) // 发送GET请求指定获取用户文章标签数量的接口地址并传递当前用户的ID作为参数
.then(response => {
const labelNum = response; // 获取标签数量
document.getElementById("labelTotalNum").innerText = labelNum;
this.labelTotalNum = labelNum;
console.log(labelNum); // 在控制台打印标签数量
console.log("label日志");
})
.catch(error => {
console.error('请求错误:', error);
});
},
getUserArticles() {
const id = this.$store.state.currentUser.id; // 获取当前用户的ID
this.$http.get(`/admin/article/getArticleByUserId?id=${id}`) // 发送GET请求指定获取用户文章列表的接口地址并传递当前用户的ID作为参数
.then(response => {
if (!this.$common.isEmpty(response.data)) {
this.articles = response.data;
const currentUser = this.$store.state.currentUser; // 获取当前用户信息
this.articles.forEach(article => {
article.username = currentUser.username;
article.labelName = this.blogLabels[article.labelId-1];
console.log(article.labelId+"haha")
});
document.getElementById("totalBlogNum").innerText = this.articles.length;
console.log(response.data);
this.getUserArticleLabelTotalNum();
}
})
.catch(error => {
this.$message({
message: error.message,
type: "error"
});
});
},
showTip() {
this.$router.push({path: '/weiYan'});
},
cancelEdit() {
// 取消编辑
this.showEditor = false;
this.showUpdateBtn = false;
this.showPublishBtn = true;
this.blogContent = "";
this.blogContentTitle = "";
},
saveBlog() {
let selectedIndex = this.selectedCategoryIndex+1;
console.log('选中的分类索引号为:' + selectedIndex);
const articleVO = {
userId:this.$store.state.currentUser.id,
articleContent: this.blogContent ,// 获取博客内容
articleTitle:this.blogContentTitle,
// 其他博客相关数据...
sortId:1,
labelId:selectedIndex,
// articleCover:
};
console.log(this.$store.state.currentUser)
console.log(this.$store.state.currentUser)
// console.log("index:"+document.getElementById('category').select)
this.$http.post('/article/saveArticle', articleVO)
.then(response => {
// 请求成功处理逻辑
console.log('博客保存成功!');
this.getUserArticles();
this.showEditor = false;
this.blogContent = "";
this.blogContentTitle = "";
this.$message({
message: '发布成功',
type: 'success'
});
})
.catch(error => {
// 请求失败处理逻辑
console.error('博客保存失败:', error);
this.$message({
message: '发布失败',
type: 'error'
});
});
},
deleteArticle(article){
// 发送异步请求删除文章
this.$http.get(`/article/deleteArticle?id=${article.id}`)
// .then(response => response.json())
.then(response => {
// 请求成功处理逻辑
console.log('博客删除成功!');
console.log(response)
this.getUserArticles()
this.getUserArticleLabelTotalNum()
})
.catch(error => {
// 请求失败处理逻辑
console.error('删除博客失败:', error);
});
},
updateArticle(article) {
this.showEditor = true;
this.showUpdateBtn = true;
this.showPublishBtn = false;
this.blogContentTitle = article.articleTitle;
this.blogContent = article.articleContent;
this.selectedCategoryIndex = article.labelId - 1; // 设置下拉框选中的索引值
this.articleUp.id = article.id;
// this.blogLabelName
// 判断是否找到了 #editorArea 元素
const editorArea = document.getElementById('editorArea');
if (editorArea) {
editorArea.scrollIntoView({ behavior: "smooth", block: "start" });
} else {
console.log("#editorArea not found");
}
},
updateBlog(){
this.blogContentTitle = document.getElementById('areaTitle').value
this.blogContent = document.getElementById('areaContent').value
// document.getElementById('category').
this.articleUp.articleContent = document.getElementById('areaContent').value
this.articleUp.articleTitle = document.getElementById('areaTitle').value
this.articleUp.username = this.$store.state.currentUser.username
this.articleUp.labelId = this.selectedCategoryIndex+1
//发送异步请求更新文章
this.$http.post('/article/updateArticle', this.articleUp)
.then(response => {
// 请求成功处理逻辑
console.log('博客更新成功!');
console.log(response)
this.getUserArticles()
this.getUserArticleLabelTotalNum()
this.$message({
message: '更新成功',
type: 'success'
});
this.showEditor = false;
this.showPublishBtn = true;
this.showUpdateBtn = false;
this.blogContent = "";
this.blogContentTitle = "";
})
.catch(error => {
// 请求失败处理逻辑
console.error('更新博客失败:', error);
this.$message({
message: '更新失败',
type: 'error'
});
this.showPublishBtn = true;
this.showUpdateBtn = false;
this.blogContent = "";
this.blogContentTitle = "";
});
},
getBlogLabels() {
const url = "/webInfo/listLabel";
console.log("gettingLabels");
// 发送GET请求
axios.get(url)
.then(response => {
console.log(response.data.data)
const labels = response.data.data;
this.blogLabels = Object.values(labels).map(label => label.labelName);
// 将标签数据赋值给blogLabels数组
// this.blogLabels = labels;
})
.catch(error => {
// 请求失败,处理错误
console.error(error);
});
},
handleFileChange() {
let file0 = this.$refs.fileInput.files[0];
this.file = file0;
console.log('上传的文件:', file0);
// 这里可以进行进一步的处理,比如上传文件到服务器等操作
}
}
}
</script>
<style scoped>
.outside{
background: linear-gradient(-45deg, #e8d8b9, #fae1d9, #a3e9eb, #bdbdf0, #eec1ea);
}
/* 组件的样式 */
.card-content1 {
background: linear-gradient(-45deg, #e8d8b9, #eccec5, #a3e9eb, #bdbdf0, #eec1ea);
background-size: 400% 400%;
animation: gradientBG 10s ease infinite;
display: flex;
flex-direction: column;
align-items: center;
border-radius: 10px;
position: relative;
/*color: var(--white);*/
overflow: hidden;
}
.card-content1 :not(:first-child) {
z-index: 10;
}
.web-name {
font-size: 30px;
font-weight: bold;
margin: 20px 0;
}
.web-info {
width: 80%;
display: flex;
flex-direction: row;
justify-content: space-around;
}
.blog-info-box {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
font-size: 24px;
}
.blog-info-num {
margin-top: 12px;
}
.collection-btn {
position: relative;
margin-top: 12px;
background: var(--lightGreen);
cursor: pointer;
width: 65%;
height: 35px;
border-radius: 1rem;
text-align: center;
line-height: 35px;
color: var(--white);
overflow: hidden;
z-index: 1;
margin-bottom: 25px;
}
.collection-btn::before {
background: var(--gradualRed);
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
content: "";
transform: scaleX(0);
transform-origin: 0;
transition: transform 0.5s ease-out;
transition-timing-function: cubic-bezier(0.45, 1.64, 0.47, 0.66);
border-radius: 1rem;
z-index: -1;
}
.collection-btn:hover::before {
transform: scaleX(1);
}
.write-blog-btn {
position: absolute;
left: 470px;
top: 197px;
width: 160px;
height: 63px;
background-color: var(--gradualRed);
color: #181313;
border-radius: 20px;
font-size: 24px;
font-weight: bold;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
transition: all .2s ease-in-out;
border: 2px solid #1675b4; /* 添加边框 */
}
.write-blog-btn:hover {
transform: scale(1.1);
border: 2px solid #053246; /* 鼠标悬停时修改边框颜色 */
}
.write-blog-btn:hover {
transform: scale(1.1); /* 鼠标悬停时缩放 */
}
.blog-editor {
margin: 0 auto;
align-self: center;
width: 80%;
height: 598px;
background-color: #e7deef;
border-radius: 20px;
margin-top: 20px;
padding: 10px;
border: #5a0bb9 1px solid;
box-sizing: border-box;
}
.blog-editor-title {
display: block;
margin: 0 auto;
width: 40%;
height: 60px;
background-color: #ffffff;
border-radius: 20px;
padding: 10px;
box-sizing: border-box;
font-weight: bolder;
font-size: 23px;
text-align: center; /* 将文本居中对齐 */
font-family: "Microsoft YaHei";
}
.blog-editor-content {
display: block;
margin: 0 auto;
width: 100%;
height: 386px;
//resize: none;
//border: none;
//outline: none;
border-radius: 20px;
font-size: 30px;
font-weight: bold;
margin-top: 10px;
//font-family: "Microsoft YaHei";
}
.editor-btns {
display: inline-block;
float: right;
justify-content: flex-end;
margin-top: 16px;
}
.cancel-btn,
.publish-btn {
width: 100px;
height: 35px;
color: #fff;
border-radius: 10px;
cursor: pointer;
transition: all .2s linear;
font-size: 19px;
font-weight: bold;
margin-top: 12px;
}
.cancel-btn {
background-color: #ccc;
margin-right: 10px;
}
.publish-btn {
background-color: var(--gradualRed);
color: #1d1f21;
}
.cancel-btn:hover,
.publish-btn:hover {
transform: translateY(-2px);
}
.card-content1 {
background: linear-gradient(-45deg, #e8d8b9, #eccec5, #a3e9eb, #bdbdf0, #eec1ea);
background-size: 400% 400%;
animation: gradientBG 10s ease infinite;
display: flex;
flex-direction: column;
align-items: center;
border-radius: 10px;
position: relative;
/*color: var(--white);*/
overflow: hidden;
}
.card-content1 :not(:first-child) {
z-index: 10;
}
.web-name {
font-size: 30px;
font-weight: bold;
margin: 20px 0;
}
.web-info {
width: 80%;
display: flex;
flex-direction: row;
justify-content: space-around;
}
.blog-info-box {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
}
.blog-info-num {
margin-top: 12px;
}
.collection-btn {
position: relative;
margin-top: 12px;
background: var(--lightGreen);
cursor: pointer;
width: 65%;
height: 35px;
border-radius: 1rem;
text-align: center;
line-height: 35px;
color: var(--white);
overflow: hidden;
z-index: 1;
margin-bottom: 25px;
}
.collection-btn::before {
background: var(--gradualRed);
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
content: "";
transform: scaleX(0);
transform-origin: 0;
transition: transform 0.5s ease-out;
transition-timing-function: cubic-bezier(0.45, 1.64, 0.47, 0.66);
border-radius: 1rem;
z-index: -1;
}
.collection-btn:hover::before {
transform: scaleX(1);
}
.card-content2-title {
font-size: 18px;
margin-bottom: 20px;
text-align: center;
}
.card-content2-icon {
color: var(--red);
margin-right: 5px;
animation: scale 1s ease-in-out infinite;
font-size: 30px;
}
.aside-post-detail {
display: flex;
cursor: pointer;
width: 70%;
//background-color: #1a252f;
}
.aside-post-image {
width: 200px;
border-radius: 0.2rem;
margin-right: 8px;
overflow: hidden;
font-size: 30px;
}
.error-aside-image {
display: inline-block;
background: var(--themeBackground);
color: var(--white);
padding: 10px;
text-align: center;
width: 100px;
height: 100%;
//background-color: #1abc9c;
}
.aside-post-title {
display: inline-block;
width: 360px;
text-align: center;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
background-color: rgb(236, 231, 153);
line-height: 30px; /* 假设容器高度为 30px */
text-indent: -15px; /* 负的半个 line-height */
padding-top: 3px;
border-radius: 5px;
font-size: 30px;
}
.aside-post-content {
display: inline-block;
width: 100%;
text-align: center;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
background-color: rgb(193, 236, 153);
line-height: 30px; /* 假设容器高度为 30px */
text-indent: -15px; /* 负的半个 line-height */
padding-top: 3px;
border-radius: 5px;
margin-left: 10px;
font-size: 20px;
}
.error-aside-image:hover,
.aside-post-title:hover,
.aside-post-content:hover,
.aside-post-label {
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
}
.aside-post-label {
width: 300px;
display: inline-block;
background-color: #ffffff;
margin-top: 8px;
margin-bottom: 20px;
margin-left: 10px;
color: var(--greyFont);
font-size: 23px;
text-align: center;
background-color: #eebcf1;
}
.aside-post-date {
margin-top: 8px;
margin-bottom: 20px;
color: var(--greyFont);
font-size: 23px;
}
.recommend-aside-header-author {
display: inline-block;
text-align: center;
width: 100px;
font-size: 30px;
margin-right: 20px;
background-color: #c5fcf1;
margin-bottom: 10px;
}
.recommend-aside-header-title {
display: inline-block;
text-align: center;
width: 200px;
font-size: 30px;
background-color: #f5dedf;
margin-bottom: 10px;
}
.recommend-aside-header-content {
margin-left: 20px;
display: inline-block;
font-size: 30px;
text-align: center;
width: 609px;
background-color: #e1f7f8;
margin-bottom: 10px;
}
.recommend-aside-header-label {
margin-left: 42px;
display: inline-block;
font-size: 30px;
text-align: center;
width: 160px;
background-color: #e1f7f8;
margin-bottom: 10px;
}
.delete-icon {
//background-image: url(../assets/file/delete.jpg);
background-repeat: no-repeat;
background-size: contain;
width: 26px; /* 图标的宽度 */
height: 26px; /* 图标的高度 */
cursor: pointer;
margin-top: 4px;
margin-left: 3px;
}
.update-icon {
//background-image: url(../assets/file/delete.jpg);
background-repeat: no-repeat;
background-size: contain;
width: 29px; /* 图标的宽度 */
height: 26px; /* 图标的高度 */
cursor: pointer;
margin-top: 4px;
margin-left: 6px;
}
.labelSelect {
//margin: 30px;
padding: 4px;
//background-color: rgba(215, 188, 248, 0.64);
margin: 0 auto;
width: 100%;
display: inline-block;
text-align: center;
font-size: 23px;
}
select {
font-size: 20px; /* 修改select框的字体大小 */
padding: 8px; /* 添加一些内边距 */
border-radius: 10px; /* 圆角边框 */
border: 2px solid #ccc; /* 边框样式 */
background-color: #f5f5f5; /* 背景颜色 */
}
option {
font-size: 18px; /* 修改选项的字体大小 */
color: #333; /* 修改选项的字体颜色 */
}
.blog-card-container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.blog-card {
width: 31%;
margin-bottom: 20px;
margin-top: 20px;
background: linear-gradient(to bottom, #f3dcfc, #e5ddff);
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
border-radius: 10px;
padding: 20px;
height: 350px;
}
.blog-card:hover {
transform: translateY(-5px); /* 鼠标悬停时微微抬起 */
}
.blog-card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.author {
font-weight: bold;
font-size: 16px;
}
.title {
font-size: 24px;
cursor: pointer;
color: #333; /* 标题颜色 */
}
.blog-card-content {
font-size: 18px;
line-height: 1.6;
overflow: auto; /* 使用滚动条来展示溢出的内容 */
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3; /* 控制正文行数 */
-webkit-box-orient: vertical;
height: 74% /* 设置卡片内容的最大高度 */
}
.blog-card-content::-webkit-scrollbar {
width: 8px; /* 设置滚动条的宽度 */
}
.blog-card-content::-webkit-scrollbar-thumb {
background-color: purple; /* 设置滚动条滑块的颜色 */
border-radius: 4px; /* 设置滚动条滑块的圆角 */
}
.blog-card-content::-webkit-scrollbar-track {
background-color: lightgray; /* 设置滚动条轨道的背景颜色 */
border-radius: 4px; /* 设置滚动条轨道的圆角 */
}
.blog-card-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 20px;
font-size: 14px;
color: #666; /* 页脚文字颜色 */
}
.label,
.date {
margin-right: 10px;
font-size: 17px;
display: inline-block;
}
.actions {
display: flex;
align-items: center;
}
.delete-icon,
.update-icon {
margin-left: 10px;
cursor: pointer;
}
.pictureUpload {
display: inline-block;
margin-top: 17px;
background-color: #d0c9f8; /* 设置按钮背景颜色 */
color: #fff; /* 设置文字颜色为白色 */
border: none; /* 移除边框 */
padding: 10px 20px; /* 调整内边距 */
font-size: 18px; /* 设置字体大小 */
border-radius: 10px; /* 添加圆角边框 */
cursor: pointer; /* 鼠标悬停时显示手型光标 */
transition: background-color 0.3s ease; /* 添加过渡效果 */
}
.pictureUpload:hover {
background-color: #b5a9f1; /* 鼠标悬停时修改背景颜色 */
}
</style>