mirror of
https://codeup.aliyun.com/67762337eccfc218f6110e0e/vue/learning-system-portal.git
synced 2025-12-18 07:16:44 +08:00
2022年5月29日从svn移到git
This commit is contained in:
177
src/components/Course/assess.vue
Normal file
177
src/components/Course/assess.vue
Normal file
@@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="has" class="assess-div">
|
||||
<div>
|
||||
<div class="assess-info">课程满意度计算方式:{{info.countType}};</div>
|
||||
<div class="assess-info">满意度:{{info.countText}}</div>
|
||||
<hr />
|
||||
<div v-if="info.items">
|
||||
<div v-for="(ass,assIdx) in info.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">
|
||||
<el-input type="textarea" rows="4" show-word-limit maxlength="255" v-model="ass.answer" placeholder="请输入作业内容(限255个字)"></el-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-if="allowSubmit && showSubmit" style="text-align: center; margin-bottom: 15px" >
|
||||
<el-button type="primary" @click="submitAsscess">提交</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else style="text-align: center;padding-top: 20px;color: red;">此课程无评估</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import apiCourseStudy from '@/api/modules/courseStudy.js';
|
||||
export default{
|
||||
props:{
|
||||
studyId: {
|
||||
type: String,
|
||||
},
|
||||
showRecord:{
|
||||
type:Boolean,
|
||||
default:true
|
||||
},
|
||||
showSubmit:{
|
||||
type:Boolean,
|
||||
default:true
|
||||
},
|
||||
content:{
|
||||
type: Object,
|
||||
default:()=>{}
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
has:true,//是否有评估信息
|
||||
allowSubmit:true,//是否可以提交评估
|
||||
info:{},//评估信息
|
||||
studyItemId:'',//学习内容id
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.loadAssessInfo();
|
||||
},
|
||||
watch:{
|
||||
content(newVal){
|
||||
this.loadAssessInfo();
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
loadAssessInfo(){//评估保存失败
|
||||
if(this.content.content!='' && this.content.content.length>10){
|
||||
let json=JSON.parse(this.content.content);
|
||||
if(json){
|
||||
json.items.forEach(item=>{
|
||||
if(item.qType==1){
|
||||
item.answer=0;
|
||||
}else{
|
||||
item.answer='';
|
||||
}
|
||||
})
|
||||
}
|
||||
//console.log(json,"info")
|
||||
this.info=json;
|
||||
if(this.showRecord){
|
||||
this.loadHistory();
|
||||
}
|
||||
}
|
||||
},
|
||||
loadHistory(){
|
||||
if(this.studyId==''){
|
||||
return;
|
||||
}
|
||||
let params={
|
||||
studyId:this.studyId,
|
||||
contentId:this.content.id
|
||||
}
|
||||
apiCourseStudy.myAssessList(params).then(res=>{
|
||||
if(res.status==200){
|
||||
if(res.result.length>0){
|
||||
this.allowSubmit=false;
|
||||
this.info=JSON.parse(res.result[0].asContent);
|
||||
//回调处理
|
||||
this.$emit("success", this.info);
|
||||
}
|
||||
}else{
|
||||
this.$message.error(res.message);
|
||||
}
|
||||
})
|
||||
},
|
||||
submitAsscess() {
|
||||
let dataJson=JSON.stringify(this.info);
|
||||
//计算评估得分
|
||||
let countStr=this.info.resultCount;
|
||||
let countScore=0;
|
||||
let pass=true;
|
||||
this.info.items.forEach((item,idx)=>{
|
||||
if(item.qType==1){
|
||||
if(item.answer==0){
|
||||
pass=false;
|
||||
}
|
||||
var str='[q'+(idx+1)+']';
|
||||
countStr=countStr.replace(str,item.answer);
|
||||
}
|
||||
});
|
||||
if(!pass){
|
||||
this.$message.error("请填写完整再提交");
|
||||
return
|
||||
}
|
||||
//console.log(countStr);
|
||||
countScore=eval(countStr);
|
||||
//console.log(countScore,"countScore");
|
||||
let pamars = {
|
||||
studyItemId: this.studyItemId,//学习内容记录id,
|
||||
studyId: this.studyId,//学习id,
|
||||
courseId: this.content.courseId,//课程id,
|
||||
contentId: this.content.id,//内容id,
|
||||
asContent: dataJson,//内容
|
||||
asScore: countScore//评估得分
|
||||
}
|
||||
apiCourseStudy.saveAssess(pamars).then(res=>{
|
||||
if(res.status==200){
|
||||
this.allowSubmit=false;
|
||||
this.$message.success("提交成功,谢谢您的评估");
|
||||
this.content.status=9;
|
||||
//this.content.status=
|
||||
}else{
|
||||
this.$message.error(res.message);
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.assess-div {
|
||||
border: 1px solid #dadada;
|
||||
min-height: 500px;
|
||||
padding: 20px;
|
||||
text-align: left;
|
||||
font-size: 14px;
|
||||
.assess-info {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
673
src/components/Course/auditCourse1.vue
Normal file
673
src/components/Course/auditCourse1.vue
Normal file
@@ -0,0 +1,673 @@
|
||||
<template>
|
||||
<div class="examine-index">
|
||||
<!--微课审核-->
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane label="课程信息" name="info">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="24">
|
||||
<el-form label-width="120px" size="mini" v-if="isEdit">
|
||||
<el-form-item label="名称">{{courseInfo.name}}</el-form-item>
|
||||
<el-form-item label="封面图片">
|
||||
<el-col :span="8">
|
||||
<div style="width: 160px;height: 90px">
|
||||
<img style="width:100%;height:100%" v-if="courseCoverurl == ''" :src="webBaseUrl + '/images/bgimg/course.png'" alt="" srcset="">
|
||||
<img style="width:100%;height:100%" v-else :src="courseCoverurl" alt="" srcset="">
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<el-form-item label="内容分类">
|
||||
<span>{{sysTypeName(courseInfo.sysType1)}}</span>
|
||||
<span v-if="courseInfo.sysType2 !=''">/{{sysTypeName(courseInfo.sysType2)}}</span>
|
||||
<span v-if="courseInfo.sysType3 !=''">/{{sysTypeName(courseInfo.sysType3)}}</span>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="资源归属">
|
||||
<span>{{resOwnerName(courseInfo.resOwner1)}}</span>
|
||||
<span v-if="courseInfo.resOwner2 != ''">/{{resOwnerName(courseInfo.resOwner2)}}</span>
|
||||
<span v-if="courseInfo.resOwner3 != ''">/{{resOwnerName(courseInfo.resOwner3)}}</span>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="场景">
|
||||
{{ sceneFilter(courseInfo.forScene)}}
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="授课教师" ><!--授课老师默认是当前操作人-->
|
||||
{{teacher && teacher.join(',')}}</el-form-item>
|
||||
<!-- <el-form-item label="系统标签">{{courseInfo.tags}}</el-form-item> -->
|
||||
<el-form-item label="课程来源">{{courseInfo.source == 2?'外部':'内部'}}</el-form-item>
|
||||
<el-form-item label="目标人群">{{courseInfo.forUsers}}</el-form-item>
|
||||
<el-form-item label="观看设置">
|
||||
{{courseInfo.device == 3? '多端可见': courseInfo.device == 2?'移动端可见':'PC端可见'}}
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="关键字">
|
||||
{{courseInfo.keywords}}
|
||||
</el-form-item> -->
|
||||
<el-form-item label="课程价值">{{courseInfo.value}}</el-form-item>
|
||||
<el-form-item label="课程简介">
|
||||
{{courseInfo.summary}}
|
||||
</el-form-item>
|
||||
|
||||
<!-- <el-form-item label="完成规则" v-if="!weike.onlyRequired"><el-input maxlength="50" v-model="params.forScene" placeholder="可基于组织树或受众选择"></el-input></el-form-item> -->
|
||||
<!-- <el-form-item label="开放权限">{{courseInfo.openObject}}</el-form-item> -->
|
||||
<!-- <el-form-item label="课程描述">
|
||||
<div v-html="courseInfo.overview"></div>
|
||||
</el-form-item> -->
|
||||
<el-form-item v-if="isShow"><el-button type="primary" @click="isEdit = false">编辑</el-button> </el-form-item>
|
||||
</el-form>
|
||||
<!-- rules 以下是课程的基本信息编辑 ,可以做成一个单独的组件,传course对象,教师列表,通过回调方法的方式处理 -->
|
||||
<el-form label-width="120px" size="mini" v-else>
|
||||
<el-form-item label="名称" required><el-input maxlength="100" v-model="courseInfo.name" placeholder="课程名称(限100字以内)"></el-input></el-form-item>
|
||||
<el-form-item label="封面图片" required >
|
||||
<el-col :span="8">
|
||||
<imageUpload :value="courseCoverurl" width="160px" height="90px" @success="uploadCoverImgSuccess" @remove="removeCoverImgSuccess"></imageUpload>
|
||||
<div>上传为16:9(如:800*450)的png或jpg图片</div>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<el-form-item label="内容分类" required>
|
||||
<el-cascader placeholder="选择内容分类" style="width: 90%;" clearable v-model="sysType" :props="sysProps" :options="sysTypeListMap"></el-cascader>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="资源归属" required>
|
||||
<el-cascader placeholder="选择资源归属" style="width: 90%;" clearable v-model="resOwnerArray" :props="defaultProps" :options="resOwnerListMap"></el-cascader>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="场景">
|
||||
<el-select v-model="courseInfo.forScene" style="width: 90%;">
|
||||
<el-option v-for="item in sceneList" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="授课教师" required ><!--授课老师默认是当前操作人-->
|
||||
<el-select style="width: 90%;"
|
||||
v-model="teacherName"
|
||||
multiple
|
||||
filterable
|
||||
remote
|
||||
disabled
|
||||
value-key="teacherId"
|
||||
reserve-keyword
|
||||
placeholder="请输入授课教师姓名"
|
||||
:remote-method="remoteMethod"
|
||||
:loading="loading">
|
||||
<el-option v-for="item in teacherList" :key="item.teacherId" :label="item.teacherName" :value="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="目标人群" >
|
||||
<el-input maxlength="50" show-word-limit v-model="courseInfo.forUsers" placeholder="目标人群(限50字以内)"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="课程价值"><el-input maxlength="200" show-word-limit v-model="courseInfo.value" placeholder="课程价值(限200字以内)"></el-input></el-form-item>
|
||||
<!-- <el-form-item label="系统标签">
|
||||
<el-col :span="14">
|
||||
<el-select style="width: 100%;"
|
||||
v-model="showTags"
|
||||
multiple
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
placeholder="请输入关键词"
|
||||
:remote-method="remoteTagMethod"
|
||||
:loading="loading">
|
||||
<el-option v-for="item in tagList" :key="item.id" :label="item.name" :value="item.name"> </el-option>
|
||||
</el-select>
|
||||
</el-col> -->
|
||||
<!-- <el-col :span="10">
|
||||
<el-form-item label="关键字"><el-input v-model="courseInfo.keywords" maxlength="50" placeholder="请输入关键字(限100字以内)"></el-input></el-form-item>
|
||||
</el-col> -->
|
||||
<!-- </el-form-item> -->
|
||||
<el-form-item label="观看设置">
|
||||
<el-col :span="14">
|
||||
<el-radio v-model="courseInfo.device" :label="1">PC端可见</el-radio>
|
||||
<el-radio v-model="courseInfo.device" :label="2">移动端可见</el-radio>
|
||||
<el-radio v-model="courseInfo.device" :label="3">多端可见</el-radio>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-form-item label="课程来源">
|
||||
<el-radio-group v-model="courseInfo.source" >
|
||||
<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="完成规则" v-if="!weike.onlyRequired"><el-input maxlength="50" v-model="params.forScene" placeholder="可基于组织树或受众选择"></el-input></el-form-item> -->
|
||||
<!-- <el-form-item label="开放权限"><el-input maxlength="50" v-model="courseInfo.openObject" placeholder="可基于组织树或受众选择"></el-input></el-form-item> -->
|
||||
<el-form-item label="课程简介">
|
||||
<el-input type="textarea" maxlength="100" show-word-limit :rows="3" v-model="courseInfo.summary" placeholder="课程介绍,要换成富文本编辑器"></el-input>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="课程描述">
|
||||
<WxEditor v-model="courseInfo.overview" :minHeight="100"></WxEditor>
|
||||
</el-form-item> -->
|
||||
<el-form-item label=""><el-button type="primary" v-loading="btnLoading" @click="saveEdit">保存</el-button> </el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="课件" name="courseware">
|
||||
<div v-if="coursewareInfo.content.contentType == 10" style="position: relative;">
|
||||
<videoPlayer :src="fileBaseUrl+curriculumData.url"
|
||||
@onPlayerPlaying="onPlayerPlaying"
|
||||
@onPlayerPlay="onPlayerPlay"
|
||||
@onPlayerPause="onPlayerPause"
|
||||
@onPlayerEnded="onPlayerEnded"></videoPlayer>
|
||||
<!-- <video :src="fileBaseUrl+coursewareInfo.content.content" width="100%" controls controlslist="nodownload" style="width: 100%; height: 100%; object-fit: fill"></video> -->
|
||||
</div>
|
||||
<div v-if="coursewareInfo.content.contentType == 20">
|
||||
<audioPlayer :url="fileBaseUrl+curriculumData.url"
|
||||
:name="coursewareInfo.content.contentName"
|
||||
@onPlaying="audioPlaying"
|
||||
@onPlay="audioPlay"
|
||||
@onPause="audioPause"
|
||||
@onPlayEnd="audioEnd"
|
||||
></audioPlayer>
|
||||
<!-- <audio width="100%" controls :src="fileBaseUrl+coursewareInfo.content.content">
|
||||
您的浏览器不支持 audio 标签。
|
||||
</audio> -->
|
||||
</div>
|
||||
<div v-if="coursewareInfo.content.contentType == 40">
|
||||
<pdfPreview :filePath="fileBaseUrl+contentData.content"></pdfPreview>
|
||||
</div>
|
||||
<div v-if="coursewareInfo.content.contentType == 41">
|
||||
<div class="picture-text" v-html="coursewareInfo.content.content"></div>
|
||||
</div>
|
||||
<div v-if="coursewareInfo.content.contentType == 52">
|
||||
<div v-if="coursewareInfo.content.content!=''">
|
||||
<!-- <hyper-link :content="coursewareInfo.content"></hyper-link> -->
|
||||
<!-- <iframe :src="coursewareInfo.content.content" style="width: 100%;border:0px;min-height: 473px;" frameborder="0"></iframe> -->
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="homeworkInfo.id" label="作业" name="homework">
|
||||
<homework :showRecord="isDetails" v-if="homeworkInfo.id" :showSubmit="false" :content="homeworkInfo" ></homework>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="examInfo.id" label="考试" name="test">
|
||||
<exam :showRecord="isDetails" :showTest="showTest" v-if="examInfo.id" :showSubmit="false" :content="examInfo"></exam>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="assessInfo.id" label="评估" name="assess">
|
||||
<assess :showSubmit="false" v-if="assessInfo.id" :showRecord="false" :content="assessInfo"></assess>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="修改记录" name="record" v-if="isShow">
|
||||
<div class="grid-info">
|
||||
<el-table border style="margin-bottom: 20px" height="350" :data="dataList">
|
||||
<el-table-column type="expand">
|
||||
<template slot-scope="props">
|
||||
<el-table border style="margin-bottom: 10px" :data="props.row.logData">
|
||||
<el-table-column label="内容" prop="title"></el-table-column>
|
||||
<el-table-column label="修改前" prop="before" show-overflow-tooltip>
|
||||
<template slot-scope="props">
|
||||
{{props.row.before == 'null' || props.row.before == ''? '--':props.row.before}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="修改后" prop="after" show-overflow-tooltip></el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="修改人" prop="sysCreateBy"></el-table-column>
|
||||
<el-table-column label="修改时间" prop="sysCreateTime"></el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import apiCoursePortal from "@/api/modules/coursePortal.js";
|
||||
import {
|
||||
formatDate,
|
||||
courseType,
|
||||
getType,
|
||||
numberToLetter
|
||||
} from "@/utils/tools.js";
|
||||
import imageUpload from "@/components/ImageUpload/index.vue";
|
||||
import pdfPreview from "@/components/PdfPreview/index.vue";
|
||||
import weikeContent from "@/components/Course/weikeContent.vue";
|
||||
import catalogCourseware from "@/components/Course/catalogCourseware.vue";
|
||||
import apiCourse from "@/api/modules/course.js";
|
||||
import scene from "../../api/modules/scene.js";
|
||||
import exam from "@/components/Course/exam";
|
||||
import homework from "@/components/Course/homework";
|
||||
import assess from "@/components/Course/assess";
|
||||
import WxEditor from "@/components/Editor/index.vue";
|
||||
import apiTag from "../../api/modules/tag.js";
|
||||
import videoPlayer from "@/components/VideoPlayer/index.vue";
|
||||
import audioPlayer from "@/components/AudioPlayer/index.vue";
|
||||
import { mapGetters, mapActions } from "vuex";
|
||||
// import hyperLink from '@/components/Course/hyperLink.vue';
|
||||
export default {
|
||||
name: "auditCourse1",
|
||||
components: {
|
||||
weikeContent,
|
||||
catalogCourseware,
|
||||
imageUpload,
|
||||
exam,
|
||||
homework,
|
||||
assess,
|
||||
WxEditor,
|
||||
pdfPreview,
|
||||
videoPlayer,
|
||||
audioPlayer
|
||||
// hyperLink
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["resOwnerMap", "sysTypeMap"])
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
isDetails: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
isShow: {
|
||||
// 控制修改记录,编辑按钮是否出现
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showTest: {
|
||||
//预览显示试题
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
courseType: courseType,
|
||||
isEdit: true,
|
||||
homeworkInfo: {},
|
||||
examInfo: {},
|
||||
assessInfo: {},
|
||||
fileBaseUrl: process.env.VUE_APP_FILE_BASE_URL,
|
||||
btnLoading: false,
|
||||
coursewareInfo: {
|
||||
content: {},
|
||||
finish: false,
|
||||
studyItemId: ""
|
||||
},
|
||||
curriculumData: {
|
||||
url: "",
|
||||
isDrag: false,
|
||||
completeSetup: 1
|
||||
},
|
||||
sceneList: [],
|
||||
sysType: [],
|
||||
tagList: [], // 标签
|
||||
showTags: [], //用于显示标签
|
||||
teacherList: [],
|
||||
teacherName: [],
|
||||
teacher: [],
|
||||
loading: false,
|
||||
resOwnerArray: [],
|
||||
defaultProps: {
|
||||
value: "code",
|
||||
label: "name"
|
||||
},
|
||||
sysProps: {
|
||||
value: "id",
|
||||
label: "name"
|
||||
},
|
||||
courseCoverurl: "",
|
||||
courseInfo: {}, //基本信息
|
||||
dataList: [],
|
||||
activeName: "info",
|
||||
resOwnerListMap: [],
|
||||
resOwnerListMap: [],
|
||||
rules: {
|
||||
name: [{ required: true, message: "请输入课程名称", trigger: "blur" }],
|
||||
kind: [
|
||||
{ required: true, message: "请选择课程分类", trigger: "change" }
|
||||
],
|
||||
location: [
|
||||
{ required: true, message: "请选择资源归属", trigger: "change" }
|
||||
],
|
||||
aim: [{ required: true, message: "请输入目标人群", trigger: "blur" }],
|
||||
courseValue: [
|
||||
{ required: true, message: "请输入课程价值", trigger: "blur" }
|
||||
],
|
||||
tag: [{ required: true, message: "请输入标签", trigger: "blur" }],
|
||||
power: [{ required: true, message: "请输入开放权限", trigger: "blur" }]
|
||||
}
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.getDetail();
|
||||
this.getSceneData();
|
||||
this.updateLogs();
|
||||
this.getResOwnerTree().then(rs => {
|
||||
this.resOwnerListMap = rs;
|
||||
});
|
||||
this.getSysTypeTree().then(rs => {
|
||||
this.sysTypeListMap = rs;
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
getResOwnerTree: "resOwner/getResOwnerTree",
|
||||
loadResOwners: "resOwner/loadResOwners",
|
||||
getSysTypeTree: "sysType/getSysTypeTree",
|
||||
loadSysTypes: "sysType/loadSysTypes"
|
||||
}),
|
||||
resOwnerName(code) {
|
||||
if (code == "") {
|
||||
return "";
|
||||
}
|
||||
return this.resOwnerMap.get(code);
|
||||
},
|
||||
sysTypeName(code) {
|
||||
if (code == "") {
|
||||
return "";
|
||||
}
|
||||
return this.sysTypeMap.get(code);
|
||||
},
|
||||
onPlayerPlay() {
|
||||
console.log("开始播放");
|
||||
},
|
||||
onPlayerPause() {
|
||||
console.log("暂停");
|
||||
},
|
||||
onPlayerEnded() {
|
||||
console.log("播放结束");
|
||||
},
|
||||
onPlayerPlaying(itme) {
|
||||
console.log("当前播放" + itme);
|
||||
},
|
||||
audioPlaying(item) {
|
||||
console.log("当前播放" + item);
|
||||
},
|
||||
audioPlay() {
|
||||
console.log("开始播放");
|
||||
},
|
||||
audioPause() {
|
||||
console.log("暂停");
|
||||
},
|
||||
audioEnd() {
|
||||
console.log("播放结束");
|
||||
},
|
||||
// 场景过滤
|
||||
sceneFilter(forScene) {
|
||||
// sceneList
|
||||
// this.courseInfo.forScene
|
||||
let name = "";
|
||||
this.sceneList.forEach(item => {
|
||||
if (item.id === forScene) {
|
||||
name = item.name;
|
||||
}
|
||||
});
|
||||
return name;
|
||||
},
|
||||
//修改记录
|
||||
updateLogs() {
|
||||
let params = {
|
||||
courseId: this.id,
|
||||
name: ""
|
||||
};
|
||||
apiCourse.findUpdateLogs(params).then(res => {
|
||||
if (res.status === 200) {
|
||||
res.result.forEach(item => {
|
||||
item.logData = JSON.parse(item.logData);
|
||||
});
|
||||
this.dataList = res.result;
|
||||
} else {
|
||||
this.$message.error(res.message);
|
||||
}
|
||||
});
|
||||
},
|
||||
saveEdit() {
|
||||
this.btnLoading = true;
|
||||
this.courseInfo.tags = this.showTags.join();
|
||||
//处理资源归属
|
||||
// if (this.resOwnerArray.length > 0) {
|
||||
// this.courseInfo.resOwner1 = this.resOwnerArray[0]; //资源归属一级的id
|
||||
// this.courseInfo.resOwner2 = this.resOwnerArray[1]; //资源归属二级的id
|
||||
// } else {
|
||||
// this.$message.error("请选择资源归属");
|
||||
// this.btnLoading = false;
|
||||
// return;
|
||||
// }
|
||||
if (this.resOwnerArray.length > 2) {
|
||||
this.courseInfo.resOwner3 = this.resOwnerArray[2]; //资源归属三级的id
|
||||
}
|
||||
// 分类
|
||||
if (this.sysType.length > 0) {
|
||||
this.courseInfo.sysType1 = this.sysType[0]; //资源归属一级的id
|
||||
this.courseInfo.sysType2 = this.sysType[1]; //资源归属二级的id
|
||||
} else {
|
||||
this.$message.error("请选择内容分类");
|
||||
this.btnLoading = false;
|
||||
return;
|
||||
}
|
||||
if (this.sysType.length > 2) {
|
||||
this.courseInfo.sysType3 = this.sysType[2]; //资源归属三级的id
|
||||
}
|
||||
// let postData = {
|
||||
// course: this.courseInfo,
|
||||
// // teachers: this.teacherName
|
||||
// };
|
||||
apiCourse
|
||||
.saveOnlyCourse(this.courseInfo)
|
||||
.then(res => {
|
||||
if (res.status === 200) {
|
||||
this.$message.success("操作成功!");
|
||||
// let result = res.result;
|
||||
this.isEdit = true;
|
||||
this.courseInfo = result.course;
|
||||
// this.curCourseId = result.course.id; //设置当前课程的id
|
||||
// this.courseTeachers = result.teachers;
|
||||
// let list = [];
|
||||
// this.courseTeachers.forEach(item => {
|
||||
// list.push(item.teacherName);
|
||||
// });
|
||||
this.btnLoading = false;
|
||||
} else {
|
||||
this.$message.error(res.message);
|
||||
this.btnLoading = false;
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
this.btnLoading = false;
|
||||
});
|
||||
},
|
||||
// 标签远程查询
|
||||
async remoteTagMethod(query) {
|
||||
if (query) {
|
||||
try {
|
||||
const { result, status } = await apiTag.findByName(1, query);
|
||||
if (status === 200) {
|
||||
this.tagList = result;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
} else {
|
||||
this.tagList = [];
|
||||
}
|
||||
},
|
||||
//获取场景,保留
|
||||
async getSceneData() {
|
||||
try {
|
||||
const { result, status } = await scene.list(1);
|
||||
if (status === 200) {
|
||||
this.sceneList = result;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
// 教师列标,远程查询
|
||||
async remoteMethod(query) {
|
||||
if (query) {
|
||||
this.loading = true;
|
||||
try {
|
||||
const { result, status } = await apiTeacher.findByName(query);
|
||||
if (status === 200) {
|
||||
let list = [];
|
||||
result.forEach(item => {
|
||||
list.push({
|
||||
teacherId: item.id,
|
||||
teacherName: item.name
|
||||
});
|
||||
});
|
||||
this.teacherList = list;
|
||||
this.loading = false;
|
||||
}
|
||||
} catch (error) {
|
||||
this.loading = false;
|
||||
}
|
||||
} else {
|
||||
this.teacherList = [];
|
||||
}
|
||||
},
|
||||
//上传课程图片处理
|
||||
uploadCoverImgSuccess(res) {
|
||||
this.courseInfo.coverImg = res.result.filePath;
|
||||
this.courseCoverurl = res.result.httpPath;
|
||||
},
|
||||
removeCoverImgSuccess() {
|
||||
this.courseCoverurl = "";
|
||||
this.courseInfo.coverImg = "";
|
||||
},
|
||||
getDetail() {
|
||||
let $this = this;
|
||||
apiCoursePortal.detail(this.id).then(rs => {
|
||||
if (rs.status == 200) {
|
||||
this.courseInfo = rs.result.course;
|
||||
this.teacherList = rs.result.teachers;
|
||||
this.teacherName = rs.result.teachers;
|
||||
this.teacher = rs.result.teachers.map(res => res.teacherName);
|
||||
this.totalContent = rs.result.contents.length; //计算总内容数
|
||||
if (this.courseInfo.tags != "") {
|
||||
this.showTags = this.courseInfo.tags.split(",");
|
||||
}
|
||||
if (rs.result.course.coverImg !== "") {
|
||||
this.courseCoverurl = this.fileBaseUrl + rs.result.course.coverImg;
|
||||
}
|
||||
if (rs.result.course.resOwner3 == "") {
|
||||
this.resOwnerArray = [
|
||||
rs.result.course.resOwner1,
|
||||
rs.result.course.resOwner2
|
||||
];
|
||||
} else {
|
||||
this.resOwnerArray = [
|
||||
rs.result.course.resOwner1,
|
||||
rs.result.course.resOwner2,
|
||||
rs.result.course.resOwner3
|
||||
];
|
||||
}
|
||||
if (
|
||||
rs.result.course.sysType3 == "" &&
|
||||
rs.result.course.sysType2 == ""
|
||||
) {
|
||||
this.sysType = [rs.result.course.sysType1];
|
||||
} else if (rs.result.course.sysType3 == "") {
|
||||
this.sysType = [
|
||||
rs.result.course.sysType1,
|
||||
rs.result.course.sysType2
|
||||
];
|
||||
} else {
|
||||
this.sysType = [
|
||||
rs.result.course.sysType1,
|
||||
rs.result.course.sysType2,
|
||||
rs.result.course.sysType3
|
||||
];
|
||||
}
|
||||
rs.result.contents.forEach(con => {
|
||||
if (con.sortIndex == 1) {
|
||||
$this.coursewareInfo.content = con;
|
||||
if (
|
||||
$this.coursewareInfo.content.contentType == 10 ||
|
||||
$this.coursewareInfo.content.contentType == 20
|
||||
) {
|
||||
if (con.content.startsWith("{")) {
|
||||
this.curriculumData = JSON.parse(con.content);
|
||||
} else {
|
||||
this.curriculumData.url = con.content;
|
||||
}
|
||||
}
|
||||
if ($this.coursewareInfo.content.contentType == 40) {
|
||||
let url = this.fileBaseUrl + r.content;
|
||||
}
|
||||
} else if (con.sortIndex == 2) {
|
||||
$this.homeworkInfo = con;
|
||||
//查询作业信息,并显示
|
||||
} else if (con.sortIndex == 3) {
|
||||
$this.examInfo = con;
|
||||
} else if (con.sortIndex == 4) {
|
||||
$this.assessInfo = con;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$message.error(rs.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .picture-text{
|
||||
img{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.examine-index {
|
||||
.grid-info {
|
||||
display: flex;
|
||||
padding: 0 20px;
|
||||
.grid-item {
|
||||
flex: 1;
|
||||
.item-one {
|
||||
font-size: 16px;
|
||||
height: 20px;
|
||||
}
|
||||
.item-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
.demo-table-expand {
|
||||
font-size: 0;
|
||||
}
|
||||
.demo-table-expand label {
|
||||
width: 90px;
|
||||
color: #99a9bf;
|
||||
}
|
||||
.demo-table-expand .el-form-item {
|
||||
margin-right: 0;
|
||||
margin-bottom: 0;
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
.homework-div {
|
||||
border: 1px solid;
|
||||
min-height: 500px;
|
||||
padding: 20px;
|
||||
font-size: 14px;
|
||||
.homework-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.homework-content {
|
||||
color: #666;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
.test-div {
|
||||
border: 1px solid;
|
||||
min-height: 500px;
|
||||
padding: 20px;
|
||||
font-size: 14px;
|
||||
.test-info {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
.assess-div {
|
||||
border: 1px solid;
|
||||
min-height: 500px;
|
||||
padding: 20px;
|
||||
font-size: 14px;
|
||||
.assess-info {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
764
src/components/Course/auditCourse2.vue
Normal file
764
src/components/Course/auditCourse2.vue
Normal file
@@ -0,0 +1,764 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--在线课录播课审核-->
|
||||
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="18" v-show="type === 0">
|
||||
<div class="player" style="min-height: 473px;border: 1px solid #d0d0d0;background-color: #FFFFFF;padding-top: 10px;">
|
||||
<!--课程基本信息-->
|
||||
<div>
|
||||
<!-- v-if="contentData.contentType == 0" -->
|
||||
<div v-if="!contentData.contentType" style="position: relative;">
|
||||
<el-form label-width="120px" size="mini" v-if="isEdit">
|
||||
<el-form-item label="名称">{{courseInfo.name}}</el-form-item>
|
||||
<el-form-item label="封面图片">
|
||||
<el-col :span="8">
|
||||
<!-- <imageUpload :value="courseCoverurl" @success="uploadCoverImgSuccess" @remove="removeCoverImgSuccess"></imageUpload> -->
|
||||
<div style="width: 160px;height: 90px">
|
||||
<img style="width:100%;height:100%" v-if="courseCoverurl == ''" :src="webBaseUrl + '/images/bgimg/course.png'" alt="" srcset="">
|
||||
<img style="width:100%;height:100%" v-else :src="courseCoverurl" alt="" srcset="">
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<el-form-item label="内容分类">
|
||||
<span>{{sysTypeName(courseInfo.sysType1)}}</span>
|
||||
<span v-if="courseInfo.sysType2 !=''">/{{sysTypeName(courseInfo.sysType2)}}</span>
|
||||
<span v-if="courseInfo.sysType3 !=''">/{{sysTypeName(courseInfo.sysType3)}}</span>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="资源归属">
|
||||
<span>{{resOwnerName(courseInfo.resOwner1)}}</span>
|
||||
<span v-if="courseInfo.resOwner2 != ''">/{{resOwnerName(courseInfo.resOwner2)}}</span>
|
||||
<span v-if="courseInfo.resOwner3 != ''">/{{resOwnerName(courseInfo.resOwner3)}}</span>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="场景">
|
||||
{{sceneFilter(courseInfo.forScene)}}
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="授课教师" ><!--授课老师默认是当前操作人-->
|
||||
{{teacher && teacher.join(',')}}
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="系统标签">
|
||||
{{courseInfo.tags}}
|
||||
</el-form-item> -->
|
||||
<el-form-item label="目标人群" >
|
||||
{{courseInfo.forUsers}}
|
||||
</el-form-item>
|
||||
<el-form-item label="课程来源">
|
||||
{{courseInfo.source == 2?'外部':'内部'}}
|
||||
</el-form-item>
|
||||
<el-form-item label="观看设置">
|
||||
{{courseInfo.device == 3? '多端可见': courseInfo.device == 2?'移动端可见':'PC端可见'}}
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="关键字">
|
||||
{{courseInfo.keywords}}
|
||||
</el-form-item> -->
|
||||
<el-form-item label="课程价值" style="word-break:break-all;">
|
||||
|
||||
{{courseInfo.value}}
|
||||
</el-form-item>
|
||||
<el-form-item label="课程简介" style="word-break:break-all;">
|
||||
{{courseInfo.summary}}
|
||||
</el-form-item>
|
||||
|
||||
<!-- <el-form-item label="完成规则" v-if="!weike.onlyRequired"><el-input maxlength="50" v-model="params.forScene" placeholder="可基于组织树或受众选择"></el-input></el-form-item> -->
|
||||
<!-- <el-form-item label="开放权限">{{courseInfo.openObject}}</el-form-item> -->
|
||||
<!-- <el-form-item label="课程描述">
|
||||
<div v-html="courseInfo.overview"></div>
|
||||
</el-form-item> -->
|
||||
<el-form-item v-if="isShow"><el-button type="primary" @click="isEdit = false">编辑</el-button> </el-form-item>
|
||||
</el-form>
|
||||
<el-form label-width="80px" size="mini" v-else>
|
||||
<el-form-item label="名称" required><el-input maxlength="100" v-model="courseInfo.name" placeholder="课程名称(限100字以内)"></el-input></el-form-item>
|
||||
<!--不显示,因为标题已经代表了 <el-form-item label="授课方式">{{courseTypeMap(params.type)}}</el-form-item>-->
|
||||
<el-form-item label="封面图片" required >
|
||||
<el-col :span="8">
|
||||
<imageUpload :value="courseCoverurl" width="160px" height="90px" @success="uploadCoverImgSuccess" @remove="removeCoverImgSuccess"></imageUpload>
|
||||
<div>上传为16:9(如:800*450)的png或jpg图片</div>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<el-form-item label="内容分类" required>
|
||||
<el-cascader placeholder="选择内容分类" style="width: 90%;" clearable v-model="sysType" :props="sysProps" :options="sysTypeListMap"></el-cascader>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="资源归属" required>
|
||||
<el-cascader placeholder="选择资源归属" style="width: 90%;" clearable v-model="resOwnerArray" :props="defaultProps" :options="resOwnerListMap"></el-cascader>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="场景">
|
||||
<el-select v-model="courseInfo.forScene" style="width: 90%;">
|
||||
<el-option v-for="item in sceneList" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="授课教师" required ><!--授课老师默认是当前操作人-->
|
||||
<el-select style="width: 90%;"
|
||||
v-model="teacherName"
|
||||
multiple
|
||||
filterable
|
||||
remote
|
||||
disabled
|
||||
value-key="teacherId"
|
||||
reserve-keyword
|
||||
placeholder="请输入授课教师姓名"
|
||||
:remote-method="remoteMethod"
|
||||
:loading="loading">
|
||||
<el-option v-for="item in teacherList" :key="item.teacherId" :label="item.teacherName" :value="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="目标人群" >
|
||||
<el-input maxlength="50" show-word-limit v-model="courseInfo.forUsers" placeholder="目标人群(限50字以内)"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="课程价值" >
|
||||
<el-input maxlength="200" show-word-limit v-model="courseInfo.value" placeholder="课程价值(限200字以内)"></el-input></el-form-item>
|
||||
<!-- <el-form-item label="系统标签" >
|
||||
<el-col :span="14">
|
||||
<el-select style="width: 100%;"
|
||||
v-model="showTags"
|
||||
multiple
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
placeholder="请输入关键词"
|
||||
:remote-method="remoteTagMethod"
|
||||
:loading="loading">
|
||||
<el-option v-for="item in tagList" :key="item.id" :label="item.name" :value="item.name"> </el-option>
|
||||
</el-select>
|
||||
</el-col> -->
|
||||
<!-- <el-col :span="10">
|
||||
<el-form-item label="关键字"><el-input v-model="courseInfo.keywords" maxlength="50" placeholder="请输入关键字(限100字以内)"></el-input></el-form-item>
|
||||
</el-col> -->
|
||||
<!-- </el-form-item> -->
|
||||
<el-form-item label="观看设置">
|
||||
<el-col :span="14">
|
||||
<el-radio v-model="courseInfo.device" :label="1">PC端可见</el-radio>
|
||||
<el-radio v-model="courseInfo.device" :label="2">移动端可见</el-radio>
|
||||
<el-radio v-model="courseInfo.device" :label="3">多端可见</el-radio>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-form-item label="课程来源">
|
||||
<el-radio-group v-model="courseInfo.source" >
|
||||
<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-input maxlength="50" v-model="params.forScene" placeholder="可基于组织树或受众选择"></el-input></el-form-item> -->
|
||||
<el-form-item label="开放权限" ><el-input maxlength="50" show-word-limit v-model="courseInfo.openObject" placeholder="可基于组织树或受众选择"></el-input></el-form-item>
|
||||
<el-form-item label="课程简介">
|
||||
<el-input type="textarea" maxlength="100" show-word-limit :rows="3" v-model="courseInfo.summary" placeholder="课程介绍,要换成富文本编辑器"></el-input>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="课程描述">
|
||||
<WxEditor v-model="courseInfo.overview" :minHeight="100"></WxEditor>
|
||||
</el-form-item> -->
|
||||
<el-form-item label=""><el-button type="primary" v-loading="btnLoading" @click="saveEdit">保存</el-button> </el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div v-if="contentData.contentType == 10" style="position: relative;">
|
||||
<videoPlayer :src="fileBaseUrl+curriculumData.url"
|
||||
@onPlayerPlaying="onPlayerPlaying"
|
||||
@onPlayerPlay="onPlayerPlay"
|
||||
@onPlayerPause="onPlayerPause"
|
||||
@onPlayerEnded="onPlayerEnded"></videoPlayer>
|
||||
<!-- <video :src="fileBaseUrl+contentData.content" width="100%" controls controlslist="nodownload" style="width: 100%; height: 100%; object-fit: fill"></video> -->
|
||||
</div>
|
||||
<div v-if="contentData.contentType == 20">
|
||||
<audioPlayer :url="fileBaseUrl+curriculumData.url"
|
||||
:name="contentData.contentName"
|
||||
@onPlaying="audioPlaying"
|
||||
@onPlay="audioPlay"
|
||||
@onPause="audioPause"
|
||||
@onPlayEnd="audioEnd"
|
||||
></audioPlayer>
|
||||
<!-- <audio width="100%" controls :src="fileBaseUrl+contentData.content">
|
||||
您的浏览器不支持 audio 标签。
|
||||
</audio> -->
|
||||
</div>
|
||||
<div v-if="contentData.contentType == 40">
|
||||
<pdfPreview :filePath="fileBaseUrl+contentData.content"></pdfPreview>
|
||||
</div>
|
||||
<div v-if="contentData.contentType == 41">
|
||||
<div class="picture-text" v-html="contentData.content"></div>
|
||||
</div>
|
||||
<div v-if="contentData.contentType == 52">
|
||||
<div v-if="contentData.content!=''">
|
||||
<hyper-link :content="contentData"></hyper-link>
|
||||
<!-- <iframe :src="contentData.content" style="width: 100%;border:0px;min-height: 473px;" frameborder="0"></iframe> -->
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="contentData.contentType == 60">
|
||||
<homework :showTest="showTest" :showRecord="isDetails" :showSubmit="false" :content="contentData" ></homework>
|
||||
</div>
|
||||
<div v-if="contentData.contentType == 61">
|
||||
<exam :showTest="showTest" :showRecord="isDetails" :showSubmit="false" :content="contentData"></exam>
|
||||
</div>
|
||||
<div v-if="contentData.contentType == 62" style="padding:5px">
|
||||
<assess v-if="contentData.id" :showSubmit="false" :showRecord="false" :content="contentData"></assess>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="18" v-show="type === 1">
|
||||
<div class="grid-info">
|
||||
<el-table border style="margin-bottom: 20px" height="550" :data="dataList">
|
||||
<el-table-column type="expand">
|
||||
<template slot-scope="props">
|
||||
<el-table border style="margin-bottom: 10px" :data="props.row.logData">
|
||||
<el-table-column label="内容" prop="title"></el-table-column>
|
||||
<el-table-column label="修改前" prop="before" show-overflow-tooltip>
|
||||
<template slot-scope="props">
|
||||
{{props.row.before == 'null' || props.row.before == ''? '--':props.row.before}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="修改后" prop="after" show-overflow-tooltip></el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="修改人" prop="sysCreateBy"></el-table-column>
|
||||
<el-table-column label="修改时间" prop="sysCreateTime"></el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div><el-button size="small" @click="type =0;contentData= {}" type="info">课程基本信息</el-button>
|
||||
<el-button size="small" v-if="isShow" @click="type =1" type="info">修改记录</el-button>
|
||||
</div>
|
||||
<div style="padding: 5px;">课程内容目录</div>
|
||||
<div style="min-height: 500px;">
|
||||
<div class="catalog">
|
||||
<el-collapse class="catalog-row" v-model="activeNames">
|
||||
<el-collapse-item v-for="(item, index) in catalogTree" :key="index" :name="index">
|
||||
<template slot="title">
|
||||
<span style="font-size:12px">{{ item.section.name }}</span>
|
||||
</template>
|
||||
<ul>
|
||||
<li @click="showRes(ele)" v-for="(ele, i) in item.contents" :key="i" class="catalog-cell">
|
||||
<span style="font-size:12px">{{ getType(ele.contentType) }}</span>
|
||||
<span style="margin-left: 5px;">{{ ele.contentName}}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import apiCoursePortal from "@/api/modules/coursePortal.js";
|
||||
import exam from "@/components/Course/exam";
|
||||
import homework from "@/components/Course/homework";
|
||||
import pdfPreview from "@/components/PdfPreview/index.vue";
|
||||
import assess from "@/components/Course/assess";
|
||||
import apiTag from "../../api/modules/tag.js";
|
||||
import {
|
||||
formatDate,
|
||||
courseType,
|
||||
getType,
|
||||
numberToLetter
|
||||
} from "@/utils/tools.js";
|
||||
import imageUpload from "@/components/ImageUpload/index.vue";
|
||||
import weikeContent from "@/components/Course/weikeContent.vue";
|
||||
import catalogCourseware from "@/components/Course/catalogCourseware.vue";
|
||||
import apiCourse from "@/api/modules/course.js";
|
||||
import scene from "../../api/modules/scene.js";
|
||||
import WxEditor from "@/components/Editor/index.vue";
|
||||
import videoPlayer from '@/components/VideoPlayer/index.vue';
|
||||
import audioPlayer from '@/components/AudioPlayer/index.vue';
|
||||
import { mapGetters,mapActions} from 'vuex';
|
||||
import hyperLink from '@/components/Course/hyperLink.vue';
|
||||
export default {
|
||||
name:"auditCourse2",
|
||||
components: {
|
||||
weikeContent,
|
||||
catalogCourseware,
|
||||
imageUpload,
|
||||
exam,
|
||||
homework,
|
||||
assess,
|
||||
WxEditor,
|
||||
pdfPreview,
|
||||
videoPlayer,
|
||||
audioPlayer,
|
||||
hyperLink
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
isShow: {//编辑按钮控制
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
isDetails:{ //作业,显示记录
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showTest:{//预览显示试题
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['resOwnerMap','sysTypeMap']),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
curriculumData:{
|
||||
url:'',
|
||||
isDrag:false,
|
||||
completeSetup:1,
|
||||
},
|
||||
contentDataShow:true,//预览页面和课程内容的切换
|
||||
isEdit: true,
|
||||
fileBaseUrl: process.env.VUE_APP_FILE_BASE_URL,
|
||||
contentData: {},
|
||||
getType: getType,
|
||||
btnLoading: false,
|
||||
teacherName: [],
|
||||
teacher: [],
|
||||
loading: false,
|
||||
defaultProps: {
|
||||
value: "code",
|
||||
label: "name"
|
||||
},
|
||||
sysProps: {
|
||||
value: "id",
|
||||
label: "name"
|
||||
},
|
||||
catalogTree: [],
|
||||
resOwnerArray: [],
|
||||
sceneList: [],
|
||||
sysType: [],
|
||||
optionsList: [],
|
||||
tagList: [], // 标签
|
||||
typeList: [], // 资源归属
|
||||
showTags: [], //用于显示标签
|
||||
teacherList: [],
|
||||
courseInfo: {},
|
||||
courseCoverurl: "",
|
||||
sysTypeListMap:[],
|
||||
resOwnerListMap: [],
|
||||
dataList: [{ id: 1 }, { id: 2 }],
|
||||
activeName: "catalog",
|
||||
type: 0,
|
||||
info: {
|
||||
onlyRequired: false,
|
||||
dlgShow: false,
|
||||
fileType: "",
|
||||
shebei: []
|
||||
},
|
||||
rules: {
|
||||
name: [{ required: true, message: "请输入课程名称", trigger: "blur" }],
|
||||
kind: [
|
||||
{ required: true, message: "请选择课程分类", trigger: "change" }
|
||||
],
|
||||
location: [
|
||||
{ required: true, message: "请选择资源归属", trigger: "change" }
|
||||
],
|
||||
aim: [{ required: true, message: "请输入目标人群", trigger: "blur" }],
|
||||
courseValue: [
|
||||
{ required: true, message: "请输入课程价值", trigger: "blur" }
|
||||
],
|
||||
tag: [{ required: true, message: "请输入标签", trigger: "blur" }],
|
||||
power: [{ required: true, message: "请输入开放权限", trigger: "blur" }]
|
||||
},
|
||||
activeNames: [0, 1, 2, 3, 4]
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.getDetail();
|
||||
this.getSceneData();
|
||||
this.updateLogs();
|
||||
this.getResOwnerTree().then(rs=>{
|
||||
this.resOwnerListMap=rs;
|
||||
});
|
||||
this.getSysTypeTree().then(rs=>{
|
||||
this.sysTypeListMap=rs;
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
getResOwnerTree:'resOwner/getResOwnerTree',
|
||||
loadResOwners:'resOwner/loadResOwners',
|
||||
getSysTypeTree:'sysType/getSysTypeTree',
|
||||
loadSysTypes:'sysType/loadSysTypes'
|
||||
}),
|
||||
resOwnerName(code){
|
||||
if(code==''){return '';}
|
||||
return this.resOwnerMap.get(code);
|
||||
},
|
||||
sysTypeName(code){
|
||||
if(code==''){return '';}
|
||||
return this.sysTypeMap.get(code);
|
||||
},
|
||||
onPlayerPlay(){
|
||||
console.log("开始播放");
|
||||
},
|
||||
onPlayerPause(){
|
||||
console.log("暂停");
|
||||
},
|
||||
onPlayerEnded(){
|
||||
console.log("播放结束");
|
||||
},
|
||||
onPlayerPlaying(itme){
|
||||
console.log("当前播放"+itme);
|
||||
},
|
||||
audioPlaying(item){
|
||||
console.log("当前播放"+item);
|
||||
},
|
||||
audioPlay(){
|
||||
console.log("开始播放");
|
||||
},
|
||||
audioPause(){
|
||||
console.log("暂停");
|
||||
},
|
||||
audioEnd(){
|
||||
console.log("播放结束");
|
||||
},
|
||||
// 场景过滤
|
||||
sceneFilter(forScene) {
|
||||
// sceneList
|
||||
// this.courseInfo.forScene
|
||||
let name = "";
|
||||
this.sceneList.forEach(item => {
|
||||
if (item.id === forScene) {
|
||||
name = item.name;
|
||||
}
|
||||
});
|
||||
return name;
|
||||
},
|
||||
updateLogs() {
|
||||
let params = {
|
||||
courseId: this.id,
|
||||
name: ""
|
||||
};
|
||||
apiCourse.findUpdateLogs(params).then(res => {
|
||||
if (res.status === 200) {
|
||||
res.result.forEach(item => {
|
||||
item.logData = JSON.parse(item.logData);
|
||||
});
|
||||
this.dataList = res.result;
|
||||
} else {
|
||||
this.$message.error(res.message);
|
||||
}
|
||||
});
|
||||
},
|
||||
saveEdit() {
|
||||
this.btnLoading = true;
|
||||
//标签为什么要深复制?
|
||||
// let tags = deepClone(this.courseInfo.tags);
|
||||
// console.log(tags, 'tags222');
|
||||
// this.courseInfo.tags = tags.join();
|
||||
this.courseInfo.tags = this.showTags.join();
|
||||
//处理资源归属
|
||||
// if (this.resOwnerArray.length > 0) {
|
||||
// this.courseInfo.resOwner1 = this.resOwnerArray[0]; //资源归属一级的id
|
||||
// this.courseInfo.resOwner2 = this.resOwnerArray[1]; //资源归属二级的id
|
||||
// } else {
|
||||
// this.$message.error("请选择资源归属");
|
||||
// this.btnLoading = false;
|
||||
// return;
|
||||
// }
|
||||
if (this.resOwnerArray.length > 2) {
|
||||
this.courseInfo.resOwner3 = this.resOwnerArray[2]; //资源归属三级的id
|
||||
}
|
||||
// 分类
|
||||
if (this.sysType.length > 0) {
|
||||
this.courseInfo.sysType1 = this.sysType[0]; //资源归属一级的id
|
||||
this.courseInfo.sysType2 = this.sysType[1]; //资源归属二级的id
|
||||
} else {
|
||||
this.$message.error("请选择内容分类");
|
||||
this.btnLoading = false;
|
||||
return;
|
||||
}
|
||||
if (this.sysType.length > 2) {
|
||||
this.courseInfo.sysType3 = this.sysType[2]; //资源归属三级的id
|
||||
}
|
||||
// let postData = {
|
||||
// course: this.courseInfo,
|
||||
// // teachers: this.teacherName
|
||||
// };
|
||||
apiCourse
|
||||
.saveOnlyCourse(this.courseInfo)
|
||||
.then(res => {
|
||||
if (res.status === 200) {
|
||||
|
||||
this.$message.success("操作成功!");
|
||||
// let result = res.result;
|
||||
this.isEdit = true;
|
||||
this.courseInfo = result.course;
|
||||
// this.curCourseId = result.course.id; //设置当前课程的id
|
||||
this.courseTeachers = result.teachers;
|
||||
let list = [];
|
||||
// this.courseTeachers.forEach(item => {
|
||||
// list.push(item.teacherName);
|
||||
// });
|
||||
this.btnLoading = false;
|
||||
|
||||
} else {
|
||||
this.$message.error(res.message);
|
||||
this.btnLoading = false;
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
this.btnLoading = false;
|
||||
});
|
||||
},
|
||||
// 标签远程查询
|
||||
async remoteTagMethod(query) {
|
||||
if (query) {
|
||||
try {
|
||||
const { result, status } = await apiTag.findByName(1, query);
|
||||
if (status === 200) {
|
||||
this.tagList = result;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
} else {
|
||||
this.tagList = [];
|
||||
}
|
||||
},
|
||||
//获取场景,保留
|
||||
async getSceneData() {
|
||||
try {
|
||||
const { result, status } = await scene.list(1);
|
||||
if (status === 200) {
|
||||
this.sceneList = result;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
// 教师列标,远程查询
|
||||
async remoteMethod(query) {
|
||||
if (query) {
|
||||
this.loading = true;
|
||||
try {
|
||||
const { result, status } = await apiTeacher.findByName(query);
|
||||
if (status === 200) {
|
||||
let list = [];
|
||||
result.forEach(item => {
|
||||
list.push({
|
||||
teacherId: item.id,
|
||||
teacherName: item.name
|
||||
});
|
||||
});
|
||||
this.teacherList = list;
|
||||
this.loading = false;
|
||||
}
|
||||
} catch (error) {
|
||||
this.loading = false;
|
||||
}
|
||||
} else {
|
||||
this.teacherList = [];
|
||||
}
|
||||
},
|
||||
uploadCoverImgSuccess(res) {
|
||||
this.courseInfo.coverImg = res.result.filePath;
|
||||
this.courseCoverurl = res.result.httpPath;
|
||||
},
|
||||
removeCoverImgSuccess() {
|
||||
this.courseCoverurl = "";
|
||||
this.courseInfo.coverImg = "";
|
||||
},
|
||||
getDetail() {
|
||||
apiCoursePortal.detail(this.id).then(rs => {
|
||||
if (rs.status == 200) {
|
||||
this.courseInfo = rs.result.course;
|
||||
if(rs.result.course.coverImg !== '') {
|
||||
this.courseCoverurl = this.fileBaseUrl + rs.result.course.coverImg;
|
||||
}
|
||||
this.teacherList = rs.result.teachers;
|
||||
this.teacherName = rs.result.teachers;
|
||||
this.teacher = rs.result.teachers.map(item => item.teacherName);
|
||||
this.showTags = this.courseInfo.tags.split(",");
|
||||
if (rs.result.course.resOwner3 == "") {
|
||||
this.resOwnerArray = [
|
||||
rs.result.course.resOwner1,
|
||||
rs.result.course.resOwner2
|
||||
];
|
||||
} else {
|
||||
this.resOwnerArray = [
|
||||
rs.result.course.resOwner1,
|
||||
rs.result.course.resOwner2,
|
||||
rs.result.course.resOwner3
|
||||
];
|
||||
}
|
||||
if (
|
||||
rs.result.course.sysType3 == "" &&
|
||||
rs.result.course.sysType2 == ""
|
||||
) {
|
||||
this.sysType = [rs.result.course.sysType1];
|
||||
} else if (rs.result.course.sysType3 == "") {
|
||||
this.sysType = [
|
||||
rs.result.course.sysType1,
|
||||
rs.result.course.sysType2
|
||||
];
|
||||
} else {
|
||||
this.sysType = [
|
||||
rs.result.course.sysType1,
|
||||
rs.result.course.sysType2,
|
||||
rs.result.course.sysType3
|
||||
];
|
||||
}
|
||||
this.teachers = rs.result.teachers;
|
||||
this.contentList = rs.result.contents;
|
||||
let treeList = [];
|
||||
rs.result.sections.forEach(sec => {
|
||||
let treeNode = { section: sec, contents: [] };
|
||||
rs.result.contents.forEach(c => {
|
||||
if (c.csectionId == sec.id) {
|
||||
treeNode.contents.push(c);
|
||||
}
|
||||
});
|
||||
treeList.push(treeNode);
|
||||
});
|
||||
this.catalogTree = treeList;
|
||||
} else {
|
||||
this.$message.error(rs.message);
|
||||
}
|
||||
});
|
||||
},
|
||||
ctabChange(tab) {
|
||||
if (tab.name == "info") {
|
||||
this.activeName = "catalog";
|
||||
}
|
||||
},
|
||||
showRes(r) {
|
||||
// this.contentDataShow = true;
|
||||
this.contentData = r;
|
||||
if(r.contentType == 10 ||r.contentType == 20){
|
||||
if(r.content.startsWith('\{')){
|
||||
this.curriculumData = JSON.parse(r.content)
|
||||
}else{
|
||||
this.curriculumData.url = r.content
|
||||
}
|
||||
}
|
||||
this.type = 0;
|
||||
},
|
||||
formatChoose(format) {
|
||||
let text = "";
|
||||
switch (format) {
|
||||
case 1: {
|
||||
text = "视频";
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
text = "音频";
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
text = "文档";
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
text = "图文";
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
text = "外部链接";
|
||||
break;
|
||||
}
|
||||
case 6: {
|
||||
text = "作业";
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
text = "考试";
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
text = "评估";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return text;
|
||||
},
|
||||
statusToContent(status) {
|
||||
let data = null;
|
||||
switch (status) {
|
||||
case 1: {
|
||||
data = {
|
||||
text: "[未开始]",
|
||||
class: "catalog-cell-state1"
|
||||
};
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
data = {
|
||||
text: "[进行中]",
|
||||
class: "catalog-cell-state2"
|
||||
};
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
data = {
|
||||
text: "[已完成]",
|
||||
class: "catalog-cell-state9"
|
||||
};
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
data = {
|
||||
text: "[未开始]",
|
||||
class: "catalog-cell-state1"
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.grid-info {
|
||||
display: flex;
|
||||
padding: 0 20px;
|
||||
.grid-item {
|
||||
flex: 1;
|
||||
.item-one {
|
||||
font-size: 18px;
|
||||
height: 20px;
|
||||
}
|
||||
.item-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
::v-deep .picture-text{
|
||||
img{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.catalog {
|
||||
::v-deep .el-collapse-item__header{
|
||||
line-height: 2;
|
||||
height: 60px;
|
||||
}
|
||||
.catalog-row {
|
||||
margin: 0px;
|
||||
padding: 0px 10px 10px 10px;
|
||||
ul {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
.catalog-cell {
|
||||
line-height: 32px;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding-left: 20px;
|
||||
color: #5c5c5c;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
364
src/components/Course/auditCourseEdit.vue
Normal file
364
src/components/Course/auditCourseEdit.vue
Normal file
@@ -0,0 +1,364 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--在线课录播课审核-->
|
||||
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="18" v-show="type === 0">
|
||||
<div class="player" style="min-height: 473px;border: 1px solid #d0d0d0;background-color: #FFFFFF;padding-top: 10px;">
|
||||
<!--课程基本信息-->
|
||||
<div>
|
||||
<div v-if="resType == 0" style="position: relative;">
|
||||
<el-form label-width="80px" size="mini" :rules="rules">
|
||||
<el-form-item label="名称" prop="name"><template> 历史111与文化 </template></el-form-item>
|
||||
<el-form-item label="分类" prop="kind"><template> 集团级、B1 </template></el-form-item>
|
||||
<el-form-item label="资源归属" prop="location"><template> 集团级、B1 </template></el-form-item>
|
||||
<el-form-item label="封面" prop="face"><template>3333.jpg</template></el-form-item>
|
||||
<el-form-item label="目标人群" prop="aim"><template> 管理员</template></el-form-item>
|
||||
<el-form-item label="课程价值" prop="courseValue"><template> 有效沟通</template></el-form-item>
|
||||
<el-form-item label="课程介绍" prop="description"><template> 有效沟通 </template></el-form-item>
|
||||
<el-form-item label="标签" prop="tag"><template> 集团级、B1 </template></el-form-item>
|
||||
<el-form-item label="关键字" prop="keyword"><template> 集团级、B1 </template></el-form-item>
|
||||
<el-form-item label="观看设置" prop="setting">
|
||||
<template>pc端观看</template>
|
||||
</el-form-item>
|
||||
<el-form-item label="授课教师" prop="teacher"><template>王明宇 </template></el-form-item>
|
||||
<el-form-item label="开放权限" prop="power"><template> 集团级</template></el-form-item>
|
||||
<el-form-item label="课程来源" prop="fromSource">
|
||||
<template> 外部 </template>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div v-if="resType == 1" style="position: relative;">
|
||||
<video :src="`${webBaseUrl}/temp/video.mp4`" width="100%" controls controlslist="nodownload"
|
||||
style="width: 100%; height: 100%; object-fit: fill"></video>
|
||||
</div>
|
||||
<div v-if="resType == 2"><img :src="`${webBaseUrl}/temp/index/image_02.png`" width="100%" /></div>
|
||||
<div v-if="resType == 3"><img :src="`${webBaseUrl}/temp/doc.png`" width="100%" /></div>
|
||||
<div v-if="resType == 4"><img :src="`${webBaseUrl}/temp/index/image_02.png`" width="100%" /></div>
|
||||
<div v-if="resType == 5"><img :src="`${webBaseUrl}/temp/index/image_02.png`" width="100%" /></div>
|
||||
<div v-if="resType == 6">
|
||||
<el-form label-width="80px" size="mini" >
|
||||
<el-form-item label="名称">京东方质量奖导读-课程作业</el-form-item>
|
||||
<el-form-item label="内容">作业内容包含图文</el-form-item>
|
||||
<el-form-item label="附件">课程附件.doc</el-form-item>
|
||||
<el-form-item label="截止时间">2020-04-10 10:00</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div v-if="resType == 7">
|
||||
<el-form label-width="80px" size="mini" >
|
||||
<el-form-item label="名称">京东方质量奖导读-考试</el-form-item>
|
||||
<el-form-item label="考试时长">60分钟</el-form-item>
|
||||
<el-form-item label="尝试次数">不限制</el-form-item>
|
||||
<el-form-item label="评分方式">最高一次</el-form-item>
|
||||
<el-form-item label="及格线">60%</el-form-item>
|
||||
<el-form-item label=""> <el-link>查看试题</el-link> </el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div v-if="resType == 8" style="padding:5px">
|
||||
<p style="margin: 0;text-align: center;">问卷名称</p>
|
||||
<el-table border :data="tableData">
|
||||
<el-table-column width="500px" prop="content" label="问题">
|
||||
<template slot-scope="scope">
|
||||
<p>{{ scope.row.content }}</p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="high" center label="高">
|
||||
<template slot-scope="scope">
|
||||
<el-radio v-model="scope.row.high"></el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="middle" center label="中">
|
||||
<template slot-scope="scope">
|
||||
<el-radio v-model="scope.row.middle"></el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="low" center label="低">
|
||||
<template slot-scope="scope">
|
||||
<el-radio v-model="scope.row.low"></el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="18" v-show="type === 1">
|
||||
<div class="grid-info">
|
||||
<div class="grid-item">
|
||||
<p class="item-title">目录</p>
|
||||
<p>名称:历史与文化</p>
|
||||
<p>分类:通用力</p>
|
||||
<p>资源归属:集团级、B1</p>
|
||||
<p>封面:333.jpg</p>
|
||||
<p>目标人群: 领导层</p>
|
||||
<p>课程价值:实现高效沟通</p>
|
||||
<p>课程介绍:实现高效沟通</p>
|
||||
<p>标签:实现高效沟通</p>
|
||||
<p>关键字:实现高效沟通</p>
|
||||
<p>观看设置:pc端可见</p>
|
||||
<p>授课教师:王明宇</p>
|
||||
<p>开放权限:组织部</p>
|
||||
<p>课程来源:微课</p>
|
||||
</div>
|
||||
<div class="grid-item">
|
||||
<p class="item-title">修改后</p>
|
||||
<p>历史与文化</p>
|
||||
<p>通用力</p>
|
||||
<p>集团级、B1</p>
|
||||
<p>333.jpg</p>
|
||||
<p>领导层</p>
|
||||
<p>实现高效沟通</p>
|
||||
<p>实现高效沟通</p>
|
||||
<p>实现高效沟通</p>
|
||||
<p>实现高效沟通</p>
|
||||
<p>pc端可见</p>
|
||||
<p>王明宇</p>
|
||||
<p>组织部</p>
|
||||
<p>微课</p>
|
||||
</div>
|
||||
<div class="grid-item">
|
||||
<p class="item-title">修改前</p>
|
||||
<p>历史与前行</p>
|
||||
<p>专用力</p>
|
||||
<p>集团级、B2</p>
|
||||
<p>3444.jpg</p>
|
||||
<p>领导层</p>
|
||||
<p>实现高效沟通</p>
|
||||
<p>实现高效沟通</p>
|
||||
<p>实现高效沟通</p>
|
||||
<p>实现高效沟通</p>
|
||||
<p>pc端可见</p>
|
||||
<p>王明宇</p>
|
||||
<p>组织部</p>
|
||||
<p>微课</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div><el-button @click="resType = 0;type =0" type="info">课程基本信息</el-button>
|
||||
<el-button @click="type =1" type="info">修改记录</el-button>
|
||||
</div>
|
||||
<div style="padding: 5px;">课程内容目录</div>
|
||||
<div style="height: 650px;overflow: auto;">
|
||||
<div class="catalog">
|
||||
<el-collapse class="catalog-row" size="mini" v-model="activeNames" @change="handleChange">
|
||||
<el-collapse-item v-for="(item, index) in collapseList.children" :key="index" :name="index">
|
||||
<template slot="title">
|
||||
<!-- <i class="el-icon-video-camera"></i> -->
|
||||
<span style="font-size:12px">{{ item.title }}</span>
|
||||
</template>
|
||||
<ul>
|
||||
<li @click="showRes(ele.format)" v-for="(ele, i) in item.children" :key="i" class="catalog-cell">
|
||||
<span style="font-size:12px">{{formatChoose(ele.format) }}</span>{{ ele.title }}
|
||||
</li>
|
||||
</ul>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data(){
|
||||
return {
|
||||
activeName:'catalog',
|
||||
resType:0,
|
||||
type: 0,
|
||||
info:{
|
||||
onlyRequired: false,
|
||||
dlgShow: false,
|
||||
fileType: '',
|
||||
shebei:[]
|
||||
},
|
||||
rules: {
|
||||
name: [{ required: true, message: '请输入课程名称', trigger: 'blur' }],
|
||||
kind: [{ required: true, message: '请选择课程分类', trigger: 'change' }],
|
||||
location: [{ required: true, message: '请选择资源归属', trigger: 'change' }],
|
||||
aim: [{ required: true, message: '请输入目标人群', trigger: 'blur' }],
|
||||
courseValue:[{ required: true, message: '请输入课程价值', trigger: 'blur' }],
|
||||
tag:[{ required: true, message: '请输入标签', trigger: 'blur' }],
|
||||
power:[{ required: true, message: '请输入开放权限', trigger: 'blur' }],
|
||||
},
|
||||
activeNames: [0, 1, 2, 3, 4],
|
||||
collapseList: {
|
||||
id: 1,
|
||||
title: '资金系统操作培训',
|
||||
children: [
|
||||
{
|
||||
title: '集团账户管理',
|
||||
status: 3,
|
||||
children: [
|
||||
{
|
||||
title: '集团账户管理',
|
||||
status: 3, //1代表未开始 2代表进行中 3代表已完成
|
||||
format: 1, //1代表是视频 2代表音频 3代表文档 4代表图文 5代表外部链接
|
||||
resource: '/temp/video.mp4',
|
||||
timeLength: '1:30:00'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '接口管理',
|
||||
status: 2,
|
||||
children: [
|
||||
{
|
||||
title: '接口管理',
|
||||
status: 2, //1代表未开始 2代表进行中 3代表已完成
|
||||
format: 2, //1代表是视频 2代表音频 3代表文档 4代表图文 5代表外部链接
|
||||
resource: '',
|
||||
timeLength: '00:30:00'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '付款管理',
|
||||
status: 1,
|
||||
children: [
|
||||
{
|
||||
title: '付款管理',
|
||||
status: 1, //1代表未开始 2代表进行中 3代表已完成
|
||||
format: 3, //1代表是视频 2代表音频 3代表文档 4代表图文 5代表外部链接
|
||||
resource: ''
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '收款管理',
|
||||
status: 1,
|
||||
children: [
|
||||
{
|
||||
title: '收款管理',
|
||||
status: 1, //1代表未开始 2代表进行中 3代表已完成
|
||||
format: 4, //1代表是视频 2代表音频 3代表文档 4代表图文 5代表外部链接
|
||||
resource: ''
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '投资管理',
|
||||
status: 1,
|
||||
children: [
|
||||
{
|
||||
title: '可行性分析原则',
|
||||
status: 1, //1代表未开始 2代表进行中 3代表已完成
|
||||
format: 5, //1代表是视频 2代表音频 3代表文档 4代表图文 5代表外部链接
|
||||
resource: ''
|
||||
},
|
||||
{
|
||||
title: '结构平衡',
|
||||
status: 1, //1代表未开始 2代表进行中 3代表已完成
|
||||
format: 6, //1代表是视频 2代表音频 3代表文档 4代表图文 5代表外部链接 6代表作业
|
||||
resource: ''
|
||||
},
|
||||
{
|
||||
title: '投资价值的波动',
|
||||
status: 1, //1代表未开始 2代表进行中 3代表已完成
|
||||
format: 7, //1代表是视频 2代表音频 3代表文档 4代表图文 5代表外部链接 7代表考试
|
||||
resource: ''
|
||||
},
|
||||
{
|
||||
title: '资金系统操作评估',
|
||||
status: 1, //1代表未开始 2代表进行中 3代表已完成
|
||||
format: 8, //1代表是视频 2代表音频 3代表文档 4代表图文 5代表外部链接 8代表评估
|
||||
resource: ''
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
ctabChange(tab) {
|
||||
if(tab.name=='info'){
|
||||
this.activeName='catalog';
|
||||
}
|
||||
},
|
||||
showRes(r) {
|
||||
this.resType = r;
|
||||
this.type = 0;
|
||||
},
|
||||
handleChange(val) {
|
||||
console.log(val);
|
||||
},
|
||||
formatChoose(format) {
|
||||
let text = '';
|
||||
switch (format) {
|
||||
case 1: {
|
||||
text = '视频';
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
text = '音频';
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
text = '文档';
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
text = '图文';
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
text = '外部链接';
|
||||
break;
|
||||
}
|
||||
case 6: {
|
||||
text = '作业';
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
text = '考试';
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
text = '评估';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return text;
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.grid-info{
|
||||
display: flex;
|
||||
padding: 0 20px;
|
||||
.grid-item{
|
||||
flex: 1;
|
||||
.item-one{
|
||||
font-size: 18px;
|
||||
}
|
||||
.item-title{
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
.catalog {
|
||||
.catalog-row {
|
||||
margin: 0px;
|
||||
padding: 0px 10px 10px 10px;
|
||||
ul {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
.catalog-cell {
|
||||
line-height: 32px;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
margin: 0px;
|
||||
padding-left: 20px;
|
||||
color: #5c5c5c;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
723
src/components/Course/catalogCourseware.vue
Normal file
723
src/components/Course/catalogCourseware.vue
Normal file
@@ -0,0 +1,723 @@
|
||||
<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">
|
||||
<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 {
|
||||
fileBaseUrl:process.env.VUE_APP_FILE_BASE_URL,
|
||||
curPdfPath:'',
|
||||
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.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){
|
||||
if(rs.result.previewFilePath){
|
||||
this.curPdfPath=rs.result.previewFilePath;
|
||||
}else{
|
||||
this.curPdfPath=rs.result.filePath;
|
||||
}
|
||||
//console.log(this.curPdfPath,'this.curPdfPath');
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
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>
|
||||
176
src/components/Course/catalogSort.vue
Normal file
176
src/components/Course/catalogSort.vue
Normal file
@@ -0,0 +1,176 @@
|
||||
<template>
|
||||
<div class="cctree">
|
||||
<div v-for="(cc, ccidx) in sortData" :key="ccidx" class="cctree-chapter">
|
||||
<div class="cctree-chapter-name">
|
||||
<span class="move-btn">
|
||||
<span v-if="ccidx== 0"></span>
|
||||
<svg-icon icon-class="moveUp" v-if="ccidx !== 0" @click="moveUp(ccidx)"></svg-icon>
|
||||
<svg-icon icon-class="moveDown" v-if="ccidx !== sortData.length -1" @click="moveDown(ccidx)"></svg-icon>
|
||||
<span v-if="ccidx == sortData.length -1"></span>
|
||||
</span>
|
||||
<span>{{ cc.section.name }}</span>
|
||||
</div>
|
||||
<ul class="cctree-chapter-cells">
|
||||
<li
|
||||
class="cctree-chapter-cell"
|
||||
v-for="(child, childIdx) in cc.contents"
|
||||
:key="childIdx"
|
||||
>
|
||||
<span class="move-btn">
|
||||
<svg-icon icon-class="moveUp" @click="moveUpContent(ccidx,childIdx)"></svg-icon>
|
||||
<svg-icon icon-class="moveDown" @click="moveDownContent(ccidx,childIdx)"></svg-icon>
|
||||
</span>
|
||||
【{{ getContentTypeName(child.contentType) }}】•
|
||||
{{ child.contentName }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getType,swapArray } from "../../utils/tools.js";
|
||||
import courseApi from '@/api/modules/course.js';
|
||||
export default {
|
||||
name: "tree-sort",
|
||||
props: {
|
||||
courseId:{
|
||||
type:String,
|
||||
require:true,
|
||||
},
|
||||
treeData: {
|
||||
// 树数据
|
||||
type: Array,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
sortData: null,
|
||||
getContentTypeName: getType,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
//克隆数据
|
||||
if (this.treeData) {
|
||||
this.sortData = this.treeData;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
moveUp(ccidx) {
|
||||
if(ccidx == 0){
|
||||
this.$message.warning("已经排到第一了!");
|
||||
return;
|
||||
}
|
||||
swapArray(this.sortData,ccidx,ccidx - 1);
|
||||
},
|
||||
moveDown(ccidx) {
|
||||
if(ccidx == this.sortData.length - 1){
|
||||
this.$message.warning("已经排到最后了!");
|
||||
return;
|
||||
}
|
||||
swapArray(this.sortData,ccidx,ccidx + 1);
|
||||
},
|
||||
moveUpContent(ccidx,childIdx) {
|
||||
if(ccidx == 0 && childIdx == 0){
|
||||
this.$message.warning("已经排到第一了!");
|
||||
return;
|
||||
}
|
||||
if(childIdx != 0){
|
||||
swapArray(this.sortData[ccidx].contents,childIdx,childIdx - 1);
|
||||
}else{
|
||||
this.sortData[ccidx - 1].contents.unshift(this.sortData[ccidx].contents[childIdx]);
|
||||
this.sortData[ccidx].contents.splice(childIdx,1);
|
||||
}
|
||||
},
|
||||
moveDownContent(ccidx,childIdx) {
|
||||
if(ccidx == this.sortData.length - 1 && this.sortData[ccidx].contents.length - 1 == childIdx){
|
||||
this.$message.warning("已经排到最后了!");
|
||||
return;
|
||||
}
|
||||
if(this.sortData[ccidx].contents.length - 1 != childIdx){
|
||||
swapArray(this.sortData[ccidx].contents,childIdx,childIdx + 1);
|
||||
}else{
|
||||
this.sortData[ccidx + 1].contents.unshift(this.sortData[ccidx].contents[childIdx]);
|
||||
this.sortData[ccidx].contents.splice(childIdx,1);
|
||||
}
|
||||
},
|
||||
save(sectionList,contentList,closeDialog){
|
||||
if(this.sortData && this.sortData.length > 0){
|
||||
let items = [];
|
||||
let that = this;
|
||||
this.sortData.forEach((element,eindex) => {
|
||||
let item = {id:element.section.id,index:eindex + 1};
|
||||
if(element.contents && element.contents.length > 0){
|
||||
item.items = [];
|
||||
element.contents.forEach((content,cindex) => {
|
||||
item.items.push({id:content.id,index:cindex + 1});
|
||||
});
|
||||
}
|
||||
items.push(item);
|
||||
});
|
||||
courseApi.updateContentOrders(this.courseId,items).then(res => {
|
||||
if(res.status == 200){
|
||||
items.forEach(obj1 => {
|
||||
sectionList.forEach(section=>{
|
||||
if(section.id == obj1.id){
|
||||
section.orderIndex = obj1.index;
|
||||
return;
|
||||
}
|
||||
});
|
||||
if(obj1.items && obj1.items.length > 0){
|
||||
obj1.items.forEach(obj2 => {
|
||||
contentList.forEach(content => {
|
||||
if(content.id == obj2.id){
|
||||
content.sortIndex = obj2.index;
|
||||
return;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
closeDialog();
|
||||
}
|
||||
}).catch(error =>{
|
||||
that.$message.error(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.cctree {
|
||||
width: 98%;
|
||||
font-size: 14px;
|
||||
margin-top: 10px;
|
||||
.cctree-chapter {
|
||||
.cctree-chapter-name {
|
||||
border-bottom: 1px solid #dddddd;
|
||||
padding: 0 6px 10px 6px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.cctree-chapter-cells {
|
||||
list-style-type: none;
|
||||
margin: 0px;
|
||||
padding: 0px 6px;
|
||||
.cctree-chapter-cell {
|
||||
list-style-type: none;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.move-btn{
|
||||
margin-right: 10px;
|
||||
svg{
|
||||
margin-right: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
span{
|
||||
width: 19px;
|
||||
height: 19px;
|
||||
margin-right: 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
223
src/components/Course/chooseCourseFile.vue
Normal file
223
src/components/Course/chooseCourseFile.vue
Normal file
@@ -0,0 +1,223 @@
|
||||
<template>
|
||||
<!--选择课程文件,视频,音,文档-->
|
||||
<div style="min-height: 500px;">
|
||||
<div style="padding: 5px 5px 10px 5px;display: flex;justify-content: space-between;">
|
||||
<!-- <div>
|
||||
<el-button @click="save" type="primary" size="small">确定</el-button>
|
||||
</div> -->
|
||||
</div>
|
||||
<el-tabs type="border-card" style="min-height: 400px;">
|
||||
<el-tab-pane :label="'选择已有'+curComType.name" >
|
||||
<div style="display: flex;justify-content: flex-start;">
|
||||
<div>
|
||||
<el-input maxlength="50" v-model="keyword" placeholder="名称" size="small"></el-input>
|
||||
</div>
|
||||
<!-- <div><el-input maxlength="50" v-model="params.author" placeholder="上传人" size="small"></el-input></div> -->
|
||||
<div style="padding-left: 10px;">
|
||||
<el-button @click="findCourseFile()" type="primary" >搜索</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="findState==2" style="padding-top: 10px;">
|
||||
<el-table style="100%" :data="fileList" border stripe>
|
||||
<el-table-column label="类型" width="60" prop="author"><template slot-scope="scope">{{curComType.name}}</template></el-table-column>
|
||||
<el-table-column label="名称" prop="name"></el-table-column>
|
||||
<el-table-column label="创建" prop="sysCreateBy" width="100"></el-table-column>
|
||||
<el-table-column label="创建时间" prop="sysCreateTime" width="160"></el-table-column>
|
||||
<el-table-column label="选择" width="70" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" @click="chooseCourseFile(scope.row)" type="primary">选择</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div style="text-align: center">
|
||||
<el-pagination
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page="pageIndex"
|
||||
:page-sizes="[5, 10,20,50,100]"
|
||||
:page-size="pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="count">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="'上传新'+curComType.name">
|
||||
<div v-if="!courseFile.id">
|
||||
<el-upload class="upload-demo" :headers="headers" :data="data" drag :action="uploadFileUrl" :on-success="handleUploadSuccess" :before-upload="handleBeforeUpload">
|
||||
<i class="el-icon-upload"></i>
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<div class="el-upload__tip" slot="tip">文件大小限制:{{curComType.maxSizeName}},支持的文件类型:{{curComType.fileTypes.join(',')}}</div>
|
||||
</el-upload>
|
||||
</div>
|
||||
<div v-else style="text-align: center;">
|
||||
<div style="padding: 20px;">{{courseFile.fileName}}</div>
|
||||
<div><el-button @click="chooseCourseFile(courseFile)" type="primary" size="mini">确定</el-button></div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getToken } from "@/utils/token";
|
||||
import apiCourseFile from '../../api/modules/courseFile';
|
||||
export default{
|
||||
props: {
|
||||
minHeight:{
|
||||
type: String,
|
||||
default:'500'
|
||||
},
|
||||
resType:{
|
||||
type: Number,
|
||||
default:0
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
uploadFileUrl: process.env.VUE_APP_BASE_API + "/xboe/sys/xuploader/file/upload", // 上传的图片服务器地址
|
||||
data:{
|
||||
dir:'course'
|
||||
},
|
||||
headers: {
|
||||
'XBOE-Access-Token': getToken(),
|
||||
},
|
||||
pageSize:10,
|
||||
pageIndex:1,
|
||||
count:0,
|
||||
keyword: '',
|
||||
comTypes:[
|
||||
{id:'1',type:'video',name:'视频',img:'el-icon-video-camera',resType:10,maxSize:1024,maxSizeName:"1G",fileTypes:['mp4']},
|
||||
{id:'2',type:'sound',name:'音频',img:'el-icon-service',resType:20,maxSize:200,maxSizeName:"200M",fileTypes:['mp3']},
|
||||
{id:'3',type:'image',name:'图片',img:'el-icon-picture-outline',resType:30,maxSize:10,maxSizeName:"10M",fileTypes:["png","jpg","gif","bmp"]},
|
||||
{id:'4',type:'doc',name:'文档',img:'el-icon-document',resType:40,maxSize:500,maxSizeName:"500M",fileTypes:["doc", "xls", "ppt","docx", "xlsx", "pptx","txt","pdf"]}
|
||||
],
|
||||
curComType:{id:'',type:'',name:'',maxSizeName:'',fileTypes:[]},
|
||||
findState:1,
|
||||
courseFile:{},
|
||||
fileList:[],
|
||||
radioId:'',
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.courseFile={};
|
||||
let $this=this;
|
||||
this.comTypes.some(ct=>{
|
||||
if(ct.resType==$this.resType){
|
||||
$this.curComType=ct;
|
||||
//this.findCourseFile();
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
methods:{
|
||||
handleBeforeUpload(file) {
|
||||
if(file.name.lastIndexOf(".") ==-1) {
|
||||
this.$message({message:`文件格式不正确!`,type:'error',offset:100})
|
||||
return false;
|
||||
}
|
||||
let fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
|
||||
fileExtension=fileExtension.toLowerCase();
|
||||
// 校检文件类型
|
||||
if(this.curComType.fileTypes.indexOf(fileExtension) == -1){
|
||||
this.$message({message:`文件格式不正确, 请上传正确格式的${this.curComType.name}文件!`,type:'error',offset:100})
|
||||
return false;
|
||||
}
|
||||
// 校检文件大小
|
||||
if(this.curComType.maxSize) {
|
||||
const isLt = file.size / 1024 / 1024 < this.curComType.maxSize;
|
||||
if (!isLt) {
|
||||
this.$message({message:`上传文件大小不能超过 ${this.curComType.maxSizeName} !`,type:'error',offset:100})
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 上传失败
|
||||
handleUploadError(err) {
|
||||
this.$message({message:"上传失败, 请重试",type:'error',offset:100});
|
||||
},
|
||||
// 上传成功回调
|
||||
handleUploadSuccess(res, file) {
|
||||
//console.log(res);
|
||||
if(res.status == 200) {
|
||||
//上传到课件库
|
||||
//console.log(res.result);
|
||||
let courseWare={
|
||||
fileName:res.result.displayName,
|
||||
fileType:res.result.fileType,
|
||||
filePath:res.result.filePath,
|
||||
resType:this.resType,
|
||||
remark:'课程中直接上传'
|
||||
}
|
||||
apiCourseFile.saveUpload(courseWare).then(rs=>{
|
||||
if(rs.status==200){
|
||||
this.courseFile=rs.result;
|
||||
this.$message({message:"上传成功",type:'success',offset:100});
|
||||
// this.cware.content.contentRefId=rs.result.id;
|
||||
// this.cware.content.contentName=result.displayName;
|
||||
// this.cware.content.content=result.filePath;
|
||||
}
|
||||
});
|
||||
}else{
|
||||
this.$message({message:"上传失败:"+res.message,type:'error',offset:100});
|
||||
}
|
||||
|
||||
//this.$emit("success", res);
|
||||
},
|
||||
// 删除文件
|
||||
handleDelete(index) {
|
||||
this.fileList.splice(index, 1);
|
||||
//注意删除处理
|
||||
//this.$emit("remove", '');
|
||||
},
|
||||
// 获取文件名称
|
||||
getFileName(name) {
|
||||
if (name.lastIndexOf("/") > -1) {
|
||||
return name.slice(name.lastIndexOf("/") + 1).toLowerCase();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.pageSize = val;
|
||||
this.pageIndex = 1;
|
||||
this.findCourseFile();
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.pageIndex = val;
|
||||
this.findCourseFile();
|
||||
},
|
||||
findCourseFile(){
|
||||
this.findState=2;
|
||||
let data = {
|
||||
name: this.keyword,
|
||||
resOwner1: '',//this.params.resOwner1, //资源归属一级的id
|
||||
resOwner2: '',//this.params.resOwner2, // 资源归属二级的id
|
||||
resOwner3: '',//this.params.resOwner3, // 资源归属三级的id
|
||||
resType: this.resType, //this.params.type,
|
||||
pageSize: this.pageSize,
|
||||
pageIndex: this.pageIndex,
|
||||
self:true,//只是查询自己的
|
||||
}
|
||||
apiCourseFile.pageList(data).then(rs=>{
|
||||
if(rs.status === 200) {
|
||||
this.fileList = rs.result.list;
|
||||
this.count = rs.result.count;
|
||||
}else{
|
||||
this.$message.error(rs.message);
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
chooseCourseFile(ccfile){
|
||||
this.$emit('choose', ccfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
189
src/components/Course/collectItem.vue
Normal file
189
src/components/Course/collectItem.vue
Normal file
@@ -0,0 +1,189 @@
|
||||
<template>
|
||||
<div style="cursor: pointer;">
|
||||
<div class="uc-course" v-for="(item, idx) in items" :key="idx" @click="coudetail(item)">
|
||||
|
||||
<div class="uc-course-img" style="width: 212px;height: 119px;" @click="jump(item)">
|
||||
<course-image :course="item"></course-image>
|
||||
<!-- <img :src="imageUrl(item)" /><span v-if="isShow" class="two-line-ellipsis">{{item.title}}</span> -->
|
||||
</div>
|
||||
<div class="flex-between" @click="jump(item)">
|
||||
<div class="uc-course-name">
|
||||
<span :class="contentTypeFilter(item.contentType).class">{{ contentTypeFilter(item.contentType).text }}</span>
|
||||
<span>{{ item.title }}</span>
|
||||
</div>
|
||||
<div class="uc-course-text">讲师:{{ item.authorName}}</div>
|
||||
<div class="uc-course-text">收藏日期:{{ item.time }}</div>
|
||||
</div>
|
||||
<div class="flex-between">
|
||||
<el-button v-if="remove" @click.stop="delItem(item)" type="text" icon="el-icon-remove" style="color:#8590A6;font-size:14px;">
|
||||
取消收藏
|
||||
</el-button>
|
||||
</div>
|
||||
<!-- <div class="uc-course-info">
|
||||
<div style="display: flex;justify-content: space-between;">
|
||||
<router-link target="_blank" :to="'/course/detail?id='+item.objId" class="uc-course-name">
|
||||
<span :class="contentTypeFilter(item.contentType).class">{{contentTypeFilter(item.contentType).text}}</span>
|
||||
<span>{{ item.title }}</span>
|
||||
</router-link>
|
||||
<div><el-button v-if="remove" @click="delItem(item)" type="text" icon="el-icon-remove">取消收藏</el-button></div>
|
||||
</div>
|
||||
<div style="display: flex;justify-content: space-between;align-items: flex-end;">
|
||||
<div>
|
||||
<div class="uc-course-text">讲师:{{item.authorName}}</div>
|
||||
<div class="uc-course-text">收藏日期:{{item.time}}</div>
|
||||
</div>
|
||||
<interactBar :type="0" :data="item" :views="false" :shares="false"></interactBar>
|
||||
</div>
|
||||
</div> -->
|
||||
<!-- </router-link> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import interactBar from '@/components/Portal/interactBar.vue';
|
||||
import courseImage from '@/components/Course/courseImage.vue';
|
||||
export default {
|
||||
name: 'comStudyItem',
|
||||
props: {
|
||||
items: {
|
||||
//name,
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
remove: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isShow: false,
|
||||
oData: {
|
||||
comments: '100',
|
||||
favorites: '20',
|
||||
praises: '30'
|
||||
},
|
||||
fileBaseUrl: process.env.VUE_APP_FILE_BASE_URL
|
||||
};
|
||||
},
|
||||
components: {
|
||||
interactBar,
|
||||
courseImage
|
||||
},
|
||||
methods: {
|
||||
coudetail(item) {
|
||||
// let routeData = this.$router.resolve({ path: '/course/detail?id=' + item.objId });
|
||||
// window.open(routeData.href, '_blank');
|
||||
this.$router.push({path:'/course/detail',query:{id:item.objId}})
|
||||
},
|
||||
delItem(item) {
|
||||
this.$confirm('您确定要删除所选收藏吗?', '删除提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
this.$emit('confirm', item);
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
contentTypeFilter(value) {
|
||||
let obj = {};
|
||||
switch (value) {
|
||||
case '10': {
|
||||
obj.class = 'uc-course-type2';
|
||||
obj.text = '录播';
|
||||
break;
|
||||
}
|
||||
case '21': {
|
||||
obj.class = 'uc-course-type2';
|
||||
obj.text = '直播';
|
||||
break;
|
||||
}
|
||||
case '20': {
|
||||
obj.class = 'uc-course-type2';
|
||||
obj.text = '录播';
|
||||
break;
|
||||
}
|
||||
case '30': {
|
||||
obj.class = 'uc-course-type2';
|
||||
obj.text = '面授';
|
||||
break;
|
||||
}
|
||||
case '90': {
|
||||
obj.class = 'uc-course-type2';
|
||||
obj.text = '混合';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
imageUrl(item) {
|
||||
if (item && item.image && item.image != '') {
|
||||
return process.env.VUE_APP_FILE_BASE_URL + item.image;
|
||||
} else {
|
||||
this.isShow = true;
|
||||
return this.webBaseUrl + '/images/bgimg/course.png';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.uc-course {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
padding-left: 0px;
|
||||
padding-bottom: 20px;
|
||||
padding-top: 15px;
|
||||
// margin-bottom: 10px;
|
||||
// margin-left: 10px;
|
||||
.flex-between {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
margin-left: 10px;
|
||||
.uc-course-text {
|
||||
color: #747474;
|
||||
margin-right: 20px;
|
||||
}
|
||||
&:last-of-type{
|
||||
margin-left: auto;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
// &:last-of-type {
|
||||
|
||||
// align-items: flex-start;
|
||||
// }
|
||||
}
|
||||
.uc-course-img {
|
||||
position: relative;
|
||||
img {
|
||||
width: 160px;
|
||||
height: 90px;
|
||||
border: 1px solid #f4f4f5;
|
||||
}
|
||||
> span {
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
left: 10px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: #ffffff;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
.uc-course-name {
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
> span:last-of-type {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
204
src/components/Course/courseExam.vue
Normal file
204
src/components/Course/courseExam.vue
Normal file
@@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="exam.show==1">
|
||||
<div style="padding: 10px; text-align: center;">
|
||||
<el-button @click="changeExamShow(3)" type="primary" size="small">自定义考试</el-button>
|
||||
<el-button @click="changeExamShow(2)" type="primary" size="small">选择已有考试</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="exam.show==2">
|
||||
<div style="display: flex;justify-content: flex-start;">
|
||||
<!--需求原型中没有按知识点选择
|
||||
<div>
|
||||
<el-select v-model="exam.type" style="width: 140px;" clearable placeholder="选择知识点">
|
||||
</el-select>
|
||||
</div>
|
||||
-->
|
||||
<div><el-input maxlength="50" placeholder="名称"></el-input></div>
|
||||
<div><el-input maxlength="50" placeholder="创建人"></el-input></div>
|
||||
<div style="padding-left: 10px;"><el-button type="primary" size="small">搜索已有考试</el-button></div>
|
||||
</div>
|
||||
<div>
|
||||
<div style="text-align: center;padding-top: 10px;">
|
||||
<el-table style="100%" :data="exam.findhas.list" border stripe>
|
||||
<el-table-column label="考试名称" prop="author"><template>考试名称</template></el-table-column>
|
||||
<el-table-column label="创建时间" prop="author">
|
||||
<template slot-scope="scope">
|
||||
2022-02-03
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建人" prop="content">
|
||||
<template>
|
||||
XXX
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="选择" width="80px">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click="changeExamShow(9)" type="primary" size="mini">选择</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--分页功能-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="exam.show==3">
|
||||
<div style="display: flex;justify-content: space-between;padding:5px 10px;line-height: 30px; border: 1px solid #e7e7e7;">
|
||||
<div>自定义考试</div>
|
||||
<div>
|
||||
<el-checkbox v-model="exam.onlyQuestion">只显示试题</el-checkbox>
|
||||
<el-button style="margin-left: 10px;" @click="changeExamShow(1)" type="info" size="mini" >重新选择</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding-top: 10px;overflow: auto;">
|
||||
<div v-if="!exam.onlyQuestion">
|
||||
<el-form size="mini" label-width="80px">
|
||||
<el-form-item label="考试名称">
|
||||
<el-input v-model="exam.info.name" placeholder="请输入名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="考试时长">
|
||||
<el-col :span="10">
|
||||
<el-input v-model="exam.info.passScore" placeholder="20-120">
|
||||
<template slot="append">分钟</template>
|
||||
</el-input>
|
||||
</el-col>
|
||||
<el-col :span="14">
|
||||
<el-form-item label="及格线">
|
||||
<el-input placeholder="20-100">
|
||||
<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.info.showJieXi">允许查看解析</el-checkbox>
|
||||
</el-col>
|
||||
<el-col :span="14">
|
||||
<el-checkbox v-model="exam.info.showAnswer">允许查看答案</el-checkbox>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="试题试卷">
|
||||
<el-col :span="10">
|
||||
<el-checkbox v-model="exam.info.randomType">随机试题</el-checkbox>
|
||||
</el-col>
|
||||
<el-col :span="14">
|
||||
<el-checkbox-group v-model="exam.info.qorder">
|
||||
<el-checkbox :label="1">题目乱序</el-checkbox>
|
||||
<el-checkbox :label="2">选项乱序</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="尝试次数">
|
||||
<el-col :span="10">
|
||||
<el-input placeholder="0代表不限制"></el-input>
|
||||
</el-col>
|
||||
<el-col :span="14">
|
||||
<el-form-item label="评分方式">
|
||||
<el-radio-group v-model="exam.info.randomType">
|
||||
<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>
|
||||
</div>
|
||||
<div style="padding: 10px;text-align: center;">
|
||||
<el-button type="primary">导入</el-button>
|
||||
<el-button type="primary">添加</el-button>
|
||||
<el-button @click="changeExamShow(9)" type="primary">提交</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-table :data="exam.info.questions" style="100%" border stripe>
|
||||
<el-table-column label="题干" prop="body">
|
||||
<template>试题11</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="设置得分" prop="score" width="80px">
|
||||
<template slot-scope="scope">10</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80px">
|
||||
<template slot-scope="scope">
|
||||
<el-button icon="el-icon-edit" type="text" size="mini"></el-button>
|
||||
<el-button icon="el-icon-close" type="text" size="mini"></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="exam.show==9">
|
||||
<div style="display: flex;justify-content: space-between;padding:5px 10px;line-height: 30px; border: 1px solid #e7e7e7;">
|
||||
<div>考试信息</div><div><el-button @click="changeExamShow(1)" type="info" size="mini" >重新设置考试</el-button> </div>
|
||||
</div>
|
||||
<div style="padding-top: 10px;">
|
||||
<el-form size="mini" label-width="80px">
|
||||
<el-form-item label="考试名称">XXXXXXXXXXXXXXX</el-form-item>
|
||||
<el-form-item label="考试时长">60分钟</el-form-item>
|
||||
<el-form-item label="显示解析">允许查看</el-form-item>
|
||||
<el-form-item label="显示答案">不允许查看</el-form-item>
|
||||
<el-form-item label="随机模式">是</el-form-item>
|
||||
<el-form-item label="尝试次数">不限制</el-form-item>
|
||||
<el-form-item label="试题排列">题目乱序</el-form-item>
|
||||
<el-form-item label="评分方式">最高一次</el-form-item>
|
||||
<el-form-item label="及格线">60%</el-form-item>
|
||||
<el-form-item label="">
|
||||
<el-button type="primary">编辑试卷</el-button>
|
||||
<el-button @click="exam.paperShow=true" type="primary">预览试卷</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="color: #ff0000;">只限于自定义考试,才会有编辑试卷</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog title="查看试卷" append-to-body :visible.sync="exam.paperShow" width="800px" custom-class="g-dialog">
|
||||
<div>
|
||||
<img :src="`${webBaseUrl}/temp/exampaper.png`">
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="exam.paperShow= false">关闭</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data(){
|
||||
return {
|
||||
exam:{
|
||||
show:1,
|
||||
paperShow:false,
|
||||
customerShow:false,
|
||||
has:false,
|
||||
onlyQuestion:false,
|
||||
info:{
|
||||
name:'',
|
||||
limitTimes:1,
|
||||
passScore:60,
|
||||
showJieXi:true,
|
||||
showAnswer:false,
|
||||
randomType:1,
|
||||
qorder:[],
|
||||
examTime:60,
|
||||
questions:[
|
||||
{body:'试题1',score:10},
|
||||
{body:'试题2',score:10}
|
||||
],
|
||||
|
||||
},
|
||||
findhas:{
|
||||
list:[{},{}]
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
changeExamShow(idx){
|
||||
this.exam.show=idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
1343
src/components/Course/courseForm.vue
Normal file
1343
src/components/Course/courseForm.vue
Normal file
File diff suppressed because it is too large
Load Diff
52
src/components/Course/courseHomework.vue
Normal file
52
src/components/Course/courseHomework.vue
Normal file
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form size="small" label-width="100px">
|
||||
<el-form-item label="名称">
|
||||
<el-input placeholder="作业的名称(限50字以内)" show-word-limit maxlength="50" v-model="homework.info.name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="内容">
|
||||
<el-input type="textarea" rows="5" v-model="homework.info.content" placeholder="内容换成富文编辑框(限255字以内)" show-word-limit maxlength="255"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="附件">
|
||||
<file-upload dir="files" :isShowTip="false" @success="uploadHomeworkFile" @remove="removeHomeworkFile"></file-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="截止时间">
|
||||
<el-date-picker v-model="homework.info.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.info.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>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data(){
|
||||
return {
|
||||
homework:{
|
||||
show:1,
|
||||
dtime:'',
|
||||
info:{
|
||||
answerType:'',
|
||||
name:'',
|
||||
content:'',
|
||||
files:''
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
changeHomeworkShow(idx){
|
||||
this.homework.show=idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
186
src/components/Course/courseImage.vue
Normal file
186
src/components/Course/courseImage.vue
Normal file
@@ -0,0 +1,186 @@
|
||||
<template>
|
||||
<!--用于显示课程的图片-->
|
||||
<div class="img-box" id="img-box">
|
||||
<el-image
|
||||
style="background-color: #eeeeee"
|
||||
:style="`width:${width};height:${height};`"
|
||||
fit="fill "
|
||||
:src="imageUrl"
|
||||
>
|
||||
<div slot="error" class="image-slot">
|
||||
<i class="el-icon-picture-outline"></i>
|
||||
</div>
|
||||
</el-image>
|
||||
<div v-if="isShow">
|
||||
<p v-if="imageTextSize == 4" class="te-max text effect06" v-html="name">
|
||||
</p>
|
||||
<p v-if="imageTextSize == 3" class="max text effect06" v-html="name">
|
||||
<!-- {{ course.name || course.courseName || course.title}} -->
|
||||
</p>
|
||||
<p v-if="imageTextSize == 2" class="mid text effect06" v-html="name">
|
||||
<!-- {{ course.name || course.courseName || course.title}} -->
|
||||
</p>
|
||||
<p v-if="imageTextSize == 1" class="mini text effect06" v-html="name">
|
||||
<!-- {{ course.name || course.courseName ||course.title }} -->
|
||||
</p>
|
||||
</div>
|
||||
<!-- <p :class="imageTextSize == 3? 'max':imageTextSize == 2?'mid':'mini'">{{course.name}}</p> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
course: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: "100%",
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: "100%",
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
name(){
|
||||
let name = '';
|
||||
if(this.course && this.course.name && this.course.name !== '') {
|
||||
name = this.course.name.replace('color:#FF0000','color:#fff');
|
||||
}
|
||||
if(this.course && this.course.courseName && this.course.courseName !== '') {
|
||||
name = this.course.courseName.replace('color:#FF0000','color:#fff');
|
||||
}
|
||||
if(this.course && this.course.title && this.course.title !== '') {
|
||||
name = this.course.title.replace('color:#FF0000','color:#fff');
|
||||
}
|
||||
return name;
|
||||
// course.name || course.courseName || course.title
|
||||
},
|
||||
imageUrl() {
|
||||
this.isShow = false;
|
||||
if(this.course && this.course.coverImg && this.course.coverImg.startsWith('h')) {
|
||||
return this.course.coverImg;
|
||||
}
|
||||
if(this.course && this.course.courseImage && this.course.courseImage.startsWith('h')) {
|
||||
return this.course.courseImage;
|
||||
}
|
||||
if (this.course && this.course.coverImg && this.course.coverImg != "") {
|
||||
return this.fileBaseUrl + this.course.coverImg;
|
||||
} else if (
|
||||
this.course &&
|
||||
this.course.courseImage &&
|
||||
this.course.courseImage != ""
|
||||
) {
|
||||
return this.fileBaseUrl + this.course.courseImage;
|
||||
} else if (
|
||||
this.course &&
|
||||
this.course.image &&
|
||||
this.course.image != ""
|
||||
) {
|
||||
return this.fileBaseUrl + this.course.image;
|
||||
}
|
||||
else if (this.course.coverImg == "" || this.course.courseImage == "" || this.course.image == "") {
|
||||
this.isShow = true;
|
||||
return this.webBaseUrl + "/images/bgimg/course.png";
|
||||
}
|
||||
// else if(this.course.coverImg.startsWith('h')) {
|
||||
// return this.course.coverImg;
|
||||
// }else if(this.course.courseImage.startsWith('h')){
|
||||
// return this.course.courseImage;
|
||||
// }
|
||||
// }
|
||||
|
||||
return '';
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
imageText: "", //图片上面的文字
|
||||
fileBaseUrl: process.env.VUE_APP_FILE_BASE_URL,
|
||||
isShow: false,
|
||||
imageTextSize: false,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
let obj = document.getElementById("img-box");
|
||||
if ((obj.offsetWidth > 500 || obj.offsetWidth == 500) && obj.offsetWidth < 900) {
|
||||
this.imageTextSize = 3;
|
||||
} else if (obj.offsetWidth > 200 && obj.offsetWidth < 500) {
|
||||
this.imageTextSize = 2;
|
||||
} else if (obj.offsetWidth > 900) {
|
||||
this.imageTextSize = 4;
|
||||
} else {
|
||||
this.imageTextSize = 1;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
imageError() {},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.text {
|
||||
text-shadow: 0px 0px 2px #ffffff;
|
||||
span{
|
||||
color: #ffffff !important;
|
||||
}
|
||||
}
|
||||
.image-slot{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.img-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
p {
|
||||
display: -webkit-box;
|
||||
// white-space:pre-wrap;
|
||||
overflow: hidden;
|
||||
// text-overflow:ellipsis;
|
||||
word-break:break-all;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
color: #ffffff;
|
||||
position: absolute;
|
||||
padding-right: 10px;
|
||||
}
|
||||
.mini {
|
||||
top: 30%;
|
||||
left: 8%;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
.mid {
|
||||
top: 30%;
|
||||
left: 8%;
|
||||
font-size: 20px;
|
||||
line-height: 35px;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
.max {
|
||||
top: 30%;
|
||||
left: 8%;
|
||||
font-size: 24px;
|
||||
line-height: 40px;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
.te-max {
|
||||
top: 30%;
|
||||
left: 8%;
|
||||
font-size: 20px;
|
||||
line-height: 35px;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
144
src/components/Course/editBaseInfo.vue
Normal file
144
src/components/Course/editBaseInfo.vue
Normal file
@@ -0,0 +1,144 @@
|
||||
<template><!--编辑基本信息-->
|
||||
<div>
|
||||
<div style="height: 30px; border-bottom: 1px solid #f3f3f3;margin-bottom: 10px;">
|
||||
<span>基本信息</span>
|
||||
<span style="padding-left: 50px;"><el-checkbox v-model="onlyRequired">只显示必填项</el-checkbox></span>
|
||||
</div>
|
||||
<el-form label-width="120px" size="mini">
|
||||
<el-form-item label="名称" required><el-input maxlength="100" v-model="course.name" placeholder="课程名称(限100字以内)"></el-input></el-form-item>
|
||||
<!--不显示,因为标题已经代表了 <el-form-item label="授课方式">{{courseTypeMap(params.type)}}</el-form-item>-->
|
||||
<el-form-item label="封面图片" required >
|
||||
<el-col :span="8">
|
||||
<imageUpload :value="courseCoverurl" @success="uploadCoverImgSuccess" @remove="removeCoverImgSuccess"></imageUpload>
|
||||
<div>上传为16:9(如:800*450)的png或jpg图片</div>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<el-form-item label="内容分类" required>
|
||||
<el-select v-model="course.sysType" style="width: 90%;">
|
||||
<el-option v-for="item in sysTypeList" :key="item.id" :label="item.name" :value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="资源归属" required>
|
||||
<el-cascader placeholder="选择资源归属" style="width: 90%;" clearable v-model="resOwnerValues" :props="defaultProps" :options="resOwnerList"></el-cascader>
|
||||
</el-form-item>
|
||||
<el-form-item label="场景" required>
|
||||
<el-select v-model="course.forScene" style="width: 90%;">
|
||||
<el-option v-for="item in sceneList" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="授课教师" required ><!--授课老师默认是当前操作人-->
|
||||
<el-select style="width: 90%;"
|
||||
v-model="teacherValues"
|
||||
multiple
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
placeholder="请输入授课教师姓名"
|
||||
:remote-method="loadRemoteTeachers"
|
||||
:loading="loading">
|
||||
<el-option v-for="item in teacherList" :key="item.id" :label="item.name" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="目标人群" v-if="!onlyRequired">
|
||||
<el-input maxlength="50" v-model="course.forUsers" placeholder="目标人群(限50字以内)"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="课程价值" v-if="!onlyRequired"><el-input maxlength="200" v-model="course.value" placeholder="课程价值(限200字以内)"></el-input></el-form-item>
|
||||
<el-form-item label="系统标签" v-if="!onlyRequired">
|
||||
<el-col :span="14">
|
||||
<el-select style="width: 100%;"
|
||||
v-model="showTags"
|
||||
multiple
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
placeholder="请输入关键词"
|
||||
:remote-method="remoteTagMethod"
|
||||
:loading="loading">
|
||||
<el-option v-for="item in tagList" :key="item.id" :label="item.name" :value="item.id"> </el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-form-item v-if="!onlyRequired" label="关键字"><el-input v-model="course.keywords" maxlength="50" placeholder="关键字(限100字以内)"></el-input></el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="!onlyRequired" label="观看设置">
|
||||
<el-col :span="14">
|
||||
<el-radio v-model="course.device" :label="1">PC端可见</el-radio>
|
||||
<el-radio v-model="course.device" :label="2">移动端可见</el-radio>
|
||||
<el-radio v-model="course.device" :label="3">多端可见</el-radio>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-form-item v-if="!onlyRequired" label="课程来源">
|
||||
<el-radio-group v-model="course.source" >
|
||||
<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="完成规则" v-if="!onlyRequired"><el-input maxlength="50" v-model="params.forScene" placeholder="可基于组织树或受众选择"></el-input></el-form-item> -->
|
||||
<el-form-item label="开放权限" v-if="!onlyRequired"><el-input maxlength="50" v-model="course.openObject" placeholder="可基于组织树或受众选择"></el-input></el-form-item>
|
||||
<el-form-item v-if="!onlyRequired" label="课程简介">
|
||||
<el-input type="textarea" :rows="3" v-model="course.overview" placeholder="课程介绍,要换成富文本编辑器"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
course:{
|
||||
type:Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
//绑定变量
|
||||
onlyRequired:false,
|
||||
tagValues:[],
|
||||
teacherValues:[],
|
||||
resOwnerValues:[],
|
||||
sysTypeValues:[],
|
||||
loading:false,
|
||||
//使用数据
|
||||
teacherList:[],
|
||||
resOwnerList:[],
|
||||
sysTypeList:[],
|
||||
sceneList:[]
|
||||
}
|
||||
}
|
||||
methods:{
|
||||
async loadRemoteTeachers(query) {
|
||||
if(query) {
|
||||
this.loading = true;
|
||||
try {
|
||||
const {result, status} = await apiTeacher.findByName(query);
|
||||
if(status === 200) {
|
||||
|
||||
result.forEach((item) => {
|
||||
item.value = item.id + ' ' +item.name
|
||||
});
|
||||
this.teacherList = result;
|
||||
this.loading = false;
|
||||
}
|
||||
} catch (error) {
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
this.teacherList = [];
|
||||
}
|
||||
},
|
||||
loadRemoteTags(query){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
549
src/components/Course/exam.vue
Normal file
549
src/components/Course/exam.vue
Normal file
@@ -0,0 +1,549 @@
|
||||
<template>
|
||||
<div class="exam-index">
|
||||
<div v-if="has" class="test-div">
|
||||
<div v-if="!testStart">
|
||||
<div>
|
||||
<div class="test-info" v-if="content.contentName!=''">名称:{{content.contentName}}</div>
|
||||
<div class="test-info">
|
||||
<span >考试时长:{{info.testDuration}}分钟</span>
|
||||
<span style="margin-left: 20px;">及格线:{{info.passLine}}</span>
|
||||
<span v-if="records.length>0" style="margin-left: 20px;font-size: 18px;">您的考试成绩:{{examScore}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 预览用显示试题 -->
|
||||
<div v-if="showTest">
|
||||
<div style="margin: 10px 0;">考试试题:</div>
|
||||
<div v-for="(item,index) in viewTest" :key="index">
|
||||
<div class="test-info">{{index +1}}.【{{getTypeName(item.type)}}】{{item.content}}</div>
|
||||
<div class="test-info" style="padding-left: 20px;">
|
||||
<div v-if="item.type==101 || item.type==103">
|
||||
<el-radio-group v-model="item.userAnswer" size="medium">
|
||||
<el-radio v-for="(opt,optIdx) in item.options" :key="optIdx" :label="opt.id">{{toLetter(optIdx+1)}}.{{opt.content}}</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div v-if="item.type==102">
|
||||
<el-checkbox v-for="(it,indcc) in item.options" :key="indcc" v-model="it.isCheck" :label="it.id">{{toLetter(indcc+1)}}.{{it.content}}</el-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--开始考试button-->
|
||||
<div v-if="showSubmit" style="text-align: center; margin-bottom: 15px">
|
||||
<el-button type="primary" @click="startTest()">开始考试</el-button>
|
||||
</div>
|
||||
<!--考试记录-->
|
||||
<div v-if="showRecord">
|
||||
<el-table :data="records" style="width: 100%" border>
|
||||
<el-table-column prop="lastTime" label="完成时间" align="center" ></el-table-column>
|
||||
<el-table-column prop="testDuration" label="用时" align="center">
|
||||
<template slot-scope="scope">{{formatSeconds(scope.row.testDuration)}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="score" label="成绩" align="center"></el-table-column>
|
||||
<el-table-column label="操作" width="100" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click="showExamAnswer(scope.row)" type="text" >查看试卷</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-else>
|
||||
<!--考试部分-->
|
||||
<div>
|
||||
<div style="display: flex;justify-content: space-between;padding: 10px 0px;">
|
||||
<div style="font-size: 18px;">第{{curIndex+1}}题 / 共{{total}}题</div>
|
||||
<div style="font-size: 20px;"><span style="font-size: 40upx;" :class="{'redText':timerValue<5}">{{timerValue}}</span> 分钟</div>
|
||||
</div>
|
||||
<div class="qitem">
|
||||
<div class="qitem-info">【{{getTypeName(curItem.type)}}】{{curItem.content}}</div>
|
||||
<div v-for="(opt,optIdx) in curItem.options" :key="optIdx">
|
||||
<div class="qitem-opts">
|
||||
<div class="qitem-opt" :class="{check:opt.checked}" @click="chooseOption(opt)">
|
||||
{{toLetter(optIdx+1)}}.{{opt.content}}
|
||||
<i class="el-icon-check" v-if="opt.checked" name="checkbox-mark" color="#00aa00"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="text-align: center; margin-bottom: 15px">
|
||||
<el-button :disabled="curIndex==0" type="primary" @click="prevSub()">上一题</el-button>
|
||||
<el-button type="success" icon="el-icon-check" @click="present()">提 交</el-button>
|
||||
<el-button :disabled="curIndex>=(total-1)" type="primary" @click="nextSub()">下一题</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else style="text-align: center;padding-top: 20px;color: red;">此课程无考试内容</div>
|
||||
|
||||
<el-dialog :visible.sync="detailShow" title="查询答卷详细信息" width="800px" custom-class="g-dialog">
|
||||
<div style="text-align: left;" class="upaper">
|
||||
<!--答卷信息-->
|
||||
<div v-for="(ditem,didx) in detailItems" :key="didx" class="upaper-item">
|
||||
<div class="upaper-item-q">{{didx +1}}.【{{getTypeName(ditem.type)}}】{{ditem.content}}</div>
|
||||
<div class="upaper-item-opts" style="padding-left: 20px;">
|
||||
<div v-for="(opt,optIdx) in ditem.options" :key="optIdx" class="upaper-item-opt" :class="{'upaper-item-opt-user':ditem.userOptIdxs.indexOf(optIdx)>-1}">
|
||||
<div>
|
||||
<div>{{toLetter(optIdx+1)}}, {{opt.content}}</div>
|
||||
</div>
|
||||
<div>
|
||||
<span v-if="ditem.userOptIdxs.indexOf(optIdx)>-1 && ditem.correctOptIdxs.indexOf(optIdx)>-1" style="color: #00aa00;font-size: 25px; ">√</span>
|
||||
<span v-if="ditem.userOptIdxs.indexOf(optIdx)>-1 && ditem.correctOptIdxs.indexOf(optIdx)==-1" style="color: #ff0000;font-size: 25px; ">×</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="upaper-item-answer" style="display: flex;">
|
||||
<div class="upaper-item-answer-cell">
|
||||
<span v-if="ditem.result" style="color: #00aa00; ">回答正确</span>
|
||||
<span v-else style="color: #ff0000; ">回答错误</span>
|
||||
</div>
|
||||
<div class="upaper-item-answer-cell">
|
||||
<span class="response-tit">正确答案:</span>
|
||||
<span v-for="op in ditem.correctOptIdxs" :key="op">{{toLetter(op+1)}}</span>
|
||||
</div>
|
||||
<div class="upaper-item-answer-cell">
|
||||
<span class="response-tit">我的答案:</span>
|
||||
<span v-for="op in ditem.userOptIdxs" :key="op">{{toLetter(op+1)}}</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="detailShow = false">关 闭</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import apiStudy from '@/api/modules/courseStudy.js';
|
||||
import apiCourse from '@/api/modules/course.js';
|
||||
import {formatDate,formatSeconds} from '@/utils/datetime.js';
|
||||
import {testType,correctJudgment,numberToLetter} from '@/utils/tools.js';
|
||||
export default {
|
||||
props:{
|
||||
studyId: {
|
||||
type: String,
|
||||
},
|
||||
showRecord:{
|
||||
type:Boolean,
|
||||
default:true
|
||||
},
|
||||
showSubmit:{
|
||||
type:Boolean,
|
||||
default:true
|
||||
},
|
||||
content: {
|
||||
type: Object,
|
||||
default:()=>{}
|
||||
},
|
||||
showTest:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
viewTest:[],
|
||||
correctJudgment:correctJudgment,
|
||||
toLetter:numberToLetter,
|
||||
formatSeconds:formatSeconds,
|
||||
examScore:0,//考试得分
|
||||
show:0,
|
||||
getTypeName:testType,
|
||||
has:true,
|
||||
startTime:null,//开始考试的时间,可以去掉
|
||||
testStart: false,//是否开始考试
|
||||
info:{},//考试信息
|
||||
paper:[],//试卷信息
|
||||
studyItemId:'',
|
||||
total:0,//总试题的数量
|
||||
curIndex:0,//当前视频的索引
|
||||
curItem:{},//当前试题
|
||||
timer:null,//用于计算倒计时控制
|
||||
lastScore:0,//最终得分,用于考试试卷记录
|
||||
timerValue:0,//当前倒计时的值
|
||||
noAnswers:[], //有未答完的试题
|
||||
records:[] ,//考试记录
|
||||
allowSubmit:true,//是否允许考试,尝试次数达到后不能再考试,暂时未使用
|
||||
detailShow:false,
|
||||
detailItems:[]
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.loadExamInfo();
|
||||
},
|
||||
watch:{
|
||||
content(newVal){
|
||||
this.loadExamInfo();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changeTimer(){
|
||||
if(this.timerValue==0){
|
||||
window.clearInterval(this.timer);
|
||||
//系统自动提交
|
||||
this.confirmStop();
|
||||
}else{
|
||||
this.timerValue--;
|
||||
}
|
||||
|
||||
},
|
||||
loadExamInfo(){
|
||||
apiCourse.getExam(this.content.id).then(res=>{
|
||||
if(res.status==200){
|
||||
this.info=res.result;
|
||||
if(this.showTest) {
|
||||
let paper= JSON.parse(this.info.paperContent);
|
||||
paper.items.forEach(item=>{
|
||||
//console.log(item);
|
||||
if(item.type==101){
|
||||
item.userAnswer='';
|
||||
}else if(item.type==102){
|
||||
item.userAnswer=[];
|
||||
}else{
|
||||
item.userAnswer=''
|
||||
}
|
||||
item.options.forEach(opt=>{
|
||||
opt.checked=false;
|
||||
})
|
||||
});
|
||||
this.total=paper.items.length;
|
||||
this.paper =paper;
|
||||
//console.log(this.paper);
|
||||
|
||||
|
||||
this.viewTest =paper.items;
|
||||
}
|
||||
if(!this.showTest && this.showRecord){
|
||||
this.loadStudyItemId();
|
||||
this.loadRecord();
|
||||
}
|
||||
}else if(res.status==404){
|
||||
//没有找到考试信息
|
||||
}else{
|
||||
this.$message.error(res.message);
|
||||
}
|
||||
})
|
||||
},
|
||||
loadStudyItemId(){
|
||||
//获取studyItemId;
|
||||
apiStudy.getStudyContentItem(this.studyId,this.info.contentId).then(rs=>{
|
||||
if(rs.status==200){
|
||||
this.examScore=rs.result.score;
|
||||
this.studyItemId=rs.result.id;
|
||||
}
|
||||
})
|
||||
},
|
||||
loadRecord(){
|
||||
if(this.records.length==0){
|
||||
let params={
|
||||
studyId:this.studyId,
|
||||
contentId:this.content.id
|
||||
}
|
||||
apiStudy.myExamList2(params).then(examRs=>{
|
||||
if(examRs.status==200){
|
||||
this.records=examRs.result;
|
||||
let len=examRs.result.length;
|
||||
if(this.info.times>len){
|
||||
this.allowSubmit=true;
|
||||
}else{
|
||||
this.allowSubmit=false;
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
startTest(){
|
||||
let paper= JSON.parse(this.info.paperContent);
|
||||
paper.items.forEach(item=>{
|
||||
//console.log(item);
|
||||
if(item.type==101){
|
||||
item.userAnswer='';
|
||||
}else if(item.type==102){
|
||||
item.userAnswer=[];
|
||||
}else{
|
||||
item.userAnswer=''
|
||||
}
|
||||
item.options.forEach(opt=>{
|
||||
opt.checked=false;
|
||||
})
|
||||
});
|
||||
this.total=paper.items.length;
|
||||
this.paper =paper;
|
||||
//console.log(this.paper);
|
||||
this.curItem=paper.items[this.curIndex];
|
||||
this.startTime=new Date();//记录开始时间
|
||||
this.timerValue=this.info.testDuration;
|
||||
this.timer=setInterval(this.changeTimer,60000);
|
||||
this.testStart=true;
|
||||
},
|
||||
chooseOption(opt){
|
||||
if(this.curItem.type==101 || this.curItem.type==103){
|
||||
this.curItem.options.forEach(op=>{
|
||||
op.checked=false;
|
||||
})
|
||||
opt.checked=true;
|
||||
}else{
|
||||
if(opt.checked){
|
||||
opt.checked=false;
|
||||
}else{
|
||||
opt.checked=true;
|
||||
}
|
||||
}
|
||||
},
|
||||
confirmStop(){
|
||||
this.$alert('考试时间已到,点击确定提交试卷', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
showClose:false,
|
||||
callback: action => {
|
||||
this.submitTest();
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
prevSub(){ //上一题
|
||||
if(this.curIndex==0){
|
||||
return;
|
||||
}
|
||||
this.curIndex--;
|
||||
if(this.curIndex>-1){
|
||||
this.curItem=this.paper.items[this.curIndex];
|
||||
}
|
||||
},
|
||||
nextSub() { //下一题
|
||||
if(this.curIndex>=(this.total-1)){
|
||||
return;
|
||||
}
|
||||
this.curIndex++;
|
||||
this.curItem=this.paper.items[this.curIndex];
|
||||
},
|
||||
present(){ //提交前处理
|
||||
let $this=this;
|
||||
let score=this.countTest();
|
||||
|
||||
if(this.noAnswers.length>0){
|
||||
this.$confirm('还有未答试题,您确定要提交吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
showClose:false,
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.submitTest()
|
||||
}).catch(()=>{
|
||||
|
||||
})
|
||||
}else{
|
||||
this.submitTest()
|
||||
}
|
||||
},
|
||||
countTest(){ //计算考试的分数
|
||||
//console.log(this.paper.items);
|
||||
let totalScore=0;
|
||||
this.paper.items.forEach(item => {
|
||||
totalScore+=item.score;//加到总分中
|
||||
if(item.type != 102){
|
||||
item.userAnswer='';
|
||||
item.options.forEach(opt => {
|
||||
if(opt.checked){
|
||||
item.userAnswer=opt.id;
|
||||
}
|
||||
});
|
||||
}else{
|
||||
item.userAnswer=[];
|
||||
item.options.forEach(opt => {
|
||||
if(opt.checked){
|
||||
item.userAnswer.push(opt.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
let scoreNum = 0;//用户得分
|
||||
let noAnswers=[];//是否都已答
|
||||
this.paper.items.forEach((item,idx) => {
|
||||
if(item.type != 102){
|
||||
if(item.userAnswer==''){
|
||||
noAnswers.push(idx+1);
|
||||
}
|
||||
item.options.forEach(it => {
|
||||
if(it.answer && item.userAnswer == it.id) {
|
||||
scoreNum+=item.score
|
||||
}
|
||||
})
|
||||
}else{
|
||||
if(item.userAnswer.length==0){
|
||||
noAnswers.push(idx+1);
|
||||
}
|
||||
let allRight = true;
|
||||
item.options.forEach(it =>{
|
||||
if(it.answer && item.userAnswer.indexOf(it.id)==-1) {
|
||||
allRight=false;
|
||||
}
|
||||
});
|
||||
if(allRight){
|
||||
scoreNum+=item.score;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
this.noAnswers=noAnswers;
|
||||
if(scoreNum === null)scoreNum=0;
|
||||
this.lastScore=scoreNum;
|
||||
//转化成百分制显示
|
||||
if(this.info.percentScore){
|
||||
this.lastScore=parseInt(scoreNum*100/totalScore);
|
||||
}
|
||||
return this.lastScore;
|
||||
},
|
||||
submitTest(){ //提交处理
|
||||
let now=new Date();
|
||||
let testScore=this.countTest();
|
||||
let postData={
|
||||
studyId:this.studyId,//
|
||||
studyItemId:this.studyItemId,//前面已经给了
|
||||
courseId:this.content.courseId,
|
||||
contentId:this.content.id,
|
||||
testId:this.info.id,
|
||||
testName:''+this.content.contentName,//应该是课程的名称 + 内容的名称
|
||||
testDuration:0,
|
||||
arrange:this.info.arrange,
|
||||
passLine:this.info.passLine,
|
||||
randomMode:this.info.randomMode,
|
||||
score:this.lastScore,//分数需要计算,在检查是否填写完整性时就可以计算出分数
|
||||
paperJson:JSON.stringify(this.paper),//原来是对象,这里要也要对象
|
||||
//startTime:formatDate(this.startTime),//此时间需要格式化,格式化时间可以放在util中
|
||||
//endTime:formatDate(now),
|
||||
}
|
||||
//计划考试的时长
|
||||
var dateDiff = now.getTime() - this.startTime.getTime();//时间差的毫秒数
|
||||
var minutes=Math.floor(dateDiff/(1000))//计算相差秒数,分钟记录的太大,经常为0
|
||||
postData.testDuration=minutes;
|
||||
|
||||
apiStudy.saveExam(postData).then(res=>{
|
||||
if(res.status == 200) {
|
||||
this.records.push(res.result);
|
||||
this.content.status=9;//表已学习完,判断上级的章是否已完成
|
||||
this.studyItemId=res.result.studyItemId;//第一次保存时是没有的,所以这里要赋值
|
||||
this.$alert('您本次考试得分:'+this.lastScore, '考试成绩', {
|
||||
confirmButtonText: '确定',
|
||||
callback: action => {
|
||||
this.testStart = false;
|
||||
}
|
||||
});
|
||||
this.testStart = false;
|
||||
this.$emit('submit',this.lastScore);//考试提交回调处理
|
||||
} else {
|
||||
this.$message.error(res.message);
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
showExamAnswer(item){
|
||||
//显示试卷的答卷信息
|
||||
this.detailShow=true;
|
||||
apiStudy.myExamPaper(item.id).then(rs=>{
|
||||
if(rs.status==200){
|
||||
let items=JSON.parse(rs.result.paper).items
|
||||
items.forEach((item)=>{
|
||||
item.correctOptIdxs=[];
|
||||
item.userOptIdxs=[];
|
||||
item.result=true;
|
||||
//对答案进行判断
|
||||
item.options.forEach((opt,idx)=>{
|
||||
//填充正确答案
|
||||
if(opt.answer){
|
||||
item.correctOptIdxs.push(idx);
|
||||
}
|
||||
if(item.type!=102){ //单选或判断
|
||||
if(opt.id==item.userAnswer){
|
||||
item.userOptIdxs.push(idx);
|
||||
}
|
||||
}else{ //多选
|
||||
if(item.userAnswer.indexOf(opt.id)>-1){
|
||||
item.userOptIdxs.push(idx);
|
||||
}
|
||||
}
|
||||
});
|
||||
//判断答案是否正确
|
||||
if(item.correctOptIdxs.toString()==item.userOptIdxs.toString()){
|
||||
item.result=true;
|
||||
}else{
|
||||
item.result=false;
|
||||
}
|
||||
});
|
||||
this.detailItems=items;
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.qitem {
|
||||
padding: 10px 20px;
|
||||
.qitem-info {
|
||||
font-size: 1.2em;
|
||||
padding: 10px 0px;
|
||||
}
|
||||
.qitem-opts {
|
||||
padding: 5px 0px;
|
||||
.qitem-opt {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
padding: 10px 15px;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.check{
|
||||
color:#00aa00;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.upaper{
|
||||
text-align: left;
|
||||
.upaper-item{
|
||||
border-bottom: 1px solid #dadada;
|
||||
padding: 10px;
|
||||
.upaper-item-q{
|
||||
padding: 8px 0px;
|
||||
}
|
||||
.upaper-item-opts{
|
||||
padding: 8px 0px;
|
||||
line-height: 20px;
|
||||
.upaper-item-opt{
|
||||
min-height: 50px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
background-color: #FFFFFF;
|
||||
justify-content: space-between;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
.upaper-item-opt-user{
|
||||
background-color: #fff3e5;
|
||||
}
|
||||
}
|
||||
.upaper-item-answer{
|
||||
display: flex;
|
||||
.upaper-item-answer-cell{
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.test-div {
|
||||
border: 1px solid #dadada;
|
||||
min-height: 500px;
|
||||
padding: 20px;
|
||||
font-size: 14px;
|
||||
text-align: left;
|
||||
.test-info {
|
||||
text-align: left;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
229
src/components/Course/homework.vue
Normal file
229
src/components/Course/homework.vue
Normal file
@@ -0,0 +1,229 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="has" class="homework-div">
|
||||
<div>
|
||||
<div class="homework-title">作业名称</div>
|
||||
<div class="homework-content">{{info.name}}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="homework-title">内容</div>
|
||||
<div class="homework-content">{{info.content}}</div>
|
||||
</div>
|
||||
<div v-if="info.file">
|
||||
<div class="homework-title">附件</div>
|
||||
<div class="homework-content" style="color: blue">
|
||||
<a :href="fileBaseUrl+info.file" target="_blank">下载作业附件</a></div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="homework-title">截止时间</div>
|
||||
<div class="homework-content" :style="{color:close? 'red':''}">{{info.deadTime}}</div>
|
||||
</div>
|
||||
<div v-show="!close && showSubmit">
|
||||
<div v-if="info.submitMode>1">
|
||||
<div class="homework-title">作业内容</div>
|
||||
<div class="homework-content">
|
||||
<el-input type="textarea" rows="5" show-word-limit maxlength="255" v-model="answer" placeholder="(限255个字)"></el-input>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="info.submitMode==1 || info.submitMode==3">
|
||||
<div class="homework-title">上传作业</div>
|
||||
<div class="homework-content">
|
||||
<div v-if="filePath!=''">
|
||||
<el-tag closable type="success" @close="removeHomeworkFile">作业附件</el-tag><span style="margin-left: 10px;">请点击下面的提交</span>
|
||||
</div>
|
||||
<div v-else >
|
||||
<file-upload dir="files" :isShowTip="false" @success="uploadHomeworkFile" @remove="removeHomeworkFile"></file-upload>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="text-align: center;padding-bottom: 10px;">
|
||||
<el-button type="primary" @click="submitHomework()">{{records.length>0?'重新提交':'提交'}}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="showRecord"><!--作业提交记录-->
|
||||
<el-table :data="records" style="width: 100%" border>
|
||||
<el-table-column prop="endTime" label="提交时间" width="100" align="center"></el-table-column>
|
||||
<el-table-column label="内容">
|
||||
<template slot-scope="scope">
|
||||
<div>{{scope.row.hwAnswer}}</div>
|
||||
<div style="padding-top: 5px;" v-if="scope.row.filePath!=''">
|
||||
<a :href="fileBaseUrl+scope.row.filePath" target="_blank">下载上传的作业文件</a>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else style="text-align: center;padding-top: 20px;color: red;">此课程无作业</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import apiCourseStudy from '@/api/modules/courseStudy.js';
|
||||
import apiCourse from '@/api/modules/course.js';
|
||||
import FileUpload from '@/components/FileUpload/index.vue';
|
||||
export default {
|
||||
components: { FileUpload },
|
||||
props:{
|
||||
studyId: {
|
||||
type: String,
|
||||
},
|
||||
showRecord:{
|
||||
type:Boolean,
|
||||
default:true
|
||||
},
|
||||
showSubmit:{
|
||||
type:Boolean,
|
||||
default:true
|
||||
},
|
||||
content: {
|
||||
type: Object,
|
||||
default:()=>{}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fileBaseUrl:process.env.VUE_APP_FILE_BASE_URL,
|
||||
has:true,
|
||||
info:{},
|
||||
studyItemId:'',
|
||||
filePath:'',
|
||||
answer:'',
|
||||
close:false,
|
||||
records:[],//作业记录
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.loadHomeworkInfo();
|
||||
},
|
||||
watch:{
|
||||
content(newVal){
|
||||
this.loadHomeworkInfo();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadHomeworkInfo(){
|
||||
apiCourse.getHomework(this.content.id).then(res=>{
|
||||
if(res.status==200){
|
||||
this.info=res.result;
|
||||
//检查是否过期
|
||||
if(res.result.deadTime!=''){
|
||||
var d = new Date(res.result.deadTime);
|
||||
var now=new Date();
|
||||
if(now.getTime() > d.getTime()){
|
||||
this.close=true;
|
||||
} else {
|
||||
this.close=false;
|
||||
}
|
||||
}
|
||||
if(!this.showTest && this.showRecord){
|
||||
this.loadRecord();
|
||||
}
|
||||
}else if(res.status==404){
|
||||
//没有找到作业信息
|
||||
}else{
|
||||
this.$message.error(res.message);
|
||||
}
|
||||
});
|
||||
//
|
||||
},
|
||||
loadRecord(){
|
||||
let params={
|
||||
studyId:this.studyId,
|
||||
contentId:this.content.id
|
||||
}
|
||||
apiCourseStudy.myHomeworkList(params).then(rs=>{
|
||||
if(rs.status==200){
|
||||
this.records=rs.result;
|
||||
}
|
||||
})
|
||||
},
|
||||
//作业上传
|
||||
uploadHomeworkFile(res) {
|
||||
this.filePath = res.result.filePath;
|
||||
},
|
||||
removeHomeworkFile(){
|
||||
this.$confirm('您确定要删除已上传的附件吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.filePath='';
|
||||
//从服务器端删除
|
||||
this.$message({ type: 'success', message: '删除成功!' });
|
||||
})
|
||||
|
||||
},
|
||||
submitHomework() {//提交作业
|
||||
if(this.content.submitMode==1){
|
||||
if(this.filePath==''){
|
||||
this.$message.error('请上传作业内容');
|
||||
return;
|
||||
}
|
||||
}else if(this.content.submitMode==2){
|
||||
if(this.answer==''){
|
||||
this.$message.error('请先填写作业内容');
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
if(this.answer=='' && this.filePath==''){
|
||||
this.$message.error('请填写或上传作业');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let pamars = {
|
||||
studyItemId: this.studyItemId,//学习内容记录id,
|
||||
studyId: this.studyId,//学习id,
|
||||
courseId: this.content.courseId,//课程id,
|
||||
contentId: this.content.id,//内容id,
|
||||
hwId:this.info.id,//作业的id
|
||||
hwName: this.info.name,//作业的名称
|
||||
//hwContent: this.homeworkInfo.info.content,//作业的内容,先不要此字段了
|
||||
filePath: this.filePath,//文件的路径,可以为空,
|
||||
hwAnswer: this.answer,//文本提交的信息
|
||||
score: 0
|
||||
}
|
||||
apiCourseStudy.saveHomework(pamars).then(res=>{
|
||||
if(res.status==200){
|
||||
this.$message.success("作业已提交");
|
||||
this.filePath='';
|
||||
this.answer='';
|
||||
this.studyItemId=res.result.id;
|
||||
this.records=[res.result];
|
||||
this.$emit("submit", this.content);
|
||||
}else {
|
||||
this.$message.error(res.message);
|
||||
}
|
||||
|
||||
})
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.homework-div {
|
||||
border: 1px solid #dadada;
|
||||
min-height: 500px;
|
||||
padding: 20px;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
>div{
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
.homework-title {
|
||||
margin-bottom: 10px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.homework-content {
|
||||
color: #666;
|
||||
margin-bottom: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
73
src/components/Course/hyperLink.vue
Normal file
73
src/components/Course/hyperLink.vue
Normal file
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<div class="hyper-index">
|
||||
<div>
|
||||
<!-- <div class="hyper-link" v-if="!showiframe">
|
||||
<div class="hyper-link-row">{{content.contentName}}</div>
|
||||
<div class="hyper-link-row">{{content.content}}</div>
|
||||
<div class="hyper-link-row">
|
||||
<el-button @click="showiframe = true" type="warning">本页面打开</el-button>
|
||||
<el-button @click="widthOpen(content.content)" type="primary">新窗口打开</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showiframe">
|
||||
<iframe :src="content.content" style="width: 100%;border:0px;min-height: 473px;" frameborder="0"></iframe>
|
||||
</div> -->
|
||||
<div class="hyper-link" v-if="conLink.openType==2">
|
||||
<div class="hyper-link-row">{{content.contentName}}</div>
|
||||
<div class="hyper-link-row">{{conLink.url}}</div>
|
||||
</div>
|
||||
<div v-if="conLink.openType==1">
|
||||
<iframe :src="conLink.url" style="width: 100%;border:0px;min-height: 473px;" frameborder="0"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import apiStudy from '@/api/modules/courseStudy.js';
|
||||
import apiCourse from '@/api/modules/course.js';
|
||||
import {formatDate,formatSeconds} from '@/utils/datetime.js';
|
||||
import {testType,correctJudgment,numberToLetter} from '@/utils/tools.js';
|
||||
export default {
|
||||
props:{
|
||||
content: {
|
||||
type: Object,
|
||||
default:()=>{}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showiframe:false,
|
||||
conLink:{openType:1,url:''},//对于超连接的内容
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.content,'content');
|
||||
if(this.content.content.startsWith('\{')){
|
||||
this.conLink=JSON.parse(this.content.content);
|
||||
}else{
|
||||
this.conLink.url=this.content.content;
|
||||
this.conLink.openType=1;
|
||||
}
|
||||
if(this.conLink.openType==2){
|
||||
//直接设置完成状态
|
||||
this.widthOpen(this.conLink.url);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
widthOpen(url) {
|
||||
window.open(this.webBaseUrl+url,'_blank');
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.hyper-link{
|
||||
padding-left:20px;
|
||||
text-align: center;
|
||||
padding-top: 100px;
|
||||
.hyper-link-row{
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
200
src/components/Course/shareItem.vue
Normal file
200
src/components/Course/shareItem.vue
Normal file
@@ -0,0 +1,200 @@
|
||||
<template>
|
||||
<div style="">
|
||||
<div class="uc-course" @click="jumpRouter(item)" v-for="(item, idx) in items" :key="idx">
|
||||
<div class="uc-course-img" style="width: 212px;height: 119px;">
|
||||
<course-image :course="item"></course-image>
|
||||
<!-- <img :src="imageUrl(item)" /><span class="two-line-ellipsis">{{item.title}}</span> -->
|
||||
</div>
|
||||
<div class="uc-course-info">
|
||||
<div style="height: 100%;display: flex;justify-content:space-between;">
|
||||
<div style="display: flex;flex-direction: column;justify-content: space-between;">
|
||||
<div class="uc-course-name">
|
||||
<span class="uc-course-font" :class="contentTypeFilter(item.contentType).class">{{ contentTypeFilter(item.contentType).text }}</span>
|
||||
<span v-html="$keywordActiveShow(item.title,keyword)"></span>
|
||||
</div>
|
||||
<!-- <div class="uc-course-text" v-if="type=='myShare'">-->
|
||||
<!-- 分享给:{{ item.toAname }}
|
||||
</div> -->
|
||||
<!-- <div class="uc-course-text" v-else>分享人:{{ item.toAname }}</div> -->
|
||||
<div style="display:flex;flex-direction: column;">
|
||||
<div class="uc-course-textTo">分享时间:{{ item.time }}</div>
|
||||
<div class="uc-course-textToInfo">
|
||||
<span v-if="type=='myShare'" style="margin-right:10px">分享给{{item.toAname}}</span>
|
||||
<span v-else style="margin-right:10px">{{item.authorName}}分享给我</span>
|
||||
<el-button type="text" v-if="item.isRead" icon="el-icon-folder-opened" style="color: #8590A6;padding:0;">已查看</el-button>
|
||||
<el-button type="text" icon="el-icon-folder" v-else style="color: #8590A6;padding:0;">未查看</el-button>
|
||||
<el-button v-if="!item.isRead&&type=='myShare'" type="text" @click.stop="deleteshares(item)" icon="el-icon-refresh-right" style="color: #8590A6;">撤回</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="btn" > -->
|
||||
<!-- <span>{{item.isRead?'[已查看]':'[未查看]'}}</span> -->
|
||||
|
||||
|
||||
<!-- </div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import interactBar from '@/components/Portal/interactBar.vue';
|
||||
import courseImage from "@/components/Course/courseImage.vue"
|
||||
import apiShares from '@/api/modules/shares.js';
|
||||
export default {
|
||||
name: 'comStudyItem',
|
||||
props: {
|
||||
items: {
|
||||
//name,
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
type:{
|
||||
type:String,
|
||||
default:()=>{
|
||||
return 'myShare'
|
||||
}
|
||||
},
|
||||
keyword:{
|
||||
type:String,
|
||||
default:()=>{
|
||||
return ''
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
imageUrl(item) {
|
||||
if (item && item.image && item.image != '') {
|
||||
return process.env.VUE_APP_FILE_BASE_URL + item.image;
|
||||
} else {
|
||||
return this.webBaseUrl + "/images/bgimg/course.png";
|
||||
}
|
||||
},
|
||||
deleteshares(item){
|
||||
this.$emit('confirm',item)
|
||||
},
|
||||
contentTypeFilter(value) {
|
||||
let obj = {};
|
||||
switch (value) {
|
||||
case '10': {
|
||||
obj.class = 'uc-course-type2';
|
||||
obj.text = '录播';
|
||||
break;
|
||||
}
|
||||
case '21': {
|
||||
obj.class = 'uc-course-type2';
|
||||
obj.text = '直播';
|
||||
break;
|
||||
}
|
||||
case '20': {
|
||||
obj.class = 'uc-course-type2';
|
||||
obj.text = '录播';
|
||||
break;
|
||||
}
|
||||
case '30': {
|
||||
obj.class = 'uc-course-type2';
|
||||
obj.text = '面授';
|
||||
break;
|
||||
}
|
||||
case '90': {
|
||||
obj.class = 'uc-course-type2';
|
||||
obj.text = '混合';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
jumpRouter(item){
|
||||
if(this.type!='myShare'){
|
||||
apiShares.updateIsRead(item.id).then(res=>{
|
||||
if(res.status==200){
|
||||
this.$emit('confirm',item)
|
||||
}
|
||||
})
|
||||
}
|
||||
this.$router.push({path:'/course/detail',query:{id:item.objId}})
|
||||
// window.open(`${this.webBaseUrl}/course/detail?id=${item.objId}`)
|
||||
},
|
||||
},
|
||||
components: {
|
||||
courseImage
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// .uc-course-type1 {
|
||||
// padding: 3px;
|
||||
// border: 1px dotted #1ea0fa;
|
||||
// color: #1ea0fa;
|
||||
// }
|
||||
// .uc-course-type2 {
|
||||
// padding: 3px;
|
||||
// border: 1px dotted #ffaa00;
|
||||
// color: #ffaa00;
|
||||
// }
|
||||
.uc-course {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
// border: 1px solid #f0f0f0;
|
||||
// padding: 10px;
|
||||
padding-bottom: 24px;
|
||||
margin-top: 24px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
cursor: pointer;
|
||||
.uc-course-img {
|
||||
position: relative;
|
||||
img {
|
||||
width: 160px;
|
||||
height: 90px;
|
||||
border: 1px solid #f4f4f5;
|
||||
}
|
||||
>span{
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
left: 10px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: #ffffff;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
.uc-course-info {
|
||||
flex: 1;
|
||||
line-height: 28px;
|
||||
padding: 0px 12px;
|
||||
.uc-course-name {
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
.uc-course-font{
|
||||
width: 58px;
|
||||
height: 26px;
|
||||
font-size: 14px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
.uc-course-text {
|
||||
color: #747474;
|
||||
font-size: 16px;
|
||||
}
|
||||
.uc-course-textTo{
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
}
|
||||
.readed{
|
||||
color: #2AB28B;
|
||||
}
|
||||
.noRead{
|
||||
color:#FF3E3E;
|
||||
}
|
||||
.btn{
|
||||
text-align: right;
|
||||
width: 250px;
|
||||
font-size: 14px;
|
||||
// margin-top: 70px;
|
||||
padding-top:90px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
229
src/components/Course/simpleTestPaper.vue
Normal file
229
src/components/Course/simpleTestPaper.vue
Normal file
@@ -0,0 +1,229 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--简单的试卷内容,传入参数字符串,传出参数字符串-->
|
||||
<div style="display: flex;justify-content: space-between; padding: 5px;">
|
||||
<div>
|
||||
<el-button-group>
|
||||
<el-button type="primary" size="mini" @click="addQuestion(101)" icon="el-icon-plus">单选</el-button>
|
||||
<el-button type="primary" size="mini" @click="addQuestion(102)" icon="el-icon-plus">多选</el-button>
|
||||
<el-button type="primary" size="mini" @click="addQuestion(103)" icon="el-icon-plus">判断</el-button>
|
||||
</el-button-group>
|
||||
</div>
|
||||
<div style="padding-top: 10px;color: #919191; ">点题干编辑</div>
|
||||
<div style="line-height:40px; text-align: center;font-size: 16px;">
|
||||
<el-checkbox v-model="optShow">显示选项</el-checkbox>
|
||||
<span style="margin-left: 8px;">共<span class="bigred"> {{data.items.length}} </span>题,<span class="bigred">{{total}}</span> 分</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paper">
|
||||
<div v-for="(item, idx) in data.items" :key="idx" class="paper-item">
|
||||
<div style="display: flex;justify-content: space-between;padding: 5px;">
|
||||
<div style="flex:1;padding-right: 5px;">
|
||||
<div v-if="editIndex!=idx" @mouseenter="showOptions(item)" @mouseleave="hideOptions(item)">
|
||||
<div style="cursor: pointer;" @click="handleEditItem(item,idx)">
|
||||
{{idx+1}}.【
|
||||
<span v-if="item.type == 101">单选题</span>
|
||||
<span v-if="item.type == 102">多选题</span>
|
||||
<span v-if="item.type == 103">判断题</span>
|
||||
】{{ item.content }}
|
||||
</div>
|
||||
<div v-if="optShow || item.optShow" style="padding: 5px;">
|
||||
<div class="paper-opt" v-for="(opt, optIdx) in item.options" :key="optIdx" @click="setOptAnswer(item,opt)" :class="{'paper-opt-yes':opt.answer}">
|
||||
{{ optIdx + 1 }}, {{ opt.content }} <i v-if="opt.answer" class="el-icon-check"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="editIndex==idx">
|
||||
<div><el-input v-model="item.content" placeholder="试题的内容"></el-input> </div>
|
||||
<div style="color: red;">注:一行就一个选项</div>
|
||||
<div><el-input :rows="5" type="textarea" v-model="curTextOptions" placeholder="试题的内容"></el-input> </div>
|
||||
<div><el-button @click="handleSaveItem(item)" type="warning" size="small"> 编辑完成 </el-button> </div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 110px;">
|
||||
<el-input style="width: 50px;" size="mini" v-model="item.score" placeholder="分数"></el-input>
|
||||
<el-button @click="removeQuestion(idx)" style="margin-left: 6px;" type="danger" icon="el-icon-delete" size="mini"></el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {snowflakeGenerator} from 'snowflake-id-js';
|
||||
export default {
|
||||
name: 'articleItems',
|
||||
props:{
|
||||
data:{
|
||||
type:Object,
|
||||
default(){
|
||||
return {
|
||||
generator:null,
|
||||
items:[]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
editIndex:-1,//当前编辑的项
|
||||
curTextOptions:'',
|
||||
optShow:true,
|
||||
qdata: [
|
||||
{
|
||||
id: '1',
|
||||
type: 101,
|
||||
score: 5,
|
||||
checked: false,
|
||||
optShow:false,
|
||||
content: '点击编辑试题内容',
|
||||
options: [
|
||||
{ id: '11', content: '选项',answer:false },
|
||||
{ id: '12', content: '选项',answer:true},
|
||||
{ id: '13', content: '选项',answer:false},
|
||||
{ id: '14', content: '选项',answer:false},
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
var seed=Math.floor(Math.random() * (50 - 1 + 1) + 1);
|
||||
this.generator= snowflakeGenerator(seed);
|
||||
this.initItem();
|
||||
},
|
||||
computed:{
|
||||
total(){
|
||||
var t=0;
|
||||
this.data.items.forEach(item=>{
|
||||
t+=parseFloat(item.score);
|
||||
});
|
||||
return t;
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
initItem(){
|
||||
let $this=this;
|
||||
//添加测试数据
|
||||
if(this.data.items.length==0){
|
||||
this.qdata.forEach(item=>{
|
||||
$this.data.items.push(item);
|
||||
})
|
||||
}
|
||||
},
|
||||
showOptions(item){
|
||||
item.optShow=true;
|
||||
},
|
||||
hideOptions(item){
|
||||
item.optShow=false;
|
||||
},
|
||||
setOptAnswer(item,opt){
|
||||
if(item.type!=102){//单选的情况,先清空
|
||||
item.options.forEach(op=>{
|
||||
op.answer=false;
|
||||
})
|
||||
}
|
||||
if(opt.answer){
|
||||
opt.answer=false;
|
||||
}else{
|
||||
opt.answer=true;
|
||||
}
|
||||
},
|
||||
handleEditItem(item,idx){
|
||||
this.editIndex=idx;
|
||||
var txt='';
|
||||
item.options.forEach(function(q){
|
||||
if(txt.length>1){
|
||||
txt+='\n';
|
||||
}
|
||||
txt+=q.content;
|
||||
});
|
||||
this.curTextOptions=txt;
|
||||
},
|
||||
handleSaveItem(item){
|
||||
var txt = this.curTextOptions;
|
||||
if(txt==''){
|
||||
return;
|
||||
}
|
||||
var txtArray=txt.split("\n");
|
||||
//保存选中的
|
||||
var answerRows=[];
|
||||
item.options.forEach((op,opidx)=>{
|
||||
if(op.answer){
|
||||
answerRows.push(opidx);
|
||||
}
|
||||
})
|
||||
//重新指定
|
||||
let $this=this;
|
||||
var newOptions=[];
|
||||
txtArray.forEach(function(t,i){
|
||||
var newOpt={ id:$this.generator.next().value, content: t,answer:false };
|
||||
answerRows.some(an=>{
|
||||
if(an==i){
|
||||
newOpt.answer=true;
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
})
|
||||
newOptions.push(newOpt);
|
||||
|
||||
});
|
||||
item.options=newOptions;
|
||||
this.editIndex=-1;
|
||||
},
|
||||
addQuestion(t){
|
||||
//let gen= snowflakeGenerator(512).next().value;
|
||||
//let qid=snowflakeGenerator(512).next().value;
|
||||
let qid=this.generator.next().value;
|
||||
console.log(qid);
|
||||
let q={
|
||||
id: qid,
|
||||
type: t,
|
||||
score: 5,
|
||||
checked: false,
|
||||
optShow:false,
|
||||
content: '点击编辑试题内容',
|
||||
options: []
|
||||
}
|
||||
if(t==101 || t==102){
|
||||
q.options.push({id:this.generator.next().value,content:'选项',answer:false});
|
||||
q.options.push({id:this.generator.next().value,content:'选项',answer:false});
|
||||
q.options.push({id:this.generator.next().value,content:'选项',answer:false});
|
||||
}else{
|
||||
q.options.push({id:this.generator.next().value,content:'正确',answer:false});
|
||||
q.options.push({id:this.generator.next().value,content:'错误',answer:false});
|
||||
}
|
||||
this.data.items.push(q)
|
||||
},
|
||||
removeQuestion(idx){
|
||||
this.data.items.splice(idx,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.paper{
|
||||
border: 1px solid #dfdfdf;
|
||||
padding: 5px 0px;
|
||||
height: 500px;
|
||||
overflow: auto;
|
||||
.paper-item{
|
||||
padding: 5px 10px;
|
||||
border-bottom: 1px solid #CCCCCC;
|
||||
.paper-opt{
|
||||
line-height: 25px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.paper-opt-yes{
|
||||
color: green;
|
||||
}
|
||||
}
|
||||
}
|
||||
.bigred {
|
||||
color: red;
|
||||
font-size: 20px;
|
||||
}
|
||||
</style>
|
||||
155
src/components/Course/studyImage.vue
Normal file
155
src/components/Course/studyImage.vue
Normal file
@@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<!--用于显示课程的图片-->
|
||||
<div class="img-box" id="img-box">
|
||||
<el-image
|
||||
style="background-color: #eeeeee"
|
||||
:style="`width:${width};height:${height};`"
|
||||
fit="fill "
|
||||
:src="imageUrl"
|
||||
>
|
||||
<div slot="error" class="image-slot">
|
||||
<i class="el-icon-picture-outline"></i>
|
||||
</div>
|
||||
</el-image>
|
||||
<div v-if="isShow">
|
||||
<p v-if="imageTextSize == 4" class="te-max text effect06">
|
||||
{{ course.name || course.courseName || course.title }}
|
||||
</p>
|
||||
<p v-if="imageTextSize == 3" class="max text effect06">
|
||||
{{ course.name || course.courseName || course.title}}
|
||||
</p>
|
||||
<p v-if="imageTextSize == 2" class="mid text effect06">
|
||||
{{ course.name || course.courseName || course.title}}
|
||||
</p>
|
||||
<p v-if="imageTextSize == 1" class="mini text effect06">
|
||||
{{ course.name || course.courseName ||course.title }}
|
||||
</p>
|
||||
</div>
|
||||
<!-- <p :class="imageTextSize == 3? 'max':imageTextSize == 2?'mid':'mini'">{{course.name}}</p> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
course: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: "100%",
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: "100%",
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
imageUrl() {
|
||||
if (this.course && this.course.coverImg && this.course.coverImg != "") {
|
||||
return this.course.coverImg;
|
||||
} else if (
|
||||
this.course &&
|
||||
this.course.courseImage &&
|
||||
this.course.courseImage != ""
|
||||
) {
|
||||
return this.course.courseImage;
|
||||
} else if (
|
||||
this.course &&
|
||||
this.course.image &&
|
||||
this.course.image != ""
|
||||
) {
|
||||
return this.course.image;
|
||||
}
|
||||
else if (this.course.coverImg == "" || this.course.courseImage == "" || this.course.image == "") {
|
||||
this.isShow = true;
|
||||
return this.webBaseUrl + "/images/bgimg/course.png";
|
||||
}
|
||||
return '';
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
imageText: "", //图片上面的文字
|
||||
fileBaseUrl: process.env.VUE_APP_FILE_BASE_URL,
|
||||
isShow: false,
|
||||
imageTextSize: false,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
let obj = document.getElementById("img-box");
|
||||
if (obj.offsetWidth > 500 && obj.offsetWidth < 900) {
|
||||
this.imageTextSize = 3;
|
||||
} else if (obj.offsetWidth > 200 && obj.offsetWidth < 600) {
|
||||
this.imageTextSize = 2;
|
||||
} else if (obj.offsetWidth > 900) {
|
||||
this.imageTextSize = 4;
|
||||
} else {
|
||||
this.imageTextSize = 1;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
imageError() {},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.text {
|
||||
text-shadow: 0px 0px 2px #ffffff;
|
||||
}
|
||||
.image-slot{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.img-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
p {
|
||||
display: -webkit-box;
|
||||
// white-space:pre-wrap;
|
||||
overflow: hidden;
|
||||
// text-overflow:ellipsis;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
color: #ffffff;
|
||||
position: absolute;
|
||||
padding-right: 10px;
|
||||
}
|
||||
.mini {
|
||||
top: 30px;
|
||||
left: 10px;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
.mid {
|
||||
top: 50px;
|
||||
left: 20px;
|
||||
font-size: 20px;
|
||||
line-height: 35px;
|
||||
-webkit-line-clamp: 3;
|
||||
}
|
||||
.max {
|
||||
top: 90px;
|
||||
left: 40px;
|
||||
font-size: 24px;
|
||||
line-height: 40px;
|
||||
-webkit-line-clamp: 3;
|
||||
}
|
||||
.te-max {
|
||||
top: 180px;
|
||||
left: 80px;
|
||||
font-size: 20px;
|
||||
line-height: 35px;
|
||||
-webkit-line-clamp: 3;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
118
src/components/Course/studyItem.vue
Normal file
118
src/components/Course/studyItem.vue
Normal file
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div style="">
|
||||
<div class="uc-course" v-for="(item,idx) in items" :key="idx">
|
||||
<div class="uc-course-img" style="width: 160px;height:90px">
|
||||
<course-image :course="item"></course-image>
|
||||
</div>
|
||||
<div class="uc-course-info">
|
||||
<div class="uc-course-name" @click="jumpRouter(item)" style="cursor: pointer;">
|
||||
<span v-if="item.courseType==10" class="uc-course-type2">录播</span>
|
||||
<span v-if="item.courseType==20" class="uc-course-type2">录播</span>
|
||||
<!-- <a :href="`${webBaseUrl}/course/detail?id=`" target="_blank"> {{item.name}}</a> -->
|
||||
{{item.courseName}}
|
||||
</div>
|
||||
<div style="width: 80%;"><el-progress :percentage="item.progress"></el-progress></div>
|
||||
<div class="uc-course-text">报名时间:{{item.addTime}}</div>
|
||||
<div class="uc-course-text">来源:<span>{{item.source == 1?'内部':'外部'}}</span></div>
|
||||
</div>
|
||||
<div class="uc-course-btns">
|
||||
<!-- :href="item.courseType==10 ?`/course/micro?id=${item.id}`:`/course/studyindex?id=${item.id}`" target="_blank" -->
|
||||
<span @click="jumpRouter(item)">
|
||||
<el-button v-if="item.progress==0" type="primary" size="small">开始学习</el-button>
|
||||
<el-button v-if="item.progress>0 && item.progress<100" type="primary" size="small">继续学习</el-button>
|
||||
<el-button v-if="item.progress==100" type="primary" size="small">回顾</el-button>
|
||||
<el-button v-if="item.progress==100" type="primary" size="small">重新学习</el-button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import courseImage from "@/components/Course/courseImage.vue"
|
||||
export default {
|
||||
name: 'comStudyItem',
|
||||
components: { courseImage },
|
||||
props: {
|
||||
items: { //name,
|
||||
type: Array,
|
||||
default:()=>[]
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
fileUrl:process.env.VUE_APP_FILE_BASE_URL,//文章的url路径
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods:{
|
||||
toStudy(item){
|
||||
this.$router.push({path:'/uc/study/index?id='+item.courseId});
|
||||
},
|
||||
jumpRouter(item){
|
||||
if(item.courseType==10){
|
||||
let routeData = this.$router.resolve({ path: '/course/micro?id='+item.courseId}); // , query: { id: 1 }
|
||||
window.open(this.webBaseUrl+routeData.href, '_blank');
|
||||
}
|
||||
if(item.courseType==20){
|
||||
if(item.progress>0 && item.progress<100) {
|
||||
let routeData = this.$router.resolve({ path: '/course/studyindex?id='+item.courseId}); // , query: { id: 1 }
|
||||
window.open(this.webBaseUrl+routeData.href, '_blank');
|
||||
} else {
|
||||
let routeData = this.$router.resolve({ path: '/course/detail?id='+item.courseId}); // , query: { id: 1 }
|
||||
window.open(this.webBaseUrl+routeData.href, '_blank');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// .uc-course-type1{
|
||||
// padding: 3px;
|
||||
// border: 1px dotted #1EA0FA;
|
||||
// color:#1EA0FA;
|
||||
// }
|
||||
// .uc-course-type2{
|
||||
// padding: 3px;
|
||||
// border: 1px dotted #ffaa00;
|
||||
// color:#ffaa00;
|
||||
// }
|
||||
.uc-course{
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
border: 1px solid #F0F0F0;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
.uc-course-img{
|
||||
width: 200px;
|
||||
img{
|
||||
width: 200px;
|
||||
border: 1px solid #F4F4F5;
|
||||
}
|
||||
}
|
||||
.uc-course-info{
|
||||
flex: 1;
|
||||
line-height: 28px;
|
||||
padding: 0px 10px;
|
||||
.uc-course-name{
|
||||
font-size: 16px;
|
||||
// font-weight: 700;
|
||||
}
|
||||
.uc-course-text{
|
||||
// line-height: 40px;
|
||||
color: #747474;
|
||||
span{
|
||||
color: #ffaa00;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.uc-course-btns{
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
90
src/components/Course/ucList.vue
Normal file
90
src/components/Course/ucList.vue
Normal file
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<div style="">
|
||||
<div class="uc-course" v-for="(item,idx) in items" :key="idx">
|
||||
<div class="uc-course-img" style="width: 200px;">
|
||||
<img :src="`${webBaseUrl}/images/course.png`">
|
||||
</div>
|
||||
<div class="uc-course-info">
|
||||
<div class="uc-course-name">
|
||||
<span v-if="item.type==1" class="uc-course-type2">录播</span>
|
||||
<span v-if="item.type==2" class="uc-course-type2">录播</span>
|
||||
<a :href="`${webBaseUrl}/course/detail?id=`" target="_blank"> {{item.name}}</a>
|
||||
</div>
|
||||
<div style="width: 80%;"><el-progress :percentage="item.percentage"></el-progress></div>
|
||||
<div class="uc-course-text">来源:自主学习</div>
|
||||
<!-- <div class="uc-course-text">截至日期:2022-03-30</div> -->
|
||||
</div>
|
||||
<div class="uc-course-btns">
|
||||
<el-button type="primary" >继续制作</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'comStudyItem',
|
||||
props: {
|
||||
items: { //name,
|
||||
type: Array,
|
||||
default:()=>[]
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods:{
|
||||
toStudy(item){
|
||||
this.$router.push({path:'/uc/study/index',params:{id:item.id}});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.uc-course-type1{
|
||||
padding: 3px;
|
||||
border: 1px dotted #1EA0FA;
|
||||
color:#1EA0FA;
|
||||
}
|
||||
.uc-course-type2{
|
||||
padding: 3px;
|
||||
border: 1px dotted #ffaa00;
|
||||
color:#ffaa00;
|
||||
}
|
||||
.uc-course{
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
border: 1px solid #F0F0F0;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
.uc-course-img{
|
||||
width: 200px;
|
||||
img{
|
||||
width: 200px;
|
||||
border: 1px solid #F4F4F5;
|
||||
}
|
||||
}
|
||||
.uc-course-info{
|
||||
flex: 1;
|
||||
line-height: 28px;
|
||||
padding: 0px 10px;
|
||||
.uc-course-name{
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.uc-course-text{
|
||||
color: #747474;
|
||||
}
|
||||
}
|
||||
.uc-course-btns{
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
1092
src/components/Course/weikeContent.vue
Normal file
1092
src/components/Course/weikeContent.vue
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user