把学生端的实验台复制过来

dev_2022-05-11
yujialong 3 years ago
parent 1e956972db
commit 653209b48c
  1. 5
      src/api/index.js
  2. 8
      src/layouts/navbar/index.vue
  3. 121
      src/pages/station/list/index.vue
  4. 533
      src/pages/station/preview/index.vue
  5. 27
      src/router/index.js
  6. 5
      src/setting.js

@ -11,6 +11,11 @@ export default {
isClient: `${host}users/users/user/isClient`,// 是否为客户
getUserAllRoleByToken : `${host}users/role/getUserAllRoleByToken`,
//实验台
curriculumDetail: `${host}nakadai/nakadai/curriculum/curriculumDetail`, // 课程详情
curriculumChapter: `${host}nakadai/curriculum/chapter/queryChaptersAndSubsections`, // 根据课程id查询章节小节,树状结构
curriculumGetSubsection: `${host}nakadai/curriculum/subsection/getSubsection`, // 根据小节id获取预览文件地址
// 权限管理
getUserRolesPermissionMenu: `${host}users/user-role/getUserRolesPermissionMenu`,

@ -36,6 +36,11 @@ export default {
return {
active: this.$route.path,
defaultMenus: [
{
icon: "el-icon-s-platform",
index: "/station/list",
title: "实验台"
},
{
icon: "el-icon-user",
index: "/student/list",
@ -119,7 +124,8 @@ export default {
this.defaultMenus.map(e => {
this.routers.find(n => n == e.index) && menus.push(e);
});
this.menus = menus;
// this.menus = menus;
this.menus = this.defaultMenus
// } else {
// this.menus = this.defaultMenus;
// }

@ -0,0 +1,121 @@
<template>
<!-- 实验台 -->
<div class="box">
<div class="search">
<input type="text" placeholder="请输入关键词" v-model="keyword">
<button>搜索</button>
</div>
<div class="wrap">
<template v-for="(item,index) in curriculumList">
<a class="item" @click="goPreview(item)" :key="index" v-if="!keyword || item.curriculumName.includes(keyword)">
<img :src="item.coverUrl" alt="">
<p class="text" v-html="item.curriculumName"></p>
</a>
</template>
</div>
</div>
</template>
<script>
export default {
name: "backstage",
data() {
return {
keyword: "",
curriculumList: []
}
},
mounted() {
this.getschoolCourse();
},
methods: {
getschoolCourse() { //
this.$get(this.api.schoolCourse).then(res => {
this.curriculumList = res.data;
}).catch(err => {
console.log(err);
});
},
goPreview(item) {
// let systemName = item.name.replace("<br>","")
this.$router.push(`/station/preview?courseId=${item.cid}&curriculumName=${item.curriculumName}`);
},
}
};
</script>
<style lang="scss" scoped>
.box {
padding: 20px;
background-color: #fff;
}
/deep/ .el-card {
margin-bottom: 0;
}
.search {
position: relative;
width: 30%;
margin: 50px auto 150px;
border-radius: 30px;
border: 1px solid #9076FF;
border-right: 0;
overflow: hidden;
input {
width: 100%;
height: 44px;
line-height: 44px;
padding: 0 20px;
font-size: 14px;
color: #333;
border: 0;
outline: none !important;
box-sizing: border-box;
}
button {
position: absolute;
top: 0;
right: 0;
padding: 0 20px;
line-height: 46px;
color: #fff;
background-color: #9076FF;
border: 0;
outline: none !important;
}
}
.wrap {
display: flex;
flex-wrap: wrap;
width: 70%;
margin: 0 auto;
min-height: calc(100vh - 520px);
box-sizing: border-box;
.item {
width: 16%;
margin: 20px;
text-align: center;
cursor: pointer;
&:hover {
opacity: .9;
}
img {
width: 100px;
height: 100px;
margin: 0 auto 6px;
}
.text {
font-size: 14px;
text-align: center;
color: #333;
}
}
}
</style>

@ -0,0 +1,533 @@
<template>
<div style="padding: 24px">
<el-card shadow="hover" class="m-b-20">
<div class="flex-between">
<el-page-header @back="goBack" :content="curriculumName"></el-page-header>
</div>
</el-card>
<el-card shadow="hover" class="m-b-20" style="background: none;">
<div class="flex">
<div class="cover" :class="{'is-word': showMask1}">
<!--实验台不显示课程封面-->
<img v-if="coverUrl" :src="coverUrl" alt="" width="100%" height="100%">
<template v-else-if="iframeSrc">
<iframe class="inner fileIframe" id="fileIframe" :src="iframeSrc" frameborder="0"></iframe>
<template v-if="showMask">
<div class="mask" style="width:100%;background: #393A3D;height: 30px;top: 53px;"></div>
<div class="mask" style="width:100%;background: #393A3D;height: 30px;top: 53px;"></div>
</template>
<template v-if="showMask1">
<div class="word-mask" style="height: 40px;"></div>
<div class="word-mask2"
style="top: 55px;left: 28%;width: 44%;height: calc(100% - 80px);"></div>
</template>
<template v-if="showMask2">
<div class="excel-mask1" style="height: 48px;"></div>
</template>
</template>
<div class="pdf inner" v-else-if="pdfSrc">
<p class="arrow">
<span @click="changePdfPage(0)" class="turn el-icon-arrow-left"
:class="{grey: currentPage==1}"></span>
{{ currentPage }} / {{ pageCount }}
<span @click="changePdfPage(1)" class="turn el-icon-arrow-right"
:class="{grey: currentPage==pageCount}"></span>
</p>
<div style='color:#393A3D;height: 30px;
background: #393A3D;'></div>
<pdf
class="pdf-wrap"
:src="pdfSrc"
:page="currentPage"
@num-pages="pageCount=$event"
@page-loaded="currentPage=$event"
@loaded="loadPdfHandler">
</pdf>
</div>
<div class="inner" v-else-if="playAuth">
<div class="video_wid" id="player"></div>
</div>
</div>
<div class="catalog flex-1">
<div class="m-b-20">
<el-button type="primary" @click="goSystem" style="width: 100%; height: 50px; font-size: 18px"> </el-button>
</div>
<div class="list">
<h4 class="title">{{ courseName }}</h4>
<div class="chapters">
<template v-if="chapterList.length">
<div class="chapter" v-for="(item,index) in chapterList" :key="index">
<div class="chapterName">{{ item.name }}</div>
<div class="section" v-if="item.subsectionList.length">
<div v-for="(section,i) in item.subsectionList" :key="i" @click="preview(section, item.name)">
<p class="sectionName" :class="{active: curLink === `${item.name}${section.name}`}">{{ section.name }}</p>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
</div>
</el-card>
<el-card shadow="hover" class="m-b-20">
<h4 style="margin-bottom: 10px">课程简介</h4>
<p>{{ briefIntroduction }}</p>
</el-card>
<el-card shadow="hover" class="m-b-20">
<h4 style="margin-bottom: 10px">课程目标</h4>
<p>{{ teachingObjectives }}</p>
</el-card>
<!--
<el-card shadow="hover" class="m-b-20">
<h4 style="margin-bottom: 10px">课程进度</h4>
<el-progress :text-inside="true" :stroke-width="16" :percentage="70"></el-progress>
</el-card>
-->
</div>
</template>
<script>
import util from "@/libs/util";
import Setting from "@/setting";
import { mapState } from "vuex";
import pdf from "vue-pdf";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
import bus from "@/libs/bus";
export default {
components: { pdf },
data() {
return {
courseId: this.$route.query.courseId,
curriculumName: this.$route.query.curriculumName,
video: "http://liuwanr.oss-cn-shenzhen.aliyuncs.com/mp4/20200519/1589871025648.mp4",
chapterList: [], //
coverUrl: "", //
courseName: "", //
briefIntroduction: "", //
teachingObjectives: "", //
assessmentList: "", //
curLink: "", //
playAuth: "",
player: null,
previewImg: "",
iframeSrc: "",
isWord: false,
isPPT: false,
isExcel: false,
showMask: false,
showMask1: false,
showMask2: false,
closePosi: {
top: "80px"
},
pdfVisible: false,
pdfSrc: "",
currentPage: 0, // pdf
pageCount: 0, // pdf
fileType: "pdf", //
desShrink: false
};
},
computed: {
...mapState("user", [
"userId", "studentId", "roleId", "userName"
])
},
mounted() {
bus.$emit("setBg", "none");
this.insertScript();
this.getData();
this.getChapter();
},
methods: {
goBack() {
this.$router.back();
},
async getData() {
let { data } = await this.$post(`${this.api.curriculumDetail}?cid=${this.courseId}`);
this.courseName = data.curriculumName;
// this.coverUrl = data.coverUrl;
this.briefIntroduction = data.briefIntroduction;
this.teachingObjectives = data.teachingObjectives;
this.assessmentList = data.assessmentConfig;
},
async getChapter() {
let res = await this.$get(`${this.api.curriculumChapter}/${this.courseId}`);
this.chapterList = res.chapterList;
if (this.chapterList.length && this.chapterList[0].subsectionList && this.chapterList[0].subsectionList.length) {
// console.log(this.chapterList[0].subsectionList[0]);
this.preview(this.chapterList[0].subsectionList[0], this.chapterList[0].name);
}
},
//
insertScript() {
const linkTag = document.createElement("link");
linkTag.id = "aliplayerLink";
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.id = "aliplayerScript";
scriptTag.type = "text/javascript";
scriptTag.src = "https://g.alicdn.com/de/prismplayer/2.8.2/aliplayer-min.js";
document.body.appendChild(scriptTag);
this.$once("hook:beforeDestroy", function() {
document.body.removeChild(document.querySelector("#aliplayerLink"));
document.body.removeChild(document.querySelector("#aliplayerScript"));
});
},
transferType(ext) {
if ("jpg,jpeg,png,gif,svg,psd".includes(ext)) return "图片";
if ("mp4,3gp,mov,m4v,avi,dat,mkv,flv,vob,rmvb,rm,qlv".includes(ext)) return "视频";
return ext;
},
preview(row, chapterName) {
this.curLink = `${chapterName}${row.name}`; // +
this.player = null;
this.playauth = "";
this.coverUrl = "";
this.pdfSrc = "";
this.iframeSrc = "";
this.isPPT = false;
this.isWord = false;
this.isExcel = false;
if (this.transferType(row.fileType) == "视频") {
this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => {
this.playAuth = res.data.playAuth;
this.$nextTick(() => {
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.coverUrl = row.fileUrl;
} else if (row.fileType == "pdf") {
this.pdfSrc = row.fileUrl;
this.pdfVisible = true;
} else {
this.$get(`${this.api.curriculumGetSubsection}/${row.id}`).then(res => {
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;
}
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.iframeSrc = res.previewUrl;
}).catch(err => {});
}
},
closePlayer() {
this.playAuth = "";
this.player.pause();
},
closeIframe() {
this.iframeSrc = "";
this.showMask = false;
this.showMask1 = false;
},
closePdf() {
this.pdfSrc = "";
this.currentPage = 1;
},
changePdfPage(val) {
if (val === 0 && this.currentPage > 1) {
this.currentPage--;
}
if (val === 1 && this.currentPage < this.pageCount) {
this.currentPage++;
}
},
loadPdfHandler(e) {
this.currentPage = 1;
},
goSystem() { //
let id = this.assessmentList[0].systemId;
let href = ''
let token = util.local.get(Setting.tokenKey);
let roleId = this.roleId == 4 ? 0 : 1;
let userName = window.btoa(encodeURIComponent(this.userName));
if (id == 11) {
href = `${Setting.bankPath}/#/index/list?token=${token}&cid=${this.courseId}&systemId=${this.assessmentList[0].systemId}&projectId=&assessmentId=&classId=&stopTime=&test=true`
} else if (id == 21) {
window.open(`http://121.37.29.24:80/yyyflogin?userId=${this.userId}&userName=${userName}&userType=${roleId}&reqType=1&reqId=3989a0ad671849b99dcbdcc208782333&caseId=9681f86902314b10bc752909121f9ab9&authorization=87DIVy348Oxzj3ha&classId=1876&courserId=7ff5d4715b114b7398b6f26c20fac460`);
} else if (id == 22) {
window.open(`https://danbao.czcyedu.com/#/loginFromYyyf?userId=${this.userId}&userName=${userName}&userType=${roleId}&reqType=1&reqId=eb7d8355119d449184c548b07dc01ed9&caseId=1198241070647873538&authorization=87DIVy348Oxzj3ha&classId=1876&courserId=faaedd82adb9444285a5785e4a3dd4f9`);
} else {
if(process.env.NODE_ENV === 'development') {
href = 'http://192.168.31.125:8080/#/'
} else {
href = `${location.origin}/pyTrials` // 8pythoncookiesystemId
}
}
if (id != 21 && id != 22) {
util.cookies.set("assessmentId", "", -1);
util.cookies.set("projectId", "", -1);
util.cookies.set("startTime", "", -1);
util.cookies.set("stopTime", "", -1);
util.cookies.set("token", token);
util.cookies.set("courseId", this.courseId);
util.cookies.set("systemId", id);
location.href = href;
}
}
}
};
</script>
<style lang="scss" scoped>
$height: 700px;
.video_wid,.cover{
position: relative;
width: 76%;
max-width: 1400px;
height: $height !important;
border: 0;
}
.cover{
img{
border-radius: 8px;
}
&.is-word{
overflow: hidden;
}
}
.fileIframe{
height: $height !important;
}
.video_wid,.inner{
width: 100%;
height: 100% !important;
border: 0;
overflow: auto;
}
.cover.is-word{
.inner{
height: calc(100% + 38px) !important;
margin-top: -38px;
}
}
.video_wid:focus{
outline: none;
}
.catalog{
margin-left: 40px;
}
.list{
height: calc(700px - 70px) ;
overflow-y: auto;
padding: 24px 16px;
background: #fff;
.title{
margin-bottom: 8px;
color: rgba(0, 0, 0, 0.85);
font-size: 20px;
}
.desc-wrap{
position: relative;
.desc{
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
line-height: 22px;
@include mul-ellipsis(2);
&.active{
display: block;
overflow: visible;
}
}
.arrow{
position: absolute;
bottom: 2px;
right: 0;
display: flex;
justify-content: space-between;
width: 46px;
background-color: #fff;
span{
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
}
img{
width: 16px;
cursor: pointer;
}
&.active{
span{
opacity: 0;
}
img{
transform: rotate(180deg);
}
}
}
}
.chapters{
margin-top: 16px;
max-height: calc(100% - 53px);
overflow: auto;
}
.chapter{
margin-bottom: 20px;
.chapterName{
color: rgba(0, 0, 0, 0.85);
font-size: 16px;
}
.section{
padding: 5px 15px;
margin-top: 8px;
background: rgba(0, 0, 0, 0.02);
.sectionName{
margin: 10px 0;
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
cursor: pointer;
@include ellipsis;
&.active{
color: #9278FF;
}
}
}
}
}
.el-image-viewer__wrapper{
transform: translateY(-10px);
transition: transform .5s;
&.active{
transform: translateY(0)
}
}
.el-image-viewer__close{
z-index: 2000;
top: 15px;
right: 15px;
&.doc-close{
i{
color: #000 !important;
}
}
}
.list::-webkit-scrollbar {
width: 4px;
}
.list::-webkit-scrollbar-thumb {
border-radius: 10px;
background: rgba(0, 0, 0, 0.06);
}
.mask{
z-index: 9;
position: absolute;
background-color: rgb(57,58,61);
}
.word-mask{
z-index: 9;
position: absolute;
top: 0;
right: 0;
width: 100%;
background-color: rgb(243,242,241);
}
.word-mask1{
z-index: 9;
position: absolute;
top: 0;
right: 0;
width: 100%;
background-color: #185abd;
}
.word-mask2{
z-index: 9;
position: absolute;
background-color: transparent;
}
.excel-mask1{
z-index: 9;
position: absolute;
top: 0;
left: 20%;
width: 60%;
background-color: #107c41;
}
/deep/.pdf-dia{
border-radius: 0 !important;
.el-dialog__header{
display: none;
}
.el-dialog__body{
padding: 0;
}
.el-dialog__headerbtn{
top: 10px;
.el-dialog__close{
color: #fff;
font-size: 16px;
}
}
}
.pdf{
.arrow{
padding: 10px 0;
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
color: #fff;
background-color: #333;
.turn{
margin: 0 10px;
font-size: 18px;
cursor: pointer;
}
}
.pdf-wrap{
width: 80%;
margin: 0 auto;
}
}
</style>

@ -57,7 +57,30 @@ function getPermission() {
// 该项目的路由实际上做了两层处理,一层指向了默认的路由,对应模块,用于基础布局的nav,下面一层才是实际上的路由跳转,
// 所以需要默认进行赋值,实际操作时根据path去禁用掉对应的nav即可。
const arr = ['achievement','assessment','course',"evaluation",'information','match','project','setting','student','system'];
let permissionRouters = []; // 最后处理好的路由数组
let permissionRouters = [
{
path: "/station",
name: "station",
redirect: {
name: `stationlist`
},
component: BasicLayout,
children: [
{
name: `stationlist`,
path: `/station/list`,
component: () => import("@/pages/station/list"),
meta: { title: "实验台" }
},
{
name: `stationPreview`,
path: `/station/preview`,
component: () => import("@/pages/station/preview"),
meta: { title: "实验台" }
}
]
}
]; // 最后处理好的路由数组
let data = res.permissionMenu[0].children;
if (data.length > 0) {
@ -227,7 +250,7 @@ function getPermission() {
}
}
});
// console.log(permissionRouters, "处理好的");
console.log(permissionRouters, "处理好的");
// 把处理完成的路由,add到router里
// 记录一下路由的名称,用于nav
let nav = data.map(e => e.path);

@ -9,6 +9,7 @@ const isBeta = url.includes("120.78.198.231"); //是否职站测试
const isPro = url.includes("occupationlab.com"); //是否职站生产
const isTest = url.includes('39.108.250.202'); //是否中台测试服
let bankPath = '' // 银行系统地址
let jumpPath = "";
let host = "";
let title = "";
@ -28,17 +29,19 @@ if (isHh) {
} else if (isPro) {
// 职站生产
host = "http://www.occupationlab.com:9000/";
bankPath = `http://www.huorantech.cn/banksystem`
title = "职站服务端管理系统";
} else if (isTest){
jumpPath = "http://39.108.250.202/judgmentPoint/";
host = "http://39.108.250.202:9000/";
bankPath = `${bankPath}/banksystem`
title = "职站服务端管理系统";
} else if (isDev) {
jumpPath = "http://192.168.31.154:8087/";
bankPath = `http://192.168.31.125:8093`
// host = "http://www.occupationlab.com:9000/";//线上
host = "http://39.108.250.202:9000/"; // 中台测试服
// host = "http://192.168.31.151:9000/"; // 榕
// host = "http://192.168.31.125:9000/"; // 坤
// host = 'http://192.168.31.137:9000/'; // 赓
title = "职站服务端管理系统";
} else {

Loading…
Cancel
Save