|
|
@@ -0,0 +1,536 @@
|
|
|
+<template>
|
|
|
+ <ContentWrap>
|
|
|
+ <!-- 搜索工作栏 -->
|
|
|
+ <el-form
|
|
|
+ ref="queryFormRef"
|
|
|
+ :inline="true"
|
|
|
+ :model="queryParams"
|
|
|
+ class="-mb-15px"
|
|
|
+ label-width="68px"
|
|
|
+ >
|
|
|
+ <el-form-item label="用户ID" prop="userId">
|
|
|
+ <el-input
|
|
|
+ v-model="queryParams.userId"
|
|
|
+ class="!w-240px"
|
|
|
+ clearable
|
|
|
+ placeholder="请输入用户ID"
|
|
|
+ @keyup.enter="handleQuery"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="标题" prop="title">
|
|
|
+ <el-input
|
|
|
+ v-model="queryParams.title"
|
|
|
+ class="!w-240px"
|
|
|
+ clearable
|
|
|
+ placeholder="请输入标题"
|
|
|
+ @keyup.enter="handleQuery"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="状态" prop="status">
|
|
|
+ <el-select
|
|
|
+ v-model="queryParams.status"
|
|
|
+ class="!w-240px"
|
|
|
+ clearable
|
|
|
+ placeholder="请选择状态"
|
|
|
+ >
|
|
|
+ <el-option label="正常" :value="1" />
|
|
|
+ <el-option label="删除" :value="2" />
|
|
|
+ <el-option label="审核中" :value="3" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="置顶" prop="isTop">
|
|
|
+ <el-select
|
|
|
+ v-model="queryParams.isTop"
|
|
|
+ class="!w-240px"
|
|
|
+ clearable
|
|
|
+ placeholder="请选择是否置顶"
|
|
|
+ >
|
|
|
+ <el-option label="是" :value="1" />
|
|
|
+ <el-option label="否" :value="0" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="精华" prop="isEssence">
|
|
|
+ <el-select
|
|
|
+ v-model="queryParams.isEssence"
|
|
|
+ class="!w-240px"
|
|
|
+ clearable
|
|
|
+ placeholder="请选择是否精华"
|
|
|
+ >
|
|
|
+ <el-option label="是" :value="1" />
|
|
|
+ <el-option label="否" :value="0" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button @click="handleQuery">
|
|
|
+ <Icon class="mr-5px" icon="ep:search" />
|
|
|
+ 搜索
|
|
|
+ </el-button>
|
|
|
+ <el-button @click="resetQuery">
|
|
|
+ <Icon class="mr-5px" icon="ep:refresh" />
|
|
|
+ 重置
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ v-hasPermi="['community:post:delete']"
|
|
|
+ :disabled="checkedIds.length === 0"
|
|
|
+ plain
|
|
|
+ type="danger"
|
|
|
+ @click="handleDeleteBatch"
|
|
|
+ >
|
|
|
+ <Icon class="mr-5px" icon="ep:delete" />
|
|
|
+ 批量删除
|
|
|
+ </el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </ContentWrap>
|
|
|
+
|
|
|
+ <!-- 列表 -->
|
|
|
+ <ContentWrap>
|
|
|
+ <el-table
|
|
|
+ v-loading="loading"
|
|
|
+ :data="list"
|
|
|
+ @selection-change="handleRowCheckboxChange"
|
|
|
+ >
|
|
|
+ <el-table-column type="selection" width="55" />
|
|
|
+ <el-table-column label="帖子ID" align="center" prop="id" width="80" />
|
|
|
+ <el-table-column label="用户" align="center" width="150">
|
|
|
+ <template #default="scope">
|
|
|
+ <div>
|
|
|
+ <div>{{ scope.row.userNickname || '-' }}</div>
|
|
|
+ <div class="text-xs text-gray-500">ID: {{ scope.row.userId }}</div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ label="标题"
|
|
|
+ align="left"
|
|
|
+ prop="title"
|
|
|
+ :show-overflow-tooltip="true"
|
|
|
+ min-width="200"
|
|
|
+ >
|
|
|
+ <template #default="scope">
|
|
|
+ <el-link
|
|
|
+ type="primary"
|
|
|
+ @click="openDetail(scope.row.id)"
|
|
|
+ >
|
|
|
+ {{ scope.row.title }}
|
|
|
+ </el-link>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="内容类型" align="center" prop="contentType" width="100">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-tag v-if="scope.row.contentType === 1" type="info">普通文本</el-tag>
|
|
|
+ <el-tag v-else-if="scope.row.contentType === 2" type="warning">Markdown</el-tag>
|
|
|
+ <el-tag v-else-if="scope.row.contentType === 3" type="success">图片</el-tag>
|
|
|
+ <el-tag v-else-if="scope.row.contentType === 4" type="primary">视频</el-tag>
|
|
|
+ <el-tag v-else-if="scope.row.contentType === 5" type="danger">图文混合</el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="统计" align="center" width="200">
|
|
|
+ <template #default="scope">
|
|
|
+ <div class="flex gap-2 justify-center">
|
|
|
+ <el-tag size="small" type="info">浏览: {{ scope.row.viewCount || 0 }}</el-tag>
|
|
|
+ <el-tag size="small" type="success">点赞: {{ scope.row.likeCount || 0 }}</el-tag>
|
|
|
+ <el-tag size="small" type="warning">评论: {{ scope.row.commentCount || 0 }}</el-tag>
|
|
|
+ <el-tag size="small" type="primary">收藏: {{ scope.row.collectCount || 0 }}</el-tag>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="状态" align="center" prop="status" width="100">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-tag v-if="scope.row.status === 1" type="success">正常</el-tag>
|
|
|
+ <el-tag v-else-if="scope.row.status === 2" type="danger">删除</el-tag>
|
|
|
+ <el-tag v-else-if="scope.row.status === 3" type="warning">审核中</el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="置顶" align="center" prop="isTop" width="80">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-switch
|
|
|
+ v-model="scope.row.isTop"
|
|
|
+ :active-value="1"
|
|
|
+ :inactive-value="0"
|
|
|
+ @change="handleTopChange(scope.row)"
|
|
|
+ :disabled="!checkPermi(['community:post:update'])"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="精华" align="center" prop="isEssence" width="80">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-switch
|
|
|
+ v-model="scope.row.isEssence"
|
|
|
+ :active-value="1"
|
|
|
+ :inactive-value="0"
|
|
|
+ @change="handleEssenceChange(scope.row)"
|
|
|
+ :disabled="!checkPermi(['community:post:update'])"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ label="创建时间"
|
|
|
+ align="center"
|
|
|
+ prop="createTime"
|
|
|
+ :formatter="dateFormatter"
|
|
|
+ width="180"
|
|
|
+ />
|
|
|
+ <el-table-column label="操作" align="center" width="200" fixed="right">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-button
|
|
|
+ v-hasPermi="['community:post:query']"
|
|
|
+ link
|
|
|
+ type="primary"
|
|
|
+ @click="openDetail(scope.row.id)"
|
|
|
+ >
|
|
|
+ 详情
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ v-hasPermi="['community:post:update']"
|
|
|
+ link
|
|
|
+ type="warning"
|
|
|
+ @click="openStatusForm(scope.row)"
|
|
|
+ >
|
|
|
+ 状态
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ v-hasPermi="['community:post:delete']"
|
|
|
+ link
|
|
|
+ type="danger"
|
|
|
+ @click="handleDelete(scope.row.id)"
|
|
|
+ >
|
|
|
+ 删除
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <!-- 分页 -->
|
|
|
+ <Pagination
|
|
|
+ :total="total"
|
|
|
+ v-model:page="queryParams.pageNo"
|
|
|
+ v-model:limit="queryParams.pageSize"
|
|
|
+ @pagination="getList"
|
|
|
+ />
|
|
|
+ </ContentWrap>
|
|
|
+
|
|
|
+ <!-- 详情弹窗 -->
|
|
|
+ <Dialog v-model="detailVisible" title="帖子详情" width="900px">
|
|
|
+ <el-descriptions :column="2" border v-if="detailData">
|
|
|
+ <el-descriptions-item label="帖子ID">{{ detailData.id }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="用户">
|
|
|
+ {{ detailData.userNickname }} (ID: {{ detailData.userId }})
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="标题" :span="2">{{ detailData.title }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="内容类型">
|
|
|
+ <el-tag v-if="detailData.contentType === 1" type="info">普通文本</el-tag>
|
|
|
+ <el-tag v-else-if="detailData.contentType === 2" type="warning">Markdown</el-tag>
|
|
|
+ <el-tag v-else-if="detailData.contentType === 3" type="success">图片</el-tag>
|
|
|
+ <el-tag v-else-if="detailData.contentType === 4" type="primary">视频</el-tag>
|
|
|
+ <el-tag v-else-if="detailData.contentType === 5" type="danger">图文混合</el-tag>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="状态">
|
|
|
+ <el-tag v-if="detailData.status === 1" type="success">正常</el-tag>
|
|
|
+ <el-tag v-else-if="detailData.status === 2" type="danger">删除</el-tag>
|
|
|
+ <el-tag v-else-if="detailData.status === 3" type="warning">审核中</el-tag>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="浏览数">{{ detailData.viewCount || 0 }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="点赞数">{{ detailData.likeCount || 0 }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="评论数">{{ detailData.commentCount || 0 }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="收藏数">{{ detailData.collectCount || 0 }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="是否置顶">
|
|
|
+ <el-tag v-if="detailData.isTop === 1" type="success">是</el-tag>
|
|
|
+ <el-tag v-else type="info">否</el-tag>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="是否精华">
|
|
|
+ <el-tag v-if="detailData.isEssence === 1" type="warning">是</el-tag>
|
|
|
+ <el-tag v-else type="info">否</el-tag>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="标签">{{ detailData.tags || '-' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="创建时间" :span="2">
|
|
|
+ {{ formatDate(detailData.createTime) }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="内容" :span="2">
|
|
|
+ <div class="max-h-200px overflow-auto">
|
|
|
+ <pre class="whitespace-pre-wrap">{{ detailData.content }}</pre>
|
|
|
+ </div>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="媒体内容" :span="2" v-if="detailData.mediaList && detailData.mediaList.length > 0">
|
|
|
+ <div class="flex flex-wrap gap-4">
|
|
|
+ <div
|
|
|
+ v-for="(media, index) in detailData.mediaList"
|
|
|
+ :key="index"
|
|
|
+ class="relative"
|
|
|
+ >
|
|
|
+ <!-- 图片 -->
|
|
|
+ <div v-if="media.mediaType === 1" class="relative">
|
|
|
+ <el-image
|
|
|
+ :src="media.mediaUrl"
|
|
|
+ :preview-src-list="detailData.mediaList.filter(m => m.mediaType === 1).map(m => m.mediaUrl)"
|
|
|
+ :initial-index="detailData.mediaList.filter(m => m.mediaType === 1).findIndex(m => m.mediaUrl === media.mediaUrl)"
|
|
|
+ fit="cover"
|
|
|
+ class="w-200px h-200px border border-gray-200 rounded cursor-pointer"
|
|
|
+ :preview-teleported="true"
|
|
|
+ />
|
|
|
+ <div class="text-xs text-gray-500 mt-1 text-center">
|
|
|
+ 图片 {{ index + 1 }}
|
|
|
+ <span v-if="media.fileSize">({{ formatFileSize(media.fileSize) }})</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 视频 -->
|
|
|
+ <div v-else-if="media.mediaType === 2" class="relative">
|
|
|
+ <div class="relative w-200px h-200px border border-gray-200 rounded overflow-hidden">
|
|
|
+ <img
|
|
|
+ v-if="media.coverUrl"
|
|
|
+ :src="media.coverUrl"
|
|
|
+ class="w-full h-full object-cover"
|
|
|
+ alt="视频封面"
|
|
|
+ />
|
|
|
+ <div v-else class="w-full h-full bg-gray-100 flex items-center justify-center">
|
|
|
+ <Icon icon="ep:video-play" class="text-4xl text-gray-400" />
|
|
|
+ </div>
|
|
|
+ <div class="absolute inset-0 flex items-center justify-center bg-black bg-opacity-30">
|
|
|
+ <Icon icon="ep:video-play" class="text-4xl text-white" />
|
|
|
+ </div>
|
|
|
+ <div v-if="media.duration" class="absolute bottom-2 right-2 bg-black bg-opacity-60 text-white text-xs px-2 py-1 rounded">
|
|
|
+ {{ formatDuration(media.duration) }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="text-xs text-gray-500 mt-1 text-center">
|
|
|
+ 视频 {{ index + 1 }}
|
|
|
+ <span v-if="media.fileSize">({{ formatFileSize(media.fileSize) }})</span>
|
|
|
+ </div>
|
|
|
+ <el-link
|
|
|
+ :href="media.mediaUrl"
|
|
|
+ target="_blank"
|
|
|
+ type="primary"
|
|
|
+ class="text-xs mt-1 block text-center"
|
|
|
+ >
|
|
|
+ 查看视频
|
|
|
+ </el-link>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+ </Dialog>
|
|
|
+
|
|
|
+ <!-- 状态修改弹窗 -->
|
|
|
+ <Dialog v-model="statusFormVisible" title="修改帖子状态" width="500px">
|
|
|
+ <el-form
|
|
|
+ ref="statusFormRef"
|
|
|
+ :model="statusFormData"
|
|
|
+ :rules="statusFormRules"
|
|
|
+ label-width="100px"
|
|
|
+ >
|
|
|
+ <el-form-item label="状态" prop="status">
|
|
|
+ <el-radio-group v-model="statusFormData.status">
|
|
|
+ <el-radio :value="1" border>正常</el-radio>
|
|
|
+ <el-radio :value="2" border>删除</el-radio>
|
|
|
+ <el-radio :value="3" border>审核中</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="是否置顶" prop="isTop">
|
|
|
+ <el-radio-group v-model="statusFormData.isTop">
|
|
|
+ <el-radio :value="1" border>是</el-radio>
|
|
|
+ <el-radio :value="0" border>否</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="是否精华" prop="isEssence">
|
|
|
+ <el-radio-group v-model="statusFormData.isEssence">
|
|
|
+ <el-radio :value="1" border>是</el-radio>
|
|
|
+ <el-radio :value="0" border>否</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <el-button :disabled="statusFormLoading" type="primary" @click="submitStatusForm">确 定</el-button>
|
|
|
+ <el-button @click="statusFormVisible = false">取 消</el-button>
|
|
|
+ </template>
|
|
|
+ </Dialog>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import { dateFormatter } from '@/utils/formatTime'
|
|
|
+import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
|
|
+import * as PostApi from '@/api/community/post'
|
|
|
+import { checkPermi } from '@/utils/permission'
|
|
|
+import { formatDate } from '@/utils/formatTime'
|
|
|
+
|
|
|
+defineOptions({ name: 'CommunityPost' })
|
|
|
+
|
|
|
+const message = useMessage() // 消息弹窗
|
|
|
+const { t } = useI18n() // 国际化
|
|
|
+
|
|
|
+const loading = ref(true) // 列表的加载中
|
|
|
+const list = ref([]) // 列表的数据
|
|
|
+const total = ref(0) // 列表的总页数
|
|
|
+const queryParams = reactive({
|
|
|
+ pageNo: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ userId: undefined,
|
|
|
+ title: undefined,
|
|
|
+ status: undefined,
|
|
|
+ isTop: undefined,
|
|
|
+ isEssence: undefined
|
|
|
+})
|
|
|
+const queryFormRef = ref() // 搜索的表单
|
|
|
+const checkedIds = ref<number[]>([]) // 选中的列表
|
|
|
+
|
|
|
+// 详情相关
|
|
|
+const detailVisible = ref(false) // 详情弹窗
|
|
|
+const detailData = ref<PostApi.PostVO>() // 详情数据
|
|
|
+
|
|
|
+// 状态表单相关
|
|
|
+const statusFormVisible = ref(false) // 状态表单弹窗
|
|
|
+const statusFormLoading = ref(false) // 状态表单的加载中
|
|
|
+const statusFormData = ref<PostApi.PostUpdateStatusReqVO>({
|
|
|
+ id: undefined,
|
|
|
+ status: 1,
|
|
|
+ isTop: 0,
|
|
|
+ isEssence: 0
|
|
|
+})
|
|
|
+const statusFormRef = ref() // 状态表单 Ref
|
|
|
+const statusFormRules = reactive({
|
|
|
+ status: [{ required: true, message: '状态不能为空', trigger: 'change' }]
|
|
|
+})
|
|
|
+
|
|
|
+/** 查询列表 */
|
|
|
+const getList = async () => {
|
|
|
+ loading.value = true
|
|
|
+ try {
|
|
|
+ const data = await PostApi.getPostPage(queryParams)
|
|
|
+ list.value = data.list
|
|
|
+ total.value = data.total
|
|
|
+ } finally {
|
|
|
+ loading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/** 搜索按钮操作 */
|
|
|
+const handleQuery = () => {
|
|
|
+ queryParams.pageNo = 1
|
|
|
+ getList()
|
|
|
+}
|
|
|
+
|
|
|
+/** 重置按钮操作 */
|
|
|
+const resetQuery = () => {
|
|
|
+ queryFormRef.value.resetFields()
|
|
|
+ handleQuery()
|
|
|
+}
|
|
|
+
|
|
|
+/** 打开详情 */
|
|
|
+const openDetail = async (id: number) => {
|
|
|
+ detailVisible.value = true
|
|
|
+ try {
|
|
|
+ detailData.value = await PostApi.getPost(id)
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取帖子详情失败', error)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/** 打开状态表单 */
|
|
|
+const openStatusForm = (row: any) => {
|
|
|
+ statusFormVisible.value = true
|
|
|
+ statusFormData.value = {
|
|
|
+ id: row.id,
|
|
|
+ status: row.status,
|
|
|
+ isTop: row.isTop,
|
|
|
+ isEssence: row.isEssence
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/** 提交状态表单 */
|
|
|
+const submitStatusForm = async () => {
|
|
|
+ if (!statusFormRef.value) return
|
|
|
+ const valid = await statusFormRef.value.validate()
|
|
|
+ if (!valid) return
|
|
|
+ statusFormLoading.value = true
|
|
|
+ try {
|
|
|
+ await PostApi.updatePostStatus(statusFormData.value)
|
|
|
+ message.success('更新成功')
|
|
|
+ statusFormVisible.value = false
|
|
|
+ await getList()
|
|
|
+ } finally {
|
|
|
+ statusFormLoading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/** 置顶状态修改 */
|
|
|
+const handleTopChange = async (row: any) => {
|
|
|
+ try {
|
|
|
+ await PostApi.updatePostStatus({
|
|
|
+ id: row.id,
|
|
|
+ isTop: row.isTop
|
|
|
+ })
|
|
|
+ message.success('更新成功')
|
|
|
+ } catch (error) {
|
|
|
+ // 取消操作后,进行回退
|
|
|
+ row.isTop = row.isTop === 1 ? 0 : 1
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/** 精华状态修改 */
|
|
|
+const handleEssenceChange = async (row: any) => {
|
|
|
+ try {
|
|
|
+ await PostApi.updatePostStatus({
|
|
|
+ id: row.id,
|
|
|
+ isEssence: row.isEssence
|
|
|
+ })
|
|
|
+ message.success('更新成功')
|
|
|
+ } catch (error) {
|
|
|
+ // 取消操作后,进行回退
|
|
|
+ row.isEssence = row.isEssence === 1 ? 0 : 1
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/** 删除按钮操作 */
|
|
|
+const handleDelete = async (id: number) => {
|
|
|
+ try {
|
|
|
+ // 删除的二次确认
|
|
|
+ await message.delConfirm()
|
|
|
+ // 发起删除
|
|
|
+ await PostApi.deletePost(id)
|
|
|
+ message.success(t('common.delSuccess'))
|
|
|
+ // 刷新列表
|
|
|
+ await getList()
|
|
|
+ } catch {}
|
|
|
+}
|
|
|
+
|
|
|
+/** 批量删除按钮操作 */
|
|
|
+const handleDeleteBatch = async () => {
|
|
|
+ try {
|
|
|
+ // 删除的二次确认
|
|
|
+ await message.delConfirm()
|
|
|
+ // 发起删除
|
|
|
+ await PostApi.deletePostList(checkedIds.value)
|
|
|
+ message.success(t('common.delSuccess'))
|
|
|
+ // 刷新列表
|
|
|
+ await getList()
|
|
|
+ checkedIds.value = []
|
|
|
+ } catch {}
|
|
|
+}
|
|
|
+
|
|
|
+/** 表格选中行变化 */
|
|
|
+const handleRowCheckboxChange = (selection: any[]) => {
|
|
|
+ checkedIds.value = selection.map((item) => item.id)
|
|
|
+}
|
|
|
+
|
|
|
+/** 格式化文件大小 */
|
|
|
+const formatFileSize = (bytes: number): string => {
|
|
|
+ if (!bytes || bytes === 0) return '0 B'
|
|
|
+ const k = 1024
|
|
|
+ const sizes = ['B', 'KB', 'MB', 'GB']
|
|
|
+ const i = Math.floor(Math.log(bytes) / Math.log(k))
|
|
|
+ return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i]
|
|
|
+}
|
|
|
+
|
|
|
+/** 格式化视频时长 */
|
|
|
+const formatDuration = (seconds: number): string => {
|
|
|
+ if (!seconds) return '00:00'
|
|
|
+ const mins = Math.floor(seconds / 60)
|
|
|
+ const secs = seconds % 60
|
|
|
+ return `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`
|
|
|
+}
|
|
|
+
|
|
|
+/** 初始化 **/
|
|
|
+onMounted(() => {
|
|
|
+ getList()
|
|
|
+})
|
|
|
+</script>
|
|
|
+
|