From 802f9516b59f342d7aa8a734d35061a1ab910520 Mon Sep 17 00:00:00 2001 From: xiangpei <xiangpei@timesnew.cn> Date: 星期日, 03 十一月 2024 23:12:45 +0800 Subject: [PATCH] 教学资源附件查看/下载 --- src/views/folder/index.vue | 358 ++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 290 insertions(+), 68 deletions(-) diff --git a/src/views/folder/index.vue b/src/views/folder/index.vue index 1901e4e..3b6c849 100644 --- a/src/views/folder/index.vue +++ b/src/views/folder/index.vue @@ -1,52 +1,140 @@ <template> - <div class="train-container w-screen h-screen bg-slate-50 flex flex-col items-center"> + <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="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="璇疯緭鍏ユ悳绱㈠唴瀹�" :prefix-icon="Search" maxlength="20" /> - <el-button type="primary" class="ml-4" @click="searchFile">鎼滅储</el-button> + <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"> + <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" /> + <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 + 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)"> + <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> + <el-button + link + type="primary" + @click.prevent="showAttachment(scope.row.attachment)" + v-if="scope.row.attachment && scope.row.attachment.length > 0" + > + 鏌ョ湅闄勪欢 </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="prev, pager, next" :total="fileList.length" - :default-page-size="20" - :currentPage="currentIndex" - :hide-on-single-page="true" - @current-change="handleCurrentChange" /> + <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> @@ -55,26 +143,29 @@ </div> <!-- pdf鏌ョ湅 --> - <div class="pdf-container" v-show="pdfViewer"> + <!-- <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 /> + <Close/> </el-icon> </template> </el-button> </div> - </div> + </div> --> <!-- image鏌ョ湅 --> <div class="image-container" v-show="imageViewer"> - <el-image-viewer :url-list="imageList" @close="closeViewer"></el-image-viewer> + <el-image-viewer + :url-list="imageList" + @close="closeViewer" + ></el-image-viewer> </div> <!-- 瑙嗛鏌ョ湅 --> - <div class="video-container" v-show="videoViewer"> + <div class="video-container" v-if="videoViewer"> <VideoViewer :videoUrl="videoUrl"></VideoViewer> <div class="close-btn"> <el-button type="danger" size="large" circle @click="closeViewer"> @@ -86,64 +177,130 @@ </el-button> </div> </div> + <!-- 寮圭獥 --> + <!-- <el-drawer + v-model="fileViewer" + direction="btt" + size="90%" + :before-close="handleClose" + > + <DocumentViewer :fileUrl="fileUrl"></DocumentViewer> + </el-drawer> --> + + <el-dialog + v-model="attachmentShow" + title="闄勪欢" + width="500" + :close-on-click-modal="false" + :before-close="handleClose" + > + <div v-for="(attachment, index) in attachmentList" :key="index"> + <el-link type="primary" :href="'/api/upload/download?url=' + attachment.url +'&fileName=' + attachment.name"> + {{ attachment.name }} + </el-link> + </div> + <div></div> + <template #footer> + <div class="dialog-footer"> + <el-button @click="handleClose">鍙栨秷</el-button> + </div> + </template> + </el-dialog> </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 { 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 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'; +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: 'ws://192.168.3.64:8000/websocket/' + userInfo.value.id, - heartBeatData: 'ping' -}); +const { status, message, error, connect, disconnect, sendMessage } = + useWebScoket({ + url: "wss://www.kgmeet.com:18443/websocket/" + userInfo.value.id, + heartBeatData: "ping", + }); const time = ref(null); - +const attachmentShow = ref(false) const fileType = { - 'img': { - iconPath: '/static/icons/file_type_image.png', + img: { + iconPath: "/static/icons/file_type_image.png", handle: (item) => { - console.log(item); imageViewer.value = true; - imageList.value = [item.contentUrl.url]; + imageList.value = ["/api/files/" + item.contentUrl.url]; resendMessage(); - } + }, }, - 'video': { - iconPath: '/static/icons/file_type_video.png', + 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 = [item.contentUrl.url]; + videoUrl.value = "/api/files/" + item.contentUrl.url; resendMessage(); - } + }, }, - 'pdf': { - iconPath: '/static/icons/file_type_pdf.png', + excel: { + iconPath: "/static/icons/file_type_excel.png", handle: (item) => { console.log(item); pdfViewer.value = true; - pdfFile.value = item.contentUrl.url; + pdfFile.value = "/api/files/" + item.contentUrl.url; resendMessage(); - } + }, }, }; -const searchText = ref(''); +const searchText = ref(""); +const searchSubject = ref(""); +const searchContentType = ref(""); +const attachmentList = ref([]); const loading = ref(false); @@ -152,17 +309,47 @@ const videoViewer = ref(false); const imageList = ref([]); -const pdfFile = ref(''); -const videoUrl = 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 handleClose = () => { + attachmentShow.value = false +} + +const showAttachment = (attachmentListParam) => { + + attachmentList.value = attachmentListParam + console.log(attachmentList.value, "ww") + attachmentShow.value = true +} 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; @@ -173,22 +360,43 @@ const getData = () => { loading.value = true; - getFileList().then(res => { - loading.value = false; - fileList.value = res.data; - }).catch(() => { - loading.value = false; - }); + 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' }); + sendMessage({ id: userInfo.value.id, command: "recordStudyTime" }); time.value = setInterval(() => { - sendMessage({ id: userInfo.value.id, command: 'recordStudyTime' }); + sendMessage({ id: userInfo.value.id, command: "recordStudyTime" }); }, 5000); }; @@ -197,15 +405,23 @@ return fileType[type].iconPath; } }; - -const handleCurrentChange = (val) => { +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(() => { @@ -232,7 +448,13 @@ margin-right: 20px; } } +.long-input { + width: 200px; +} +.long-select { + width: 200px; +} .pdf-container { width: 100%; height: 100%; @@ -278,4 +500,4 @@ } } } -</style> \ No newline at end of file +</style> -- Gitblit v1.8.0