Intelligent-Medical-Guidance-Large-Model
/
frontend
/src
/views
/streaming
/StreamingRoomListView.vue
<script setup lang="ts"> | |
import { onMounted, ref, computed } from 'vue' | |
import { useRouter } from 'vue-router' | |
import { ElMessage, ElMessageBox } from 'element-plus/es' | |
import { Plus, Delete } from '@element-plus/icons-vue' | |
import { | |
type StreamingRoomInfo, | |
streamerRoomListRequest, | |
deleteStreamingRoomByIdRequest | |
} from '@/api/streamingRoom' | |
import { AxiosError } from 'axios' | |
// 获取主播信息 | |
const streamingList = ref([] as StreamingRoomInfo[]) | |
const router = useRouter() | |
onMounted(async () => { | |
try { | |
// 获取直播间信息 | |
const { data } = await streamerRoomListRequest() | |
if (data.code === 0) { | |
streamingList.value = data.data | |
ElMessage.success('获取直播间信息成功') | |
} else { | |
ElMessage.error('获取直播间信息失败' + data.message) | |
} | |
} catch (error: unknown) { | |
if (error instanceof AxiosError) { | |
ElMessage.error('获取直播间信息失败' + error.message) | |
} else { | |
ElMessage.error('未知错误:' + error) | |
} | |
} | |
}) | |
const DeleteStreamingRoom = async (id: number, productName: string) => { | |
ElMessageBox.confirm(`确定要删除 "${productName}" 吗?`, '警告', { | |
confirmButtonText: '确定', | |
cancelButtonText: '取消', | |
type: 'warning' | |
}) | |
.then(async () => { | |
const { data } = await deleteStreamingRoomByIdRequest(id) | |
if (data.code === 0) { | |
ElMessage.success('删除成功') | |
// 获取直播间信息 | |
const { data } = await streamerRoomListRequest() | |
if (data.code === 0) { | |
streamingList.value = data.data | |
ElMessage.success('获取直播间信息成功') | |
} | |
} else { | |
ElMessage.error('删除失败') | |
} | |
}) | |
.catch(() => { | |
ElMessage.error('删除失败') | |
}) | |
} | |
const chunkArray = (array: StreamingRoomInfo[], chunkSize: number) => { | |
// 切割每 n 个为一行(即一个数组),方便后续进行 v-for 遍历 | |
const result = [] | |
for (let i = 0; i < array.length; i += chunkSize) { | |
result.push(array.slice(i, i + chunkSize)) | |
} | |
return result | |
} | |
const chunkedArray = computed(() => chunkArray(streamingList.value, 4)) | |
const tagMap = { 0: '未开播', 1: '直播中', 2: '已下播' } | |
</script> | |
<template> | |
<div> | |
<div style="margin-bottom: 20px"> | |
<el-button @click="router.push({ name: 'StreamingCreate' })" type="primary"> | |
<el-icon style="margin-right: 5px"> | |
<Plus /> | |
</el-icon> | |
新建直播间 | |
</el-button> | |
</div> | |
<div v-for="(row, rowIndex) in chunkedArray" :key="rowIndex" class="row"> | |
<el-row :gutter="20"> | |
<el-col v-for="(item, index) in row" :key="index" :span="8"> | |
<el-card style="max-width: 480px"> | |
<img :src="item.room_poster" style="width: 100%" /> | |
<div class="title"> | |
<h3>{{ item.name }}</h3> | |
<el-tag type="success" effect="light"> | |
{{ tagMap[item.status.live_status as keyof typeof tagMap] }} | |
</el-tag> | |
</div> | |
<div> | |
<p>主播:{{ item.streamer_info.name }}</p> | |
<p>商品数:{{ item.product_list.length }}</p> | |
<p> | |
开播时间: {{ item.status.live_status === 1 ? item.status.start_time : '未开播' }} | |
</p> | |
</div> | |
<div class="bottom-button"> | |
<el-button | |
type="primary" | |
@click="router.push({ name: 'StreamingEdit', params: { roomId: item.room_id } })" | |
> | |
编辑直播间 | |
</el-button> | |
<el-button | |
type="primary" | |
:disabled="item.status.live_status !== 1" | |
@click="router.push({ name: 'StreamingOnAir', params: { roomId: item.room_id } })" | |
> | |
进入直播间 | |
</el-button> | |
<el-button | |
type="danger" | |
:disabled="item.status.live_status === 1" | |
:icon="Delete" | |
@click="DeleteStreamingRoom(item.room_id, item.name)" | |
/> | |
</div> | |
</el-card> | |
</el-col> | |
</el-row> | |
</div> | |
</div> | |
</template> | |
<style lang="scss" scoped> | |
.row { | |
margin-bottom: 20px; | |
} | |
.el-card { | |
padding: 20px; | |
border-radius: 20px; | |
} | |
.title { | |
display: flex; | |
justify-content: space-between; | |
.h3 { | |
font-size: 50px; | |
font-weight: 600; | |
margin: 24px 0px 8px 0px; | |
} | |
} | |
.bottom-button { | |
margin-top: 20px; // 距离上面的控件有一定的距离 | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
} | |
</style> | |