| | |
| | | <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="请输入搜索内容" class="long-input" :prefix-icon="Search"/> |
| | | <el-select v-model="searchSubject" placeholder="请选择科目" class="ml-4 long-select" 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" clearable> |
| | | <el-input |
| | | v-model="searchText" |
| | | placeholder="请输入搜索内容" |
| | | class="long-input" |
| | | :prefix-icon="Search" |
| | | /> |
| | | <el-select |
| | | v-model="searchSubject" |
| | | placeholder="请选择科目" |
| | | class="ml-4 long-select" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="item in contentTypeList" |
| | | :key="item.value" |
| | | :label="item.name" |
| | | :value="item.value"> |
| | | 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" |
| | | 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> |
| | | <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> |
| | | </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> |
| | |
| | | |
| | | <!-- 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"> |
| | | <template #icon> |
| | | <el-icon :size="20"> |
| | | <Close/> |
| | | <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> |
| | | <!-- <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 { 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://42.193.1.25:8000/websocket/' + userInfo.value.id, |
| | | heartBeatData: 'ping' |
| | | }); |
| | | const { userInfo } = storeToRefs(userStore); |
| | | const { status, message, error, connect, disconnect, sendMessage } = |
| | | useWebScoket({ |
| | | url: "ws://42.193.1.25:8000/websocket/" + userInfo.value.id, |
| | | heartBeatData: "ping", |
| | | }); |
| | | |
| | | const time = ref(null); |
| | | |
| | | |
| | | 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 = ['/api/files/' + 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 = ['/api/files/' + 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 = '/api/files/' + item.contentUrl.url; |
| | | pdfFile.value = "/api/files/" + item.contentUrl.url; |
| | | resendMessage(); |
| | | } |
| | | }, |
| | | }, |
| | | }; |
| | | const searchText = ref(''); |
| | | const searchSubject = ref('') |
| | | const searchContentType = ref('') |
| | | const searchText = ref(""); |
| | | const searchSubject = ref(""); |
| | | const searchContentType = ref(""); |
| | | |
| | | const loading = ref(false); |
| | | |
| | |
| | | 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 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 fileUrl = ref(""); |
| | | const pageSize = ref(10); |
| | | const total = ref(0); |
| | | // const fileUrl = ref(""); |
| | | const fileViewer = ref(false); |
| | | const checkRow = (item) => { |
| | | fileUrl.value = item.contentUrl.url; |
| | | // fileUrl.value = item.contentUrl.url; |
| | | fileType[item.contentType] && fileType[item.contentType].handle(item); |
| | | fileViewer.value = true |
| | | }; |
| | | |
| | | const handleClose = () => { |
| | | fileViewer.value = false; |
| | | fileUrl.value = ""; |
| | | console.log("我是否关闭:",fileUrl.value); |
| | | }; |
| | | // const handleClose = () => { |
| | | // fileViewer.value = false; |
| | | // fileUrl.value = ""; |
| | | // console.log("我是否关闭:", fileUrl.value); |
| | | // }; |
| | | |
| | | const closeViewer = () => { |
| | | pdfViewer.value = false; |
| | |
| | | |
| | | const getData = () => { |
| | | loading.value = true; |
| | | getFileList({introduction: searchText.value, subjectId: searchSubject.value, contentType:searchContentType.value}).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; |
| | | }); |
| | | 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); |
| | | }; |
| | | |
| | |
| | | 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(() => { |