<template> <div> <el-card shadow="hover" class="m-b-20"> <div class="flex-between"> <el-page-header @back="goBack" :content="sorting? '更改排序' : '内容设置'"></el-page-header> </div> </el-card> <!--内容设置--> <el-card shadow="hover" class="m-b-20"> <div class="page"> <div class="relative"> <div class="p-title">内容设置</div> <div class="btns" style="top: -10px"> <template v-if="!sorting"> <el-button v-auth="'/course/list:课程管理:内容设置:添加章节'" type="primary" round @click="addChapter">添加章节</el-button> <el-button v-auth="'/course/list:课程管理:内容设置:编辑顺序'" type="primary" round @click="sort">编辑顺序</el-button> </template> <template v-else> <el-button type="primary" round @click="move">批量移动</el-button> <el-button type="primary" round @click="cancelSort">取消</el-button> <el-button type="primary" round @click="saveSort">保存</el-button> </template> </div> </div> <el-divider></el-divider> <div class="page-content"> <div class="m-b-20" v-for="(chapter,index) in chapters" :key="chapter.id"> <div class="flex j-between a-center m-b-10"> <div>{{ chapter.name }}</div> <div> <template v-if="!sorting"> <el-button v-auth="'/course/list:课程管理:内容设置:修改章节名称'" class="action-btn" type="primary" round @click="editChapter(chapter)">修改章节名称</el-button> <el-button v-auth="'/course/list:课程管理:内容设置:添加小节'" class="action-btn" type="primary" round @click="addSection(chapter.id)">添加小节</el-button> <el-button v-auth="'/course/list:课程管理:内容设置:章节删除'" class="action-btn" type="primary" round @click="delChapter(chapter.id)">删除</el-button> </template> <template v-else> <i class="el-icon-top sort-icon" :class="{disabled: index == 0}" style="margin-right: 5px" @click="sortChapter(chapter,'up',index == 0,index)"></i> <i class="el-icon-bottom sort-icon" :class="{disabled: index == chapters.length-1}" @click="sortChapter(chapter,'down',index == chapter.length-1,index)"></i> </template> </div> </div> <el-table :data="chapter.subsectionList" class="table" stripe header-align="center"> <el-table-column v-if="sorting" width="55" align="center"> <template slot-scope="scope"> <el-checkbox v-model="scope.row.check"></el-checkbox> </template> </el-table-column> <el-table-column type="index" width="100" label="序号" align="center"></el-table-column> <el-table-column prop="name" label="资源名称"> </el-table-column> <el-table-column prop="fileType" label="资源类型" align="center"> <template slot-scope="scope"> {{ transferType(scope.row.fileType) }} </template> </el-table-column> <el-table-column label="操作" align="center" width="300"> <template slot-scope="scope"> <template v-if="!sorting"> <el-button v-auth="'/course/list:课程管理:内容设置:查看'" type="text" @click="preview(scope.row)">查看</el-button> <el-button v-auth="'/course/list:课程管理:内容设置:小节删除'" type="text" @click="delSection(scope.row)">删除</el-button> <el-button v-auth="'/course/list:课程管理:内容设置:修改小节名称'" type="text" @click="editSectionName(scope.row,chapter.id)">修改小节名称</el-button> <el-button v-auth="'/course/list:课程管理:内容设置:更换文件'" type="text" @click="switchFile(scope.row,chapter.id)">更换文件</el-button> </template> <template v-else> <i class="el-icon-top sort-icon" :class="{disabled: scope.$index == 0}" style="margin-right: 5px" @click="sortSection(index,'up',scope.$index == 0,scope.$index)"></i> <i class="el-icon-bottom sort-icon" :class="{disabled: scope.$index == chapter.subsectionList.length-1}" @click="sortSection(index,'down',scope.$index == chapter.subsectionList.length-1,scope.$index)"></i> </template> </template> </el-table-column> </el-table> </div> <el-dialog :title="chapterId ? '编辑章节' : '新增章节'" :visible.sync="chapterVisible" width="24%" :close-on-click-modal="false"> <el-form> <el-form-item> <el-input placeholder="请输入章节名称,便于对小节归类" v-model="chapterName" maxlength="50"></el-input> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="chapterVisible = false">取消</el-button> <el-button type="primary" @click="chapterSubmit">确定</el-button> </span> </el-dialog> <el-dialog title="添加小节" :visible.sync="sectionVisible" width="28%" @close="closeSection" :close-on-click-modal="false"> <el-form label-width="80px"> <el-form-item label="资源添加"> <el-upload :before-upload="beforeUpload" :on-remove="handleRemove" :on-error="uploadError" :on-success="uploadSuccess" :before-remove="beforeRemove" :limit="1" :on-exceed="handleExceed" :action="this.api.fileupload" :file-list="uploadList" :headers="headers" :http-request="handleRequest" name="file" > <el-button size="small"><img src="@/assets/img/upload.png" alt=""> 上传资源</el-button> </el-upload> <el-progress v-if="showProgress" :stroke-width="3" :percentage="progressPercent"></el-progress> </el-form-item> <el-form-item label="小节名称"> <el-input placeholder="请输入小节名称" v-model="sectionName" maxlength="50"></el-input> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="sectionVisible = false">取消</el-button> <el-button type="primary" @click="sectionSubmit">确定</el-button> </span> </el-dialog> <el-dialog title="更换文件" :visible.sync="switchVisible" width="28%" :close-on-click-modal="false" @close="closeSwitch"> <div style="text-align: center"> <el-upload :before-upload="beforeUpload" :on-remove="handleRemove" :on-error="uploadError" :on-success="uploadSuccess" :before-remove="beforeRemove" :limit="1" :on-exceed="handleExceed" :action="this.api.fileupload" :file-list="uploadList" :headers="headers" :http-request="handleRequest" name="file" > <el-button size="small"><img src="@/assets/img/upload.png" alt=""> 上传资源</el-button> </el-upload> <el-progress v-if="showProgress" :stroke-width="3" :percentage="progressPercent"></el-progress> </div> <span slot="footer" class="dialog-footer"> <el-button @click="switchVisible = false">取消</el-button> <el-button type="primary" @click="switchSubmit">确定</el-button> </span> </el-dialog> <el-dialog title="修改小节名称" :visible.sync="sectionNameVisible" width="24%" :close-on-click-modal="false"> <el-form> <el-form-item> <el-input placeholder="请输入小节名称" v-model="sectionName" maxlength="50"></el-input> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="sectionNameVisible = false">取消</el-button> <el-button type="primary" @click="sectionNameSubmit">确定</el-button> </span> </el-dialog> <div v-show="previewImg" class="el-image-viewer__wrapper" :class="{active: previewImg}" style="z-index: 2000"> <div class="el-image-viewer__mask"></div> <span class="el-image-viewer__btn el-image-viewer__close" @click="previewImg = ''"><i class="el-icon-circle-close" style="color: #fff"></i></span> <div class="el-image-viewer__canvas"> <img :src="previewImg" class="el-image-viewer__img" style="transform: scale(1) rotate(0deg);margin-top: -1px; max-height: 100%; max-width: 100%;"> </div> </div> <div v-show="iframeSrc" class="el-image-viewer__wrapper" :class="{active: iframeSrc}" style="z-index: 2000"> <div class="el-image-viewer__mask"></div> <span class="el-image-viewer__btn el-image-viewer__close" :class="{'doc-close': isWord}" :style="{top: isWord ? '50px' : '5px'}" @click="closeIframe"><i class="el-icon-circle-close" style="color: #fff"></i></span> <div class="el-image-viewer__canvas"> <iframe v-if="iframeSrc" class="fileIframe" id="fileIframe" :src="iframeSrc" frameborder="0"></iframe> <template v-if="showMask"> <div class="mask" style="width: 200px;height: 30px;top: 53px;right: 320px"></div> <div class="mask" style="width: 175px;height: 30px;top: 53px;right: 5px"></div> </template> <template v-if="showMask1"> <div class="word-mask1" style="width: 200px;height: 50px;"></div> <div class="word-mask" style="height: 40px;top: 48px;"></div> <div class="word-mask2" style="top: 55px;left: 28%;width: 44%;height: calc(100% - 80px);"></div> </template> <template v-if="showMask2 && iframeSrc"> <div class="excel-mask1" style="height: 48px;"></div> </template> </div> </div> <div v-show="playAuth" class="el-image-viewer__wrapper" :class="{active: playAuth}" style="z-index: 2000"> <div class="el-image-viewer__mask"></div> <span class="el-image-viewer__btn el-image-viewer__close" @click="closePlayer"><i class="el-icon-circle-close" style="color: #fff"></i></span> <div class="player" id="player"></div> </div> <pdf :visible.sync="pdfVisible" :src.sync="pdfSrc"></pdf> </div> </div> </el-card> <el-dialog title="资源移动" :visible.sync="moveVisible" :close-on-click-modal="false" width="330px"> <el-form> <el-form-item label="目标章节"> <el-select v-model="moveForm.id" placeholder="请选择目标章节" @change="chapterChange"> <el-option v-for="(item, i) in chapters" :key="i" :label="item.name" :value="item.id"></el-option> </el-select> </el-form-item> <el-form-item label="目标排序"> <el-select v-model="moveForm.sort" placeholder="请选择目标排序"> <el-option v-for="(item, i) in sortList" :key="i" :label="item.name" :value="item.id"></el-option> </el-select> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="moveVisible = false">取消</el-button> <el-button type="primary" @click="moveConfirm">确定</el-button> </span> </el-dialog> </div> </template> <script> import util from "@/libs/util"; import Setting from "@/setting"; import { Loading } from "element-ui"; import pdf from "@/components/pdf"; import axios from 'axios' export default { name: "contentSettings", data() { return { headers: { token: util.local.get(Setting.tokenKey) }, id: "", originChapters: [], chapters: [], sorting: false, uploading: false, uploadList: [], chapterVisible: false, chapterId: "", chapterName: "", sectionVisible: false, sectionName: "", sectionId: "", switchVisible: false, sectionNameVisible: false, fileId: "", fileName: "", fileUrl: "", originalFileName: "", fileType: "", playAuth: "", player: null, previewImg: "", iframeSrc: "", curFile: {}, isAddSection: false, isWord: false, isPPT: false, isExcel: false, showMask: false, showMask1: false, showMask2: false, loadIns: null, pdfVisible: false, pdfSrc: "", showProgress: false, progressPercent: 0, previewing: false, moveVisible: false, checkList: [], sortList: [ { id: 'bottom', name: '置末' }, { id: 'top', name: '置顶' } ], moveForm: { id: '', sort: 'bottom' }, moved: false // 是否移动过 }; }, components: { pdf }, mounted() { this.insertScript(); this.id = this.$route.query.id; this.id && this.getData(); // 处理预览资源后返回弹框不会消失的问题 if (window.history && window.history.pushState) { history.pushState(null, null, document.URL); window.addEventListener("popstate", this.goBack, false); } }, destroyed() { window.removeEventListener("popstate", this.goBack, false); }, methods: { getData() { this.$get(`${this.api.queryChaptersAndSubsections}?courseId=${this.id}`) .then(res => { this.chapters = res.chapterList; }) .catch(err => { }); }, goBack() { // 如果是预览则关闭预览 if (this.previewing) { this.closeIframe(); } else { // 排序中 if (this.sorting) { // 已经移动了顺序 if (this.moved) { this.$confirm(`编辑的内容未保存,是否保存?`, '提示', { type: 'warning' }).then(() => { this.saveSort() this.moved = false }).catch(() => { this.sorting = false this.chapters = JSON.parse(JSON.stringify(this.originChapters)) }) } else { this.sorting = false } } else { this.$router.back() } } }, iframeOnload() { document.querySelector("#fileIframe").onload = e => { if (this.isPPT) { this.showMask = true; } else { this.showMask = false; } if (this.isWord) { this.showMask1 = true; } else { this.showMask1 = false; } if (this.isExcel) { this.showMask2 = true; } else { this.showMask2 = false; } this.loadIns.close(); }; }, insertScript() { const linkTag = document.createElement("link"); linkTag.rel = "stylesheet"; linkTag.href = "https://g.alicdn.com/de/prismplayer/2.8.2/skins/default/aliplayer-min.css"; document.body.appendChild(linkTag); const scriptTag = document.createElement("script"); scriptTag.type = "text/javascript"; scriptTag.src = "https://g.alicdn.com/de/prismplayer/2.8.2/aliplayer-min.js"; document.body.appendChild(scriptTag); }, // 上传文件 beforeUpload(file) { let type = this.transferType(file.name.substring(file.name.lastIndexOf(".") + 1)); if (type != "视频" && type != "图片" && type != "pdf" && (file.size / 1024 / 1024) > 10) { util.errorMsg("请上传10M以内的文件"); return false; } this.uploading = true; this.originalFileName = file.name; if (this.isAddSection) this.sectionName = file.name.substring(0, file.name.lastIndexOf(".")); this.fileType = file.name.substring(file.name.lastIndexOf(".") + 1); this.showProgress = true }, handleExceed(files, fileList) { util.warningMsg( `当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!` ); }, // 自定义上传 handleRequest(data) { const param = new FormData() param.append('file', data.file) const config = { timeout: 10000000000, headers: { 'Accept': '*/*', 'Content-Type': 'multipart/form-data', token: util.local.get(Setting.tokenKey) }, // 获取上传进度,自带的组件上传进度不准确 onUploadProgress: progressEvent => { const per = Number((progressEvent.loaded / progressEvent.total * 100).toFixed(2)) console.log("🚀 ~ file: contentSettings.vue ~ line 329 ~ handleRequest ~ per", per, this.progressPercent) if (this.progressPercent <= 80) this.progressPercent = (per > 80) ? (Math.random() * 10 + 80).toFixed(2) : per } } axios.post(this.api.fileupload, param, config).then(res => { this.progressPercent = 100 this.showProgress = false const { fileId, fileType, fileUrl, ossFileName } = res.data.data.filesResult this.uploading = false this.fileId = fileId this.fileType = fileType this.fileUrl = fileUrl this.fileName = ossFileName }) }, uploadSuccess(res, file, fileList) { this.uploading = false; this.fileId = res.data.filesResult.fileId; this.fileType = res.data.filesResult.fileType; this.fileUrl = res.data.filesResult.fileUrl; this.fileName = res.data.filesResult.ossFileName; }, uploadError(err, file, fileList) { this.$message({ message: "上传出错,请重试!", type: "error", center: true }); }, beforeRemove(file, fileList) { if ((file.size / 1024 / 1024) < 10) { return this.$confirm(`确定移除 ${file.name}?`); } }, handleRemove(file, fileList) { this.uploadList = fileList; }, uploadSure() { this.importVisible = false; this.pageNo = 1; this.staffGradeId = ""; this.keyword = ""; this.getTeacher(); }, goback() { this.$router.push("course"); }, transferType(ext) { const suf = ext.toLowerCase() if ("jpg,jpeg,png,gif,svg,psd".includes(suf)) return "图片"; if ("mp4,3gp,mov,m4v,avi,dat,mkv,flv,vob,rmvb,rm,qlv".includes(suf)) return "视频"; return suf; }, addChapter() { this.chapterName = ""; this.chapterId = ""; this.chapterVisible = true; }, sort() { this.originChapters = JSON.parse(JSON.stringify(this.chapters)) this.sorting = true; }, // 批量移动 move() { const list = this.chapters const checkList = [] list.map(e => { e.subsectionList.map(n => { n.check && checkList.push(n) }) }) this.checkList = checkList if (checkList.length) { this.moveForm = { id: '', sort: 'bottom' } this.sortList = [ { id: 'bottom', name: '置末' }, { id: 'top', name: '置顶' } ] this.moveVisible = true } else { this.$message.warning('请选择小节!') } }, // 目标章节选择回调 chapterChange(id) { const list = [] // 获取多少个小节 this.chapters.find(e => e.id === id).subsectionList.map((e, i) => { list.push({ id: i, name: i+1 }) }) // 置末和置顶写死 this.sortList = [ { id: 'bottom', name: '置末' }, ...list, { id: 'top', name: '置顶' } ] }, // 资源移动校验 moveConfirm() { let { id, sort } = this.moveForm if (!id) return this.$message.warning('请选择目标章节') if (sort === '') return this.$message.warning('请选择目标排序') if (typeof sort === 'string') sort = sort === 'top' ? 0 : this.sortList.length - 2 // 置顶和置末直接给排序 this.moveVisible = false const list = this.checkList list.map(e => e.check = false) const ids = list.map(e => e.id) const { chapters } = this chapters.map(e => { e.children = [] e.subsectionList.map(n => { if (!ids.includes(n.id)) { e.children.push(n) } }) e.subsectionList = e.children delete e.children if (e.id === id) e.subsectionList.splice(sort, 0, ...list) }) this.moved = true }, cancelSort() { this.chapters = JSON.parse(JSON.stringify(this.originChapters)) this.sorting = false; }, saveSort() { this.chapters.forEach((n, k) => { n.sort = k + 1; n.subsectionList.forEach((j, i) => { j.sort = i + 1 j.chapterId = n.id }); }); let data = { chapterVOList: this.chapters }; this.$post(this.api.reorder, data).then(res => { this.sorting = false; }).catch(res => { }); }, editChapter(item) { this.chapterId = item.id; this.chapterName = item.name; this.chapterVisible = true; }, delChapter(id) { this.$confirm("此删除操作不可逆,是否确认删除选中项?", "提示", { type: "warning" }) .then(() => { this.$del(`${this.api.deleteChapter}?chapterId=${id}`).then(res => { util.successMsg("删除成功"); this.getData(); }).catch(res => { }); }) .catch(() => { }); }, closeSection() { this.isAddSection = false; }, addSection(id) { this.chapterId = id; this.sectionName = ""; this.fileUrl = ""; this.uploadList = []; this.sectionId = ""; this.isAddSection = true; this.sectionVisible = true; }, chapterSubmit() { if (!this.chapterName) return util.warningMsg("请填写章节名称"); let data = { courseId: this.id, name: this.chapterName }; if (this.chapterId) { data.id = this.chapterId; this.$put(this.api.editChapter, data).then(res => { util.successMsg("修改成功"); this.chapterVisible = false; this.getData(); }) .catch(err => { }); } else { this.$post(this.api.addChapter, data).then(res => { util.successMsg("添加成功"); this.chapterVisible = false; this.getData(); }) .catch(err => { }); } }, sectionSubmit() { if (!this.sectionName) return util.warningMsg("请填写小节名称"); if (this.uploading) return util.warningMsg("资源正在上传中,请稍候"); if (!this.fileUrl && !this.fileId) return util.warningMsg("请上传资源"); let data = { id: this.sectionId, courseId: this.id, chapterId: this.chapterId, name: this.sectionName, fileId: this.fileId, fileUrl: this.fileUrl, fileName: this.fileName, fileType: this.fileType, originalFileName: this.originalFileName }; this.$post(this.api.addSubsection, data).then(res => { util.successMsg("添加成功"); this.sectionVisible = false; this.getData(); }) .catch(err => { }); }, closeSwitch() { this.fileId = ""; this.fileName = ""; this.fileType = ""; this.fileUrl = ""; this.sectionId = ""; }, preview(row) { if (this.transferType(row.fileType) == "视频") { this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => { this.playAuth = res.data.playAuth; if (this.player) { this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth); } else { this.player = new Aliplayer({ id: "player", width: "100%", autoplay: false, vid: row.fileId, playauth: this.playAuth, encryptType: 1 //当播放私有加密流时需要设置。 }); } }).catch(res => { }); } else if (this.transferType(row.fileType) == "图片") { this.previewImg = row.fileUrl; } else if (row.fileType == "pdf") { this.pdfSrc = row.fileUrl; this.pdfVisible = true; } else { this.$get(`${this.api.getSubsection}?subsectionId=${row.id}`).then(res => { this.previewing = true; this.loadIns = Loading.service(); this.$route.fullPath.includes("#file") || history.pushState({ file: true }, "文件预览", "#" + this.$route.fullPath + "#file"); if (row.fileType == "pptx") { this.isPPT = true; this.isWord = false; this.isExcel = false; } else if (row.fileType == "doc" || row.fileType == "docx") { this.isPPT = false; this.isWord = true; this.isExcel = false; } else if (row.fileType == "xls" || row.fileType == "xlsx") { this.isExcel = true; this.isPPT = false; this.isWord = false; } else { this.isPPT = false; this.isWord = false; this.isExcel = false; } this.iframeSrc = res.previewUrl; this.$nextTick(() => { this.iframeOnload(); }); }) .catch(err => { }); } }, editSectionName(row, chapterId) { this.chapterId = chapterId; this.sectionId = row.id; this.sectionName = row.name; this.sectionNameVisible = true; }, switchFile(row, chapterId, sectionId) { this.uploadList = []; this.curFile = { fileId: row.fileId, fileName: row.fileName, fileType: row.fileType, fileUrl: row.fileUrl }; this.chapterId = chapterId; this.sectionId = row.id; this.sectionName = row.sectionName; this.switchVisible = true; }, switchSubmitFile() { let data = { id: this.sectionId, courseId: this.id, chapterId: this.chapterId, name: this.sectionName, fileId: this.fileId, fileName: this.fileName, fileType: this.fileType, fileUrl: this.fileUrl, originalFileName: this.originalFileName }; this.$put(this.api.editSubsection, data).then(res => { util.successMsg("更换成功"); this.switchVisible = false; this.getData(); }) .catch(err => { }); }, switchSubmit() { if (this.uploading) return util.warningMsg("资源正在上传中,请稍候"); if (!this.fileUrl && !this.fileId) return util.warningMsg("请上传资源"); if (this.transferType(this.curFile.fileType) == "视频") { let data = { videoIdList: [this.sectionId] }; this.$del(`${this.api.removeVideo}/${this.curFile.fileId}`).then(res => { this.switchSubmitFile(); }).catch(res => { }); } else { this.$del(`${this.api.fileDeletion}?keys=${this.curFile.fileName}`).then(res => { this.switchSubmitFile(); }).catch(res => { }); } }, delSection(row) { this.$confirm("此删除操作不可逆,是否确认删除选中项?", "提示", { type: "warning" }) .then(() => { this.$del(`${this.api.deleteSubsection}?subsectionId=${row.id}`).then(res => { util.successMsg("删除成功"); this.getData(); }).catch(res => { }); }) .catch(() => { }); }, sortChapter(row, type, disabled, index) { if (!disabled) { if (type == "up") { let tempItem = this.chapters.splice(index - 1, 1)[0]; this.chapters.splice(index, 0, tempItem); } else { let tempItem = this.chapters.splice(index + 1, 1)[0]; this.chapters.splice(index, 0, tempItem); } } }, sortSection(chapterIndex, type, disabled, index) { if (!disabled) { this.moved = true let list = this.chapters[chapterIndex].subsectionList; if (type == "up") { let tempItem = list.splice(index - 1, 1)[0]; list.splice(index, 0, tempItem); } else { let tempItem = list.splice(index + 1, 1)[0]; list.splice(index, 0, tempItem); } this.chapters[chapterIndex].subsectionList = list; } }, sectionNameSubmit() { if (!this.sectionName) return util.warningMsg("请填写小节名称"); let data = { id: this.sectionId, courseId: this.id, chapterId: this.chapterId, name: this.sectionName }; this.$put(this.api.editSubsection, data).then(res => { util.successMsg("修改成功"); this.sectionNameVisible = false; this.getData(); }) .catch(err => { }); }, closePlayer() { this.playAuth = ""; this.player.pause(); }, closeIframe() { this.iframeSrc = ""; this.showMask = false; this.showMask1 = false; this.showMask2 = false; this.previewing = false; } } }; </script> <style scoped lang="scss"> .btns { position: absolute; top: 12px; right: 24px; .el-button { font-size: 14px; } } /deep/.el-progress-bar { padding-right: 70px; margin-right: -70px; } .sort-icon { font-size: 24px; cursor: pointer; &.disabled { color: #ccc; cursor: not-allowed } } .el-image-viewer__wrapper { transform: translateY(-10px); transition: transform .5s; &.active { transform: translateY(0) } } .el-image-viewer__close { z-index: 10000; top: 15px; right: 15px; &.doc-close { i { color: #000 !important; } } } .player { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 1200px !important; height: 600px !important; } .fileIframe { z-index: 1; position: absolute; top: 0; left: 0; bottom: 0; right: 0; width: 100%; height: 100%; } .mask { z-index: 1000; position: fixed; background-color: rgb(57, 58, 61); } .word-mask { z-index: 1000; position: fixed; right: 0; width: 100%; background-color: rgb(243, 242, 241); } .word-mask1 { z-index: 1000; position: fixed; top: 0; right: 0; background-color: #2b579a; } .word-mask2 { z-index: 1000; position: fixed; background-color: transparent; } .excel-mask1 { z-index: 9; position: absolute; top: 0; left: 20%; width: 80%; background-color: #107c41; } </style>