Files
learning-system-portal/src/components/Course/catalogCourseware.vue
2022-06-01 19:50:43 +08:00

729 lines
32 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div style="border: 1px solid #f4f4f4;">
<div v-if="content.csectionId==''">
<div style="text-align: center;font-weight: 700;padding-top: 50px;">请点击左边+添加章节按钮进行建课</div>
</div>
<div v-else style="padding: 10px;">
<!--选择内容-->
<div v-if="content.contentType==0">
<div style="text-align: center;font-weight: 700;">添加新组件</div>
<el-row :gutter="10">
<el-col :span="6" v-for="(com,comidx) in comTypes" :key="comidx" >
<div class="com-type" @click="chooseComType(com)">
<div> <i :class="com.img" style="font-size: 40px;"></i></div>
<div><span>{{com.name}}</span></div>
</div>
</el-col>
</el-row>
</div>
<!--显示内容-->
<div v-else style="margin: 0px 10px;">
<!--视频-->
<div v-show="content.contentType>0 && content.contentType<41">
<div style="display: flex;justify-content:space-between">
<div>
<el-input maxlength="50" @change="updateName" v-model="content.contentName" placeholder="内容的名称(限50字以内)"></el-input>
</div>
<div>
<el-button type="danger" @click="toReChoose()" size="small">重新选择</el-button>
</div>
</div>
<div v-if="content.contentRefId!='' && content.content!=''">
<div style="padding: 10px;" v-if="content.contentType==10">
<videoPlayer :src="fileBaseUrl+curriculumData.url" v-if="content.contentType==10 && content.contentRefId!='' && content.content!=''"></videoPlayer>
<div style="display: flex;justify-content:space-between;margin-top: 20px;">
<div>
<div>是否允许拖拽
<el-radio-group v-model="curriculumData.isDrag">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</div>
<div style="margin-top:10px">完成规则设置
<el-radio-group v-model="curriculumData.completeSetup">
<el-radio :label="0">默认(系统自动控制)</el-radio>
<el-radio :label="1">按进度
<el-input-number style="margin-top:10px;" v-model="curriculumData.setupTage" size="mini" :min="0" :max="100" label="描述文字" controls-position="right"></el-input-number>
%</el-radio>
<!-- <el-radio :label="2">时长
<el-input-number style="margin-top:10px" v-model="curriculumData.second" size="mini" :min="0" :max="100" label="描述文字" controls-position="right"></el-input-number>
</el-radio> -->
</el-radio-group>
<br/>
</div>
</div>
</div>
<div style="margin-top:35px;text-align: center"> <el-button type="primary" @click="saveData()" size="mini">保存</el-button> </div>
</div>
<div v-if="content.contentType==20">
<div style="text-align: center;padding-top: 20px;">
<audioPlayer :url="fileBaseUrl+curriculumData.url" v-if="content.contentType==20" :autoplay="false"></audioPlayer>
<div style="margin-top: 20px;">
<div>
<div style="text-align: left;">是否允许拖拽
<el-radio-group v-model="curriculumData.isDrag">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</div>
<div style="margin-top:10px;text-align: left;">完成规则设置
<el-radio-group v-model="curriculumData.completeSetup">
<el-radio :label="0">默认(系统自动控制)</el-radio>
<el-radio :label="1">按进度
<el-input-number style="margin-top:10px" v-model="curriculumData.setupTage" size="mini" :min="0" :max="100" label="描述文字" controls-position="right"></el-input-number>
%</el-radio>
<!-- <el-radio :label="2">时长
<el-input-number style="margin-top:10px" v-model="curriculumData.second" size="mini" :min="0" :max="100" label="描述文字" controls-position="right"></el-input-number>
</el-radio> -->
</el-radio-group>
</div>
</div>
<div style="margin-top:35px;text-align: center;"> <el-button type="primary" @click="saveData()" size="mini">保存</el-button> </div>
</div>
</div>
</div>
<div v-if="content.contentType==30">
<el-image :src="fileBaseUrl+content.content" fit="fill"></el-image>
</div>
<div v-if="content.contentType==40" style="text-align: center;">
<div style="padding: 10px;color: #767676; " v-if="converStatus < 2">
<div>文档文件转化中还未转化完成</div>
<div>上传时间{{curCFile.sysCreateTime}}</div>
</div>
<div style="padding: 10px;color: #767676;color: #ff0000;" v-if="converStatus == 3">
<div>文件转化失败请重新上传不要上传加密的文件请联系管理员</div>
</div>
<pdfPreview v-if="content.contentType==40 && curPdfPath!=''" :filePath="fileBaseUrl+curPdfPath"></pdfPreview>
</div>
</div>
</div>
<!--课件选择或上传的公用组件-->
<div v-show="content.contentRefId=='' && content.contentType>0 && content.contentType<41">
<choose-course-file ref="coursewarePanel" :resType="content.contentType" @choose="chooseFile"></choose-course-file>
</div>
<!--图文-->
<div v-show="content.contentType==41">
<div style="display: flex;justify-content:space-between">
<div>
<el-input maxlength="50" @change="updateName" v-model="content.contentName" placeholder="内容的名称(限50字以内)"></el-input>
</div>
<div>
<el-button type="primary" @click="saveData()" >保存</el-button>
<el-button type="danger" @click="toReChoose()" >重新选择</el-button>
</div>
</div>
<div style="padding-top: 10px;">
<WxEditor v-model="htmlContent" :minHeight="300"></WxEditor>
</div>
</div>
<!--外部连接-->
<div v-show="content.contentType==52">
<div style="display: flex;justify-content:space-between">
<div>
<el-input maxlength="50" @change="updateName" v-model="content.contentName" placeholder="内容的名称(限50字以内)"></el-input>
</div>
<div>
<el-button type="primary" @click="saveData()" >保存</el-button>
<el-button type="danger" @click="toReChoose()" >重新选择</el-button>
</div>
</div>
<div style="padding-top: 10px;">
<el-form label-width="90px">
<el-form-item label="URL地址">
<el-input v-model="linkInfo.url" placeholder="http://"></el-input>
</el-form-item>
<el-form-item label="打开方式">
<el-radio-group v-model="linkInfo.openType">
<el-radio :label="1">页面中嵌入</el-radio>
<el-radio :label="2">新窗口打开</el-radio>
</el-radio-group>
<div v-if="linkInfo.openType==1" style="color:#ff0000; ">有些页面是有防嵌入控制代码的 </div>
</el-form-item>
</el-form>
</div>
</div>
<!--考试-->
<div v-if="content.contentType==61">
<div style="display: flex;justify-content:space-between">
<div>
<el-input maxlength="50" @change="updateName" v-model="content.contentName" placeholder="内容的名称(限50字以内)"></el-input>
</div>
<div>
<el-checkbox style="margin-right: 10px;" v-model="onlyQuestion">只显示试题</el-checkbox>
<el-button type="primary" @click="saveData()" >保存</el-button>
<el-button type="danger" @click="toReChoose()" >重新选择</el-button>
</div>
</div>
<div style="padding-top: 10px;overflow: auto;">
<div v-if="!onlyQuestion">
<el-form size="small" label-width="80px">
<el-form-item label="考试时长">
<el-col :span="6">
<el-input v-model="exam.testDuration" placeholder="20-120">
<template slot="append">分钟</template>
</el-input>
</el-col>
<!-- <el-col :span="9">
<el-form-item label="尝试次数">
<el-input-number v-model="exam.times" :min="0" :max="10" label="0表不限制"></el-input-number>
</el-form-item>
</el-col> -->
<el-col :span="9">
<el-form-item label="及格线">
<el-input placeholder="20-120" v-model="exam.passLine">
<template slot="append">%</template>
</el-input>
</el-form-item>
</el-col>
</el-form-item>
<!-- <el-form-item label="显示">
<el-col :span="10"><el-checkbox v-model="exam.showAnalysis">允许查看解析</el-checkbox> </el-col>
<el-col :span="14"><el-checkbox v-model="exam.showAnswer">允许查看答案</el-checkbox></el-col>
</el-form-item> -->
<!-- <el-form-item label="模式"> -->
<!-- <el-col :span="10"><el-checkbox v-model="exam.randomMode">随机生成试题</el-checkbox></el-col> -->
<!-- <el-col :span="14"> -->
<!-- <el-form-item label="数量">
<el-input-number v-model="exam.qnum" :min="1" :max="10" label="数量"></el-input-number>
</el-form-item> -->
<!-- </el-col> -->
<!-- </el-form-item> -->
<!-- <el-form-item label="试题排列">
<el-col :span="10">
<el-select v-model="exam.arrange">
<el-option :value="0" label="按顺序"></el-option>
<el-option :value="1" label="只题目乱序"></el-option>
<el-option :value="2" label="只选项乱序"></el-option>
<el-option :value="3" label="题目选项全乱序"></el-option>
</el-select>
</el-col>
<el-col :span="14">
<el-form-item label="评分方式">
<el-radio-group v-model="exam.scoringType">
<el-radio :label="1">最高一次</el-radio>
<el-radio :label="2">最后一次</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-form-item> -->
<el-form-item label="评分方式">
<el-col :span="8">
<el-radio-group v-model="exam.scoringType">
<el-radio :label="1">最高一次</el-radio>
<el-radio :label="2">最后一次</el-radio>
</el-radio-group>
</el-col>
<el-col :span="15">
<el-form-item label="百分制">
<el-checkbox v-model="exam.percentScore">按百分制显示成绩实际成绩*100/实际总分</el-checkbox>
</el-form-item>
</el-col>
</el-form-item>
<el-form-item label="考试说明">
<el-input type="textarea" show-word-limit v-model="exam.info" placeholder="关于考试的说明(限255字以内)" maxlength="255"></el-input>
</el-form-item>
</el-form>
</div>
<div>
<simplePaper :data="examPaper" ></simplePaper>
</div>
</div>
</div>
<!--作业-->
<div v-if="content.contentType==60">
<div style="display: flex;justify-content:space-between">
<div>
<el-input maxlength="50" @change="updateName" v-model="content.contentName" placeholder="内容的名称(限50字以内)"></el-input>
</div>
<div>
<el-button type="primary" @click="saveData()" >保存</el-button>
<el-button type="danger" @click="toReChoose()" >重新选择</el-button>
</div>
</div>
<!--作业表单-->
<div style="padding-top: 10px;">
<el-form label-width="100px">
<el-form-item label="名称">
<el-input placeholder="作业的名称(限50字以内)" v-model="homework.name" maxlength="50" show-word-limit></el-input>
</el-form-item>
<el-form-item label="内容">
<el-input type="textarea" rows="5" maxlength="255" show-word-limit v-model="homework.content" placeholder="限255字以内"></el-input>
</el-form-item>
<el-form-item label="附件">
<div v-if="homework.file!=''">
<a :href="fileBaseUrl+homework.file" target="_blank">下载作业附件 </a> <i @click="removeHomeworkFile" style="color: red;" class="el-icon-close"></i>
</div>
<div v-else>
<file-upload dir="files" :isShowTip="false" @success="uploadHomeworkFile" @remove="removeHomeworkFile"></file-upload>
</div>
</el-form-item>
<el-form-item label="截止时间">
<el-date-picker v-model="homework.deadTime" value-format="yyyy-MM-dd HH:mm:ss" type="datetime" placeholder="选择日期时间"></el-date-picker>
</el-form-item>
<el-form-item label="提交模式">
<el-radio-group v-model="homework.submitMode">
<el-radio :label="1">附件文档</el-radio>
<el-radio :label="2">在线填写</el-radio>
<el-radio :label="3">前两种任选</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</div>
</div>
<!--评估-->
<div v-if="content.contentType==62">
<!--评估内容需要讨论-->
<div style="display: flex;justify-content:space-between">
<div>
<el-input maxlength="50" @change="updateName" v-model="content.contentName" placeholder="内容的名称(限50字以内)"></el-input>
</div>
<div>
<el-button v-if="content.id==''" type="primary" @click="saveData()" >保存</el-button>
<el-button v-else type="danger" @click="toReChoose()" >重新选择</el-button>
</div>
</div>
<div style="padding-top: 10px;">
<div>
<div class="assess-info">课程满意度计算方式{{assess.countType}}</div>
<div class="assess-info">满意度{{assess.countText}}</div>
<hr />
<div v-if="assess.items">
<div v-for="(ass,assIdx) in assess.items" :key="assIdx">
<div class="assess-info">{{assIdx+1}}.{{ass.question}}</div>
<div v-if="ass.qType==1" class="assess-info" style="height: 20px">
<span style="float: left">{{ass.minText}}</span>
<span style="float: right">{{ass.maxText}}</span>
</div>
<div v-if="ass.qType==1" class="assess-info">
<el-radio-group v-model="ass.answer" class="assessRadio1">
<el-radio-button :label="1">1</el-radio-button>
<el-radio-button :label="2">2</el-radio-button>
<el-radio-button :label="3">3</el-radio-button>
<el-radio-button :label="4">4</el-radio-button>
<el-radio-button :label="5">5</el-radio-button>
<el-radio-button :label="6">6</el-radio-button>
<el-radio-button :label="7">7</el-radio-button>
<el-radio-button :label="8">8</el-radio-button>
<el-radio-button :label="9">9</el-radio-button>
<el-radio-button :label="10">10</el-radio-button>
</el-radio-group>
</div>
<div v-if="ass.qType==9" class="assess-info">
<textarea :rows="4" v-model="ass.answer" style="width: 100%" placeholder=""></textarea>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import chooseCourseFile from '@/components/Course/chooseCourseFile.vue'
import courseHomework from '@/components/Course/courseHomework.vue'
import courseExam from '@/components/Course/courseExam.vue'
import simplePaper from "@/components/Course/simpleTestPaper.vue";
import WxEditor from "@/components/Editor/index.vue";
import fileUpload from '@/components/FileUpload/index.vue';
import apiCourse from '../../api/modules/course.js';
import apiCourseFile from '../../api/modules/courseFile.js';
import pdfPreview from "@/components/PdfPreview/index.vue";
import audioPlayer from '@/components/AudioPlayer/index.vue';
import videoPlayer from '@/components/VideoPlayer/index.vue';
export default{
props: {
reset:{
type:String,
default:''
},
content:{
type: Object,
default(){
return{
courseId:'',
csectionId:'',
contentName:'',
contenRefId:'',
content:'',
contentType:0,
}
}
},
course:{
type: Object,
}
},
components:{chooseCourseFile,WxEditor,courseHomework,courseExam,simplePaper,fileUpload,pdfPreview,audioPlayer,videoPlayer},
// inject: [ "informationDetails" ],
data(){
return {
converStatus:4,
fileBaseUrl:process.env.VUE_APP_FILE_BASE_URL,
curPdfPath:'',
curCFile:{},//当前课件的内容
comTypes:[
//文件类型,10视频20音频30图片 40 文档41表图文50表scrom包,90表其它
//图文41连接52作业60考试61评估62
{id:'1',type:'video',name:'视频',img:'el-icon-video-camera',resType:10},
{id:'2',type:'sound',name:'音频',img:'el-icon-service',resType:20},
{id:'3',type:'doc',name:'文档',img:'el-icon-document',resType:40},
{id:'4',type:'html',name:'图文',img:'el-icon-document-copy',resType:41},
{id:'5',type:'link',name:'外部连接',img:'el-icon-link',resType:52},
{id:'6',type:'exam',name:'考试',img:'el-icon-document-checked',resType:61},
{id:'7',type:'homework',name:'作业',img:'el-icon-reading',resType:60},
{id:'8',type:'assess',name:'评估',img:'el-icon-user',resType:62}
],
htmlContent:'',
linkInfo:{
url:'',
openType:1
},
curriculumData:{
url:'',
isDrag:true,
completeSetup:0,
second:5,
setupTage:0,
},
homework:{courseId: '', name:'', content:'', file:'', deadTime: '', submitMode: 3},
exam:{
courseId:'',
contentId:'',
testName:this.course.name,
testDuration:30,
showAnalysis:false,
showAnswer:false,
times:1,
qnum:0,//试题数量,只是模式是随机生成试题时才会有
arrange:0,
scoringType:1,
passLine:60,
randomMode:false,
percentScore:true,//默认是百分制
paperType:1,//自定义试卷
paperId:'',//试卷的id,只有paperType为2的时间才会有值
info:'',//考试说明
paperContent:'',//试题的json字符串
},
onlyQuestion:true,
examPaper:{items:[]},
assess:{
countType:'权重配置',
countText:'问题1*80%+问题2*10%+问题3*10%',
resultCount:'[q1]*0.8+[q2]*0.1+[q3]*0.1',
items:[
{id:'1',question: "您觉的课程对工作有帮助/启发呢?",minText:'完全没用',maxText:'非常有帮助/启发',qType:1},
{id:'2',question: "您愿意推荐其它同事来上这门课程吗?",minText:'不愿意',maxText:'非常愿意',qType:1},
{id:'3',question: "您愿意参加该教师开设的其它课程吗?",minText:'不愿意',maxText:'非常愿意',qType:1},
{id:'4',question: "学员之声(写下您想说的话)",minText:'',maxText:'',qType:9},
]
}
}
},
created() {
//console.log(this.ctype, this.course,'ctype');
},
watch:{
reset(newVal){
this.resetData();
},
content(newVal,oldVal){
this.resetData();
if(newVal.id!=''){
if(newVal.contentType==40){
//检查是否是pdf文件如果是还需要获取pdf路径
this.loadPdfFile();
}else if(newVal.contentType==41){
this.htmlContent=newVal.content;
}else if(newVal.contentType==52){
//外部连接
if(newVal.content!=''){
if(newVal.content.startsWith('\{')){
this.linkInfo=JSON.parse(newVal.content);
}else{
this.linkInfo.url=newVal.content;
}
}
//this.htmlContent=newVal.content;
}else if(newVal.contentType==60){
//作业
this.loadHomeworkInfo();
}else if(newVal.contentType==61){
//考试
this.loadExamInfo();
}else if(newVal.contentType==62){
//评估
this.loadAssessInfo();
} else if(newVal.contentType==10 || newVal.contentType==20) {
if(newVal.content!=''){
if(newVal.content.startsWith('\{')){
this.curriculumData =JSON.parse(newVal.content);
}else{
this.curriculumData.url=newVal.content;
}
}
}
}
}
},
methods:{
resetData(){
//清空数据
this.homework={courseId: '', name:'', content:'', file:'', deadTime: '', submitMode: 3};
this.linkInfo.url='';
this.htmlContent='';
this.curPdfPath='';
this.curCFile={};
this.exam.contentId='';
this.exam.paperContent='';
this.exam.info='';
this.exam.id='';//一定要重置id
this.exam.qnum='';
this.exam.paperId='';
this.exam.passLine=60;
this.examPaper={items:[]};
this.curriculumData={
url:'',
isDrag:true,
completeSetup:0,
second:5,
setupTage:0,
};
//this.assess
},
loadPdfFile(){
//检查当前是否是pdf如果是pdf那么就不需要再查询一次了
let fname=this.content.content;
if(fname && fname.indexOf('.pdf')>-1){
this.curPdfPath=this.content.content;
}else{
apiCourseFile.detail(this.content.contentRefId).then(rs=>{
if(rs.status==200){
this.curCFile=rs.result;
this.converStatus = rs.result.converStatus;
this.curPdfPath=rs.result.previewFilePath;
}
});
}
},
loadHomeworkInfo(){
apiCourse.getHomework(this.content.id).then(res=>{
if(res.status==200){
this.homework=res.result;
}else if(res.status==404){
//没有找到作业信息
}else{
this.$message.error(res.message);
}
})
},
loadExamInfo(){
apiCourse.getExam(this.content.id).then(res=>{
if(res.status==200){
this.exam=res.result;
this.examPaper=JSON.parse(res.result.paperContent);
}else if(res.status==404){
//没有找到作业信息
}else{
this.$message.error(res.message);
}
})
},
loadAssessInfo(){
if(this.content.content!='' && this.content.content.length>10){
this.assess=JSON.parse(this.content.content);
}
},
updateName(value){
console.log(value);
if(this.content.id==''){
return;
}
apiCourse.updateContentName({id:this.content.id,name:value}).then(rs=>{
if(rs.status!=200){
console.log('更新名称失败:'+rs.message);
}saveData
})
},
// 作业上传
uploadHomeworkFile(res) {
this.homework.file = res.result.filePath;
},
removeHomeworkFile(){
this.homework.file='';
},
saveData() {
//执行成功后调用外部方法
this.content.courseId=this.course.id;
this.content.sortIndex=1;//先设置为
if(this.content.contentType==41){
//对图文的处理
this.content.content=this.htmlContent;
}else if(this.content.contentType==52){
if(this.linkInfo.url==''){
this.$message.error("请填写URL地址");
return;
}else{
this.content.content=JSON.stringify(this.linkInfo);
}
} else if(this.content.contentType==10 || this.content.contentType==20) {
this.content.content=JSON.stringify(this.curriculumData);
}
let jsonData={
content:this.content,
homework:null,
exam:null
}
if(this.content.contentType==60){
jsonData.homework=this.homework;
}else if(this.content.contentType==61){
//检查内容的完整性
if(this.examPaper.items.length==0){
this.$message.error("您还没有添加考试的试题");
return;
}
let pass=true;
this.examPaper.items.forEach(qitem=>{
if(qitem.options.length==0){
pass=false;
}else{
let hasAnswer=qitem.options.some(opt=>{
return opt.answer;
});
if(!hasAnswer){
pass=false;
}
}
});
if(!pass){
this.$message.error("试卷试题请填写完整,每个试题必须要有答案");
return;
}
this.exam.paperContent=JSON.stringify(this.examPaper);
jsonData.exam=this.exam;
}else if(this.content.contentType==62){
this.content.content=JSON.stringify(this.assess);
}
apiCourse.saveContent(jsonData).then(rs=>{
if(rs.status === 200) {
this.$message.success('保存成功!');
// this.content=rs.result.content;
this.$emit('save',rs.result.content);
}else{
this.$message.error(rs.message)
}
})
},
delData(id){
//需要调用外部方法完成
if(this.content.id==''){
return;
}
let params={
id:this.content.id,
ctype:this.content.contentType,
erasable:this.course.erasable
}
apiCourse.delContent(params).then(rs=>{
if(rs.status === 200) {
this.$message.success('删除成功!');
this.$emit('remove');
}else{
this.$message.error(rs.message)
}
})
},
toReChoose(){
let $this=this;
if(this.content.id.length>1){
//需要先删除再选择
this.$confirm('您确定要删除当前内容重新选择吗?', '提示', {
confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'
}).then(() => {
//this.$message({ type: 'success', message: '删除成功!' });
//执行删除操作
$this.delData();
});
}else{
this.content.contentType=0;
this.content.content='';
}
},
chooseComType(ct){
this.content.contentType=ct.resType;
this.content.contentRefId='';
//if(this.content.contentName==''){
this.content.contentName=ct.name;
this.content.content='';
this.htmlContent='';
//}
if(ct.resType>0 && ct.resType<41){
//未初始化会调用失败所以这里要等vue变化后再调用
this.$nextTick(function(){
this.$refs.coursewarePanel.findCourseFile();
})
}
},
//选上已上传的文件
chooseFile(cfile){
this.content.contentRefId=cfile.id;
//如果是非pdf文档 这里需要使用cfile.id再去获取
// this.content.content.url=cfile.filePath;
if(this.content.contentType==10 || this.content.contentType==20){
this.curriculumData.url = cfile.filePath;
}else{
if(cfile.previewFilePath){
this.content.content=cfile.previewFilePath;
}else{
this.content.content=cfile.filePath;
}
}
this.content.courseId=this.course.id;
this.content.duration=cfile.duration;//时长
this.content.sortIndex=1;
this.saveData();
let $this=this;
if(this.content.contentType==40){
setTimeout(function(){
$this.loadPdfFile();
},2000);
}
}
}
}
</script>
<style lang="scss" scoped >
.el-input-number--mini{
width: 95px;
}
.com-type{
margin: 10px;
text-align: center;
cursor: pointer;
border: 1px solid #e7e7e7;
padding: 10px;
img{
width: 100px;
height: 100px;
}
.info{
padding-top: 10px;
}
}
.content-title{
padding: 10px 5px;
}
</style>