<template>
|
<div
|
class="train-container w-screen h-screen bg-slate-50 flex flex-col items-center"
|
>
|
<NormalHeader class="shrink-0"></NormalHeader>
|
|
<div class="list-container container grow relative">
|
<div class="list-content absolute top-0 bottom-0 left-0 right-0 py-4">
|
<div class="list-wrapper w-full h-full">
|
<el-card class="h-full" :body-style="{ height: '100%' }">
|
<div
|
class="card-wrapper w-full h-full flex flex-col px-8 box-border"
|
>
|
<div
|
class="card-header flex justify-between items-center shrink-0"
|
>
|
<div class="header-search flex items-center">
|
<el-input
|
v-model="searchText"
|
placeholder="请输入搜索内容"
|
class="long-input"
|
:prefix-icon="Search"
|
@input="searchFile"
|
/>
|
<el-select
|
v-model="searchSubject"
|
placeholder="请选择科目"
|
class="ml-4 long-select"
|
@change="searchFile"
|
clearable
|
>
|
<el-option
|
v-for="item in subjectList"
|
:key="item.id"
|
:label="item.name"
|
:value="item.id"
|
/>
|
</el-select>
|
<el-select
|
v-model="searchContentType"
|
placeholder="请选择文件类型"
|
class="ml-4 long-select"
|
@change="searchFile"
|
clearable
|
>
|
<el-option
|
v-for="item in contentTypeList"
|
:key="item.value"
|
:label="item.name"
|
:value="item.value"
|
>
|
</el-option>
|
</el-select>
|
<el-button type="primary" class="ml-4" @click="searchFile"
|
>搜索</el-button
|
>
|
</div>
|
</div>
|
|
<div class="card-main flex-1 my-5 relative">
|
<div
|
class="main-content absolute top-0 bottom-0 left-0 right-0"
|
>
|
<el-table :data="fileList" height="100%" v-loading="loading">
|
<el-table-column label="文件名称">
|
<template #default="scope">
|
<div class="row-info">
|
<div class="icon">
|
<img
|
:src="getIcon(scope.row.contentType)"
|
class="width-img"
|
/>
|
</div>
|
<div class="label">{{ scope.row.introduction }}</div>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
prop="className"
|
label="班级"
|
align="center"
|
/>
|
<el-table-column
|
prop="typeName"
|
label="科目"
|
align="center"
|
/>
|
<el-table-column
|
prop="updateTime"
|
label="上传时间"
|
align="center"
|
/>
|
<el-table-column>
|
<template #default="scope">
|
<el-button
|
link
|
type="primary"
|
@click.prevent="checkRow(scope.row)"
|
v-if="
|
scope.row.contentType == 'video' ||
|
scope.row.contentType == 'audio'
|
"
|
>
|
查看
|
</el-button>
|
<el-button
|
link
|
type="primary"
|
@click.prevent="download(scope.row)"
|
v-else
|
>
|
下载
|
</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
</div>
|
<div class="card-footer flex justify-center mb-7 shrink-0">
|
<el-pagination
|
background
|
layout="total, sizes, prev, pager, next, jumper"
|
:total="total"
|
:page-sizes="[10, 20, 50]"
|
:page-size="pageSize"
|
:currentPage="currentIndex"
|
@size-change="handleSizeChange"
|
@current-change="handleCurrentChange"
|
/>
|
</div>
|
</div>
|
</el-card>
|
</div>
|
</div>
|
</div>
|
|
<!-- pdf查看 -->
|
<!-- <div class="pdf-container" v-show="pdfViewer">
|
<PDFViewer :pdfUrl="pdfFile"></PDFViewer>
|
<div class="close-btn">
|
<el-button type="danger" size="large" circle @click="closeViewer">
|
<template #icon>
|
<el-icon :size="18">
|
<Close/>
|
</el-icon>
|
</template>
|
</el-button>
|
</div>
|
</div> -->
|
|
<!-- image查看 -->
|
<div class="image-container" v-show="imageViewer">
|
<el-image-viewer
|
:url-list="imageList"
|
@close="closeViewer"
|
></el-image-viewer>
|
</div>
|
|
<!-- 视频查看 -->
|
<div class="video-container" v-if="videoViewer">
|
<VideoViewer :videoUrl="videoUrl"></VideoViewer>
|
<div class="close-btn">
|
<el-button type="danger" size="large" circle @click="closeViewer">
|
<template #icon>
|
<el-icon :size="20">
|
<Close />
|
</el-icon>
|
</template>
|
</el-button>
|
</div>
|
</div>
|
<!-- 弹窗 -->
|
<!-- <el-drawer
|
v-model="fileViewer"
|
direction="btt"
|
size="90%"
|
:before-close="handleClose"
|
>
|
<DocumentViewer :fileUrl="fileUrl"></DocumentViewer>
|
</el-drawer> -->
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, onMounted, onBeforeUnmount } from "vue";
|
import { storeToRefs } from "pinia";
|
import { Close } from "@element-plus/icons-vue";
|
import NormalHeader from "@/components/NormalHeader/index.vue";
|
import { Search } from "@element-plus/icons-vue";
|
import { getFileList } from "@/api/modules/file.js";
|
import { getSubjectList } from "@/api/modules/subject.js";
|
|
import PDFViewer from "@/components/PDFViewer/index.vue";
|
import VideoViewer from "@/components/VideoViewer/index.vue";
|
import DocumentViewer from "@/components/DocumentViewer/index.vue";
|
|
import { useUserStore } from "@/store/index.js";
|
import useWebScoket from "@/hooks/useWebScoket.js";
|
|
const userStore = useUserStore();
|
const { userInfo } = storeToRefs(userStore);
|
const { status, message, error, connect, disconnect, sendMessage } =
|
useWebScoket({
|
url: "wss://ycl.easyblog.vip:82/websocket/" + userInfo.value.id,
|
heartBeatData: "ping",
|
});
|
|
const time = ref(null);
|
|
const fileType = {
|
img: {
|
iconPath: "/static/icons/file_type_image.png",
|
handle: (item) => {
|
imageViewer.value = true;
|
imageList.value = ["/api/files/" + item.contentUrl.url];
|
resendMessage();
|
},
|
},
|
video: {
|
iconPath: "/static/icons/file_type_video.png",
|
handle: (item) => {
|
videoViewer.value = true;
|
videoUrl.value = ["/api/files/" + item.contentUrl.url];
|
resendMessage();
|
},
|
},
|
pdf: {
|
iconPath: "/static/icons/file_type_pdf.png",
|
handle: (item) => {
|
pdfViewer.value = true;
|
pdfFile.value = "/api/files/" + item.contentUrl.url;
|
resendMessage();
|
},
|
},
|
word: {
|
iconPath: "/static/icons/file_type_word.png",
|
handle: (item) => {
|
pdfViewer.value = true;
|
pdfFile.value = "/api/files/" + item.contentUrl.url;
|
resendMessage();
|
},
|
},
|
ppt: {
|
iconPath: "/static/icons/file_type_ppt.png",
|
handle: (item) => {
|
pdfViewer.value = true;
|
pdfFile.value = "/api/files/" + item.contentUrl.url;
|
resendMessage();
|
},
|
},
|
audio: {
|
iconPath: "/static/icons/file_type_audio.png",
|
handle: (item) => {
|
console.log(item);
|
videoViewer.value = true;
|
videoUrl.value = "/api/files/" + item.contentUrl.url;
|
resendMessage();
|
},
|
},
|
excel: {
|
iconPath: "/static/icons/file_type_excel.png",
|
handle: (item) => {
|
console.log(item);
|
pdfViewer.value = true;
|
pdfFile.value = "/api/files/" + item.contentUrl.url;
|
resendMessage();
|
},
|
},
|
};
|
const searchText = ref("");
|
const searchSubject = ref("");
|
const searchContentType = ref("");
|
|
const loading = ref(false);
|
|
const pdfViewer = ref(false);
|
const imageViewer = ref(false);
|
const videoViewer = ref(false);
|
|
const imageList = ref([]);
|
const pdfFile = ref("");
|
const videoUrl = ref("");
|
|
const fileList = ref([]);
|
const subjectList = ref([]);
|
const contentTypeList = ref([
|
{ name: "视频", value: "video" },
|
{ name: "图片", value: "img" },
|
{ name: "音频", value: "audio" },
|
{ name: "PDF", value: "pdf" },
|
{ name: "EXCEL", value: "excel" },
|
{ name: "WORD", value: "word" },
|
{ name: "PPT", value: "ppt" },
|
]);
|
const currentIndex = ref(1);
|
const pageSize = ref(10);
|
const total = ref(0);
|
// const fileUrl = ref("");
|
const fileViewer = ref(false);
|
const checkRow = (item) => {
|
// fileUrl.value = item.contentUrl.url;
|
fileType[item.contentType] && fileType[item.contentType].handle(item);
|
};
|
|
// const handleClose = () => {
|
// fileViewer.value = false;
|
// fileUrl.value = "";
|
// console.log("我是否关闭:", fileUrl.value);
|
// };
|
|
const closeViewer = () => {
|
pdfViewer.value = false;
|
imageViewer.value = false;
|
videoViewer.value = false;
|
clearInterval(time.value);
|
};
|
|
const getData = () => {
|
loading.value = true;
|
getFileList({
|
introduction: searchText.value,
|
subjectId: searchSubject.value,
|
contentType: searchContentType.value,
|
pageSize: pageSize.value,
|
pageNum: currentIndex.value,
|
})
|
.then((res) => {
|
loading.value = false;
|
fileList.value = res.data;
|
total.value = res.total;
|
})
|
.catch(() => {
|
loading.value = false;
|
});
|
};
|
getData();
|
|
const getSubject = () => {
|
loading.value = true;
|
getSubjectList()
|
.then((res) => {
|
loading.value = false;
|
subjectList.value = res.data;
|
})
|
.catch(() => {
|
loading.value = false;
|
});
|
};
|
getSubject();
|
const resendMessage = () => {
|
if (time.value) {
|
clearInterval(time.value);
|
}
|
sendMessage({ id: userInfo.value.id, command: "recordStudyTime" });
|
time.value = setInterval(() => {
|
sendMessage({ id: userInfo.value.id, command: "recordStudyTime" });
|
}, 5000);
|
};
|
|
const getIcon = (type) => {
|
if (fileType[type]) {
|
return fileType[type].iconPath;
|
}
|
};
|
const handleSizeChange = (val) => {
|
currentIndex.value = 1;
|
pageSize.value = val;
|
getData();
|
};
|
const handleCurrentChange = (val) => {
|
currentIndex.value = val;
|
getData();
|
};
|
|
const searchFile = () => {
|
getData();
|
};
|
//下载
|
const download = (row) => {
|
window.open(row.visitUrl, '_blank');
|
};
|
|
// -----------------------------------生命周期
|
onMounted(() => {
|
// 连接webscoket
|
connect();
|
});
|
|
onBeforeUnmount(() => {
|
clearInterval(time.value);
|
});
|
</script>
|
|
<style lang="scss" scoped>
|
:deep(.el-tabs__nav-wrap:after) {
|
display: none;
|
}
|
|
.row-info {
|
display: flex;
|
align-items: center;
|
|
.icon {
|
width: 35px;
|
margin-right: 20px;
|
}
|
}
|
.long-input {
|
width: 200px;
|
}
|
|
.long-select {
|
width: 200px;
|
}
|
.pdf-container {
|
width: 100%;
|
height: 100%;
|
position: absolute;
|
z-index: 99999;
|
top: 50%;
|
left: 50%;
|
transform: translate(-50%, -50%);
|
|
.close-btn {
|
position: absolute;
|
top: 2px;
|
right: 30px;
|
z-index: 9999999;
|
|
:deep(.el-button) {
|
width: fit-content;
|
height: fit-content;
|
padding: 5px !important;
|
}
|
}
|
}
|
|
.video-container {
|
width: 100%;
|
height: 100%;
|
position: absolute;
|
z-index: 99999;
|
top: 50%;
|
left: 50%;
|
transform: translate(-50%, -50%);
|
|
.close-btn {
|
position: absolute;
|
top: 60px;
|
right: 100px;
|
z-index: 9999999;
|
|
:deep(.el-button) {
|
width: fit-content;
|
height: fit-content;
|
padding: 10px !important;
|
}
|
}
|
}
|
</style>
|