lsc 2 years ago
parent
commit
68cd05070a

BIN
src/assets/icon/fourthToolList/interVideo.png


+ 70 - 12
src/components/pages/addCourse.vue

@@ -103,7 +103,7 @@
                   <span style="color: rgb(15, 126, 255)">添加课程</span>
                 </el-breadcrumb-item>
               </el-breadcrumb>
-              <el-button type="primary" @click="pasteStage" size="small" v-if="steps == 3 && (!cid || cid && userid == courseUserid)" style="margin-left: 20px;">智能粘贴</el-button>
+              <el-button type="primary" @click="pasteStage" size="small" v-if="steps == 3 && (!cid || (cid && (userid == courseUserid || role == '1')))" style="margin-left: 20px;">智能粘贴</el-button>
               
             </div>
             <div v-if="steps == 1 || steps == 2 || steps == 3" class="stepsWord">
@@ -123,9 +123,9 @@
           <div class="rightBox" v-if="this.steps == 1" @mousewheel="scrollChange">
             <div class="updateMask" :style="{
                       height: rightBoxHeight ? rightBoxHeight + 'px' : '100%',
-                    }" v-if="cid && userid != courseUserid"></div>
+                    }" v-if="cid && userid != courseUserid && role != '1'"></div>
             <div class="whiteBg">
-              <div class="right_title" :class="{ updateTips: cid && userid != courseUserid }">
+              <div class="right_title" :class="{ updateTips: cid && userid != courseUserid && role != '1' }">
                 课程基本信息
               </div>
               <div class="basic_box">
@@ -249,7 +249,7 @@
                       </div>
                     </div>
                     <div style="flex: 0.5 1 0%; margin: 0; width: 180px"
-                      v-if="courseUserid != '' ? courseUserid == userid : true">
+                      v-if="courseUserid != '' ? (courseUserid == userid  || role == '1') : true">
                       <div class="bInfo_title">协同编辑</div>
                       <div class="addPeople" @click="openMember" style="background: #6b92c9">
                         添加协同成员
@@ -1175,6 +1175,18 @@
                                 </div>
                               </div>
                             </div>
+                            <div class="tool">
+                              <div class="whiteBIcon" @click="openTools(itemTaskIndex, 62, toolIndex)">
+                                <img src="../../assets/icon/fourthToolList/interVideo.png" alt />
+                                <div style="margin: 5px 0">交互视频</div>
+                              </div>
+                              <div class="check" @click="addTools(62, itemTaskIndex, toolIndex)">
+                                <img src="../../assets/icon/checkNo.png" alt v-if="itemTool.tool.indexOf(62) == -1" />
+                                <div class="checkDiv" v-else>
+                                  <img src="../../assets/icon/checkedIs.png" alt /><span>已选择</span>
+                                </div>
+                              </div>
+                            </div>
                           </div>
                           <div class="toolSort" v-if="itemTool.toolType == 1">
                             <div class="tool">
@@ -2982,6 +2994,7 @@
         <el-button type="primary" @click="addGroupJson">确定</el-button>
       </span>
     </el-dialog>
+    <interVideo :dialogVisibleVideo.sync="dialogVisibleVideo" :videoJson="videoJson" @add="addVideoJson"></interVideo>
   </div>
 </template>
 
@@ -2997,9 +3010,10 @@ import Sunburst from "../tools/sunburst";
 import SeeBoard from "../tools/seeBoard";
 import weilaiData from "./components/weilai.js";
 import sourceDialog from "./teacherSource/dialog.vue";
+import interVideo from "./interVideo/index.vue";
 
 export default {
-  components: { EditorBar, Mind, Time, Sunburst, SeeBoard, Table, sourceDialog },
+  components: { EditorBar, Mind, Time, Sunburst, SeeBoard, Table, sourceDialog,interVideo },
   data() {
     return {
       checkAll: false,
@@ -3057,6 +3071,7 @@ export default {
       dialogVisiblemb: false,
       dialogVisibleInvite: false,
       dialogVisibleSource: false,
+      dialogVisibleVideo:false,
       isClickColor: 0,
       publicTool: 0,
       searchPeople: "",
@@ -3195,7 +3210,8 @@ export default {
       inviteId: "",
       icode: "",
       easyArray: [2, 4],
-      sourceData: {}
+      sourceData: {},
+      videoJson:{}
     };
   },
   computed: {
@@ -3490,7 +3506,7 @@ export default {
           if (this.cid == "" || this.cid == undefined) {
             this.addWork();
           } else {
-            if (this.userid != this.courseUserid) {
+            if (this.userid != this.courseUserid && this.role != '1') {
               // this.updateWork2();
             } else {
               this.updateWork();
@@ -3519,7 +3535,7 @@ export default {
           if (this.cid == "" || this.cid == undefined) {
             this.addWork();
           } else {
-            if (this.userid != this.courseUserid) {
+            if (this.userid != this.courseUserid && this.role != '1') {
               // this.updateWork2();
             } else {
               this.updateWork();
@@ -3554,7 +3570,7 @@ export default {
             if (this.cid == "" || this.cid == undefined) {
               this.addWork();
             } else {
-              if (this.userid != this.courseUserid) {
+              if (this.userid != this.courseUserid && this.role != '1') {
                 // this.updateWork2();
               } else {
                 this.updateWork();
@@ -3578,7 +3594,7 @@ export default {
               this.$message.error("请将信息填写完整");
               return;
             } else {
-              if (this.userid != this.courseUserid) {
+              if (this.userid != this.courseUserid && this.role != '1') {
                 this.updateWork2();
               } else {
                 this.updateWork();
@@ -3593,7 +3609,7 @@ export default {
             if (this.cid == "" || this.cid == undefined) {
               this.addWork();
             } else {
-              if (this.userid != this.courseUserid) {
+              if (this.userid != this.courseUserid && this.role != '1') {
                 // this.updateWork2();
               } else {
                 this.updateWork();
@@ -3627,7 +3643,7 @@ export default {
               this.$message.error("请将信息填写完整");
               return;
             } else {
-              if (this.userid != this.courseUserid) {
+              if (this.userid != this.courseUserid && this.role != '1') {
                 this.updateWork2();
               } else {
                 this.updateWork();
@@ -5537,6 +5553,26 @@ export default {
           this.groupJson = groupJson;
         }
         this.dialogVisibleGroup = true;
+      } else if (i == 62) {
+        if (
+          this.unitJson[this.unitIndex].chapterInfo[0].taskJson[itemTaskIndex]
+            .toolChoose[toolIndex].videoJson
+        ) {
+          this.videoJson = JSON.parse(
+            JSON.stringify(
+              this.unitJson[this.unitIndex].chapterInfo[0].taskJson[
+                itemTaskIndex
+              ].toolChoose[toolIndex].videoJson
+            )
+          );
+        } else {
+          var videoJson = {
+            video: "",
+            setting:[]
+          };
+          this.videoJson = videoJson;
+        }
+        this.dialogVisibleVideo = true;
       } else if (i == 15) {
         this.answerQ = this.unitJson[this.unitIndex].chapterInfo[0].taskJson[
           itemTaskIndex
@@ -5754,6 +5790,15 @@ export default {
           return;
         }
       }
+      if (i == 62) {
+        if (
+          !this.unitJson[this.unitIndex].chapterInfo[0].taskJson[itemTaskIndex]
+            .toolChoose[toolIndex].videoJson
+        ) {
+          this.openTools(itemTaskIndex, 62, toolIndex);
+          return;
+        }
+      }
       if (i == 15) {
         if (
           !this.unitJson[this.unitIndex].chapterInfo[0].taskJson[itemTaskIndex]
@@ -6050,6 +6095,19 @@ export default {
         this.addTools(45, this.taskCount, this.toolIndex);
       }
     },
+    addVideoJson(videoJson){
+      this.unitJson[this.unitIndex].chapterInfo[0].taskJson[
+        this.taskCount
+      ].toolChoose[this.toolIndex].videoJson = videoJson;
+
+      this.dialogVisibleVideo = false;
+      if (
+        this.unitJson[this.unitIndex].chapterInfo[0].taskJson[this.taskCount]
+          .toolChoose[this.toolIndex].tool != 62
+      ) {
+        this.addTools(62, this.taskCount, this.toolIndex);
+      }
+    },
     //自动获取剪贴板
     pasteOption() {
       let iframe = top.document.querySelectorAll("#AIChat iframe")[0]

+ 657 - 0
src/components/pages/choice/index.vue

@@ -0,0 +1,657 @@
+<template>
+    <div>
+        <el-dialog title="选择题设置" :visible.sync="dialogVisibleChoice" :append-to-body="true" width="800px"
+            :before-close="handleClose" class="dialog_diy">
+            <div v-if="dialogVisibleChoice">
+                <div class="a_addBox">
+                    <div style="font-size: 16px; color: #c7c7c7">
+                        请输入题目内容
+                        <!-- <el-button type="primary" size="small" @click="pasteOption" style="margin-left:10px">智能粘贴</el-button> -->
+                    </div>
+                    <div class="a_add_box" v-for="(item1, index1) in testJson.testCount" :key="index1">
+                        <div class="a_add_checkType">
+                            <span :class="{ active: testJson.testJson[index1].type == '1' }"
+                                @click="checkTestType('1', testJson.testJson[index1])">单选题</span>
+                            <span :class="{ active: testJson.testJson[index1].type == '2' }"
+                                @click="checkTestType('2', testJson.testJson[index1])">多选题</span>
+                        </div>
+                        <div class="a_add_head">
+                            <div class="timuUpImg">
+                                <div>
+                                    {{ index1 + 1 + "、" }}
+                                    <el-input class="a_add_head_input" v-model="testJson.testJson[index1].teststitle"
+                                        placeholder="请输入题目...">
+                                    </el-input>
+                                </div>
+                                <div class="xzUpImg" @click.stop="addImg($event)">
+                                    <img src="../../../assets/icon/xzUpImg.png" alt="" />
+                                    <input type="file" accept="image/*" style="display: none"
+                                        @change="beforeUploadTiMu($event, index1)" />
+                                </div>
+                            </div>
+                            <div class="a_add_head_div">
+                                <el-button type="primary" size="small" @click="addTestList()">添加</el-button>
+                                <el-button type="primary" size="small" @click="deleteTestList(index1)"
+                                    v-if="testJson.testCount != 1">删除
+                                </el-button>
+                            </div>
+                        </div>
+                        <div class="timuImgBox" v-if="testJson.testJson[index1].timuList &&
+                            testJson.testJson[index1].timuList.length
+                            ">
+                            <div v-for="(timg, tIndex) in testJson.testJson[index1].timuList" :key="tIndex" class="timuImg"
+                                @click.stop="previewImg(timg.src)">
+                                <img :src="timg.src" alt="" />
+                                <div class="deleteWord" @click.stop="deleteM(index1, tIndex)">
+                                    <img src="../../../assets/icon/delete.png" alt="" />
+                                </div>
+                            </div>
+                        </div>
+                        <div class="a_add_body">
+                            <div class="a_add_input a_add_input_choice">
+                                <el-radio-group v-model="testJson.testJson[index1].answer"
+                                    v-if="testJson.testJson[index1].type == 1">
+                                    <div class="radioBox">
+                                        <el-radio v-for="(item2, checkIndex) in testJson.testJson[index1]
+                                            .testItem" :key="checkIndex" :label="checkIndex">
+                                            <div style="margin-right: 10px">
+                                                选项{{ checkIndex + 1 }}
+                                            </div>
+                                            <div style="margin-right: 10px; width: 300px" v-if="testJson.testJson[index1].checkList[checkIndex] &&
+                                                testJson.testJson[index1].checkList[checkIndex]
+                                                    .imgType &&
+                                                testJson.testJson[index1].checkList[checkIndex]
+                                                    .imgType == 1
+                                                ">
+                                                <div class="inImg" @click.stop="previewImg(
+                                                    testJson.testJson[index1].checkList[checkIndex]
+                                                        .src
+                                                )
+                                                    ">
+                                                    <el-image :src="testJson.testJson[index1].checkList[checkIndex]
+                                                        .src
+                                                        " lazy />
+                                                </div>
+                                            </div>
+
+                                            <el-input v-else v-model="testJson.testJson[index1].checkList[checkIndex]
+                                                " placeholder="请输入选项..."
+                                                style="width: 300px; margin-right: 10px"></el-input>
+                                            <div class="xzUpImg" @click.stop="addImg($event)">
+                                                <img src="../../../assets/icon/xzUpImg.png" alt="" />
+                                                <input type="file" accept="image/*" style="display: none"
+                                                    @change="beforeUploadTi($event, index1, checkIndex)" />
+                                            </div>
+                                        </el-radio>
+                                    </div>
+                                </el-radio-group>
+                                <el-checkbox-group v-model="testJson.testJson[index1].answer"
+                                    v-if="testJson.testJson[index1].type == '2'">
+                                    <div class="radioBox">
+                                        <el-checkbox v-for="(item2, checkIndex1) in testJson.testJson[index1]
+                                            .testItem" :key="checkIndex1" :label="checkIndex1">
+                                            <div style="margin-right: 10px">
+                                                选项{{ checkIndex1 + 1 }}
+                                            </div>
+                                            <div style="margin-right: 10px; width: 300px" v-if="testJson.testJson[index1].checkList[checkIndex1] &&
+                                                testJson.testJson[index1].checkList[checkIndex1]
+                                                    .imgType &&
+                                                testJson.testJson[index1].checkList[checkIndex1]
+                                                    .imgType == 1
+                                                ">
+                                                <div class="inImg" @click.stop="previewImg(
+                                                    testJson.testJson[index1].checkList[checkIndex1]
+                                                        .src
+                                                )
+                                                    ">
+                                                    <el-image :src="testJson.testJson[index1].checkList[checkIndex1]
+                                                        .src
+                                                        " lazy />
+                                                </div>
+                                            </div>
+
+                                            <el-input v-else v-model="testJson.testJson[index1].checkList[checkIndex1]
+                                                " placeholder="请输入选项..."
+                                                style="width: 300px; margin-right: 10px"></el-input>
+                                            <div class="xzUpImg" @click.stop="addImg($event)">
+                                                <img src="../../../assets/icon/xzUpImg.png" alt="" />
+                                                <input type="file" accept="image/*" style="display: none"
+                                                    @change="beforeUploadTi($event, index1, checkIndex1)" />
+                                            </div>
+                                        </el-checkbox>
+                                    </div>
+                                </el-checkbox-group>
+                            </div>
+                            <div class="a_add_body_div" style="margin-bottom: 3px">
+                                <el-button type="primary" size="small"
+                                    @click="addTcheckList(testJson.testJson[index1])">添加</el-button>
+                                <el-button type="primary" size="small" @click="deleteTcheckList(testJson.testJson[index1])"
+                                    v-if="testJson.testJson[index1].testItem != 1">删除
+                                </el-button>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="close()">取 消</el-button>
+                <el-button type="primary" @click="addTest">确 定</el-button>
+            </span>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+export default {
+    props: {
+        dialogVisibleChoice: {
+            type: Boolean,
+            default: false
+        },
+        json: {
+            type: Object
+        }
+    },
+    data() {
+        return {
+            testJson: {
+
+            }
+        }
+    },
+    watch: {
+        dialogVisibleChoice(newValue, oldValue) {
+            this.testJson = JSON.parse(JSON.stringify(this.json));
+        }
+    },
+    methods: {
+        handleClose(done) {
+            this.close()
+            done()
+        },
+        close() {
+            this.$emit("update:dialogVisibleChoice", false)
+        },
+        addImg(e) {
+            var el = e.currentTarget;
+            el.getElementsByTagName("input")[0].click();
+            e.target.value = "";
+        },
+        previewImg(url) {
+            this.$hevueImgPreview(url);
+        },
+        //自动获取剪贴板
+        pasteOption() {
+            let iframe = top.document.querySelectorAll("#AIChat iframe")[0]
+            if (!iframe) {
+                this.$message.error("请使用AI共创生成题目")
+                return;
+            }
+            let copyData = iframe.contentWindow.copyData
+            if (!copyData || !copyData.selectData.length) {
+                this.$message.error("请使用AI共创生成题目")
+                return;
+            }
+            let selectData = copyData.selectData;
+            for (var i = 0; i < selectData.length; i++) {
+                let answer = 0
+                switch (selectData[i].answer[0]) {
+                    case 'A':
+                        answer = 0
+                        break;
+                    case 'B':
+                        answer = 1
+                        break;
+                    case 'C':
+                        answer = 2
+                        break;
+                    case 'D':
+                        answer = 3
+                        break;
+                    case 'E':
+                        answer = 4
+                        break;
+                    default:
+                        break;
+                }
+                this.testJson.testJson.push({
+                    teststitle: selectData[i].subject,
+                    testItem: selectData[i].options.length,
+                    checkList: selectData[i].options,
+                    timuList: [],
+                    answer: answer,
+                    type: "1",
+                });
+                this.testJson.testCount++;
+            }
+            var isTestJson = JSON.parse(JSON.stringify(this.testJson));
+            isTestJson.testJson = this.testJson.testJson.filter((el) => {
+                var elc = el.checkList.filter((element) => {
+                    return element != "";
+                });
+                return (
+                    (el.teststitle != "" || el.timuList.length > 0) && elc.length != 0
+                );
+            });
+            isTestJson.testCount = isTestJson.testJson.length;
+            this.testJson = isTestJson
+            this.$forceUpdate();
+        },
+        //切换选择题类型
+        checkTestType(type, json) {
+            json.type = type;
+            if(json.type == '2'){
+                json.answer = [];
+            }else{
+                json.answer = ""
+            }
+        },
+        //添加选择题图片
+        beforeUploadTiMu(event, i) {
+            const loading = this.openLoading();
+            var file = event.target.files[0];
+            var credentials = {
+                accessKeyId: "AKIATLPEDU37QV5CHLMH",
+                secretAccessKey: "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",
+            }; //秘钥形式的登录上传
+            window.AWS.config.update(credentials);
+            window.AWS.config.region = "cn-northwest-1"; //设置区域
+
+            var bucket = new window.AWS.S3({ params: { Bucket: "ccrb" } }); //选择桶
+            var _this = this;
+
+            if (file) {
+                var params = {
+                    Key:
+                        file.name.split(".")[0] +
+                        new Date().getTime() +
+                        "." +
+                        file.name.split(".")[file.name.split(".").length - 1],
+                    ContentType: file.type,
+                    Body: file,
+                    "Access-Control-Allow-Credentials": "*",
+                    ACL: "public-read",
+                }; //key可以设置为桶的相抵路径,Body为文件, ACL最好要设置
+                var options = {
+                    partSize: 2048 * 1024 * 1024,
+                    queueSize: 2,
+                    leavePartsOnError: true,
+                };
+                bucket
+                    .upload(params, options)
+                    .on("httpUploadProgress", function (evt) {
+                        //这里可以写进度条
+                        // console.log("Uploaded : " + parseInt((evt.loaded * 80) / evt.total) + '%');
+                    })
+                    .send(function (err, data) {
+                        loading.close();
+                        if (err) {
+                            _this.$message.error("上传失败");
+                        } else {
+                            if (_this.testJson.testJson[i].timuList) {
+                                _this.testJson.testJson[i].timuList.push({
+                                    src: data.Location,
+                                });
+                            } else {
+                                _this.testJson.testJson[i].timuList = [];
+                                _this.testJson.testJson[i].timuList.push({
+                                    src: data.Location,
+                                });
+                            }
+                            _this.$forceUpdate();
+                        }
+                    });
+            }
+        },
+        //添加选择题题目图片
+        beforeUploadTi(event, i, j) {
+            const loading = this.openLoading();
+            var file = event.target.files[0];
+            var credentials = {
+                accessKeyId: "AKIATLPEDU37QV5CHLMH",
+                secretAccessKey: "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",
+            }; //秘钥形式的登录上传
+            window.AWS.config.update(credentials);
+            window.AWS.config.region = "cn-northwest-1"; //设置区域
+
+            var bucket = new window.AWS.S3({ params: { Bucket: "ccrb" } }); //选择桶
+            var _this = this;
+
+            if (file) {
+                var params = {
+                    Key:
+                        file.name.split(".")[0] +
+                        new Date().getTime() +
+                        "." +
+                        file.name.split(".")[file.name.split(".").length - 1],
+                    ContentType: file.type,
+                    Body: file,
+                    "Access-Control-Allow-Credentials": "*",
+                    ACL: "public-read",
+                }; //key可以设置为桶的相抵路径,Body为文件, ACL最好要设置
+                var options = {
+                    partSize: 2048 * 1024 * 1024,
+                    queueSize: 2,
+                    leavePartsOnError: true,
+                };
+                bucket
+                    .upload(params, options)
+                    .on("httpUploadProgress", function (evt) {
+                        //这里可以写进度条
+                        // console.log("Uploaded : " + parseInt((evt.loaded * 80) / evt.total) + '%');
+                    })
+                    .send(function (err, data) {
+                        loading.close();
+                        if (err) {
+                            _this.$message.error("上传失败");
+                        } else {
+                            _this.testJson.testJson[i].checkList[j] = {};
+                            _this.testJson.testJson[i].checkList[j].src = data.Location;
+                            _this.testJson.testJson[i].checkList[j].imgType = 1;
+                            _this.$forceUpdate();
+                        }
+                    });
+            }
+        },
+        //添加题目
+        addTestList() {
+            this.testJson.testJson.push({
+                teststitle: "",
+                testItem: 1,
+                checkList: [],
+                timuList: [],
+                answer: "",
+                type: "1",
+            });
+            this.testJson.testCount++;
+        },
+        //删除题目
+        deleteTestList(index) {
+            this.testJson.testJson.splice(index, 1);
+            this.testJson.testCount--;
+        },
+        //删除题目图片
+        deleteM(i, j) {
+            this.testJson.testJson[i].timuList.splice(j, 1);
+        },
+        //添加选项
+        addTcheckList(json) {
+            json.checkList.length++;
+            json.testItem++;
+        },
+        //删除选项    
+        deleteTcheckList(json) {
+            if(json.type == '1' && json.answer == (json.checkList.length-1)){
+                json.answer = ""
+            }else if(json.type == '2' && json.answer.indexOf(json.checkList.length-1) != -1){
+                json.answer.splice(json.checkList.length-1,1)
+            }
+            json.checkList.length--;
+            json.testItem--;
+        },
+        //添加选择题
+        addTest() {
+            var aj = this.testJson.testJson;
+            var b = 1;
+            for (var i = 0; i < aj.length; i++) {
+                if (aj[i].teststitle === "" && aj[i].timuList.length == 0) {
+                    var a = 1;
+                    for (let index = 0; index < aj[i].testItem; index++) {
+                        const element = aj[i].checkList[index]
+                            ? aj[i].checkList[index]
+                            : "";
+                        if (element != "") {
+                            b++;
+                            this.$message.error("填写了选项,题目不能为空!");
+                            return;
+                        } else {
+                            a++;
+                        }
+                    }
+                    if (b == 1) {
+                        this.$message.error("至少填写一个问题");
+                        return;
+                    }
+                } else if (aj[i].teststitle != "" || aj[i].timuList.length > 0) {
+                    for (let index = 0; index < aj[i].testItem; index++) {
+                        const element = aj[i].checkList[index]
+                            ? aj[i].checkList[index]
+                            : "";
+                        var index = 0;
+                        for (var z = 0; z < aj[i].checkList.length; z++) {
+                            var checkC = aj[i].checkList[z] ? aj[i].checkList[z] : "";
+                            if (checkC != "") {
+                                index++;
+                            } else {
+                                this.$message.error("选项不能为空!");
+                                return;
+                            }
+                        }
+                        b++;
+                        if (index < 2) {
+                            this.$message.error("填写了的题目,选项至少要有两项!");
+                            return;
+                        }
+                        if (
+                            (aj[i].type == "2" && !aj[i].answer.length) ||
+                            (aj[i].type == "1" && aj[i].answer !== 0 && !aj[i].answer)
+                        ) {
+                            this.$message.error("有题目未选择答案请选择答案");
+                            return;
+                        }
+                    }
+                }
+            }
+            var isTestJson = JSON.parse(JSON.stringify(this.testJson));
+            isTestJson.testJson = this.testJson.testJson.filter((el) => {
+                var elc = el.checkList.filter((element) => {
+                    return element != "";
+                });
+                return (
+                    (el.teststitle != "" || el.timuList.length > 0) && elc.length != 0
+                );
+            });
+            isTestJson.testCount = isTestJson.testJson.length;
+
+            this.$emit("add",45,isTestJson)
+        },
+    },
+    mounted() {
+        this.testJson = JSON.parse(JSON.stringify(this.json));
+    },
+}
+</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;
+}
+
+.a_addBox {
+    margin: 10px 0;
+    background: #fff;
+    padding: 15px;
+    max-height: 600px;
+    overflow: auto;
+}
+
+.a_add_box {
+    border-bottom: 2px solid #eee;
+    padding-bottom: 25px;
+}
+
+.a_add_head {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin: 10px 0 0 0;
+    font-size: 18px;
+}
+
+.a_add_checkType {
+    margin-top: 10px;
+    display: flex;
+    font-size: 16px;
+    align-items: center;
+}
+
+.a_add_checkType span {
+    box-sizing: border-box;
+    padding: 0 0 5px 0;
+    cursor: pointer;
+}
+
+.a_add_checkType span+span {
+    margin-left: 10px;
+}
+
+.a_add_checkType .active {
+    border-bottom: 2px solid #409eff;
+    color: #409eff;
+}
+
+.a_add_head .a_add_head_input {
+    width: 300px;
+}
+
+.a_add_head .a_add_head_div {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+}
+
+.a_add_body {
+    display: flex;
+    /* align-items: center; */
+    align-items: flex-end;
+}
+
+.a_add_input {
+    display: flex;
+    align-items: center;
+    flex-wrap: wrap;
+}
+
+.a_add_input_choice {
+    flex-direction: column;
+    margin-right: 10px;
+}
+
+.a_add_input_choice>>>.el-radio {
+    display: flex;
+    align-items: center;
+    flex-direction: row-reverse;
+    margin: 30px 0 0 0;
+}
+
+.a_add_input_choice>>>.el-checkbox {
+    display: flex;
+    align-items: center;
+    flex-direction: row-reverse;
+    margin: 30px 0 0 0;
+}
+
+.xzUpImg {
+    width: 25px;
+    height: 25px;
+    cursor: pointer;
+}
+
+.xzUpImg>img {
+    width: 100%;
+    height: 100%;
+}
+
+.timuUpImg {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+}
+
+.timuUpImg>div:nth-child(1) {
+    margin-right: 10px;
+}
+
+.timuImgBox {
+    margin: 10px 0;
+    display: flex;
+    flex-direction: column;
+    flex-wrap: wrap;
+    align-items: flex-start;
+}
+
+.timuImg {
+    width: 100px;
+    margin: 5px 0;
+    cursor: pointer;
+    position: relative;
+}
+
+.timuImg:hover .deleteWord {
+    display: block;
+}
+
+.deleteWord {
+    width: 25px;
+    height: 25px;
+    position: absolute;
+    right: -5px;
+    top: -5px;
+    cursor: pointer;
+    display: none;
+}
+
+.timuImg>img,
+.deleteWord>img {
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+}
+
+.radioBox>div {
+    margin: 10px 0 0 10px;
+}
+
+.radioBox>>>.el-radio__input,
+.radioBox>>>.el-checkbox__inner {
+    margin-left: 10px;
+}
+
+.radioBox>>>.el-radio__label,
+.radioBox>>>.el-checkbox__label {
+    display: flex;
+    align-items: center;
+}
+
+.inImg {
+    width: 50px;
+}
+
+.inImg>img {
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+}
+</style>

+ 465 - 0
src/components/pages/interVideo/index.vue

@@ -0,0 +1,465 @@
+<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="btnBox">
+                    <el-button type="primary" size="default" @click="addImg($event)" v-if="!this.json.video">
+                        添加视频
+                        <input type="file" accept="video/mp4, video/quicktime, video/x-msvideo" style="display: none"
+                            @change="addVideo($event)" />
+                    </el-button>
+                    <el-button type="primary" size="default" @click="reset" v-else>重置</el-button>
+
+                </div>
+                <div class="videoBox">
+                    <video-player class="video-player vjs-custom-skin" ref="videoPlayer" :playsinline="true"
+                        :options="playerO" v-if="this.json.video"></video-player>
+                    <div class="content" v-else>请上传视频</div>
+                </div>
+                <div class="settingBox" v-if="this.json.video">
+                    <div class="settingBtn">
+                        <span class="title">交互设置</span>
+                        <el-button type="primary" size="small" @click="addSetting">添加</el-button>
+                    </div>
+                    <div class="settingContent">
+                        <div class="setting_b" v-for="(item, index) in json.setting" :key="index">
+                            <div class="time_box">
+                                <span>触发时间:</span>
+                                <el-input-number v-model="item.time" :controls="false" :min="1" placeholder="视频第几秒"
+                                    @change="changeTime(item.time, index)"></el-input-number>
+                            </div>
+                            <div class="setting_fool">
+                                <span>工具设置:</span>
+                                <el-button type="primary" size="mini" @click="setting(index)">{{ item.tool.tool ? "已设置" :
+                                    "工具设置" }}</el-button>
+                            </div>
+                            <div>
+                                <el-button type="primary" size="mini" @click="deleteSetting(index)">删除</el-button>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="close">取 消</el-button>
+                <el-button type="primary" @click="addV">确定</el-button>
+            </span>
+        </el-dialog>
+        <choiceDialog :dialogVisibleChoice.sync="dialogVisibleChoice" :json="settingJson" @add="addSettingJson"
+            v-if="dialogVisibleVideo"></choiceDialog>
+        <div v-if="proVisible" class="mask">
+            <div class="progressBox">
+                <div class="lbox">
+                    <img src="../../../assets/loading.gif" />上传中,请稍后
+                </div>
+                <div style="margin-bottom: 10px">
+                    <span>{{ isFinishSize }}M</span> / <span>{{ isAllSize }}M</span>
+                </div>
+                <el-progress :text-inside="true" :stroke-width="20" :percentage="progress" style="width: 80%"></el-progress>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import choiceDialog from '../choice/index.vue'
+export default {
+    props: {
+        dialogVisibleVideo: {
+            type: Boolean,
+            default: false
+        },
+        videoJson: {
+            type: Object
+        }
+    },
+    components: {
+        choiceDialog,
+    },
+    data() {
+        return {
+            json: {},
+            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: true, //全屏按钮
+                },
+            },
+            playerO: {},
+            videoTime: 0,
+            settingIndex: 0,
+            settingJson: {},
+            dialogVisibleChoice: false,
+            proVisible: false,
+            isFinishSize: 0,
+            isAllSize: 0,
+            progress: 0,
+        }
+    },
+    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.$nextTick(() => {
+                    setTimeout(() => {
+                        this.videoTime = Math.round(this.$refs['videoPlayer'].player.cache_.duration)
+                    }, 500)
+                })
+            }
+        }
+    },
+    methods: {
+        handleClose(done) {
+            this.close()
+            done()
+        },
+        close() {
+            this.$emit("update:dialogVisibleVideo", false)
+        },
+        addV() {
+            if (!this.json.video) {
+                this.$message.error("请上传视频")
+                return;
+            }
+            if (!this.json.setting.length) {
+                this.$message.error("请添加至少一个交互")
+                return;
+            }
+            let settingType = 1
+            let settingToolType = 1
+            let settingTypeArray = []
+            for (var i = 0; i < this.json.setting.length; i++) {
+                if (settingTypeArray.indexOf(this.json.setting[i].time) == -1) {
+                    settingTypeArray.push(this.json.setting[i].time)
+                } else {
+                    settingType = 2
+                    break
+                }
+                if (!this.json.setting[i].tool.tool) {
+                    settingToolType = 2
+                }
+            }
+            if (settingType == 2) {
+                this.$message.error("不能设置一样的触发时间")
+                return;
+            }
+            if (settingToolType == 2) {
+                this.$message.error("请对交互设置工具")
+                return;
+            }
+            this.$emit('add', this.json)
+        },
+        addSettingJson(tool, json) {
+            this.json.setting[this.settingIndex].tool.tool = tool
+            this.json.setting[this.settingIndex].tool.toolJson = json
+            this.dialogVisibleChoice = false
+        },
+        setting(index) {
+            this.settingIndex = index
+            let testJson = {}
+            if (this.json.setting[index].tool.tool) {
+                testJson = JSON.parse(JSON.stringify(this.json.setting[index].tool.toolJson))
+            } else {
+                testJson = {
+                    testCount: 1,
+                    testTitle: "",
+                    testJson: [
+                        {
+                            teststitle: "",
+                            testItem: 1,
+                            checkList: [],
+                            timuList: [],
+                            answer: "",
+                            type: "1",
+                        },
+                    ],
+                };
+            }
+
+            this.settingJson = testJson
+            this.dialogVisibleChoice = true
+        },
+        changeTime(time, index) {
+            if (time > this.videoTime) {
+                this.$message.error("设置时间不能大于视频播放时长")
+                this.$nextTick(() => {
+                    this.json.setting[index].time = 1
+                    this.$forceUpdate();
+                })
+            }
+        },
+        addSetting() {
+            this.json.setting.push({
+                time: "",
+                tool: {
+                    tool: "",
+                    toolJson: {}
+                }
+            })
+        },
+        deleteSetting(index) {
+            this.json.setting.splice(index, 1)
+        },
+        reset() {
+            this
+                .$confirm("确定重置么?", "提示", {
+                    confirmButtonText: "确定",
+                    cancelButtonText: "取消",
+                    type: "warning",
+                })
+                .then(() => {
+                    this.json = {
+                        video: "",
+                        setting: []
+                    }
+                })
+                .catch(() => {
+                    return;
+                });
+        },
+        addImg(e) {
+            var el = e.currentTarget;
+            el.getElementsByTagName("input")[0].click();
+            e.target.value = "";
+        },
+        addVideo(event) {
+
+            var file = event.target.files[0];
+            var credentials = {
+                accessKeyId: "AKIATLPEDU37QV5CHLMH",
+                secretAccessKey: "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",
+            }; //秘钥形式的登录上传
+            window.AWS.config.update(credentials);
+            window.AWS.config.region = "cn-northwest-1"; //设置区域
+
+            var bucket = new window.AWS.S3({ params: { Bucket: "ccrb" } }); //选择桶
+            var _this = this;
+            _this.progress = 0;
+            _this.proVisible = true;
+            _this.isFinishSize = 0;
+            _this.isAllSize = (file.size / 1024 / 1024).toFixed(2);
+            if (file) {
+                var params = {
+                    Key:
+                        file.name.split(".")[0] +
+                        new Date().getTime() +
+                        "." +
+                        file.name.split(".")[file.name.split(".").length - 1],
+                    ContentType: file.type,
+                    Body: file,
+                    "Access-Control-Allow-Credentials": "*",
+                    ACL: "public-read",
+                }; //key可以设置为桶的相抵路径,Body为文件, ACL最好要设置
+                var options = {
+                    partSize: 2048 * 1024 * 1024,
+                    queueSize: 2,
+                    leavePartsOnError: true,
+                };
+                bucket
+                    .upload(params, options)
+                    .on("httpUploadProgress", function (evt) {
+                        //这里可以写进度条
+                        // console.log("Uploaded : " + parseInt((evt.loaded * 80) / evt.total) + '%');
+                        _this.progress = parseInt((evt.loaded / evt.total) * 100);
+                        _this.isFinishSize = (evt.loaded / 1024 / 1024).toFixed(2);
+                        _this.$forceUpdate();
+                    })
+                    .send(function (err, data) {
+                        _this.progress = 100;
+                        _this.isFinishSize = _this.isAllSize;
+                        _this.$forceUpdate();
+                        setTimeout(() => {
+                            _this.proVisible = false;
+                            _this.$forceUpdate();
+                        }, 500);
+                        if (err) {
+                            _this.$message.error("上传失败");
+                        } else {
+                            _this.json.video = data.Location;
+                            _this.playerO = JSON.parse(JSON.stringify(_this.playerOptions));
+                            _this.playerO.sources[0].src = data.Location
+                            _this.$nextTick(() => {
+                                setTimeout(() => {
+                                    console.log(_this.$refs['videoPlayer']);
+                                    _this.videoTime = Math.round(_this.$refs['videoPlayer'].player.cache_.duration)
+                                }, 500)
+                            })
+                            _this.$forceUpdate();
+                        }
+                    });
+            }
+        }
+    },
+    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;
+}
+
+.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%;
+}
+
+.settingBox {
+    margin-top: 20px;
+}
+
+.settingBtn {
+    display: flex;
+    align-items: center;
+}
+
+.settingBtn>.title {
+    font-size: 22px;
+    margin-right: 10px;
+    color: #222;
+}
+
+.settingContent {
+    width: 100%;
+    display: flex;
+    flex-wrap: wrap;
+    margin-top: 20px;
+}
+
+.setting_b {
+    margin: 0 20px 20px 0;
+}
+
+.setting_b div+div {
+    margin: 10px 0 0 0;
+}
+
+.time_box {}
+
+.setting_fool {}
+
+.settingBox>>>.el-input-number.is-without-controls .el-input__inner {
+    text-align: left;
+}
+
+.mask {
+    background-color: rgb(0 0 0 / 30%);
+    position: fixed;
+    /* position: absolute; */
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    z-index: 99999;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.progressBox {
+    width: 300px;
+    height: 150px;
+    background: #fff;
+    border-radius: 10px;
+    box-shadow: 0 0 6px 1px #bfbfbf;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    flex-direction: column;
+    position: relative;
+    color: #6c6c6c;
+}
+
+.progressBox>>>.el-progress-bar__outer {
+    background-color: #d1dfff !important;
+}
+
+.progressBox .lbox {
+    height: 50px;
+    font-size: 19px;
+    display: flex;
+    align-items: center;
+    color: #747474;
+}
+
+.progressBox .lbox img {
+    width: 40px;
+    margin-right: 20px;
+}
+</style>

+ 8 - 4
src/components/pages/teacherSource/dialog.vue

@@ -168,14 +168,18 @@ export default {
                         })
                     }else if(this.typea == '3b12e8d9-866f-46bb-aa22-76cb3b7788b3'){
                         return this.CourseTypeJson[tid].filter(e => {
-                            return ['语文','科学','英语','历史','化学'].indexOf(e.name) != -1 
+                            return ['语文','科学','英语','历史','化学','信息技术','物理','科学','音乐','通用'].indexOf(e.name) != -1 
                         })
                     }else if(this.typea == 'd760341a-5ab7-417f-bfc8-0fd3f183408a'){
                         return this.CourseTypeJson[tid].filter(e => {
-                            return  ['优质课例'].indexOf(e.name) != -1 
+                            return  ['优质课例','理论研究'].indexOf(e.name) != -1 
+                        })
+                    }else if(this.typea == '926efcf3-da23-4123-aa57-50341bf7d85f'){
+                        return this.CourseTypeJson[tid].filter(e => {
+                            return  ['图像获取','图像处理','图像生成','视频处理','视频生成'].indexOf(e.name) != -1 
                         })
                     }else{
-                        return this.CourseTypeJson[tid]
+                        return []
                     }
                 }
             };
@@ -248,9 +252,9 @@ export default {
                 });
         },
         getCourse2(typeName, ftypeId, typeid, type) {
-            this.typeb = "";
             this.page = 1;
             if (typeName == "场景") {
+                this.typeb = "";
                 if (type == 1) {
                     if (this.typeE.indexOf(typeid) != -1) {
                         this.typeE.splice(this.typeE.indexOf(typeid), 1);

+ 11 - 6
src/components/pages/teacherSource/index.vue

@@ -9,7 +9,8 @@
             <div class="pb_head">
                 <span>教师资源</span>
                 <div class="student_button">
-                    <el-button type="primary" class="bgColor" @click="addSource" v-show="false">添加资源</el-button>
+                    <el-button type="primary" class="bgColor" @click="addSource">添加资源</el-button>
+                    <!-- v-show="false" -->
                 </div>
             </div>
             <div class="reBox">
@@ -84,7 +85,7 @@
                                     ">{{ item.name }}</span>
                                 <el-checkbox-group v-model="courseTypeId2" v-if="CourseTypeJson[item.id].length > 0
                                     ">
-                                    <el-checkbox v-for="item1 in ctype" :key="item1.id"
+                                    <el-checkbox v-for="item1 in CourseTypeJson[item.id]" :key="item1.id"
                                         :label="item1.id">{{ item1.name }}</el-checkbox>
                                 </el-checkbox-group>
                             </div>
@@ -169,14 +170,18 @@ export default {
                         })
                     }else if(this.typea == '3b12e8d9-866f-46bb-aa22-76cb3b7788b3'){
                         return this.CourseTypeJson[tid].filter(e => {
-                            return ['语文','科学','英语','历史','化学'].indexOf(e.name) != -1 
+                            return ['语文','科学','英语','历史','化学','信息技术','物理','科学','音乐','通用'].indexOf(e.name) != -1 
                         })
                     }else if(this.typea == 'd760341a-5ab7-417f-bfc8-0fd3f183408a'){
                         return this.CourseTypeJson[tid].filter(e => {
-                            return  ['优质课例'].indexOf(e.name) != -1 
+                            return  ['优质课例','理论研究'].indexOf(e.name) != -1 
+                        })
+                    }else if(this.typea == '926efcf3-da23-4123-aa57-50341bf7d85f'){
+                        return this.CourseTypeJson[tid].filter(e => {
+                            return  ['图像获取','图像处理','图像生成','视频处理','视频生成'].indexOf(e.name) != -1 
                         })
                     }else{
-                        return this.CourseTypeJson[tid]
+                        return []
                     }
                 }
             };
@@ -239,9 +244,9 @@ export default {
                 });
         },
         getCourse2(typeName, ftypeId, typeid, type) {
-            this.typeb = "";
             this.page = 1;
             if (typeName == "场景") {
+                this.typeb = "";
                 if (type == 1) {
                     if (this.typeE.indexOf(typeid) != -1) {
                         this.typeE.splice(this.typeE.indexOf(typeid), 1);