123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- <template>
- <div style="position: relative;">
- <el-dialog title="交互视频" :visible.sync="dialogVisibleVideo" :append-to-body="true" width="95%"
- :before-close="handleClose" class="dialog_diy">
- <div v-if="dialogVisibleVideo">
- <div class="videoBox">
- <video-player class="video-player vjs-custom-skin" ref="videoPlayer" :playsinline="true"
- :options="playerO" v-if="this.json.video" @timeupdate="onPlayerTimeupdate($event)"></video-player>
-
- <div class="chooseNodeBox">
- <div class="chooseNodeItem" v-for="(item,index) in json.setting" @click.stop="chooseNode(item)">
- <!-- <div v-if="userChooseAnswer.find(i=>i.testJson[0].teststitle==item.tool.toolJson.testJson[0].teststitle)" class="el-icon-circle-check"></div> -->
- <div v-if="userChooseAnswer[index]" class="el-icon-circle-check"></div>
- <div v-else>{{ index+1 }}</div>
- </div>
- </div>
- </div>
- <div class="accuracy" v-if="accuracyList.length>0">
- <span>准确率:</span>
- <div class="accuracyItem" v-for="(item,index) in accuracyList">
- <div class="accuracyTitle">第 {{ index+1 }} 题:</div>
- <div class="accuracyValue">正确率{{item}}%</div>
- </div>
- </div>
- </div>
-
- <span slot="footer" class="dialog-footer">
- <el-button @click="close">关 闭</el-button>
- <el-button @click.stop="submitBtn" type="primary">确认</el-button>
- </span>
- </el-dialog>
- <choiceD
- ref="choiceD"
- :dialogVisibleChoice.sync="dialogVisibleChoice"
- :json="toolJson"
- :userChooseAnswer:="userChooseAnswer"
- @play="gotoPlay"
- :userid="userid"
- :id="id"
- :courseType="courseType"
- :taskCount="taskCount"
- :toolindex="toolindex"
- :videoTime="stopTime"
- :videoType="videoType"
- @success="choiceAnswer"
- ></choiceD>
- </div>
- </template>
- <script>
- import choiceD from '../Choice/index.vue'
- export default {
- emits:['success'],
- props: {
- dialogVisibleVideo: {
- type: Boolean,
- default: false
- },
- videoJson: {
- type: Object
- },
- userid: {
- type: String,
- },
- id: {
- type: String,
- },
- courseType: {
- type: String || Number,
- },
- taskCount: {
- type: Number,
- },
- toolindex: {
- type: Number,
- },
- videoType:{
- type:Number,
- default:0
- }
- },
- components: {
- choiceD,
- },
- data() {
- return {
- json: {},
- userChooseAnswer:[],
- accuracyList:[],
- playerOptions: {
- playbackRates: [0.7, 1.0, 1.5, 2.0], //播放速度
- autoplay: false, //如果true,浏览器准备好时开始回放。
- muted: false, // 默认情况下将会消除任何音频。
- loop: false, // 导致视频一结束就重新开始。
- preload: "auto", // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
- language: "zh-CN",
- aspectRatio: "16:9", // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
- fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
- sources: [
- {
- type: "video/mp4", //这里的种类支持很多种:基本视频格式、直播、流媒体等,具体可以参看git网址项目 || "video/ogg"|| "video/webm"
- src: "", //url地址require("../../assets/media/aaa.mp4")
- },
- ],
- // poster: require("../../assets/tu31.png"), //你的封面地址
- // poster: dataRes.imgUrl, //你的封面地址
- notSupportedMessage: "此视频暂无法播放,请稍后再试", //允许覆盖Video.js无法播放媒体源时显示的默认信息。
- controlBar: {
- timeDivider: true, //当前时间和持续时间的分隔符
- durationDisplay: true, //显示持续时间
- remainingTimeDisplay: false, //是否显示剩余时间功能
- fullscreenToggle: false, //全屏按钮
- },
- },
- playerO: {},
- videoTime: 0,
- dialogVisibleChoice: false,
- stopTime: 0,
- toolJson: {}
- }
- },
- watch: {
- dialogVisibleVideo(newValue, oldValue) {
- this.json = JSON.parse(JSON.stringify(this.videoJson));
- if (this.json.video) {
- this.playerO = JSON.parse(JSON.stringify(this.playerOptions));
- this.playerO.sources[0].src = this.json.video
- this.videoType==1?this.userChooseAnswer = this.json.setting.map(i=>i.tool.toolJson):[];
- this.getAccuracyList();
- this.$nextTick(() => {
- setTimeout(() => {
- this.videoTime = Math.round(this.$refs['videoPlayer'].player.cache_.duration)
- }, 500)
- })
- }
- if(!newValue)this.json = [];
- }
- },
- methods: {
- handleClose(done) {
- this.close()
- done()
- },
- close() {
- this.$emit("update:dialogVisibleVideo", false)
- },
- onPlayerTimeupdate(player) {
- let gklog = player.cache_.currentTime;//当前播放的秒数
- let gklog2 = parseInt(gklog)
- for (var i = 0; i < this.json.setting.length; i++) {
- if (gklog2 == this.json.setting[i].time) {
- this.stopTime = this.json.setting[i].time
- player.pause()
- if (this.json.setting[i].tool.tool == 45) {
- this.dialogVisibleChoice = true
- this.toolJson = this.json.setting[i].tool.toolJson
- let answerIndex = this.json.setting.findIndex(i=>JSON.stringify(i.tool.toolJson)==JSON.stringify(this.toolJson))
- if(answerIndex!=-1 && this.userChooseAnswer[answerIndex]){
- this.$refs['choiceD'].setUserAnswer(this.userChooseAnswer[answerIndex].testJson.map(i=>i.answer2))
- }
- }
- }
- }
- console.log(" onPlayerTimeupdate!", gklog);
- console.log(" onPlayerTimeupdate!", gklog2);
- },
- gotoPlay() {
- this.$refs['videoPlayer'].player.currentTime(this.stopTime + 1)
- this.$refs['videoPlayer'].player.play()
- },
- // 点击了节点
- chooseNode(setting){
- this.$refs['videoPlayer'].player.currentTime(setting.time)
- this.stopTime = setting.time;
- this.$refs['videoPlayer'].player.pause()
- if (setting.tool.tool == 45) {
- this.dialogVisibleChoice = true
- this.toolJson = setting.tool.toolJson
- let answerIndex = this.json.setting.findIndex(i=>JSON.stringify(i.tool.toolJson)==JSON.stringify(this.toolJson))
- if(answerIndex!=-1 && this.userChooseAnswer[answerIndex]){
- this.$refs['choiceD'].setUserAnswer(this.userChooseAnswer[answerIndex].testJson.map(i=>i.answer2))
- }
- }
- },
- // 选择答案并且确定
- choiceAnswer(data){
- let answer = data.answer;
- let testJson = data.json;
- let changeIndex = this.json.setting.findIndex(i=>JSON.stringify(i.tool.toolJson)==JSON.stringify(testJson))
- if(changeIndex!=-1){
- testJson.testJson.forEach((i,index)=>{
- i.answer2 = answer[index];
- })
- this.userChooseAnswer[changeIndex] = testJson;
- }
- this.getAccuracyList();
- },
- getAccuracyList(){
- if(this.userChooseAnswer.length<0)return;
- let score = [];
- this.json.setting.forEach((item,index)=>{
- if(this.userChooseAnswer[index]){
- let count = 0;
- let type = item.tool.toolJson.testJson.map(i=>i.type)
- let userAnswer = this.userChooseAnswer[index].testJson.map(i=>i.answer2);
- let rightAnswer = this.userChooseAnswer[index].testJson.map(i=>i.answer);
- let num = item.tool.toolJson.testJson.length;
- userAnswer.forEach((item2,index2)=>{
- if(type[index2]=='2'){
- if(JSON.stringify(userAnswer[index2].sort((a,b)=>a-b))==JSON.stringify(rightAnswer[index2].sort((a,b)=>a-b))){
- count++
- }
- }else if(type[index2]=='1'){
- if(userAnswer[index2]==rightAnswer[index2]){
- count++;
- }
- }
- })
- score.push((count/num).toFixed(2)*100)
- }else{
- score.push(0)
- }
- })
- this.accuracyList = score;
- this.$forceUpdate();
- },
- submitBtn(){
- if(this.videoType==1)return this.close();
- if(this.userChooseAnswer<this.json.setting.length)return this.$message.info("请答题");
- let data = this.json;
- data.setting.forEach((i,index)=>i.tool.toolJson = this.userChooseAnswer[index])
- let params = [{
- uid:this.userid,
- cid:this.id,
- stage:this.courseType,
- task:this.taskCount,
- tool:this.toolindex,
- content:encodeURIComponent(JSON.stringify(data)),
- type:14,
- atool:62,
- text:"",
- }]
- // return;
- this.ajax
- .post(this.$store.state.api + "addCourseWorks5", params)
- .then((res) => {
- this.$message.success("提交成功");
- this.close();
- })
- .catch((err) => {
- this.$message.error("提交失败");
- console.error(err);
- });
- },
- },
- mounted() {
- this.json = JSON.parse(JSON.stringify(this.videoJson));
- if (this.json.video) {
- this.playerO = JSON.parse(JSON.stringify(this.playerOptions));
- this.playerO.sources[0].src = this.json.video
- this.$nextTick(() => {
- setTimeout(() => {
- this.videoTime = Math.round(this.$refs['videoPlayer'].player.cache_.duration)
- }, 500)
- })
- }
- },
- }
- </script>
- <style scoped>
- .dialog_diy>>>.el-dialog__header {
- background: #3c3c3c !important;
- padding: 15px 20px;
- }
- .dialog_diy>>>.el-dialog__title {
- color: #fff;
- }
- .dialog_diy>>>.el-dialog__headerbtn {
- top: 19px;
- }
- .dialog_diy>>>.el-dialog__headerbtn .el-dialog__close {
- color: #fff;
- }
- .dialog_diy>>>.el-dialog__headerbtn .el-dialog__close:hover {
- color: #fff;
- }
- .dialog_diy>>>.el-dialog__body,
- .dialog_diy>>>.el-dialog__footer {
- background: #fafafa;
- }
- .videoBox {
- width: 100%;
- height: 600px;
- background: #fff;
- margin-top: 20px;
- position: relative;
- }
- .chooseNodeBox{
- width: auto;
- height:50px;
- position:absolute;
- bottom:45px;
- left:50%;
- transform:translateX(-50%);
- display:flex;
- justify-content: center;
- align-items: center;
- background-color: none;
- }
- .chooseNodeBox>.chooseNodeItem{
- width: 40px;
- height: 40px;
- background: black;
- margin: 0 10px;
- border-radius: 50%;
- cursor: pointer;
- z-index: 9;
- display: flex;
- justify-content: center;
- align-items: center;
- color: white;
- font-size: 1.5em;
- font-weight: bold;
- }
- .videoBox>.content {
- /* position: absolute; */
- line-height: 600px;
- text-align: center;
- font-size: 18px;
- user-select: none;
- }
- .videoBox .video-player {
- height: 100%;
- width: auto;
- }
- .videoBox>>>.vjs-fluid {
- padding: 0 !important;
- height: 100%;
- }
- .accuracy{
- width: 300px;
- height: auto;
- background-color: #d4dde1;
- border-radius: 5px;
- margin: 10px 0;
- box-sizing: border-box;
- padding: 10px;
- }
- .accuracy>span{
- font-size: 22px;
- font-weight: bold;
- margin: 10px 0;
- }
- .accuracy>.accuracyItem{
- width: 100%;
- height: 40px;
- margin-top: 10px;
- display: flex;
- align-items: center;
- }
- .accuracyItem>.accuracyTitle{
- width: 120px;
- height: 100%;
- display: flex;
- justify-content: center;
- align-items: center;
- font-weight: bold;
- font-size:1.3em;
- background-color: #2c2f3b;
- color: white;
- border-radius: 5px;
- }
- .accuracyItem>.accuracyValue{
- width:120px;
- margin-left: 20px;
- font-size: 16px;
- box-sizing: border-box;
- padding: 5px;
- border-radius: 5px;
- border:solid 1px #0061FF;
- color:#0061FF;
- }
- </style>
|