基本功能实现
Change-Id: I4fb8dfa2eed093c13d7c1e4304c4b4d012512ba9
diff --git a/src/views/forum/ForumTopicView.vue b/src/views/forum/ForumTopicView.vue
new file mode 100644
index 0000000..027083f
--- /dev/null
+++ b/src/views/forum/ForumTopicView.vue
@@ -0,0 +1,933 @@
+<template>
+ <div class="topic-detail-page">
+ <div class="page-container">
+ <!-- 面包屑导航 -->
+ <div class="breadcrumb">
+ <el-breadcrumb separator="/">
+ <el-breadcrumb-item :to="{ path: '/forum' }">论坛首页</el-breadcrumb-item>
+ <el-breadcrumb-item :to="{ path: `/forum/section/${topic.sectionId}` }">
+ {{ topic.sectionName }}
+ </el-breadcrumb-item>
+ <el-breadcrumb-item>{{ topic.title }}</el-breadcrumb-item>
+ </el-breadcrumb>
+ </div>
+
+ <!-- 主题信息 -->
+ <div class="topic-header">
+ <div class="topic-info">
+ <div class="topic-title-row">
+ <h1 class="topic-title">{{ topic.title }}</h1>
+ <div class="topic-status">
+ <el-tag v-if="topic.pinned" type="warning" size="small">置顶</el-tag>
+ <el-tag v-if="topic.hot" type="danger" size="small">热门</el-tag>
+ <el-tag v-if="topic.closed" type="info" size="small">已关闭</el-tag>
+ </div>
+ </div>
+
+ <div class="topic-tags">
+ <el-tag
+ v-for="tag in topic.tags"
+ :key="tag"
+ size="small"
+ type="info"
+ effect="plain"
+ >
+ {{ tag }}
+ </el-tag>
+ </div>
+
+ <div class="topic-meta">
+ <div class="author-info">
+ <el-avatar :size="32">{{ topic.author.charAt(0) }}</el-avatar>
+ <div class="author-details">
+ <span class="author-name">{{ topic.author }}</span>
+ <span class="post-time">发表于 {{ formatDateTime(topic.createTime) }}</span>
+ </div>
+ </div>
+
+ <div class="topic-stats">
+ <div class="stat-item">
+ <el-icon><View /></el-icon>
+ <span>{{ topic.views }} 浏览</span>
+ </div>
+ <div class="stat-item">
+ <el-icon><Comment /></el-icon>
+ <span>{{ topic.replies }} 回复</span>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="topic-actions">
+ <el-button
+ v-if="!topic.closed"
+ type="primary"
+ :icon="Edit"
+ @click="showReplyDialog = true"
+ >
+ 回复主题
+ </el-button>
+ <el-dropdown @command="handleTopicAction">
+ <el-button :icon="More">
+ 更多 <el-icon class="el-icon--right"><ArrowDown /></el-icon>
+ </el-button>
+ <template #dropdown>
+ <el-dropdown-menu>
+ <el-dropdown-item command="favorite">
+ {{ isFavorited ? '取消收藏' : '收藏主题' }}
+ </el-dropdown-item>
+ <el-dropdown-item command="share">分享主题</el-dropdown-item>
+ <el-dropdown-item command="report" divided>举报主题</el-dropdown-item>
+ </el-dropdown-menu>
+ </template>
+ </el-dropdown>
+ </div>
+ </div>
+
+ <!-- 主题内容和回复列表 -->
+ <div class="posts-container">
+ <!-- 主楼 -->
+ <div class="post-item main-post">
+ <div class="post-header">
+ <div class="floor-number">#1</div>
+ <div class="post-author">
+ <el-avatar :size="48">{{ topic.author.charAt(0) }}</el-avatar>
+ <div class="author-info">
+ <span class="author-name">{{ topic.author }}</span>
+ <span class="author-title">{{ topic.authorTitle || '会员' }}</span>
+ <div class="author-stats">
+ <span>帖子: {{ topic.authorPosts || 0 }}</span>
+ <span>声望: {{ topic.authorReputation || 0 }}</span>
+ </div>
+ </div>
+ </div>
+ <div class="post-time">
+ {{ formatDateTime(topic.createTime) }}
+ </div>
+ </div>
+
+ <div class="post-content">
+ <div class="content-text" v-html="formatContent(topic.content)"></div>
+ </div>
+
+ <div class="post-actions">
+ <el-button type="text" size="small" @click="likePost(topic.id)">
+ <el-icon><Like /></el-icon>
+ {{ topic.likes || 0 }}
+ </el-button>
+ <el-button type="text" size="small" @click="quotePost(topic)">
+ <el-icon><ChatDotRound /></el-icon>
+ 引用
+ </el-button>
+ <el-button type="text" size="small" @click="reportPost(topic.id)">
+ <el-icon><Flag /></el-icon>
+ 举报
+ </el-button>
+ </div>
+ </div>
+
+ <!-- 回复列表 -->
+ <div
+ v-for="(reply, index) in replies"
+ :key="reply.id"
+ class="post-item reply-post"
+ >
+ <div class="post-header">
+ <div class="floor-number">#{{ index + 2 }}</div>
+ <div class="post-author">
+ <el-avatar :size="48">{{ reply.author.charAt(0) }}</el-avatar>
+ <div class="author-info">
+ <span class="author-name">{{ reply.author }}</span>
+ <span class="author-title">{{ reply.authorTitle || '会员' }}</span>
+ <div class="author-stats">
+ <span>帖子: {{ reply.authorPosts || 0 }}</span>
+ <span>声望: {{ reply.authorReputation || 0 }}</span>
+ </div>
+ </div>
+ </div>
+ <div class="post-time">
+ {{ formatDateTime(reply.createTime) }}
+ </div>
+ </div>
+
+ <div class="post-content">
+ <div v-if="reply.quotedPost" class="quoted-content">
+ <div class="quote-header">
+ <el-icon><ChatDotRound /></el-icon>
+ <span>{{ reply.quotedPost.author }} 发表于 {{ formatDateTime(reply.quotedPost.time) }}</span>
+ </div>
+ <div class="quote-text">{{ reply.quotedPost.content }}</div>
+ </div>
+ <div class="content-text" v-html="formatContent(reply.content)"></div>
+ </div>
+
+ <div class="post-actions">
+ <el-button type="text" size="small" @click="likePost(reply.id)">
+ <el-icon><Like /></el-icon>
+ {{ reply.likes || 0 }}
+ </el-button>
+ <el-button type="text" size="small" @click="quotePost(reply)">
+ <el-icon><ChatDotRound /></el-icon>
+ 引用
+ </el-button>
+ <el-button type="text" size="small" @click="reportPost(reply.id)">
+ <el-icon><Flag /></el-icon>
+ 举报
+ </el-button>
+ </div>
+ </div>
+ </div>
+
+ <!-- 分页 -->
+ <div class="pagination-wrapper">
+ <el-pagination
+ v-model:current-page="currentPage"
+ v-model:page-size="pageSize"
+ :page-sizes="[10, 20, 50]"
+ :total="totalReplies"
+ layout="total, sizes, prev, pager, next, jumper"
+ @size-change="handleSizeChange"
+ @current-change="handleCurrentChange"
+ />
+ </div>
+
+ <!-- 快速回复 -->
+ <div v-if="!topic.closed" class="quick-reply">
+ <h3>快速回复</h3>
+ <el-input
+ v-model="quickReplyContent"
+ type="textarea"
+ :rows="4"
+ placeholder="输入你的回复..."
+ maxlength="2000"
+ show-word-limit
+ />
+ <div class="quick-reply-actions">
+ <el-button @click="clearQuickReply">清空</el-button>
+ <el-button type="primary" @click="submitQuickReply" :loading="submittingReply">
+ 发表回复
+ </el-button>
+ </div>
+ </div>
+ </div>
+
+ <!-- 回复对话框 -->
+ <el-dialog
+ v-model="showReplyDialog"
+ title="回复主题"
+ width="700px"
+ :before-close="handleCloseReplyDialog"
+ >
+ <el-form
+ ref="replyFormRef"
+ :model="replyForm"
+ :rules="replyRules"
+ label-width="80px"
+ >
+ <el-form-item v-if="quotedContent" label="引用内容">
+ <div class="quoted-preview">
+ <div class="quote-header">
+ <span>{{ quotedContent.author }}</span>
+ </div>
+ <div class="quote-content">{{ quotedContent.content }}</div>
+ <el-button type="text" size="small" @click="clearQuote">
+ 清除引用
+ </el-button>
+ </div>
+ </el-form-item>
+
+ <el-form-item label="回复内容" prop="content">
+ <el-input
+ v-model="replyForm.content"
+ type="textarea"
+ :rows="8"
+ placeholder="请输入回复内容..."
+ maxlength="5000"
+ show-word-limit
+ />
+ </el-form-item>
+ </el-form>
+
+ <template #footer>
+ <el-button @click="handleCloseReplyDialog">取消</el-button>
+ <el-button type="primary" @click="submitReply" :loading="submittingReply">
+ 发表回复
+ </el-button>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script>
+import { ref, reactive, onMounted } from 'vue'
+import { useRoute, useRouter } from 'vue-router'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import {
+ Edit,
+ More,
+ View,
+ Comment,
+ Like,
+ ChatDotRound,
+ Flag,
+ ArrowDown
+} from '@element-plus/icons-vue'
+
+export default {
+ name: 'ForumTopicView',
+ setup() {
+ const route = useRoute()
+ const router = useRouter()
+ const replyFormRef = ref(null)
+
+ const showReplyDialog = ref(false)
+ const submittingReply = ref(false)
+ const isFavorited = ref(false)
+ const currentPage = ref(1)
+ const pageSize = ref(20)
+ const totalReplies = ref(0)
+ const quickReplyContent = ref('')
+ const quotedContent = ref(null)
+
+ const topic = ref({
+ id: 1,
+ title: '2024年度最佳PT站点推荐与对比分析',
+ sectionId: 1,
+ sectionName: '站务讨论',
+ author: 'PTExpert',
+ authorTitle: '资深会员',
+ authorPosts: 1256,
+ authorReputation: 2890,
+ createTime: '2025-06-01T10:30:00',
+ content: `
+ <p>大家好,作为一个使用PT站点多年的老用户,我想和大家分享一下2024年各大PT站点的使用体验和对比分析。</p>
+
+ <h3>评测标准</h3>
+ <ul>
+ <li>资源丰富度:种子数量、更新速度、稀有资源</li>
+ <li>用户体验:界面设计、功能完善度、响应速度</li>
+ <li>社区氛围:用户活跃度、互帮互助程度</li>
+ <li>规则友好性:考核难度、分享率要求、保种要求</li>
+ </ul>
+
+ <h3>推荐站点</h3>
+ <p>经过综合评测,以下几个站点值得推荐:</p>
+ <ol>
+ <li><strong>站点A</strong>:资源最全,更新最快,适合影视爱好者</li>
+ <li><strong>站点B</strong>:音乐资源丰富,无损居多,音质发烧友首选</li>
+ <li><strong>站点C</strong>:软件资源全面,更新及时,开发者必备</li>
+ </ol>
+
+ <p>具体的详细评测报告我会在后续回复中逐一介绍,欢迎大家讨论和补充!</p>
+ `,
+ views: 2856,
+ replies: 147,
+ likes: 89,
+ tags: ['PT站点', '推荐', '对比'],
+ pinned: true,
+ hot: true,
+ closed: false
+ })
+
+ const replies = ref([
+ {
+ id: 2,
+ author: 'MovieLover88',
+ authorTitle: '影视达人',
+ authorPosts: 567,
+ authorReputation: 1234,
+ createTime: '2025-06-01T11:15:00',
+ content: '感谢楼主的详细分析!特别期待站点A的详细评测,最近正在寻找好的影视资源站点。',
+ likes: 12
+ },
+ {
+ id: 3,
+ author: 'TechGuru',
+ authorTitle: '技术专家',
+ authorPosts: 890,
+ authorReputation: 2156,
+ createTime: '2025-06-01T12:30:00',
+ content: '站点C确实不错,软件资源很全面。不过楼主能不能也评测一下游戏类的PT站点?',
+ likes: 8,
+ quotedPost: {
+ author: 'PTExpert',
+ time: '2025-06-01T10:30:00',
+ content: '站点C:软件资源全面,更新及时,开发者必备'
+ }
+ }
+ ])
+
+ const replyForm = reactive({
+ content: ''
+ })
+
+ const replyRules = {
+ content: [
+ { required: true, message: '请输入回复内容', trigger: 'blur' },
+ { min: 5, max: 5000, message: '内容长度在 5 到 5000 个字符', trigger: 'blur' }
+ ]
+ }
+
+ onMounted(() => {
+ const topicId = route.params.id
+ fetchTopicDetail(topicId)
+ })
+
+ const fetchTopicDetail = async (id) => {
+ try {
+ console.log('获取主题详情:', id)
+ totalReplies.value = 147
+ } catch (error) {
+ ElMessage.error('获取主题详情失败')
+ router.back()
+ }
+ }
+
+ const formatDateTime = (dateString) => {
+ const date = new Date(dateString)
+ return date.toLocaleString('zh-CN', {
+ year: 'numeric',
+ month: '2-digit',
+ day: '2-digit',
+ hour: '2-digit',
+ minute: '2-digit'
+ })
+ }
+
+ const formatContent = (content) => {
+ return content.replace(/\n/g, '<br>')
+ }
+
+ const handleTopicAction = (command) => {
+ switch (command) {
+ case 'favorite':
+ isFavorited.value = !isFavorited.value
+ ElMessage.success(isFavorited.value ? '已收藏' : '已取消收藏')
+ break
+ case 'share':
+ navigator.clipboard.writeText(window.location.href)
+ ElMessage.success('链接已复制到剪贴板')
+ break
+ case 'report':
+ reportPost(topic.value.id)
+ break
+ }
+ }
+
+ const likePost = (postId) => {
+ if (postId === topic.value.id) {
+ topic.value.likes = (topic.value.likes || 0) + 1
+ } else {
+ const reply = replies.value.find(r => r.id === postId)
+ if (reply) {
+ reply.likes = (reply.likes || 0) + 1
+ }
+ }
+ ElMessage.success('点赞成功')
+ }
+
+ const quotePost = (post) => {
+ quotedContent.value = {
+ author: post.author,
+ content: post.content.replace(/<[^>]*>/g, '').substring(0, 100) + '...',
+ time: post.createTime
+ }
+ showReplyDialog.value = true
+ }
+
+ const reportPost = async (postId) => {
+ try {
+ await ElMessageBox.prompt('请说明举报原因', '举报内容', {
+ confirmButtonText: '提交举报',
+ cancelButtonText: '取消',
+ inputType: 'textarea',
+ inputPlaceholder: '请详细说明举报原因...'
+ })
+
+ ElMessage.success('举报已提交,我们会尽快处理')
+ } catch {
+ // 用户取消
+ }
+ }
+
+ const clearQuote = () => {
+ quotedContent.value = null
+ }
+
+ const handleCloseReplyDialog = () => {
+ if (replyForm.content) {
+ ElMessageBox.confirm(
+ '确定要关闭吗?未保存的内容将会丢失。',
+ '提示',
+ {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning'
+ }
+ ).then(() => {
+ resetReplyForm()
+ showReplyDialog.value = false
+ }).catch(() => {
+ // 用户取消
+ })
+ } else {
+ resetReplyForm()
+ showReplyDialog.value = false
+ }
+ }
+
+ const submitReply = async () => {
+ try {
+ await replyFormRef.value?.validate()
+
+ submittingReply.value = true
+
+ await new Promise(resolve => setTimeout(resolve, 1500))
+
+ const newReply = {
+ id: Date.now(),
+ author: localStorage.getItem('username') || '用户',
+ authorTitle: '会员',
+ authorPosts: 0,
+ authorReputation: 0,
+ createTime: new Date().toISOString(),
+ content: replyForm.content,
+ likes: 0,
+ quotedPost: quotedContent.value
+ }
+
+ replies.value.push(newReply)
+ topic.value.replies += 1
+
+ ElMessage.success('回复发表成功!')
+ resetReplyForm()
+ showReplyDialog.value = false
+
+ } catch (error) {
+ console.error('表单验证失败:', error)
+ } finally {
+ submittingReply.value = false
+ }
+ }
+
+ const submitQuickReply = async () => {
+ if (!quickReplyContent.value.trim()) {
+ ElMessage.warning('请输入回复内容')
+ return
+ }
+
+ submittingReply.value = true
+ try {
+ await new Promise(resolve => setTimeout(resolve, 1000))
+
+ const newReply = {
+ id: Date.now(),
+ author: localStorage.getItem('username') || '用户',
+ authorTitle: '会员',
+ authorPosts: 0,
+ authorReputation: 0,
+ createTime: new Date().toISOString(),
+ content: quickReplyContent.value,
+ likes: 0
+ }
+
+ replies.value.push(newReply)
+ topic.value.replies += 1
+ quickReplyContent.value = ''
+
+ ElMessage.success('回复发表成功!')
+ } catch (error) {
+ ElMessage.error('发表回复失败')
+ } finally {
+ submittingReply.value = false
+ }
+ }
+
+ const clearQuickReply = () => {
+ quickReplyContent.value = ''
+ }
+
+ const resetReplyForm = () => {
+ replyFormRef.value?.resetFields()
+ replyForm.content = ''
+ quotedContent.value = null
+ }
+
+ const handleSizeChange = (size) => {
+ pageSize.value = size
+ currentPage.value = 1
+ }
+
+ const handleCurrentChange = (page) => {
+ currentPage.value = page
+ }
+
+ return {
+ showReplyDialog,
+ submittingReply,
+ isFavorited,
+ currentPage,
+ pageSize,
+ totalReplies,
+ quickReplyContent,
+ quotedContent,
+ topic,
+ replies,
+ replyForm,
+ replyRules,
+ replyFormRef,
+ formatDateTime,
+ formatContent,
+ handleTopicAction,
+ likePost,
+ quotePost,
+ reportPost,
+ clearQuote,
+ handleCloseReplyDialog,
+ submitReply,
+ submitQuickReply,
+ clearQuickReply,
+ handleSizeChange,
+ handleCurrentChange,
+ Edit,
+ More,
+ View,
+ Comment,
+ Like,
+ ChatDotRound,
+ Flag,
+ ArrowDown
+ }
+ }
+}
+</script>
+
+<style lang="scss" scoped>
+.topic-detail-page {
+ max-width: 1000px;
+ margin: 0 auto;
+ padding: 24px;
+ background: #f5f5f5;
+ min-height: 100vh;
+}
+
+.breadcrumb {
+ margin-bottom: 16px;
+}
+
+.topic-header {
+ background: #fff;
+ border-radius: 12px;
+ padding: 24px;
+ margin-bottom: 24px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
+
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ gap: 24px;
+
+ .topic-info {
+ flex: 1;
+
+ .topic-title-row {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ margin-bottom: 12px;
+
+ .topic-title {
+ font-size: 24px;
+ font-weight: 600;
+ color: #2c3e50;
+ margin: 0;
+ flex: 1;
+ }
+
+ .topic-status {
+ .el-tag {
+ margin-left: 8px;
+ }
+ }
+ }
+
+ .topic-tags {
+ margin-bottom: 16px;
+
+ .el-tag {
+ margin-right: 8px;
+ }
+ }
+
+ .topic-meta {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ .author-info {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+
+ .author-details {
+ .author-name {
+ display: block;
+ font-weight: 600;
+ color: #2c3e50;
+ font-size: 14px;
+ }
+
+ .post-time {
+ display: block;
+ font-size: 12px;
+ color: #909399;
+ }
+ }
+ }
+
+ .topic-stats {
+ display: flex;
+ gap: 16px;
+
+ .stat-item {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ font-size: 14px;
+ color: #7f8c8d;
+ }
+ }
+ }
+ }
+
+ .topic-actions {
+ display: flex;
+ gap: 12px;
+ flex-shrink: 0;
+ }
+}
+
+.posts-container {
+ .post-item {
+ background: #fff;
+ border-radius: 12px;
+ margin-bottom: 16px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
+ overflow: hidden;
+
+ &.main-post {
+ border-left: 4px solid #409eff;
+ }
+
+ .post-header {
+ background: #f8f9fa;
+ padding: 16px 24px;
+ display: flex;
+ align-items: center;
+ gap: 16px;
+ border-bottom: 1px solid #f0f0f0;
+
+ .floor-number {
+ background: #409eff;
+ color: white;
+ padding: 4px 8px;
+ border-radius: 4px;
+ font-size: 12px;
+ font-weight: 600;
+ min-width: 32px;
+ text-align: center;
+ }
+
+ .post-author {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ flex: 1;
+
+ .author-info {
+ .author-name {
+ display: block;
+ font-weight: 600;
+ color: #2c3e50;
+ font-size: 14px;
+ }
+
+ .author-title {
+ display: block;
+ font-size: 12px;
+ color: #67c23a;
+ margin-bottom: 4px;
+ }
+
+ .author-stats {
+ font-size: 11px;
+ color: #909399;
+
+ span {
+ margin-right: 12px;
+ }
+ }
+ }
+ }
+
+ .post-time {
+ font-size: 12px;
+ color: #909399;
+ }
+ }
+
+ .post-content {
+ padding: 24px;
+
+ .quoted-content {
+ background: #f5f7fa;
+ border-left: 4px solid #e4e7ed;
+ padding: 12px 16px;
+ margin-bottom: 16px;
+ border-radius: 0 4px 4px 0;
+
+ .quote-header {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-size: 12px;
+ color: #909399;
+ margin-bottom: 8px;
+ }
+
+ .quote-text {
+ font-size: 14px;
+ color: #606266;
+ line-height: 1.5;
+ }
+ }
+
+ .content-text {
+ line-height: 1.6;
+ color: #2c3e50;
+
+ :deep(h3) {
+ color: #2c3e50;
+ font-size: 18px;
+ font-weight: 600;
+ margin: 20px 0 12px 0;
+ }
+
+ :deep(p) {
+ margin-bottom: 12px;
+ }
+
+ :deep(ul), :deep(ol) {
+ margin: 12px 0;
+ padding-left: 20px;
+
+ li {
+ margin-bottom: 8px;
+ }
+ }
+ }
+ }
+
+ .post-actions {
+ padding: 12px 24px;
+ border-top: 1px solid #f0f0f0;
+ background: #fafafa;
+
+ .el-button {
+ margin-right: 16px;
+
+ .el-icon {
+ margin-right: 4px;
+ }
+ }
+ }
+ }
+}
+
+.pagination-wrapper {
+ text-align: center;
+ margin: 24px 0;
+}
+
+.quick-reply {
+ background: #fff;
+ border-radius: 12px;
+ padding: 24px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
+
+ h3 {
+ font-size: 18px;
+ font-weight: 600;
+ color: #2c3e50;
+ margin: 0 0 16px 0;
+ }
+
+ .quick-reply-actions {
+ margin-top: 12px;
+ text-align: right;
+
+ .el-button {
+ margin-left: 12px;
+ }
+ }
+}
+
+.quoted-preview {
+ background: #f5f7fa;
+ border: 1px solid #e4e7ed;
+ border-radius: 4px;
+ padding: 12px;
+
+ .quote-header {
+ font-size: 12px;
+ color: #909399;
+ margin-bottom: 8px;
+ }
+
+ .quote-content {
+ font-size: 14px;
+ color: #606266;
+ margin-bottom: 8px;
+ line-height: 1.5;
+ }
+}
+
+@media (max-width: 768px) {
+ .topic-detail-page {
+ padding: 16px;
+ }
+
+ .topic-header {
+ flex-direction: column;
+ align-items: flex-start;
+
+ .topic-actions {
+ width: 100%;
+ justify-content: flex-end;
+ }
+ }
+
+ .post-header {
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 12px;
+
+ .floor-number {
+ align-self: flex-start;
+ }
+ }
+
+ .post-content {
+ padding: 16px;
+ }
+
+ .post-actions {
+ padding: 12px 16px;
+
+ .el-button {
+ margin-right: 8px;
+ margin-bottom: 8px;
+ }
+ }
+}
+</style>
\ No newline at end of file