496 lines
11 KiB
Vue
496 lines
11 KiB
Vue
<template>
|
|
|
|
<div class="app-container" v-show="cs">
|
|
<div class="publish-section"><el-button type="primary" @click="handleEdit()">发布帖子</el-button></div>
|
|
<div v-if="list.length > 0" v-infinite-scroll="load">
|
|
<div class="post-card" v-for="(item, index) in list" :key="index">
|
|
<div class="post-content" @click="handleOpen(item)" @mouseenter="showActions[index] = true"
|
|
@mouseleave="showActions[index] = false">
|
|
<div class="post-header">
|
|
<div class="post-title">
|
|
{{ item.title || '无标题' }}
|
|
</div>
|
|
<div class="post-meta">
|
|
<div class="post-time" style="margin-right: 20px;" title="发布人">{{ item.fbrxm || '暂无发布人' }}</div>
|
|
<div class="post-time" title="发布时间">{{ item.time || '暂无时间' }}</div>
|
|
</div>
|
|
</div>
|
|
<div class="post-body">
|
|
<div class="post-text">
|
|
{{ item.content }}
|
|
</div>
|
|
<div class="post-images">
|
|
<div class="image-list">
|
|
<div v-for="(img, imgIndex) in item.tp" :key="imgIndex" class="image-item"
|
|
v-if="item.tp && item.tp.length > 0">
|
|
<el-image :src="setAddress(img)" show-progress>
|
|
<template #error>
|
|
<div class="image-slot error">
|
|
<img src="@/assets/images/default_male.png" width="80" height="80" />
|
|
</div>
|
|
</template>
|
|
</el-image>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div style="display: flex;justify-content: flex-end;margin-bottom: 10px;"
|
|
v-if="sfzh == item.fbrsfzh || isShiQingZhi()">
|
|
<el-button type="text" size="small" class="action-btn edit-btn" @click.stop="handleEdit(item)">
|
|
<el-icon>
|
|
<Edit />
|
|
</el-icon> 修改
|
|
</el-button>
|
|
<el-button type="text" size="small" class="action-btn delete-btn" @click.stop="handleDelete(item)">
|
|
<el-icon>
|
|
<Delete />
|
|
</el-icon> 删除
|
|
</el-button>
|
|
<el-button v-if="isShiQingZhi()" type="text" size="small" class="action-btn delete-btn"
|
|
@click.stop="handleSetTop(item)">
|
|
<el-icon>
|
|
<Top />
|
|
</el-icon> {{ item.sfzd == 1 ? '取消置顶' : '置顶' }}
|
|
</el-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 空数据占位 -->
|
|
<div v-else class="empty-data">
|
|
<div class="empty-icon">
|
|
<el-icon size="64">
|
|
<Document />
|
|
</el-icon>
|
|
</div>
|
|
<div class="empty-text">暂无帖子数据</div>
|
|
<div class="empty-hint">点击上方按钮发布第一条帖子吧</div>
|
|
</div>
|
|
|
|
</div>
|
|
<Release v-model="showModel" :ItemData="ItemData" @SaveReport="SaveReport" title="帖子发布" :showCancel="false"
|
|
:heightNumber="436"></Release>
|
|
<Particulars ref="particulars" />
|
|
</template>
|
|
|
|
<script setup>
|
|
import Release from './release.vue'
|
|
import { setAddress } from '@/utils/tools'
|
|
import { ref, reactive, onMounted } from 'vue'
|
|
import { tbGsxtXxltSelectPage, tbGsxtXxltDelete, tbGsxtXxltHfid, tbGsxtXxltUpdate } from '@/api/tbGsxtXxltHf'
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
import { Edit, Delete, Document } from '@element-plus/icons-vue'
|
|
import { getItem } from '@/utils/storage.js'
|
|
import Particulars from "./particulars.vue";
|
|
import { useRouter, useRoute } from 'vue-router'
|
|
import { isShiQingZhi } from "@/utils/auth.js"
|
|
|
|
const route = useRoute()
|
|
const particulars = ref()
|
|
const showModel = ref(false)
|
|
const listQuery = reactive({
|
|
pageCurrent: 1,
|
|
pageSize: 10,
|
|
})
|
|
const total = ref(0)
|
|
const list = ref([])
|
|
const showActions = ref({})
|
|
const sfzh = ref()
|
|
const ItemData = ref()
|
|
const cs = ref(false)//需要删除
|
|
onMounted(() => {
|
|
sfzh.value = getItem('idEntityCard')
|
|
SaveReport()
|
|
if (route.query.id) {
|
|
tbGsxtXxltHfid(route.query.id).then(res => {
|
|
ItemData.value = res
|
|
particulars.value.init(ItemData.value)
|
|
cs.value = true
|
|
})
|
|
} else {
|
|
cs.value = true
|
|
}
|
|
|
|
})
|
|
const SaveReport = () => {
|
|
tbGsxtXxltSelectPage(listQuery).then(res => {
|
|
// 使用可选链操作符和箭头函数隐式返回优化代码
|
|
const data = (res.records || []).map(item => ({
|
|
...item,
|
|
tp: item.tp ? item.tp.split(',') : []
|
|
}))
|
|
total.value = res.total || 0
|
|
// 初始化所有操作按钮为隐藏状态
|
|
const actions = {}
|
|
list.value = data
|
|
list.value.forEach((_, index) => {
|
|
actions[index] = false
|
|
})
|
|
|
|
showActions.value = actions
|
|
})
|
|
}
|
|
|
|
const handleOpen = (item) => {
|
|
particulars.value.init(item);
|
|
}
|
|
|
|
// 修改帖子
|
|
const handleEdit = (item) => {
|
|
ItemData.value = item
|
|
// 这里可以添加实际的修改逻辑
|
|
showModel.value = true
|
|
}
|
|
|
|
// 删除帖子
|
|
const handleDelete = (item) => {
|
|
ElMessageBox.confirm(
|
|
`确定要删除帖子「${item.title}」吗?`,
|
|
'删除确认',
|
|
{
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
type: 'warning'
|
|
}
|
|
).then(() => {
|
|
tbGsxtXxltDelete(item.id).then(res => {
|
|
if (res) {
|
|
ElMessage({ message: `帖子「${item.title}」已删除`, type: 'success' })
|
|
SaveReport() // 删除后刷新列表
|
|
} else {
|
|
ElMessage({ message: `删除帖子「${item.title}」失败:${res.msg || '未知错误'}`, type: 'error' })
|
|
}
|
|
})
|
|
}).catch(() => {
|
|
ElMessage({ message: '已取消删除', type: 'info' })
|
|
})
|
|
}
|
|
/** 置顶帖子 */
|
|
const handleSetTop = (item) => {
|
|
ElMessageBox.confirm(
|
|
`确定要置顶帖子「${item.title}」吗?`,
|
|
'置顶确认',
|
|
{
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
type: 'warning'
|
|
}
|
|
).then(async () => {
|
|
const detail = await tbGsxtXxltHfid(item.id)
|
|
detail.sfzd = item.sfzd === 1 ? 0 : 1
|
|
tbGsxtXxltUpdate(detail).then(res => {
|
|
if (res) {
|
|
ElMessage({ message: `帖子「${item.title}」已置顶`, type: 'success' })
|
|
SaveReport() // 置顶后刷新列表
|
|
} else {
|
|
ElMessage({ message: `置顶帖子「${item.title}」失败:${res.msg || '未知错误'}`, type: 'error' })
|
|
}
|
|
})
|
|
}).catch(() => {
|
|
ElMessage({ message: '已取消置顶', type: 'info' })
|
|
})
|
|
}
|
|
const load = () => {
|
|
|
|
if (listQuery.pageCurrent * listQuery.pageSize < total.value) {
|
|
listQuery.pageCurrent++
|
|
SaveReport()
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
// 主容器样式
|
|
.app-container {
|
|
padding: 16px;
|
|
color: #333;
|
|
font-size: 14px;
|
|
line-height: 1.5;
|
|
background-color: #f5f7fa;
|
|
min-height: 100%;
|
|
}
|
|
|
|
// 发布按钮区域
|
|
.publish-section {
|
|
margin-bottom: 20px;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
// 帖子卡片样式
|
|
.post-card {
|
|
background: white;
|
|
border-radius: 8px;
|
|
margin-bottom: 16px;
|
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
|
transition: all 0.3s ease;
|
|
position: relative;
|
|
overflow: hidden;
|
|
|
|
&:hover {
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
transform: translateY(-2px);
|
|
}
|
|
}
|
|
|
|
// 帖子内容区域
|
|
.post-content {
|
|
padding: 16px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
// 帖子头部
|
|
.post-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
margin-bottom: 12px;
|
|
align-items: flex-start;
|
|
}
|
|
|
|
// 帖子标题
|
|
.post-title {
|
|
font-size: 18px;
|
|
font-weight: 600;
|
|
color: #409eff;
|
|
margin-right: 16px;
|
|
flex: 1;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
transition: color 0.3s ease;
|
|
|
|
&:hover {
|
|
color: #409eff;
|
|
}
|
|
}
|
|
|
|
// 帖子元信息
|
|
.post-meta {
|
|
flex-shrink: 0;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
|
|
}
|
|
|
|
// 发布时间
|
|
.post-time {
|
|
color: #909399;
|
|
font-size: 12px;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
// 帖子主体
|
|
.post-body {
|
|
position: relative;
|
|
}
|
|
|
|
// 帖子文本内容
|
|
.post-text {
|
|
color: #606266;
|
|
font-size: 14px;
|
|
line-height: 1.6;
|
|
margin-bottom: 12px;
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 3;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
// 帖子图片容器
|
|
.post-images {
|
|
margin-top: 8px;
|
|
}
|
|
|
|
// 图片列表
|
|
.image-list {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
margin: -4px;
|
|
}
|
|
|
|
// 图片项
|
|
.image-item {
|
|
margin: 4px;
|
|
width: 100px;
|
|
height: 160px;
|
|
position: relative;
|
|
overflow: hidden;
|
|
border-radius: 4px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
// 帖子图片
|
|
.post-image {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
transition: transform 0.3s ease;
|
|
|
|
&:hover {
|
|
transform: scale(1.05);
|
|
}
|
|
}
|
|
|
|
// 更多图片提示
|
|
.image-more {
|
|
width: 80px;
|
|
height: 80px;
|
|
background: rgba(0, 0, 0, 0.6);
|
|
color: white;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
margin: 4px;
|
|
}
|
|
|
|
// 操作按钮容器
|
|
.post-actions {
|
|
position: absolute;
|
|
right: 16px;
|
|
bottom: 16px;
|
|
background: white;
|
|
padding: 8px;
|
|
border-radius: 6px;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
opacity: 0;
|
|
visibility: hidden;
|
|
transition: all 0.3s ease;
|
|
z-index: 10;
|
|
display: flex;
|
|
gap: 8px;
|
|
transform: translateY(10px);
|
|
}
|
|
|
|
// 操作按钮显示状态
|
|
.post-actions-visible {
|
|
opacity: 1;
|
|
visibility: visible;
|
|
}
|
|
|
|
// 操作按钮基础样式
|
|
.action-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
padding: 4px 12px;
|
|
border-radius: 4px;
|
|
transition: all 0.3s ease;
|
|
font-size: 12px;
|
|
color: #606266;
|
|
background: #f5f7fa;
|
|
|
|
&:hover {
|
|
transform: translateY(-1px);
|
|
}
|
|
}
|
|
|
|
// 修改按钮样式
|
|
.edit-btn:hover {
|
|
color: #409eff;
|
|
background: #ecf5ff;
|
|
}
|
|
|
|
// 删除按钮样式
|
|
.delete-btn:hover {
|
|
color: #f56c6c;
|
|
background: #fef0f0;
|
|
}
|
|
|
|
// 空数据样式
|
|
.empty-data {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 60px 20px;
|
|
background: white;
|
|
border-radius: 8px;
|
|
color: #909399;
|
|
text-align: center;
|
|
margin-top: 20px;
|
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
|
min-height: 300px;
|
|
}
|
|
|
|
.empty-icon {
|
|
margin-bottom: 16px;
|
|
color: #c0c4cc;
|
|
}
|
|
|
|
.empty-text {
|
|
font-size: 16px;
|
|
margin-bottom: 8px;
|
|
color: #606266;
|
|
}
|
|
|
|
.empty-hint {
|
|
font-size: 14px;
|
|
color: #909399;
|
|
}
|
|
|
|
// 移动端适配
|
|
@media (max-width: 768px) {
|
|
.app-container {
|
|
padding: 12px;
|
|
}
|
|
|
|
.post-card {
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.post-content {
|
|
padding: 12px;
|
|
}
|
|
|
|
.post-title {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.post-text {
|
|
font-size: 13px;
|
|
-webkit-line-clamp: 2;
|
|
}
|
|
|
|
.image-item {
|
|
width: 60px;
|
|
height: 60px;
|
|
}
|
|
|
|
.image-more {
|
|
width: 60px;
|
|
height: 60px;
|
|
}
|
|
|
|
.post-actions {
|
|
right: 12px;
|
|
padding: 6px;
|
|
}
|
|
|
|
.action-btn {
|
|
padding: 3px 8px;
|
|
font-size: 11px;
|
|
}
|
|
|
|
.empty-data {
|
|
padding: 40px 16px;
|
|
min-height: 250px;
|
|
}
|
|
|
|
.empty-icon {
|
|
font-size: 48px;
|
|
}
|
|
|
|
.empty-text {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.empty-hint {
|
|
font-size: 12px;
|
|
}
|
|
}
|
|
</style>
|