瀏覽代碼

Merge branch 'beta' into HK

lsc 1 年之前
父節點
當前提交
62447f14bc
共有 40 個文件被更改,包括 6747 次插入267 次删除
  1. 4 0
      dist/index.html
  2. 0 0
      dist/static/css/app.8f96fe47f6aaee9bfd994e51b2f7bcaa.css
  3. 0 0
      dist/static/css/app.8f96fe47f6aaee9bfd994e51b2f7bcaa.css.map
  4. 二進制
      dist/static/img/addStage.b6a9d67.png
  5. 0 0
      dist/static/js/app.427b96ffabccb102bb60.js
  6. 1 0
      dist/static/js/app.427b96ffabccb102bb60.js.map
  7. 0 0
      dist/static/js/app.d43ea31ff2f332b21a79.js.map
  8. 0 0
      dist/static/js/manifest.f583576dfec9dfc9a295.js.map
  9. 5 0
      src/App.vue
  10. 二進制
      src/assets/icon/new/addStage.png
  11. 二進制
      src/assets/icon/new/c_down.png
  12. 二進制
      src/assets/icon/new/c_up.png
  13. 二進制
      src/assets/icon/new/cover_update.png
  14. 二進制
      src/assets/icon/thirdToolList/english.png
  15. 37 36
      src/common/tools.js
  16. 454 85
      src/components/pages/addCourse.vue
  17. 90 0
      src/components/pages/components/englishRight.vue
  18. 441 68
      src/components/pages/easy/addCourse.vue
  19. 90 0
      src/components/pages/easy/commpont/englishRight.vue
  20. 1 1
      src/components/pages/synergyCourse/addCourse.vue
  21. 8 6
      src/components/pages/synergyCourse/course.vue
  22. 3 2
      src/components/pages/synergyCourse/group/group.vue
  23. 428 56
      src/components/pages/task/addCourse.vue
  24. 90 0
      src/components/pages/task/commpont/englishRight.vue
  25. 291 0
      src/components/pages/test/add/addTest.vue
  26. 361 0
      src/components/pages/test/add/components/checkOrder.vue
  27. 90 0
      src/components/pages/test/add/components/choice/choice.vue
  28. 214 0
      src/components/pages/test/add/components/choice/index.vue
  29. 315 0
      src/components/pages/test/add/edit/edit/index.vue
  30. 134 0
      src/components/pages/test/add/edit/index.vue
  31. 44 0
      src/components/pages/test/add/minxins/minxin.js
  32. 412 0
      src/components/pages/test/add/setInfo/index.vue
  33. 335 0
      src/components/pages/test/add/setInfo/manualCreated.vue
  34. 1170 0
      src/components/pages/test/index.vue
  35. 1139 0
      src/components/pages/testStudent/index.vue
  36. 110 0
      src/components/pages/testStudent/view/component/choice.vue
  37. 195 0
      src/components/pages/testStudent/view/component/topic.vue
  38. 212 0
      src/components/pages/testStudent/view/preview.vue
  39. 36 8
      src/components/tools/sunburst.vue
  40. 37 5
      src/router/index.js

+ 4 - 0
dist/index.html

@@ -25,7 +25,11 @@
       height: 100%;
       width: 100%;
       background: #e6eaf0;
+<<<<<<< HEAD
     }</style><link href=./static/css/app.b11aa36d5aafaad2eb7c3faeece27c1a.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.f583576dfec9dfc9a295.js></script><script type=text/javascript src=./static/js/vendor.88e838fb9ceb45f00767.js></script><script type=text/javascript src=./static/js/app.d43ea31ff2f332b21a79.js></script></body></html><script>function stopSafari() {
+=======
+    }</style><link href=./static/css/app.8f96fe47f6aaee9bfd994e51b2f7bcaa.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.3512a67a6213c2df4180.js></script><script type=text/javascript src=./static/js/vendor.1b8e037bd3fbbd358d74.js></script><script type=text/javascript src=./static/js/app.427b96ffabccb102bb60.js></script></body></html><script>function stopSafari() {
+>>>>>>> beta
     //阻止safari浏览器双击放大功能
     let lastTouchEnd = 0  //更新手指弹起的时间
     document.documentElement.addEventListener("touchstart", function (event) {

File diff suppressed because it is too large
+ 0 - 0
dist/static/css/app.8f96fe47f6aaee9bfd994e51b2f7bcaa.css


File diff suppressed because it is too large
+ 0 - 0
dist/static/css/app.8f96fe47f6aaee9bfd994e51b2f7bcaa.css.map


二進制
dist/static/img/addStage.b6a9d67.png


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/app.427b96ffabccb102bb60.js


File diff suppressed because it is too large
+ 1 - 0
dist/static/js/app.427b96ffabccb102bb60.js.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/app.d43ea31ff2f332b21a79.js.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/manifest.f583576dfec9dfc9a295.js.map


+ 5 - 0
src/App.vue

@@ -105,6 +105,8 @@ export default {
         "/studioCourse",
         "/teacherSource",
         "/grade",
+        "/test",
+        "/testStudent"
         // "/eventCenter",
         // "/addRace",
         // "/anliDetail",
@@ -478,4 +480,7 @@ html::-webkit-scrollbar-thumb {
   display: flex;
   align-items: center;
 }
+.el-cascader-node__label{
+  max-width: 150px;
+}
 </style>

二進制
src/assets/icon/new/addStage.png


二進制
src/assets/icon/new/c_down.png


二進制
src/assets/icon/new/c_up.png


二進制
src/assets/icon/new/cover_update.png


二進制
src/assets/icon/thirdToolList/english.png


+ 37 - 36
src/common/tools.js

@@ -1,37 +1,38 @@
 export const tools = {
-  58: { name: "模拟驾驶" },
-  59: { name: "路径搜索" },
-  60: { name: "深度学习" },
-  10: { name: "倒计时" },
-  65: { name: "挑人" },
-  7: { name: "思维网格" },
-  1: { name: "电子白板" },
-  52: { name: "文档" },
-  3: { name: "思维导图" },
-  48: { name: "表格" },
-  49: { name: "学生分组" },
-  4: { name: "问卷调查" },
-  45: { name: "选择题" },
-  15: { name: "问答" },
-  16: { name: "作业提交" },
-  50: { name: "批量上传" },
-  41: { name: "选择匹配" },
-  47: { name: "排序" },
-  40: { name: "个人评价" },
-  18: { name: "训练平台" },
-  21: { name: "AIoT Blockly" },
-  23: { name: "AI Python" },
-  24: { name: "AI Blockly" },
-  32: { name: "源码编辑" },
-  57: { name: "CocoPi" },
-  63: { name: "海龟编程" },
-  28: { name: "翻译" },
-  31: { name: "数字画板" },
-  39: { name: "GeoGebra" },
-  66: { name: "公式编辑" },
-  67: { name: "分子结构" },
-  68: { name: "时间轴" },
-  25: { name: "目标管理" },
-  26: { name: "课程设计" },
-  62: { name: "交互视频" }
-};
+    58: { name: "模拟驾驶" },
+    59: { name: "路径搜索" },
+    60: { name: "深度学习" },
+    10: { name: "倒计时" },
+    65: { name: "挑人" },
+    7: { name: "思维网格" },
+    1: { name: "电子白板" },
+    52: { name: "文档" },
+    3: { name: "思维导图" },
+    48: { name: "表格" },
+    49: { name: "学生分组" },
+    4: { name: "问卷调查" },
+    45: { name: "选择题" },
+    15: { name: "问答" },
+    16: { name: "作业提交" },
+    50: { name: "批量上传" },
+    41: { name: "选择匹配" },
+    47: { name: "排序" },
+    40: { name: "个人评价" },
+    18: { name: "训练平台" },
+    21: { name: "AIoT Blockly" },
+    23: { name: "AI Python" },
+    24: { name: "AI Blockly" },
+    32: { name: "源码编辑" },
+    57: { name: "CocoPi" },
+    63: { name: "海龟编程" },
+    28: { name: "翻译" },
+    31: { name: "数字画板" },
+    39: { name: "GeoGebra" },
+    66: { name: "公式编辑" },
+    67: { name: "分子结构" },
+    68: { name: "时间轴" },
+    69: { name: "英语写作" },
+    25: { name: "目标管理" },
+    26: { name: "课程设计" },
+    62: { name: "交互视频" }
+};

File diff suppressed because it is too large
+ 454 - 85
src/components/pages/addCourse.vue


+ 90 - 0
src/components/pages/components/englishRight.vue

@@ -0,0 +1,90 @@
+<template>
+  <div class="englishBox">
+    <div class="themeTitle">
+      <div>作文题目<span style="color: red;">*</span></div>
+      <div>
+        <el-input
+          v-model="engList.engTitle"
+          placeholder="请填写作文题目"
+          @change="setEngList"
+        ></el-input>
+      </div>
+    </div>
+    <div class="themeText">
+      <div>作文要求<span style="color: red;">*</span></div>
+      <div>
+        <editor-bar
+          placeholder="请填写作文要求"
+          v-model="engList.englishText"
+          @change="setEngList"
+        ></editor-bar>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import EditorBar from "../../../components/tools/wangEnduit";
+export default {
+  components: {
+    EditorBar,
+  },
+  props: ["englishList"],
+  data() {
+    return {
+      engList: {
+        engTitle: "",
+        englishText: "",
+      },
+    };
+  },
+  methods: {
+    setEngList() {
+      this.$emit("setEnglish", this.engList);
+    },
+  },
+  created() {
+    this.engList = this.englishList;
+  },
+};
+</script>
+
+<style scoped>
+.englishBox {
+  width: 50%;
+  margin: 50px auto 0;
+}
+.themeTitle {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  align-items: center;
+}
+.themeTitle > div:first-child {
+  min-width: 65px;
+  font-weight: bold;
+}
+.themeTitle > div:last-child {
+  width: calc(100% - 75px);
+  margin-left: 10px;
+}
+.themeText {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  align-items: flex-start;
+  margin-top: 20px;
+}
+.themeText > div:first-child {
+  min-width: 65px;
+  margin-top: 10px;
+  font-weight: bold;
+}
+.themeText > div:last-child {
+  width: calc(100% - 75px);
+  margin-left: 10px;
+}
+.themeText > div:last-child >>> .text {
+  min-height: 400px !important;
+}
+</style>

+ 441 - 68
src/components/pages/easy/addCourse.vue

@@ -94,16 +94,18 @@
                     </div> -->
                       <div class="c_info_title" style="padding: 0 0 15px;margin: 0 auto 0 0;">上传封面</div>
                       <div style="width: 100%;">
-                        <div class="uploadFm" @click="choosePicVisible = true" v-if="cover.length == 0">
-                          <img src="../../../assets/icon/addPoster.png" alt="" />
-                          <div>点击添加封面</div>
+                        <div class="uploadFm" @click="choosePicVisible = true" :class="{uploadFm2:cover.length}">
+                          <img src="../../../assets/icon/addPoster.png" alt="" v-if="cover.length == 0"/>
+                          <img :src="cover[0].url" alt="" class="cover_p" v-else/>
+                          <div v-if="cover.length == 0">点击添加封面</div>
+                          <div class="cover_mask"><img src="../../../assets/icon/new/cover_update.png" /><span style="margin-top:5px;">修改封面</span></div>
                         </div>
-                        <el-upload :class="{ disUoloadSty: noneBtnImg }" class="upCss" action="#" list-type="picture"
+                        <!-- <el-upload :class="{ disUoloadSty: noneBtnImg }" class="upCss" action="#" list-type="picture"
                           v-loading="uploadLoading1" :http-request="beforeUpload1" ref="upload1"
                           :on-preview="handlePictureCardPreview" :on-remove="handle_remove1" :show-file-list="true"
                           :file-list="cover" accept="image/*" :limit="1" :on-exceed="onExceed" v-else>
                           <i class="el-icon-plus"></i>
-                        </el-upload>
+                        </el-upload> -->
                       </div>
                     </div>
                   </div>
@@ -166,16 +168,19 @@
                   <div class="stepsBottom2">
                     <div class="navBottom" :style="{ height: heightPx }">
                       <div v-for="(t, tIndex) in unitJson[unitIndex].chapterInfo[0]
-                        .taskJson" :key="tIndex">
+                        .taskJson" :key="tIndex" :class="{
+                          dragOverTop: newIndex === tIndex && typeIndex == 'task-'+tIndex && oldIndex > tIndex,
+                          dragOverBottom: newIndex === tIndex && typeIndex == 'task-'+tIndex && oldIndex < tIndex,
+                        }">
                         <div @dragstart="dragTaskStart(t, tIndex)" @dragover.prevent="dragTaskOver(tIndex)"
                           @dragend="dragTaskEnd()" draggable @click="goToTask(tIndex)" class="navTask" :class="{
-                          isNavTask:
-                            isClickColor > 0 && isClickColor == tIndex + 1,
-                          isNavOpen: t.toolOpen
-                        }">
+                            isNavTask:
+                              isClickColor > 0 && isClickColor == tIndex + 1,
+                            isNavOpen: t.toolOpen,
+                          }">
                           <div style="left: 8px;" class="chapter_upload_drag"></div>
                           <div class="nt_taskBox">
-                            <div class="nt_taskTitle">任务{{ tIndex + 1 }}</div>
+                            <div class="nt_taskTitle">任务{{ tIndex + 1 }}</div>
                             <div class="nt_taskName">
                               <el-tooltip effect="light" :content="t.task" placement="top">
                                 <span>{{ t.task }}</span>
@@ -195,7 +200,7 @@
                           <div v-for="(tool, toolIndex2) in t.toolChoose" :key="toolIndex2"
                             @click="jumpGj(tIndex, toolIndex2)">
                             <div class="gjCss" :class="{ isGjCss: toolIndexType == `gj${tIndex}${toolIndex2}` }">
-                              <div>工具{{ toolIndex2 + 1 }}:</div>
+                              <div>工具{{ toolIndex2 + 1 }}</div>
                               <div>{{ toolsData[tool.tool[0]] && toolsData[tool.tool[0]].name }}</div>
                             </div>
                           </div>
@@ -221,6 +226,7 @@
                             align-items: center;
                           ">
                           <div class="lineTitle" style="margin-bottom:10px">学习内容</div>
+<<<<<<< HEAD
                           <div class="add_info_box">
                             <button class="c_pub_button_add pub_btn_add_img" @click="addImg($event)">
                               文件
@@ -245,6 +251,8 @@
                                 " />
                             </button> -->
                           </div>
+=======
+>>>>>>> beta
                           <div style="margin-bottom:10px" v-if="!item.taskJson[0].isFoldchapter" class="show_taskD show"
                             @click="foldC(0)"><img src="../../../assets/icon/new/icon-slide.png" />收起学习内容</div>
                           <div style="margin-bottom:10px" v-else class="show_taskD" @click="foldC(0)"><img
@@ -255,17 +263,20 @@
                             item.taskJson[0].chapterData.length == 0
                             "><img src="../../../assets/icon/new/c_none.png" alt /><span>请添加学习内容</span></div>
                           <div v-else class="add_chapters_box" style="display: flex; flex-direction: column">
-                            <div @dragstart="dragStart(item1, index1, 0)" @dragover.prevent="dragOver(index1)"
+                            <div @dragstart="dragStart(item1, index1, 0)" @dragover.prevent="dragOver(index1, 0)"
                               @dragend="dragEnd()" draggable class="chapter_upload" v-for="(item1, index1) in item.taskJson[0]
                                 .chapterData" :key="item1.id" @click="
-    getChapterData(
-      $event,
-      unitIndex,
-      index,
-      index1,
-      item1.type
-    )
-    ">
+                              getChapterData(
+                                $event,
+                                unitIndex,
+                                index,
+                                index1,
+                                item1.type
+                              )
+                              " :class="{
+                                dragOverTop2: newIndex === index1 && typeIndex == 'chapter-'+'0'+'-'+index1 && oldIndex > index1,
+                                dragOverBottom2: newIndex === index1 && typeIndex == 'chapter-'+'0'+'-'+index1 && oldIndex < index1,
+                              }">
                               <div class="chapter_upload_drag"></div>
                               <div class="chapter_upload_t" style="width: 100%"></div>
                               <div class="chapter_upload_o" style="
@@ -403,6 +414,30 @@
                             </div>
                           </div>
                         </div>
+                        <div class="add_info_box" style="margin:10px 0 0" v-if="!item.taskJson[0].isFoldchapter">
+                            <button class="c_pub_button_add pub_btn_add_img" @click="addImg($event)">
+                              文件
+                              <input type="file" accept="*" style="display: none" v-if="inputShow"
+                                @change="beforeUpload2($event, unitIndex, 13, 0)" />
+                            </button>
+                            <button class="c_pub_button_add pub_btn_add_img" @click="addAttText(0)">
+                              图文
+                            </button>
+                            <button class="c_pub_button_add pub_btn_add_img" @click="openLine(0)">
+                              链接
+                            </button>
+                            <button class="c_pub_button_add pub_btn_add_img" @click="pasteLine(0)">
+                              代码
+                            </button>
+                            <button class="c_pub_button_add pub_btn_add_img" @click="openSource(0)">
+                              资源
+                            </button>
+                            <!-- <button class="info_btn" @click="addImg($event)">
+                              其他附件
+                              <input type="file" accept="*" style="display: none" v-if="inputShow" @change="beforeUpload2($event, unitIndex, 12, itemTaskIndex)
+                                " />
+                            </button> -->
+                          </div>
                         <div v-if="unitJson[unitIndex].chapterInfo[0].taskJson[0]
                           .proVisible
                           " class="mask">
@@ -507,14 +542,14 @@
                               </div>
                               <div class="chooseWho">
                                 <div :class="itemTool.toolType == 0 ? 'isChooseActive' : ''
-                                  " @click="(itemTool.toolType = 0), (itemTool.isFold3 = true), $forceUpdate()">
+                                  " @click="(itemTool.toolType = 0), (itemTool.isFold3 = false), $forceUpdate()">
                                   互动类
                                 </div>
                                 <div :class="itemTool.toolType == 1
                                   ? 'isChooseActive'
                                   : ''
                                   " @click="
-    (itemTool.toolType = 1), (itemTool.isFold3 = true), $forceUpdate()
+    (itemTool.toolType = 1), (itemTool.isFold3 = false), $forceUpdate()
     ">
                                   思维类
                                 </div>
@@ -522,7 +557,7 @@
                                   ? 'isChooseActive'
                                   : ''
                                   " @click="
-    (itemTool.toolType = 6), (itemTool.isFold3 = true), $forceUpdate()
+    (itemTool.toolType = 6), (itemTool.isFold3 = false), $forceUpdate()
     ">
                                   协作类
                                 </div>
@@ -530,7 +565,7 @@
                                   ? 'isChooseActive'
                                   : ''
                                   " @click="
-    (itemTool.toolType = 2), (itemTool.isFold3 = true), $forceUpdate()
+    (itemTool.toolType = 2), (itemTool.isFold3 = false), $forceUpdate()
     ">
                                   测评类
                                 </div>
@@ -538,7 +573,7 @@
                                   ? 'isChooseActive'
                                   : ''
                                   " @click="
-    (itemTool.toolType = 7), (itemTool.isFold3 = true), $forceUpdate()
+    (itemTool.toolType = 7), (itemTool.isFold3 = false), $forceUpdate()
     ">
                                   评价类
                                 </div>
@@ -546,12 +581,12 @@
                                   ? 'isChooseActive'
                                   : ''
                                   " @click="
-    (itemTool.toolType = 3), (itemTool.isFold3 = true), $forceUpdate()
+    (itemTool.toolType = 3), (itemTool.isFold3 = false), $forceUpdate()
     ">
                                   编程类
                                 </div>
                                 <div :class="itemTool.toolType == 5 ? 'isChooseActive' : ''
-                                  " @click="(itemTool.toolType = 5), (itemTool.isFold3 = true), $forceUpdate()">
+                                  " @click="(itemTool.toolType = 5), (itemTool.isFold3 = false), $forceUpdate()">
                                   学科类
                                 </div>
                                 <!-- <div :class="itemTool.toolType == 4 ? 'isChooseActive' : ''
@@ -559,17 +594,35 @@
                                   其他
                                 </div> -->
                               </div>
-                              <div v-if="itemTool.isFold3" class="show_toolD show"
+                              <div class="chapter_upload_ud2" style="z-index: 9;margin:0 0 0 auto" v-if="itemTask.toolChoose.length > 1">
+                                  <div class="chapter_upload_up2" @click.stop="
+                                      upTool(
+                                        $event,
+                                        unitIndex,
+                                        itemTaskIndex, 
+                                        toolIndex
+                                      )
+                                  ">上移</div>
+                                  <div class="chapter_upload_down2" @click.stop="
+                                      downTool(
+                                        $event,
+                                        unitIndex,
+                                        itemTaskIndex, 
+                                        toolIndex
+                                      )
+                                  ">下移</div>
+                              </div>
+                              <div v-if="!itemTool.isFold3" class="show_toolD show"
                                 @click="fold3(itemTaskIndex, toolIndex)"
-                                :style="{ right: itemTask.toolChoose.length > 1 ? '45px' : '0px' }"><img
+                                :style="{ margin: itemTask.toolChoose.length > 1 ? '0px 35px 0px 10px' : '0 0 0 auto' }"><img
                                   src="../../../assets/icon/new/icon-slide.png" />收起工具栏</div>
                               <div v-else class="show_toolD" @click="fold3(itemTaskIndex, toolIndex)"
-                                :style="{ right: itemTask.toolChoose.length > 1 ? '45px' : '0px' }"><img
+                                :style="{ margin: itemTask.toolChoose.length > 1 ? '0px 35px 0px 10px' : '0 0 0 auto' }"><img
                                   src="../../../assets/icon/new/icon-slide.png" />展开工具栏</div>
                               <div class="remove" @click="deleteTool(itemTaskIndex, toolIndex)"
-                                v-if="itemTask.toolChoose.length > 1" style="position: absolute; right: 0"></div>
+                                v-if="itemTask.toolChoose.length > 1" style="position: absolute; right: 0;top:-5px;"></div>
                             </div>
-                            <div style="min-height: 163px" v-show="itemTool.isFold3">
+                            <div style="min-height: 163px" v-show="!itemTool.isFold3">
                               <div class="toolSort" v-if="itemTool.toolType == 0">
                                 <!-- <div class="tool">
                               <div
@@ -1559,6 +1612,27 @@
                                     </div>
                                   </div>
                                 </div> -->
+                                <div class="tool" :class="{ isToolChoose: itemTool.tool.indexOf(69) != -1 }"
+                                  @click="addTools(69, itemTaskIndex, toolIndex)">
+                                  <div class="whiteBIcon" @click.stop="
+                                    openTools(itemTaskIndex, 69, toolIndex)
+                                    ">
+                                    <img src="../../../assets/icon/thirdToolList/english.png" alt />
+                                    <div style="margin: 5px 0">英语写作</div>
+                                  </div>
+                                  <div class="noCTool"><img src="../../../assets/icon/new/isToolC.png" alt="" /></div>
+                                  <div class="isCTool" v-if="itemTool.tool.indexOf(69) != -1"><img
+                                      src="../../../assets/icon/new/isToolC.png" alt="" /></div>
+                                  <!-- <div class="check" @click="
+                                    addTools(4, itemTaskIndex, toolIndex)
+                                    ">
+                                    <img src="../../../assets/icon/checkNo.png" alt
+                                      v-if="itemTool.tool.indexOf(4) == -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 == 7">
                                 <div class="tool" :class="{ isToolChoose: itemTool.tool.indexOf(40) != -1 }"
@@ -1632,7 +1706,7 @@
                             </div> -->
                               </div>
                             </div>
-                            <div v-show="itemTool.isFold3">
+                            <div v-show="!itemTool.isFold3">
                               <textarea rows="3" type="text" v-autoHeight="87" placeholder="添加工具描述" class="binfo_input"
                                 style="
                                   margin: 0 0 20px 0;
@@ -1645,7 +1719,8 @@
                             </div>
                             <div>添加工具</div>
                           </div> -->
-                          <button class="c_pub_button_add pub_btn_tool_img" @click="addToolFun(itemTaskIndex)" style="margin: 0 auto 0">
+                          <button class="c_pub_button_add pub_btn_tool_img" @click="addToolFun(itemTaskIndex)"
+                            style="margin: 0 auto;padding: 0 30px;height: 45px;">
                             添加工具
                           </button>
                         </div>
@@ -3596,7 +3671,14 @@
           </el-tooltip>
         </div>
         <div class="check_class_left">
-          <div class="check_class_left_title">选择班级</div>
+          <div class="check_class_all_box">
+            <div class="check_class_left_title">选择班级</div>
+            <div style="display:flex;align-items:center;margin-left:auto;"><el-checkbox v-model="checkAll"
+                @change="handleCheckAllChange" class="all_check">全选</el-checkbox></div>
+          </div>
+          <!-- <div class="class_item" style="position:absolute; margin:0" v-if="grade2.length">            
+            <el-checkbox v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
+          </div> -->
           <el-checkbox-group v-model="checkboxList2" class="check_class_item" @change="InviteChange" v-if="grade2.length">
             <div v-for="item in grade2" :key="item.id" class="class_item">
               <el-checkbox :label="item.id">
@@ -4533,6 +4615,14 @@
         <el-button type="primary" @click="updataVideoC">确 定</el-button>
       </span>
     </el-dialog>
+    <el-dialog title="创建作文题目" :visible.sync="englishDialogVisible" :append-to-body="true" width="800px"
+      :before-close="(done) => { closePan(69) }" class="dialog_diy fullStyle">
+      <englishRight @setEngList="setEnglishList" :englishList="englishList"></englishRight>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="englishDialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="addEnglish">确 定</el-button>
+      </span>
+    </el-dialog>
     <interVideo :dialogVisibleVideo.sync="dialogVisibleVideo" :videoJson="videoJson" @add="addVideoJson"></interVideo>
   </div>
 </template>
@@ -4550,6 +4640,7 @@ import SeeBoard from "../../tools/seeBoard";
 import weilaiData from "../components/weilai.js";
 import sourceDialog from "../teacherSource/dialog.vue";
 import interVideo from "../interVideo/index.vue";
+import englishRight from "./commpont/englishRight.vue";
 
 export default {
   components: {
@@ -4561,6 +4652,7 @@ export default {
     Table,
     sourceDialog,
     interVideo,
+    englishRight,
   },
   data() {
     return {
@@ -4639,6 +4731,7 @@ export default {
       wordJson: { text: "" },
       dialogVisibleMoreUpload: false,
       dialogVisiblePreTime: false,
+      englishDialogVisible: false,
       uploadJson: [],
       classJuri: [],
       gradeList: [],
@@ -4673,6 +4766,7 @@ export default {
       testJson2: {},
       selectJson: {},
       selectJson2: {},
+      englishList:{},
       rateJson: [],
       unitJson2: [],
       unitJson: [
@@ -4782,6 +4876,10 @@ export default {
       imageList: [],
       heightPx: '100%',
       toolsData: toolsData,
+      oldIndex: 0,
+      oldData: null,
+      newIndex: "",
+      typeIndex: "",
     };
   },
   directives: {
@@ -5052,16 +5150,6 @@ export default {
         this.heightPx = $(".rightBox")[0].offsetHeight - 130 + 'px'
       }
     },
-    handleCheckAllChange(val) {
-      this.checkedCities = val ? cityOptions : [];
-      this.isIndeterminate = false;
-    },
-    handleCheckedCitiesChange(value) {
-      let checkedCount = value.length;
-      this.checkAll = checkedCount === this.cities.length;
-      this.isIndeterminate =
-        checkedCount > 0 && checkedCount < this.cities.length;
-    },
     addHw(e) {
       var el = e.currentTarget;
       el.getElementsByTagName("input")[0].click();
@@ -5117,6 +5205,12 @@ export default {
         } else {
           this.closeConfirm(tool);
         }
+      }else if (tool == 69){
+        if (JSON.stringify(this.englishList) == JSON.stringify(this.englishList)) {
+          this.englishDialogVisible = false
+        } else {
+          this.closeConfirm(tool);
+        }
       }
     },
     closeConfirm(tool) {
@@ -5137,6 +5231,8 @@ export default {
             this.addSelectAnswer();
           } else if (tool == 47) {
             this.addSentenceTool();
+          }else if(tool == 69){
+            this.addEnglish();
           }
         })
         .catch(() => {
@@ -5150,9 +5246,31 @@ export default {
             this.dialogVisibleSelect = false;
           } else if (tool == 47) {
             this.dialogVisibleSentence = false;
+          } else if (tool == 69) {
+            this.englishDialogVisible = false;
           }
         });
     },
+    addEnglish(){
+      if(this.englishList.engTitle == "" || this.englishList.englishText == ""){
+        this.$message.error("请将内容填写完整!");
+        return;
+      }
+      this.unitJson[this.unitIndex].chapterInfo[0].taskJson[
+        this.taskCount
+      ].toolChoose[this.toolIndex].englishList = this.englishList;
+      this.englishList = {};
+      this.englishDialogVisible = false;
+      if (
+        this.unitJson[this.unitIndex].chapterInfo[0].taskJson[this.taskCount]
+          .toolChoose[this.toolIndex].tool != 69
+      ) {
+        this.addTools(69, this.taskCount, this.toolIndex);
+      }
+    },
+    setEnglishList(engList){
+      this.englishList = engList;
+    },
     imgChange2(i, j) {
       var _tmp = this.testJson.testJson[i].checkList[j];
       this.noneBtnImg = _tmp.length >= 1;
@@ -5205,6 +5323,7 @@ export default {
         .$confirm("是否保存已编辑内容?", "提示", {
           confirmButtonText: "保存",
           cancelButtonText: "不保存",
+          distinguishCancelAndClose: true,   
           type: "warning",
         })
         .then(() => {
@@ -5228,17 +5347,20 @@ export default {
             }
           }
         })
-        .catch(() => {
-          this.goTo(
-            "/course?userid=" +
-            this.userid +
-            "&oid=" +
-            this.oid +
-            "&org=" +
-            this.org +
-            "&role=" +
-            this.role
-          );
+        .catch((v) => {
+          console.log(v)
+          if(v == "cancel"){
+              this.goTo(
+              "/course?userid=" +
+              this.userid +
+              "&oid=" +
+              this.oid +
+              "&org=" +
+              this.org +
+              "&role=" +
+              this.role
+            );
+          }
         });
     },
     nextSteps() {
@@ -6498,6 +6620,19 @@ export default {
           }
           this.grade2 = res.data[0];
           this.classJuri = res.data[0];
+          let _check = []
+          let _check2 = []
+          for (var i = 0; i < this.grade2.length; i++) {
+            var gid = this.grade2[i].id
+            _check.push(gid)
+          }
+          for (var i = 0; i < this.checkboxList2.length; i++) {
+            var _id = this.checkboxList2[i]
+              if (_check.indexOf(_id) !== -1) {
+                _check2.push(_id)
+              }
+          }
+          this.checkAll = _check2.length === _check.length;
         })
         .catch((err) => {
           this.isLoading = false;
@@ -6583,6 +6718,60 @@ export default {
       this.unitJson[i].chapterInfo[0].taskJson[taskCount].chapterData[ic] = a;
       this.$forceUpdate();
     },
+    upTool(e, i, j, tooli){
+      e.stopPropagation();
+      if (tooli == 0) {
+        return;
+      }
+      this.$confirm(
+        "切换工具顺序将删除此工具的提交成果,是否继续此操作?",
+        "提示",
+        {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning",
+        }
+      )
+        .then(() => {
+          var a =
+          JSON.parse(JSON.stringify(this.unitJson[i].chapterInfo[0].taskJson[j].toolChoose[tooli - 1]));
+          this.unitJson[i].chapterInfo[0].taskJson[j].toolChoose[tooli - 1] =
+            JSON.parse(JSON.stringify(this.unitJson[i].chapterInfo[0].taskJson[j].toolChoose[tooli]));
+          this.unitJson[i].chapterInfo[0].taskJson[j].toolChoose[tooli] = a;
+          this.$forceUpdate()
+        })
+        .catch(() => {
+          return;
+        });
+    },
+    downTool(e, i, j, tooli){
+      e.stopPropagation();
+      if ( tooli ==
+        this.unitJson[i].chapterInfo[0].taskJson[j].toolChoose.length -
+        1) {
+        return;
+      }
+      this.$confirm(
+        "切换工具顺序将删除此工具的提交成果,是否继续此操作?",
+        "提示",
+        {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning",
+        }
+      )
+        .then(() => {
+          var a =
+          JSON.parse(JSON.stringify(this.unitJson[i].chapterInfo[0].taskJson[j].toolChoose[tooli + 1]));
+          this.unitJson[i].chapterInfo[0].taskJson[j].toolChoose[tooli + 1] =
+            JSON.parse(JSON.stringify(this.unitJson[i].chapterInfo[0].taskJson[j].toolChoose[tooli]));
+          this.unitJson[i].chapterInfo[0].taskJson[j].toolChoose[tooli] = a;
+          this.$forceUpdate()
+        })
+        .catch(() => {
+          return;
+        });
+    },
     addWork() {
       let cPan = 1;
       for (var i = 0; i < this.unitJson.length; i++) {
@@ -7518,6 +7707,19 @@ export default {
           },
           "*"
         );
+      }else if(i == 69){
+        this.englishList = this.unitJson[this.unitIndex].chapterInfo[0].taskJson[
+          itemTaskIndex
+        ].toolChoose[toolIndex].englishList
+          ? JSON.parse(
+            JSON.stringify(
+              this.unitJson[this.unitIndex].chapterInfo[0].taskJson[
+                itemTaskIndex
+              ].toolChoose[toolIndex].englishList
+            )
+          )
+          : {  };
+        this.englishDialogVisible = true;
       }
     },
     chapAddTools(i) {
@@ -7631,6 +7833,16 @@ export default {
           return;
         }
       }
+
+      if(i == 69){
+        if (
+          !this.unitJson[this.unitIndex].chapterInfo[0].taskJson[itemTaskIndex]
+            .toolChoose[toolIndex].englishList
+        ) {
+          this.openTools(itemTaskIndex, 69, toolIndex);
+          return;
+        }
+      }
       // if (i == 48) {
       //   if (
       //     !this.unitJson[this.unitIndex].chapterInfo[0].taskJson[itemTaskIndex]
@@ -9422,6 +9634,19 @@ export default {
     },
     InviteChange(val) {
       console.log(val);
+      let _check = []
+      let _check2 = []
+      for (var i = 0; i < this.grade2.length; i++) {
+        var gid = this.grade2[i].id
+        _check.push(gid)
+      }
+      for (var i = 0; i < this.checkboxList2.length; i++) {
+        var _id = this.checkboxList2[i]
+          if (_check.indexOf(_id) !== -1) {
+            _check2.push(_id)
+          }
+      }
+      this.checkAll = _check2.length === _check.length;
       return;
       let array = JSON.parse(JSON.stringify(val));
       this.inviteCode = this.inviteCode.filter((el) => {
@@ -9434,6 +9659,31 @@ export default {
         this.getInviteCode(array[i]);
       }
     },
+    handleCheckAllChange(val) {
+      if (val) {
+        for (var i = 0; i < this.grade2.length; i++) {
+          var gid = this.grade2[i].id
+          if (this.checkboxList2.indexOf(gid) === -1) {
+            this.checkboxList2.push(gid)
+          }
+        }
+      } else {
+        let _check = []
+        let _check2 = []
+        for (var i = 0; i < this.grade2.length; i++) {
+          var gid = this.grade2[i].id
+          _check.push(gid)
+        }
+        for (var i = 0; i < this.checkboxList2.length; i++) {
+          var _id = this.checkboxList2[i]
+          if (_check.indexOf(_id) === -1) {
+            _check2.push(_id)
+          }
+        }
+        this.checkboxList2 = _check2
+      }
+      this.isIndeterminate = false;
+    },
     async getInviteCode(cid) {
       let code = this.randomNumber();
       let params = {
@@ -9649,7 +9899,8 @@ export default {
       this.oldIndex = i;
       this.oldData = val;
     },
-    dragOver(i) {
+    dragOver(i, j) {
+      this.typeIndex = "chapter-" + j + '-' + i
       this.newIndex = i;
     },
     dragEnd() {
@@ -9660,6 +9911,7 @@ export default {
       newItems.splice(this.newIndex, 0, this.oldData);
       this.unitJson[this.unitIndex].chapterInfo[0].taskJson[this.taskCount].chapterData = [...newItems];
       this.newIndex = "";
+      this.typeIndex = "";
       this.$forceUpdate()
     },
     dragTaskStart(val, i) {
@@ -9667,10 +9919,13 @@ export default {
       this.oldData = val;
     },
     dragTaskOver(i) {
+      this.typeIndex = "task-" + i
       this.newIndex = i;
     },
     dragTaskEnd() {
-      if(this.newIndex == this.oldIndex){
+      if (this.newIndex == this.oldIndex) {
+        this.typeIndex = "";
+          this.newIndex = "";
         return;
       }
       this.$confirm(
@@ -9685,7 +9940,7 @@ export default {
         .then(() => {
           let newItems = [...this.unitJson[this.unitIndex].chapterInfo[0].taskJson];
           let chapterData = []
-          if(this.oldIndex == 0){
+          if (this.oldIndex == 0) {
             chapterData = newItems[this.oldIndex].chapterData
             newItems[this.oldIndex].chapterData = []
           }
@@ -9693,14 +9948,16 @@ export default {
           newItems.splice(this.oldIndex, 1);
           // 在列表中目标位置增加新的节点
           newItems.splice(this.newIndex, 0, this.oldData);
-          if(this.oldIndex == 0){
+          if (this.oldIndex == 0) {
             newItems[0].chapterData = chapterData
           }
           this.unitJson[this.unitIndex].chapterInfo[0].taskJson = [...newItems];
+          this.typeIndex = "";
           this.newIndex = "";
           this.$forceUpdate()
         })
         .catch(() => {
+          this.typeIndex = "";
           this.newIndex = "";
           return;
         });
@@ -10226,9 +10483,9 @@ export default {
   font-size: 14px;
   cursor: pointer;
   color: #717C8D;
-  position: absolute;
+  /* position: absolute;
   right: 45px;
-  top: 5px;
+  top: 5px; */
 }
 
 .show_toolD>img {
@@ -10962,6 +11219,50 @@ export default {
   margin-bottom: 5px;
 }
 
+
+.chapter_upload_ud2 {
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  margin: 0 10px 0 0;
+}
+
+.chapter_upload_ud2>.chapter_upload_up2 {
+  margin-bottom: 0;
+  margin-right: 10px;
+}
+
+
+.chapter_upload_down2,
+.chapter_upload_up2 {
+  cursor: pointer;
+  margin: 0 auto;
+  border-radius: 5px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  color: #717C8D;
+  font-size: 14px;
+}
+.chapter_upload_up2{
+  margin-right:10px;
+}
+.chapter_upload_up2::before,
+.chapter_upload_down2::before {
+  content: '';
+  background-image: url('../../../assets/icon/new/c_up.png');
+  width: 14px;
+  height: 14px;
+  background-size: 100% 100%;
+  display: block;
+  margin-right: 5px;
+}
+
+.chapter_upload_up2::before {
+  background-image: url('../../../assets/icon/new/c_down.png') !important;
+}
+
+
 .addWordStyle {
   display: flex;
   flex-direction: row;
@@ -11304,7 +11605,7 @@ ol {
 }
 
 .tool+.tool {
-  margin-right: 45px;
+  margin-right: 10px;
 }
 
 .whiteBIcon {
@@ -11630,7 +11931,7 @@ ol {
 }
 
 .toolSort>div {
-  margin-right: 45px;
+  margin-right: 10px;
 }
 
 .tools {
@@ -11751,6 +12052,7 @@ ol {
   position: absolute;
   right: 15px;
   bottom: 35px;
+  z-index: 999;
 }
 
 .fold {
@@ -12309,6 +12611,37 @@ ol {
   align-items: center;
   font-size: 14px;
   color: #6e6e6e;
+  position:relative;
+}
+
+.cover_p{
+  width: 100% !important;
+  height: 100%;
+  object-fit: cover;
+}
+
+.uploadFm2:hover .cover_mask{
+  display: flex !important;
+}
+
+.cover_mask{
+  display:none;
+  width:100%;
+  height:100%;
+  position:absolute;
+  background:#00000054;
+  align-items: center;
+  justify-content: center;
+  flex-direction: column;
+}
+
+.cover_mask > img{
+  width: 30px;
+}
+
+.cover_mask > span{
+  color: #fff;
+  font-size: 12px;
 }
 
 .uploadFm>img {
@@ -12846,6 +13179,28 @@ ol {
   background-image: url(../../../assets/icon/new/icon_arrow_a.png) !important;
 }
 
+.dragOverTop {
+  border-top: 2px solid #0061FF !important;
+  border-radius: 0 !important;
+  margin-top: 10px;
+}
+
+.dragOverBottom {
+  border-bottom: 2px solid #0061FF !important;
+  border-radius: 0 !important;
+  margin-top: 10px;
+}
+
+.dragOverTop2 {
+  border-top: 2px solid #0061FF !important;
+  border-radius: 0 !important;
+}
+
+.dragOverBottom2 {
+  border-bottom: 2px solid #0061FF !important;
+  border-radius: 0 !important;
+}
+
 .isNavTask {
   /* background: #3681FC; */
   background: #EEF3FB;
@@ -12884,14 +13239,14 @@ ol {
   color: #060E17;
   line-height: 25px;
   font-size: 16px;
-  min-width: 45px;
+  /* min-width: 66px; */
 }
 
 .navTask .nt_taskName {
   /* color: #fff; */
   /* max-width: 130px; */
   /* width: 100%; */
-  max-width: calc(100% - 50px);
+  max-width: calc(100% - 66px);
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
@@ -13306,10 +13661,25 @@ ol {
   box-sizing: border-box;
 }
 
+.check_class_all_box {
+  display: flex;
+  margin-bottom: 10px;
+}
+
+.all_check {
+  display: flex;
+  align-items: center;
+  padding: 2px 0 0;
+  margin-left: 10px;
+}
+
+.all_check>>>.el-checkbox__label {
+  line-height: 18px;
+}
+
 .check_class_left_title {
   font-size: 16px;
   font-weight: 700;
-  margin-bottom: 10px;
 }
 
 .check_class_item {
@@ -13322,6 +13692,9 @@ ol {
   align-content: flex-start;
 }
 
+.class_item:first-child {
+  /* margin: 0 15px 15px 67px; */
+}
 .class_item {
   margin: 0 15px 15px 0;
 

+ 90 - 0
src/components/pages/easy/commpont/englishRight.vue

@@ -0,0 +1,90 @@
+<template>
+  <div class="englishBox">
+    <div class="themeTitle">
+      <div>作文题目<span style="color: red;">*</span></div>
+      <div>
+        <el-input
+          v-model="engList.engTitle"
+          placeholder="请填写作文题目"
+          @change="setEngList"
+        ></el-input>
+      </div>
+    </div>
+    <div class="themeText">
+      <div>作文要求<span style="color: red;">*</span></div>
+      <div>
+        <editor-bar
+          placeholder="请填写作文要求"
+          v-model="engList.englishText"
+          @change="setEngList"
+        ></editor-bar>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import EditorBar from "../../../../components/tools/wangEnduit";
+export default {
+  components: {
+    EditorBar,
+  },
+  props: ["englishList"],
+  data() {
+    return {
+      engList: {
+        engTitle: "",
+        englishText: "",
+      },
+    };
+  },
+  methods: {
+    setEngList() {
+      this.$emit("setEnglish", this.engList);
+    },
+  },
+  created() {
+    this.engList = this.englishList;
+  },
+};
+</script>
+
+<style scoped>
+.englishBox {
+  width: 50%;
+  margin: 50px auto 0;
+}
+.themeTitle {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  align-items: center;
+}
+.themeTitle > div:first-child {
+  min-width: 65px;
+  font-weight: bold;
+}
+.themeTitle > div:last-child {
+  width: calc(100% - 75px);
+  margin-left: 10px;
+}
+.themeText {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  align-items: flex-start;
+  margin-top: 20px;
+}
+.themeText > div:first-child {
+  min-width: 65px;
+  margin-top: 10px;
+  font-weight: bold;
+}
+.themeText > div:last-child {
+  width: calc(100% - 75px);
+  margin-left: 10px;
+}
+.themeText > div:last-child >>> .text {
+  min-height: 400px !important;
+}
+</style>

+ 1 - 1
src/components/pages/synergyCourse/addCourse.vue

@@ -10682,7 +10682,7 @@ ol {
 }
 
 .updateTips::after {
-  content: "协同建不支持修改基本信息,只支持加入分组。";
+  content: "协同建不支持修改基本信息,只支持加入分组。";
   font-size: 14px;
   margin-left: 20px;
   font-weight: 400;

+ 8 - 6
src/components/pages/synergyCourse/course.vue

@@ -6,10 +6,10 @@
     display: flex;
     align-items: center;
 ">
-          <span>协同建</span>
+          <span>协同建</span>
         </div>
         <div class="student_button">
-          <el-button type="primary" class="bgColor" @click="goToCourse3()">创建协同建</el-button>
+          <el-button type="primary" class="bgColor" @click="goToCourse3()">创建协同建</el-button>
         </div>
       </div>
       <div class="reBox">
@@ -146,7 +146,7 @@
               ">
               他人创建
             </div>
-            <div class="xtCourse" v-else>协同建</div>
+            <div class="xtCourse" v-else>协同建</div>
             <div class="tup">
               <img :src="item.cover != null && item.cover != ''
                 ? JSON.parse(item.cover).length > 0
@@ -890,7 +890,9 @@ export default {
       this.ajax
         .get(this.$store.state.api + "selectSynergyCourse", params)
         .then((res) => {
-          this.loading.close();
+          if (this.loading) {
+            this.loading.close();
+          }
           this.loading = "";
           this.isLoading = false;
           this.total = res.data[0].length > 0 ? res.data[0][0].num : 0;
@@ -1489,8 +1491,8 @@ export default {
   overflow: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
-  /* font-weight: bold; */
-  font-size: 24px;
+  font-weight: bold;
+  font-size: 16px;
 }
 
 .bottom_box>div:nth-child(1)>span:nth-child(2) {

+ 3 - 2
src/components/pages/synergyCourse/group/group.vue

@@ -157,12 +157,13 @@
                                     {{ g.name }}
                                 </div>
                                 <div>
-                                    <div v-if="courseDetail.userid == userid && groupJson.islock == 2"
+                                    <!-- && groupJson.islock == 2 -->
+                                    <div v-if="courseDetail.userid == userid"
                                         @click="deleteGroupChair(g.id, gindex)">
                                         移除组员
                                     </div>
                                     <div @click="selectGroup(g.id)"
-                                        v-else-if="groupStudentUid && groupStudentUid[g.id].indexOf(userid) == -1 && courseDetail.userid !== userid">
+                                        v-if="groupStudentUid && groupStudentUid[g.id].indexOf(userid) == -1 && courseDetail.userid !== userid">
                                         加入分组
                                     </div>
                                     <div @click="

+ 428 - 56
src/components/pages/task/addCourse.vue

@@ -92,16 +92,18 @@
                     </div> -->
                       <div class="c_info_title" style="padding: 0 0 15px;margin: 0 auto 0 0;">上传封面</div>
                       <div style="width: 100%;">
-                        <div class="uploadFm" @click="choosePicVisible = true" v-if="cover.length == 0">
-                          <img src="../../../assets/icon/addPoster.png" alt="" />
-                          <div>点击添加封面</div>
+                        <div class="uploadFm" @click="choosePicVisible = true" :class="{uploadFm2:cover.length}">
+                          <img src="../../../assets/icon/addPoster.png" alt="" v-if="cover.length == 0"/>
+                          <img :src="cover[0].url" alt="" class="cover_p" v-else/>
+                          <div v-if="cover.length == 0">点击添加封面</div>
+                          <div class="cover_mask"><img src="../../../assets/icon/new/cover_update.png" /><span style="margin-top:5px;">修改封面</span></div>
                         </div>
-                        <el-upload :class="{ disUoloadSty: noneBtnImg }" class="upCss" action="#" list-type="picture"
+                        <!-- <el-upload :class="{ disUoloadSty: noneBtnImg }" class="upCss" action="#" list-type="picture"
                           v-loading="uploadLoading1" :http-request="beforeUpload1" ref="upload1"
                           :on-preview="handlePictureCardPreview" :on-remove="handle_remove1" :show-file-list="true"
                           :file-list="cover" accept="image/*" :limit="1" :on-exceed="onExceed" v-else>
                           <i class="el-icon-plus"></i>
-                        </el-upload>
+                        </el-upload> -->
                       </div>
                     </div>
                   </div>
@@ -163,7 +165,10 @@
                     <!-- <div class="navTop">辅助导航</div> -->
                     <div class="navBottom" :style="{ height: heightPx }">
                       <div v-for="(t, tIndex) in unitJson[unitIndex].chapterInfo[0]
-                        .taskJson" :key="tIndex">
+                        .taskJson" :key="tIndex" :class="{
+                          dragOverTop: newIndex === tIndex && typeIndex == 'task-'+tIndex && oldIndex > tIndex,
+                          dragOverBottom: newIndex === tIndex && typeIndex == 'task-'+tIndex && oldIndex < tIndex,
+                        }">
                         <div @dragstart="dragTaskStart(t, tIndex)" @dragover.prevent="dragTaskOver(tIndex)"
                           @dragend="dragTaskEnd()" draggable @click="goToTask(tIndex)" class="navTask" :class="{
                           isNavTask:
@@ -172,7 +177,7 @@
                         }">
                           <div style="left: 8px;" class="chapter_upload_drag"></div>
                           <div class="nt_taskBox">
-                            <div class="nt_taskTitle">任务{{ tIndex + 1 }}</div>
+                            <div class="nt_taskTitle">任务{{ tIndex + 1 }}</div>
                             <div class="nt_taskName">
                               <el-tooltip effect="light" :content="t.task" placement="top">
                                 <span>{{ t.task }}</span>
@@ -192,7 +197,7 @@
                           <div v-for="(tool, toolIndex2) in t.toolChoose" :key="toolIndex2"
                             @click="jumpGj(tIndex, toolIndex2)">
                             <div class="gjCss" :class="{ isGjCss: toolIndexType == `gj${tIndex}${toolIndex2}` }">
-                              <div>工具{{ toolIndex2 + 1 }}:</div>
+                              <div>工具{{ toolIndex2 + 1 }}</div>
                               <div>{{ toolsData[tool.tool[0]] && toolsData[tool.tool[0]].name }}</div>
                             </div>
                           </div>
@@ -272,6 +277,7 @@
                             align-items: center;
                           ">
                           <div class="lineTitle" style="margin-bottom:10px">学习内容</div>
+<<<<<<< HEAD
                           <div class="add_info_box">
                             <button class="c_pub_button_add pub_btn_add_img" @click="addImg($event)">
                               文件
@@ -302,6 +308,8 @@
                                 " />
                             </button> -->
                           </div>
+=======
+>>>>>>> beta
                           <div style="margin-bottom:10px" v-if="!itemTask.isFoldchapter" class="show_taskD show"
                             @click="foldC(itemTaskIndex)"><img src="../../../assets/icon/new/icon-slide.png" />收起学习内容
                           </div>
@@ -313,7 +321,7 @@
                             itemTask.chapterData.length == 0
                             "><img src="../../../assets/icon/new/c_none.png" alt /><span>请添加学习内容</span></div>
                           <div v-else class="add_chapters_box" style="display: flex; flex-direction: column">
-                            <div @dragstart="dragStart(item1, index1, itemTaskIndex)" @dragover.prevent="dragOver(index1)"
+                            <div @dragstart="dragStart(item1, index1, itemTaskIndex)" @dragover.prevent="dragOver(index1,itemTaskIndex)"
                               @dragend="dragEnd()" draggable class="chapter_upload"
                               v-for="(item1, index1) in itemTask.chapterData" :key="item1.id" @click="
                                 getChapterData(
@@ -323,7 +331,10 @@
                                   index1,
                                   item1.type
                                 )
-                                ">
+                                " :class="{
+                                dragOverTop2: newIndex === index1 && typeIndex == 'chapter-'+itemTaskIndex+'-'+index1 && oldIndex > index1,
+                                dragOverBottom2: newIndex === index1 && typeIndex == 'chapter-'+itemTaskIndex+'-'+index1 && oldIndex < index1,
+                              }">
                               <div class="chapter_upload_drag"></div>
                               <div class="chapter_upload_t" style="width: 100%"></div>
                               <div class="chapter_upload_o" style="
@@ -461,6 +472,30 @@
                             </div>
                           </div>
                         </div>
+                        <div class="add_info_box" style="margin:10px 0 0" v-if="!itemTask.isFoldchapter">
+                            <button class="c_pub_button_add pub_btn_add_img" @click="addImg($event)">
+                              文件
+                              <input type="file" accept="*" style="display: none" v-if="inputShow"
+                                @change="beforeUpload2($event, unitIndex, 13, 0)" />
+                            </button>
+                            <button class="c_pub_button_add pub_btn_add_img" @click="addAttText(0)">
+                              图文
+                            </button>
+                            <button class="c_pub_button_add pub_btn_add_img" @click="openLine(0)">
+                              链接
+                            </button>
+                            <button class="c_pub_button_add pub_btn_add_img" @click="pasteLine(0)">
+                              代码
+                            </button>
+                            <button class="c_pub_button_add pub_btn_add_img" @click="openSource(0)">
+                              资源
+                            </button>
+                            <!-- <button class="info_btn" @click="addImg($event)">
+                              其他附件
+                              <input type="file" accept="*" style="display: none" v-if="inputShow" @change="beforeUpload2($event, unitIndex, 12, itemTaskIndex)
+                                " />
+                            </button> -->
+                          </div>
                         <div v-if="unitJson[unitIndex].chapterInfo[0].taskJson[
                             itemTaskIndex
                           ].proVisible
@@ -515,14 +550,14 @@
                               </div>
                               <div class="chooseWho">
                                 <div :class="itemTool.toolType == 0 ? 'isChooseActive' : ''
-                                  " @click="(itemTool.toolType = 0), (itemTool.isFold3 = true), $forceUpdate()">
+                                  " @click="(itemTool.toolType = 0), (itemTool.isFold3 = false), $forceUpdate()">
                                   互动类
                                 </div>
                                 <div :class="itemTool.toolType == 1
                                     ? 'isChooseActive'
                                     : ''
                                   " @click="
-    (itemTool.toolType = 1), (itemTool.isFold3 = true), $forceUpdate()
+    (itemTool.toolType = 1), (itemTool.isFold3 = false), $forceUpdate()
     ">
                                   思维类
                                 </div>
@@ -530,7 +565,7 @@
                                     ? 'isChooseActive'
                                     : ''
                                   " @click="
-    (itemTool.toolType = 6), (itemTool.isFold3 = true), $forceUpdate()
+    (itemTool.toolType = 6), (itemTool.isFold3 = false), $forceUpdate()
     ">
                                   协作类
                                 </div>
@@ -538,7 +573,7 @@
                                     ? 'isChooseActive'
                                     : ''
                                   " @click="
-    (itemTool.toolType = 2), (itemTool.isFold3 = true), $forceUpdate()
+    (itemTool.toolType = 2), (itemTool.isFold3 = false), $forceUpdate()
     ">
                                   测评类
                                 </div>
@@ -546,7 +581,7 @@
                                     ? 'isChooseActive'
                                     : ''
                                   " @click="
-    (itemTool.toolType = 7), (itemTool.isFold3 = true), $forceUpdate()
+    (itemTool.toolType = 7), (itemTool.isFold3 = false), $forceUpdate()
     ">
                                   评价类
                                 </div>
@@ -554,12 +589,12 @@
                                     ? 'isChooseActive'
                                     : ''
                                   " @click="
-    (itemTool.toolType = 3), (itemTool.isFold3 = true), $forceUpdate()
+    (itemTool.toolType = 3), (itemTool.isFold3 = false), $forceUpdate()
     ">
                                   编程类
                                 </div>
                                 <div :class="itemTool.toolType == 5 ? 'isChooseActive' : ''
-                                  " @click="(itemTool.toolType = 5), (itemTool.isFold3 = true), $forceUpdate()">
+                                  " @click="(itemTool.toolType = 5), (itemTool.isFold3 = false), $forceUpdate()">
                                   学科类
                                 </div>
                                 <!--<div :class="itemTool.toolType == 4 ? 'isChooseActive' : ''
@@ -567,18 +602,36 @@
                                   其他
                                 </div> -->
                               </div>
-                              <div v-if="itemTool.isFold3" class="show_toolD show"
+                              <div class="chapter_upload_ud2" style="z-index: 9;margin:0 0 0 auto" v-if="itemTask.toolChoose.length > 1">
+                                  <div class="chapter_upload_up2" @click.stop="
+                                      upTool(
+                                        $event,
+                                        unitIndex,
+                                        itemTaskIndex, 
+                                        toolIndex
+                                      )
+                                  ">上移</div>
+                                  <div class="chapter_upload_down2" @click.stop="
+                                      downTool(
+                                        $event,
+                                        unitIndex,
+                                        itemTaskIndex, 
+                                        toolIndex
+                                      )
+                                  ">下移</div>
+                              </div>
+                              <div v-if="!itemTool.isFold3" class="show_toolD show"
                                 @click="fold3(itemTaskIndex, toolIndex)"
-                                :style="{ right: itemTask.toolChoose.length > 1 ? '45px' : '0px' }"><img
+                                :style="{ margin: itemTask.toolChoose.length > 1 ? '0px 35px 0px 10px' : '0 0 0 auto' }"><img
                                   src="../../../assets/icon/new/icon-slide.png" />收起工具栏</div>
                               <div v-else class="show_toolD" @click="fold3(itemTaskIndex, toolIndex)"
-                                :style="{ right: itemTask.toolChoose.length > 1 ? '45px' : '0px' }"><img
+                                :style="{ margin: itemTask.toolChoose.length > 1 ? '0px 35px 0px 10px' : '0 0 0 auto' }"><img
                                   src="../../../assets/icon/new/icon-slide.png" />展开工具栏</div>
                               <div class="remove" @click="deleteTool(itemTaskIndex, toolIndex)"
-                                v-if="itemTask.toolChoose.length > 1" style="position: absolute; right: 0"></div>
+                                v-if="itemTask.toolChoose.length > 1" style="position: absolute; right: 0;top:-5px;"></div>
                             </div>
 
-                            <div style="min-height: 163px" v-show="itemTool.isFold3">
+                            <div style="min-height: 163px" v-show="!itemTool.isFold3">
                               <div class="toolSort" v-if="itemTool.toolType == 0">
                                 <!-- <div class="tool">
                               <div
@@ -1894,6 +1947,35 @@
                                     </div>
                                   </div>
                                 </div> -->
+                                <div class="tool" :class="{ isToolChoose: itemTool.tool.indexOf(69) != -1 }"
+                                  @click="addTools(69, itemTaskIndex, toolIndex)">
+                                  <div class="whiteBIcon" @click.stop="
+                                    openTools(itemTaskIndex, 69, toolIndex)
+                                    ">
+                                    <img src="../../../assets/icon/thirdToolList/english.png" alt />
+                                    <div style="margin: 5px 0">英语写作</div>
+                                  </div>
+                                  <div class="isCTool" v-show="itemTool.tool.indexOf(69) != -1"><img
+                                      src="../../../assets/icon/new/isToolC.png" alt="" /></div>
+                                  <!-- <div
+                                    class="check"
+                                    @click="
+                                      addTools(4, itemTaskIndex, toolIndex)
+                                    "
+                                  >
+                                    <img
+                                      src="../../../assets/icon/checkNo.png"
+                                      alt
+                                      v-if="itemTool.tool.indexOf(4) == -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 == 7">
                                 <div class="tool" :class="{ isToolChoose: itemTool.tool.indexOf(40) != -1 }"
@@ -1975,7 +2057,7 @@
                             </div> -->
                               </div>
                             </div>
-                            <div v-show="itemTool.isFold3">
+                            <div v-show="!itemTool.isFold3">
                               <textarea v-autoHeight="87" rows="3" type="text" placeholder="添加工具描述" class="binfo_input"
                                 style="
                                   margin: 0 0 20px 0;
@@ -1988,7 +2070,7 @@
                             </div>
                             <div>添加工具</div>
                           </div> -->
-                          <button class="c_pub_button_add pub_btn_tool_img" @click="addToolFun(itemTaskIndex)" style="margin: 0 auto 0">
+                          <button class="c_pub_button_add pub_btn_tool_img" @click="addToolFun(itemTaskIndex)" style="margin: 0 auto;padding: 0 30px;height: 45px;">
                             添加工具
                           </button>
                         </div>
@@ -3912,7 +3994,14 @@
           </el-tooltip>
         </div>
         <div class="check_class_left">
-          <div class="check_class_left_title">选择班级</div>
+          <div class="check_class_all_box">
+            <div class="check_class_left_title">选择班级</div>
+            <div style="display:flex;align-items:center;margin-left:auto;"><el-checkbox v-model="checkAll"
+                @change="handleCheckAllChange" class="all_check">全选</el-checkbox></div>
+          </div>
+          <!-- <div class="class_item" style="position:absolute; margin:0" v-if="grade2.length">            
+            <el-checkbox v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
+          </div> -->
           <el-checkbox-group v-model="checkboxList2" class="check_class_item" @change="InviteChange" v-if="grade2.length">
             <div v-for="item in grade2" :key="item.id" class="class_item">
               <el-checkbox :label="item.id">
@@ -4872,6 +4961,14 @@
         <el-button type="primary" @click="updataVideoC">确 定</el-button>
       </span>
     </el-dialog>
+    <el-dialog title="创建作文题目" :visible.sync="englishDialogVisible" :append-to-body="true" width="800px"
+      :before-close="(done) => { closePan(69) }" class="dialog_diy fullStyle">
+      <englishRight @setEngList="setEnglishList" :englishList="englishList"></englishRight>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="englishDialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="addEnglish">确 定</el-button>
+      </span>
+    </el-dialog>
     <interVideo :dialogVisibleVideo.sync="dialogVisibleVideo" :videoJson="videoJson" @add="addVideoJson"></interVideo>
   </div>
 </template>
@@ -4889,6 +4986,7 @@ import SeeBoard from "../../tools/seeBoard";
 import weilaiData from "../components/weilai.js";
 import sourceDialog from "../teacherSource/dialog.vue";
 import interVideo from "../interVideo/index.vue";
+import englishRight from "./commpont/englishRight.vue";
 
 export default {
   components: {
@@ -4900,6 +4998,7 @@ export default {
     Table,
     sourceDialog,
     interVideo,
+    englishRight,
   },
   data() {
     return {
@@ -4962,6 +5061,7 @@ export default {
       dialogVisibleSource: false,
       dialogVisibleVideo: false,
       dialogVisibleupdataVideoT: false,
+      englishDialogVisible: false,
       isClickColor: 1,
       toolIndexType: "",
       publicTool: 0,
@@ -5123,7 +5223,9 @@ export default {
       toolsData: toolsData,
       oldIndex: 0,
       oldData: null,
-      newIndex: 0,
+      newIndex: "",
+      englishList:{},
+      typeIndex: "",
     };
   },
   directives: {
@@ -5394,16 +5496,6 @@ export default {
         this.heightPx = $(".rightBox")[0].offsetHeight - 130 + 'px'
       }
     },
-    handleCheckAllChange(val) {
-      this.checkedCities = val ? cityOptions : [];
-      this.isIndeterminate = false;
-    },
-    handleCheckedCitiesChange(value) {
-      let checkedCount = value.length;
-      this.checkAll = checkedCount === this.cities.length;
-      this.isIndeterminate =
-        checkedCount > 0 && checkedCount < this.cities.length;
-    },
     addHw(e) {
       var el = e.currentTarget;
       el.getElementsByTagName("input")[0].click();
@@ -5459,6 +5551,12 @@ export default {
         } else {
           this.closeConfirm(tool);
         }
+      }else if (tool == 69){
+        if (JSON.stringify(this.englishList) == JSON.stringify(this.englishList)) {
+          this.englishDialogVisible = false
+        } else {
+          this.closeConfirm(tool);
+        }
       }
     },
     closeConfirm(tool) {
@@ -5479,6 +5577,8 @@ export default {
             this.addSelectAnswer();
           } else if (tool == 47) {
             this.addSentenceTool();
+          }else if(tool == 69){
+            this.addEnglish();
           }
         })
         .catch(() => {
@@ -5492,9 +5592,31 @@ export default {
             this.dialogVisibleSelect = false;
           } else if (tool == 47) {
             this.dialogVisibleSentence = false;
+          } else if (tool == 69) {
+            this.englishDialogVisible = false;
           }
         });
     },
+    addEnglish(){
+      if(this.englishList.engTitle == "" || this.englishList.englishText == ""){
+        this.$message.error("请将内容填写完整!");
+        return;
+      }
+      this.unitJson[this.unitIndex].chapterInfo[0].taskJson[
+        this.taskCount
+      ].toolChoose[this.toolIndex].englishList = this.englishList;
+      this.englishList = {};
+      this.englishDialogVisible = false;
+      if (
+        this.unitJson[this.unitIndex].chapterInfo[0].taskJson[this.taskCount]
+          .toolChoose[this.toolIndex].tool != 69
+      ) {
+        this.addTools(69, this.taskCount, this.toolIndex);
+      }
+    },
+    setEnglishList(engList){
+      this.englishList = engList;
+    },
     imgChange2(i, j) {
       var _tmp = this.testJson.testJson[i].checkList[j];
       this.noneBtnImg = _tmp.length >= 1;
@@ -5547,6 +5669,7 @@ export default {
         .$confirm("是否保存已编辑内容?", "提示", {
           confirmButtonText: "保存",
           cancelButtonText: "不保存",
+          distinguishCancelAndClose: true,   
           type: "warning",
         })
         .then(() => {
@@ -5570,17 +5693,20 @@ export default {
             }
           }
         })
-        .catch(() => {
-          this.goTo(
-            "/course?userid=" +
-            this.userid +
-            "&oid=" +
-            this.oid +
-            "&org=" +
-            this.org +
-            "&role=" +
-            this.role
-          );
+        .catch((v) => {
+          console.log(v)
+          if(v == "cancel"){
+              this.goTo(
+              "/course?userid=" +
+              this.userid +
+              "&oid=" +
+              this.oid +
+              "&org=" +
+              this.org +
+              "&role=" +
+              this.role
+            );
+          }
         });
     },
     nextSteps() {
@@ -6827,6 +6953,19 @@ export default {
           }
           this.grade2 = res.data[0];
           this.classJuri = res.data[0];
+          let _check = []
+          let _check2 = []
+          for (var i = 0; i < this.grade2.length; i++) {
+            var gid = this.grade2[i].id
+            _check.push(gid)
+          }
+          for (var i = 0; i < this.checkboxList2.length; i++) {
+            var _id = this.checkboxList2[i]
+              if (_check.indexOf(_id) !== -1) {
+                _check2.push(_id)
+              }
+          }
+          this.checkAll = _check2.length === _check.length;
         })
         .catch((err) => {
           this.isLoading = false;
@@ -6912,6 +7051,60 @@ export default {
       this.unitJson[i].chapterInfo[0].taskJson[taskCount].chapterData[ic] = a;
       this.$forceUpdate();
     },
+    upTool(e, i, j, tooli){
+      e.stopPropagation();
+      if (tooli == 0) {
+        return;
+      }
+      this.$confirm(
+        "切换工具顺序将删除此工具的提交成果,是否继续此操作?",
+        "提示",
+        {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning",
+        }
+      )
+        .then(() => {
+          var a =
+          JSON.parse(JSON.stringify(this.unitJson[i].chapterInfo[0].taskJson[j].toolChoose[tooli - 1]));
+          this.unitJson[i].chapterInfo[0].taskJson[j].toolChoose[tooli - 1] =
+            JSON.parse(JSON.stringify(this.unitJson[i].chapterInfo[0].taskJson[j].toolChoose[tooli]));
+          this.unitJson[i].chapterInfo[0].taskJson[j].toolChoose[tooli] = a;
+          this.$forceUpdate()
+        })
+        .catch(() => {
+          return;
+        });
+    },
+    downTool(e, i, j, tooli){
+      e.stopPropagation();
+      if ( tooli ==
+        this.unitJson[i].chapterInfo[0].taskJson[j].toolChoose.length -
+        1) {
+        return;
+      }
+      this.$confirm(
+        "切换工具顺序将删除此工具的提交成果,是否继续此操作?",
+        "提示",
+        {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning",
+        }
+      )
+        .then(() => {
+          var a =
+          JSON.parse(JSON.stringify(this.unitJson[i].chapterInfo[0].taskJson[j].toolChoose[tooli + 1]));
+          this.unitJson[i].chapterInfo[0].taskJson[j].toolChoose[tooli + 1] =
+            JSON.parse(JSON.stringify(this.unitJson[i].chapterInfo[0].taskJson[j].toolChoose[tooli]));
+          this.unitJson[i].chapterInfo[0].taskJson[j].toolChoose[tooli] = a;
+          this.$forceUpdate()
+        })
+        .catch(() => {
+          return;
+        });
+    },
     addWork() {
       let cPan = 1;
       for (var i = 0; i < this.unitJson.length; i++) {
@@ -7847,6 +8040,19 @@ export default {
           },
           "*"
         );
+      }else if(i == 69){
+        this.englishList = this.unitJson[this.unitIndex].chapterInfo[0].taskJson[
+          itemTaskIndex
+        ].toolChoose[toolIndex].englishList
+          ? JSON.parse(
+            JSON.stringify(
+              this.unitJson[this.unitIndex].chapterInfo[0].taskJson[
+                itemTaskIndex
+              ].toolChoose[toolIndex].englishList
+            )
+          )
+          : {  };
+        this.englishDialogVisible = true;
       }
     },
     chapAddTools(i) {
@@ -7960,6 +8166,16 @@ export default {
           return;
         }
       }
+
+      if(i == 69){
+        if (
+          !this.unitJson[this.unitIndex].chapterInfo[0].taskJson[itemTaskIndex]
+            .toolChoose[toolIndex].englishList
+        ) {
+          this.openTools(itemTaskIndex, 69, toolIndex);
+          return;
+        }
+      }
       // if (i == 48) {
       //   if (
       //     !this.unitJson[this.unitIndex].chapterInfo[0].taskJson[itemTaskIndex]
@@ -9721,6 +9937,19 @@ export default {
     },
     InviteChange(val) {
       console.log(val);
+      let _check = []
+      let _check2 = []
+      for (var i = 0; i < this.grade2.length; i++) {
+        var gid = this.grade2[i].id
+        _check.push(gid)
+      }
+      for (var i = 0; i < this.checkboxList2.length; i++) {
+        var _id = this.checkboxList2[i]
+          if (_check.indexOf(_id) !== -1) {
+            _check2.push(_id)
+          }
+      }
+      this.checkAll = _check2.length === _check.length;
       return;
       let array = JSON.parse(JSON.stringify(val));
       this.inviteCode = this.inviteCode.filter((el) => {
@@ -9733,6 +9962,31 @@ export default {
         this.getInviteCode(array[i]);
       }
     },
+    handleCheckAllChange(val) {
+      if (val) {
+        for (var i = 0; i < this.grade2.length; i++) {
+          var gid = this.grade2[i].id
+          if (this.checkboxList2.indexOf(gid) === -1) {
+            this.checkboxList2.push(gid)
+          }
+        }
+      } else {
+        let _check = []
+        let _check2 = []
+        for (var i = 0; i < this.grade2.length; i++) {
+          var gid = this.grade2[i].id
+          _check.push(gid)
+        }
+        for (var i = 0; i < this.checkboxList2.length; i++) {
+          var _id = this.checkboxList2[i]
+          if (_check.indexOf(_id) === -1) {
+            _check2.push(_id)
+          }
+        }
+        this.checkboxList2 = _check2
+      }
+      this.isIndeterminate = false;
+    },
     async getInviteCode(cid) {
       let code = this.randomNumber();
       let params = {
@@ -9948,7 +10202,8 @@ export default {
       this.oldIndex = i;
       this.oldData = val;
     },
-    dragOver(i) {
+    dragOver(i, j) {
+      this.typeIndex = "chapter-" + j + '-' + i
       this.newIndex = i;
     },
     dragEnd() {
@@ -9958,6 +10213,7 @@ export default {
       // 在列表中目标位置增加新的节点
       newItems.splice(this.newIndex, 0, this.oldData);
       this.unitJson[this.unitIndex].chapterInfo[0].taskJson[this.taskCount].chapterData = [...newItems];
+      this.typeIndex = "";
       this.newIndex = "";
       this.$forceUpdate()
     },
@@ -9966,10 +10222,13 @@ export default {
       this.oldData = val;
     },
     dragTaskOver(i) {
+      this.typeIndex = "task-" + i
       this.newIndex = i;
     },
     dragTaskEnd() {
       if(this.newIndex == this.oldIndex){
+        this.newIndex = "";
+        this.typeIndex = "";
         return;
       }
       this.$confirm(
@@ -9988,10 +10247,12 @@ export default {
           // 在列表中目标位置增加新的节点
           newItems.splice(this.newIndex, 0, this.oldData);
           this.unitJson[this.unitIndex].chapterInfo[0].taskJson = [...newItems];
+          this.typeIndex = "";
           this.newIndex = "";
           this.$forceUpdate()
         })
         .catch(() => {
+          this.typeIndex = "";
           this.newIndex = "";
           return;
         });
@@ -10516,9 +10777,9 @@ export default {
   font-size: 14px;
   cursor: pointer;
   color: #717C8D;
-  position: absolute;
+  /* position: absolute;
   right: 45px;
-  top: 5px;
+  top: 5px; */
 }
 
 .show_toolD>img {
@@ -11256,8 +11517,48 @@ export default {
   margin-bottom: 5px;
 }
 
+.chapter_upload_ud2 {
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  margin: 0 10px 0 0;
+}
+
+.chapter_upload_ud2>.chapter_upload_up2 {
+  margin-bottom: 0;
+  margin-right: 10px;
+}
 
 
+.chapter_upload_down2,
+.chapter_upload_up2 {
+  cursor: pointer;
+  margin: 0 auto;
+  border-radius: 5px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  color: #717C8D;
+  font-size: 14px;
+}
+.chapter_upload_up2{
+  margin-right:10px;
+}
+.chapter_upload_up2::before,
+.chapter_upload_down2::before {
+  content: '';
+  background-image: url('../../../assets/icon/new/c_up.png');
+  width: 14px;
+  height: 14px;
+  background-size: 100% 100%;
+  display: block;
+  margin-right: 5px;
+}
+
+.chapter_upload_up2::before {
+  background-image: url('../../../assets/icon/new/c_down.png') !important;
+}
+
 .addWordStyle {
   display: flex;
   flex-direction: row;
@@ -11596,7 +11897,7 @@ ol {
 }
 
 .tool+.tool {
-  margin-right: 45px;
+  margin-right: 10px;
 }
 
 .whiteBIcon {
@@ -11923,7 +12224,7 @@ ol {
 }
 
 .toolSort>div {
-  margin-right: 45px;
+  margin-right: 10px;
 }
 
 .tools {
@@ -12045,6 +12346,7 @@ ol {
   position: absolute;
   right: 15px;
   bottom: 35px;
+  z-index: 999;
 }
 
 .fold {
@@ -12602,6 +12904,37 @@ ol {
   align-items: center;
   font-size: 14px;
   color: #6e6e6e;
+  position:relative;
+}
+
+.cover_p{
+  width: 100% !important;
+  height: 100%;
+  object-fit: cover;
+}
+
+.uploadFm2:hover .cover_mask{
+  display: flex !important;
+}
+
+.cover_mask{
+  display:none;
+  width:100%;
+  height:100%;
+  position:absolute;
+  background:#00000054;
+  align-items: center;
+  justify-content: center;
+  flex-direction: column;
+}
+
+.cover_mask > img{
+  width: 30px;
+}
+
+.cover_mask > span{
+  color: #fff;
+  font-size: 12px;
 }
 
 .uploadFm>img {
@@ -13139,6 +13472,28 @@ ol {
   background-image: url(../../../assets/icon/new/icon_arrow_a.png) !important;
 }
 
+.dragOverTop {
+  border-top: 2px solid #0061FF !important;
+  border-radius: 0 !important;
+  margin-top: 10px;
+}
+
+.dragOverBottom {
+  border-bottom: 2px solid #0061FF !important;
+  border-radius: 0 !important;
+  margin-top: 10px;
+}
+
+.dragOverTop2 {
+  border-top: 2px solid #0061FF !important;
+  border-radius: 0 !important;
+}
+
+.dragOverBottom2 {
+  border-bottom: 2px solid #0061FF !important;
+  border-radius: 0 !important;
+}
+
 .isNavTask {
   /* background: #3681FC; */
   background: #EEF3FB;
@@ -13177,14 +13532,14 @@ ol {
   color: #060E17;
   line-height: 25px;
   font-size: 16px;
-  min-width: 45px;
-}
+  /* min-width: 66px; */
+}
 
 .navTask .nt_taskName {
   /* color: #fff; */
   /* max-width: 130px; */
   /* width: 100%; */
-  max-width: calc(100% - 50px);
+  max-width: calc(100% - 66px);
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
@@ -13598,10 +13953,24 @@ ol {
   box-sizing: border-box;
 }
 
+.check_class_all_box {
+  display: flex;
+  margin-bottom: 10px;
+}
+
+.all_check {
+  display: flex;
+  align-items: center;
+  padding: 2px 0 0;
+  margin-left: 10px;
+}
+
+.all_check>>>.el-checkbox__label {
+  line-height: 18px;
+}
 .check_class_left_title {
   font-size: 16px;
   font-weight: 700;
-  margin-bottom: 10px;
 }
 
 .check_class_item {
@@ -13614,6 +13983,9 @@ ol {
   align-content: flex-start;
 }
 
+.class_item:first-child {
+  /* margin: 0 15px 15px 67px; */
+}
 .class_item {
   margin: 0 15px 15px 0;
 

+ 90 - 0
src/components/pages/task/commpont/englishRight.vue

@@ -0,0 +1,90 @@
+<template>
+  <div class="englishBox">
+    <div class="themeTitle">
+      <div>作文题目<span style="color: red;">*</span></div>
+      <div>
+        <el-input
+          v-model="engList.engTitle"
+          placeholder="请填写作文题目"
+          @change="setEngList"
+        ></el-input>
+      </div>
+    </div>
+    <div class="themeText">
+      <div>作文要求<span style="color: red;">*</span></div>
+      <div>
+        <editor-bar
+          placeholder="请填写作文要求"
+          v-model="engList.englishText"
+          @change="setEngList"
+        ></editor-bar>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import EditorBar from "../../../../components/tools/wangEnduit";
+export default {
+  components: {
+    EditorBar,
+  },
+  props: ["englishList"],
+  data() {
+    return {
+      engList: {
+        engTitle: "",
+        englishText: "",
+      },
+    };
+  },
+  methods: {
+    setEngList() {
+      this.$emit("setEnglish", this.engList);
+    },
+  },
+  created() {
+    this.engList = this.englishList;
+  },
+};
+</script>
+
+<style scoped>
+.englishBox {
+  width: 50%;
+  margin: 50px auto 0;
+}
+.themeTitle {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  align-items: center;
+}
+.themeTitle > div:first-child {
+  min-width: 65px;
+  font-weight: bold;
+}
+.themeTitle > div:last-child {
+  width: calc(100% - 75px);
+  margin-left: 10px;
+}
+.themeText {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  align-items: flex-start;
+  margin-top: 20px;
+}
+.themeText > div:first-child {
+  min-width: 65px;
+  margin-top: 10px;
+  font-weight: bold;
+}
+.themeText > div:last-child {
+  width: calc(100% - 75px);
+  margin-left: 10px;
+}
+.themeText > div:last-child >>> .text {
+  min-height: 400px !important;
+}
+</style>

+ 291 - 0
src/components/pages/test/add/addTest.vue

@@ -0,0 +1,291 @@
+<template>
+    <div class="pb_content" style="background: #F0F2F5;" v-loading="loading">
+        <div class="pb_content_body" style="position: relative; margin: 0">
+            <div class="right">
+                <div class="courseTop">
+                    <div class="stepsNav">
+                        <el-breadcrumb separator-class="el-icon-arrow-right">
+                            <el-breadcrumb-item :to="{
+                                path:
+                                    '/test?userid=' +
+                                    userid +
+                                    '&oid=' +
+                                    oid +
+                                    '&org=' +
+                                    org +
+                                    '&role=' +
+                                    role,
+                            }">评测管理</el-breadcrumb-item>
+                            <el-breadcrumb-item>
+                                <span style="color: rgb(15, 126, 255)">新建评测</span>
+                            </el-breadcrumb-item>
+                        </el-breadcrumb>
+                    </div>
+                    <div class="r_pub_button_retrun" @click="retrunCourse">返回</div>
+                </div>
+                <div class="step_box" :style="{ width: steps == 2 && '100%' }">
+                    <setInfo v-if="steps == 1 && !loading" :oid="oid" :org="org" :steps.sync="steps" :title.sync="title"
+                        :testType.sync="testType" :see.sync="see" :cJson.sync="cJson"></setInfo>
+                    <editInfo v-if="steps == 2 && !loading" :oid="oid" :org="org" :steps.sync="steps" :title.sync="title"
+                        :cJson.sync="cJson" @save="save" @publish="publish"></editInfo>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import setInfo from './setInfo/index.vue'
+import editInfo from './edit/index.vue'
+export default {
+    components: {
+        setInfo, editInfo
+    },
+    data() {
+        return {
+            userid: this.$route.query.userid,
+            oid: this.$route.query.oid,
+            org: this.$route.query.org,
+            role: this.$route.query.role,
+            cid: this.$route.query.cid,
+            steps: 1,
+            title: "",
+            testType: [],
+            see: false,
+            cJson: [],
+            loading:false,
+            look:"",
+        }
+    },
+    watch: {
+        steps(newValue, oldValue) {
+            if (!this.title) {
+                this.$message.error("请补充填写课程名称");
+                this.steps = 1
+                return;
+            }
+            if (this.cid) {
+                this.updateWork(this.look)
+            } else {
+                this.addWork();
+            }
+        }
+    },
+    methods: {
+        retrunCourse() {
+            this
+                .$confirm("是否保存已编辑内容?", "提示", {
+                    confirmButtonText: "保存",
+                    cancelButtonText: "不保存",
+                    distinguishCancelAndClose: true,
+                    type: "warning",
+                })
+                .then(() => {
+                    if (this.cid == "" || this.cid == undefined) {
+                        if (this.title == "") {
+                            this.$message.error("请补充填写课程名称");
+                            return;
+                        } else {
+                            this.addWork();
+                        }
+                    } else {
+                        if (this.title == "") {
+                            this.$message.error("请补充填写课程名称");
+                            return;
+                        } else {
+                            this.updateWork();
+                        }
+                    }
+                })
+                .catch((v) => {
+                    console.log(v)
+                    if (v == "cancel") {
+                        this.goTo(
+                            "/test?userid=" +
+                            this.userid +
+                            "&oid=" +
+                            this.oid +
+                            "&org=" +
+                            this.org +
+                            "&role=" +
+                            this.role
+                        );
+                    }
+                });
+        },
+        goTo(path) {
+            this.$router.push(path);
+        },
+        addWork() {
+            let params = [
+                {
+                    uid: this.userid,
+                    title: this.title.replace(/%/g, "%25"),
+                    brief: "",
+                    cover: "",
+                    evaId: "",
+                    astudent: "",
+                    see: this.see == true ? 1 : 0,
+                    chapters: JSON.stringify(this.cJson).replaceAll(/%/g, "%25"),
+                    template: "",
+                    courseType: JSON.stringify(this.testType),
+                    ateacher: "",
+                    inviteCode: "",
+                },
+            ];
+            this.ajax
+                .post(this.$store.state.api + "addTestCourse", params)
+                .then((res) => {
+                    this.cid = res.data.courseId;
+                })
+                .catch((err) => {
+                    this.$message.error("网络不佳");
+                    console.error(err);
+                });
+        },
+        updateWork(look) {
+            let params = [
+                {
+                    cid: this.cid,
+                    title: this.title.replace(/%/g, "%25"),
+                    brief: "",
+                    cover: "",
+                    evaId: "",
+                    astudent: "",
+                    see: this.see == true ? 1 : 0,
+                    chapters: JSON.stringify(this.cJson).replaceAll(/%/g, "%25"),
+                    uid: this.userid,
+                    courseType: JSON.stringify(this.testType),
+                    ateacher: "",
+                    inviteCode: "",
+                    look: look == 3 ? 2 : look == 4 ? 1 : look,
+                },
+            ];
+            this.ajax
+                .post(this.$store.state.api + "updateTestCourse", params)
+                .then((res) => {
+                    if(look == 3){
+                        this.$message.success("发布成功")
+                        this.goTo(
+                            "/test?userid=" +
+                            this.userid +
+                            "&oid=" +
+                            this.oid +
+                            "&org=" +
+                            this.org +
+                            "&role=" +
+                            this.role
+                        );
+                    }else if(look == 4){
+                        this.$message.success("保存成功")
+                        this.goTo(
+                            "/test?userid=" +
+                            this.userid +
+                            "&oid=" +
+                            this.oid +
+                            "&org=" +
+                            this.org +
+                            "&role=" +
+                            this.role
+                        );
+                    }
+                    this.getData();
+                })
+                .catch((err) => {
+                    this.$message.error("网络不佳");
+                    console.error(err);
+                });
+        },
+        getData() {
+            if (this.cid == "" || this.cid == undefined) {
+                console.log("这是新增课程");
+            } else {
+                this.loading = true
+                let params = {
+                    cid: this.cid,
+                };
+                this.ajax
+                    .get(this.$store.state.api + "getTestCourseDetail", params)
+                    .then((res) => {
+                        this.cJson = JSON.parse(res.data[0][0].chapters);
+                        this.$forceUpdate();
+                        this.title = res.data[0][0].title;
+
+                        this.see = res.data[0][0].open == 1 ? true : false;
+
+              
+                        this.testType = [];
+                        for (var i = 0; i < res.data[1].length; i++) {
+                            this.testType.push(res.data[1][i].typeid);
+                        }
+                        console.log(this.testType);
+                        this.look = res.data[0][0].look
+                        this.loading = false
+
+                    })
+                    .catch((err) => {
+                        console.error(err);
+                    });
+            }
+        },
+        save() {
+            this.updateWork(4)
+        },
+        publish() {
+            this.updateWork(3)
+        },
+    },
+    mounted () {
+        this.getData();
+    },
+}
+</script>
+
+<style scoped>
+.pb_content {
+    height: 100% !important;
+    /* margin: 0 20px 0 20px; */
+}
+
+.pb_content_body {
+    width: 100% !important;
+    height: 100%;
+}
+
+.right {
+    height: 100%;
+    width: 100%;
+    display: flex;
+    overflow: hidden;
+    flex-direction: column;
+}
+
+.basic_box {
+    margin: 0 auto;
+    position: relative;
+    padding: 0 20px 0 20px;
+}
+
+.courseTop {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    width: calc(100% - 40px);
+    margin: 0 auto;
+    padding: 10px 0;
+}
+
+.stepsNav {
+    display: flex;
+    flex-direction: row;
+    justify-content: flex-start;
+    align-items: center;
+}
+
+.step_box {
+    width: calc(100% - 40px);
+    margin: 0 auto;
+    height: calc(100% - 38px);
+}
+</style>

+ 361 - 0
src/components/pages/test/add/components/checkOrder.vue

@@ -0,0 +1,361 @@
+<template>
+    <div class="co_box">
+        <div v-for="(item1, index1) in this.checkJson" :key="index1" class="mc_ti_1" :draggable="isdrag == `${index1}`"
+            :class="{ active: checkC === `x${index1}` }" @click.stop="checkTitle(`${index1}`, 1, item1)">
+            <div class="title">
+                <div class="drag" @mousedown="setDrag(`${index1}`)" @mouseup="isdrag = ''"></div>
+                <span>{{ selectType(item1, index1) }}</span>
+                <div class="btnBox">
+                    <!-- <div class="edit" @click.stop="editCheck(`${index1}`,item1)" v-if="item1.ttype == 1 && canEdit.indexOf(item1.type) !== -1 && etype == 'edit'"></div> -->
+                    <div class="delete" @click.stop="deleteCheck(`${index1}`)"></div>
+                    <div class="open" v-if="item1.array && item1.array.length" :class="{ isopen: item1.isopen }"
+                        @click.stop="openPan(index1)"></div>
+                </div>
+            </div>
+            <div v-if="item1.array && item1.array.length && item1.isopen" class="mc_ti_1_xia">
+                <div v-for="(item2, index2) in item1.array" :key="`${index1}-${index2}`" class="mc_ti_2"
+                    :draggable="isdrag == `${index1}-${index2}`" :class="{ active: checkC === `x${index1}-${index2}` }"
+                    @click.stop="checkTitle(`${index1}-${index2}`, 2, item2)">
+                    <div class="title">
+                        <div class="drag" @mousedown="setDrag(`${index1}-${index2}`)" @mouseup="isdrag = ''"></div>
+                        <span>{{ selectType(item2, index2) }}</span>
+                        <div class="btnBox">
+                            <!-- <div class="edit" @click.stop="editCheck(`${index1}-${index2}`,item2)" v-if="item2.ttype == 1 && canEdit.indexOf(item2.type) !== -1 && etype == 'edit'"></div> -->
+                            <div class="delete" @click.stop="deleteCheck(`${index1}-${index2}`)"></div>
+                            <div class="open" v-if="item2.array && item2.array.length" :class="{ isopen: item2.isopen }"
+                                @click.stop="openPan(index1, index2)"></div>
+                        </div>
+                    </div>
+                    <div v-if="item2.array && item2.array.length && item2.isopen" class="mc_ti_2_xia">
+                        <div v-for="(item3, index3) in item2.array" :key="`${index1}-${index2}-${index3}`" class="mc_ti_3"
+                            :draggable="isdrag == `${index1}-${index2}-${index3}`"
+                            :class="{ active: checkC === `x${index1}-${index2}-${index3}` }"
+                            @click.stop="checkTitle(`${index1}-${index2}-${index3}`, 3, item3)">
+                            <div class="title">
+                                <div class="drag" @mousedown="setDrag(`${index1}-${index2}-${index3}`)"
+                                    @mouseup="isdrag = ''"></div>
+                                <span>{{ selectType(item3, index3) }}</span>
+                                <div class="btnBox">
+                                    <!-- <div class="edit" @click.stop="editCheck(`${index1}-${index2}-${index3}`,item3)" v-if="item3.ttype == 1 && canEdit.indexOf(item3.type) !== -1 && etype == 'edit'"></div> -->
+                                    <div class="delete" @click.stop="deleteCheck(`${index1}-${index2}-${index3}`)"></div>
+                                </div>
+                            </div>
+                            <div v-if="item3.ttype == 1 && canEdit.indexOf(item3.type) !== -1 && etype == 'edit'"
+                                class="edit_box">
+                                <div v-if="item3.type == 1">
+                                    <choiceX :cJson="item3.json"></choiceX>
+                                    <choiceDialog v-if="item3.type == 1 && checkC === `x${index1}-${index2}-${index3}`"
+                                        :cJson="cJson" @setJson="setJson">
+                                    </choiceDialog>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div v-else-if="item2.ttype == 1 && canEdit.indexOf(item2.type) !== -1 && etype == 'edit'"
+                        class="edit_box">
+                        <div v-if="item2.type == 1">
+                            <choiceX :cJson="item2.json"></choiceX>
+                            <choiceDialog v-if="item2.type == 1 && checkC === `x${index1}-${index2}`" :cJson="cJson"
+                                @setJson="setJson"></choiceDialog>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div v-else-if="item1.ttype == 1 && canEdit.indexOf(item1.type) !== -1 && etype == 'edit'" class="edit_box">
+                <div v-if="item1.type == 1">
+                    <choiceX :cJson="item1.json"></choiceX>
+                    <choiceDialog v-if="item1.type == 1 && checkC === `x${index1}`" :cJson="cJson" @setJson="setJson">
+                    </choiceDialog>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import minxinVue from '../minxins/minxin';
+import choiceDialog from './choice/index.vue'
+import choiceX from './choice/choice.vue'
+
+export default {
+    mixins: [minxinVue],
+    components: {
+        choiceDialog,
+        choiceX
+    },
+    props: {
+        checkJson: {
+            type: Array,
+        },
+        checkC: {
+            type: String
+        },
+        etype: {
+            type: String,
+            default: ""
+        }
+    },
+    data() {
+        return {
+            manualJson: [],
+            isdrag: "",
+            canEdit: [1],
+            ctype: "",
+            cJson: {}
+        }
+    },
+    computed: {
+        selectType() {
+            return function (item, index) {
+                if (item.ttype == 1) {
+                    return index + 1 + "、" + this.options2[item.type];
+                } else if (item.ttype == 2) {
+                    return `第${index + 1}组 (共${item.array.length}题)`;
+                } else if (item.ttype == 3) {
+                    return `分页${index + 1}`;
+                }
+            };
+        }
+    },
+    watch: {
+        checkJson: {
+            handler(newVal) {
+                this.manualJson = this.depthCopy(newVal)
+            },
+            deep: true
+        }
+    },
+    methods: {
+        setDrag(index) {
+            console.log(index);
+            this.isdrag = index
+        },
+        openPan(index1, index2) {
+            console.log(this.manualJson);
+            if (index2 === 0 || index2) {
+                this.manualJson[index1].array[index2].isopen = !this.manualJson[index1].array[index2].isopen
+            } else {
+                this.manualJson[index1].isopen = !this.manualJson[index1].isopen
+            }
+            this.$forceUpdate();
+            this.$emit("changeJson", this.manualJson);
+        },
+        checkTitle(index, type, item) {
+            if (this.checkC === "x" + index) {
+                this.$emit("update:checkC", "")
+            } else {
+                this.$emit("update:checkC", 'x' + index)
+            }
+            let _index = index.split("-");
+
+            this.ctype = type
+            if (this.ctype == 1 && item.ttype == 1) {
+                this.cJson = this.manualJson[_index[0]].json
+            } else if (this.ctype == 2 && item.ttype == 1) {
+                this.cJson = this.manualJson[_index[0]].array[_index[1]].json
+            } else if (this.ctype == 3 && item.ttype == 1) {
+                this.cJson = this.manualJson[_index[0]].array[_index[1]].array[_index[2]].json
+            }
+        },
+        setJson(json) {
+            let _index = this.checkC.replace("x", "").split("-");
+            this.cJson = json
+            if (this.ctype == 1) {
+                this.manualJson[_index[0]].json = json
+            } else if (this.ctype == 2) {
+                this.manualJson[_index[0]].array[_index[1]].json = json
+            } else if (this.ctype == 3) {
+                this.manualJson[_index[0]].array[_index[1]].array[_index[2]].json = json
+            }
+            this.$forceUpdate();
+            this.$emit("changeJson", this.manualJson);
+        },
+        deleteCheck(index) {
+            let _check = index.split("-")
+            let string = ""
+            if (_check.length == 1) {
+                if (this.manualJson[_check[0]].ttype == 1) {
+                    string = "确定删除该题目吗?"
+                } else if (this.manualJson[_check[0]].ttype == 2) {
+                    string = "删除该分组将会同步删除该分组下所有内容,是否继续操作?"
+                } else if (this.manualJson[_check[0]].ttype == 3) {
+                    string = "删除该分页将会同步删除该分页下所有内容,是否继续操作?"
+                }
+            } else if (_check.length == 2) {
+                if (this.manualJson[_check[0]].array[_check[1]].ttype == 1) {
+                    string = "确定删除该题目吗?"
+                } else if (this.manualJson[_check[0]].array[_check[1]].ttype == 2) {
+                    string = "删除该分组将会同步删除该分组下所有内容,是否继续操作?"
+                }
+            } else if (_check.length == 3) {
+                string = "确定删除该题目吗?"
+            }
+            this.$confirm(string, "提示", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning",
+            })
+                .then(() => {
+                    if (_check.length == 1) {
+                        this.manualJson.splice(_check[0], 1)
+                    } else if (_check.length == 2) {
+                        this.manualJson[_check[0]].array.splice(_check[1], 1)
+                    } else if (_check.length == 3) {
+                        this.manualJson[_check[0]].array[_check[1]].array.splice(_check[2], 1)
+                    }
+                    this.$emit("update:checkC", "")
+                    this.$forceUpdate()
+                    this.$emit("changeJson", this.manualJson);
+                })
+                .catch(() => { });
+        },
+        editCheck(index, item) {
+
+        }
+    },
+    mounted() {
+        this.manualJson = this.depthCopy(this.checkJson);
+    },
+}
+</script>
+
+<style scoped>
+.co_box {
+    width: 100%;
+}
+
+.mc_ti_1 {
+    width: 100%;
+    min-height: 40px;
+    border: 1px solid #bcbcbc;
+    padding: 10px;
+    box-sizing: border-box;
+    margin-bottom: 10px;
+}
+
+
+
+.mc_ti_1+.mc_ti_1 {
+    margin-top: 10px;
+}
+
+.mc_ti_1>.title {
+    font-size: 20px;
+    cursor: pointer;
+    display: flex;
+    align-items: center;
+}
+
+.mc_ti_1_xia,
+.mc_ti_2_xia {
+    padding: 10px;
+    width: 100%;
+    box-sizing: border-box;
+}
+
+.mc_ti_2 {
+    width: 100%;
+    box-sizing: border-box;
+    padding: 10px;
+    border: 1px solid #bcbcbc;
+}
+
+.mc_ti_2+.mc_ti_2 {
+    margin-top: 10px;
+}
+
+.mc_ti_2>.title {
+    cursor: pointer;
+    font-size: 18px;
+    display: flex;
+    align-items: center;
+}
+
+
+.mc_ti_3 {
+    padding: 10px;
+    width: 100%;
+    box-sizing: border-box;
+    border: 1px solid #bcbcbc;
+}
+
+.mc_ti_3+.mc_ti_3 {
+    margin-top: 10px;
+}
+
+.mc_ti_3>.title {
+    cursor: pointer;
+    display: flex;
+    align-items: center;
+}
+
+.mc_ti_1>.title>.drag,
+.mc_ti_2>.title>.drag,
+.mc_ti_3>.title>.drag {
+    display: block;
+    background-image: url('../../../../../assets/icon/new/icon_course_drag.png');
+    background-size: 100% 100%;
+    width: 20px;
+    height: 20px;
+    cursor: pointer;
+}
+
+.mc_ti_1>.title>.btnBox,
+.mc_ti_2>.title>.btnBox,
+.mc_ti_3>.title>.btnBox {
+    margin-left: auto;
+    display: flex;
+}
+
+.mc_ti_1>.title>.btnBox .open,
+.mc_ti_2>.title>.btnBox .open {
+    display: block;
+    background-image: url('../../../../../assets/icon/new/u_arrow.png');
+    background-size: 100% 100%;
+    width: 15px;
+    height: 15px;
+    cursor: pointer;
+    transition: all .5s;
+    transform: rotate(-90deg);
+}
+
+.mc_ti_1>.title>.btnBox .delete,
+.mc_ti_2>.title>.btnBox .delete,
+.mc_ti_3>.title>.btnBox .delete {
+    display: block;
+    background-image: url('../../../../../assets/icon/new/delete_u.png');
+    background-size: 100% 100%;
+    width: 18px;
+    height: 18px;
+    cursor: pointer;
+    margin-right: 10px;
+}
+
+.mc_ti_1>.title>.btnBox .edit,
+.mc_ti_2>.title>.btnBox .edit,
+.mc_ti_3>.title>.btnBox .edit {
+    display: block;
+    background-image: url('../../../../../assets/icon/new/edit_u.png');
+    background-size: 100% 100%;
+    width: 18px;
+    height: 18px;
+    cursor: pointer;
+    margin-right: 10px;
+}
+
+.mc_ti_1>.title>.btnBox .isopen,
+.mc_ti_2>.title>.btnBox .isopen {
+    transform: rotate(0deg);
+}
+
+.mc_ti_1.active,
+.mc_ti_2.active,
+.mc_ti_3.active {
+    border: 1px solid #0062ff;
+}
+
+.edit_box {
+    width: 100%;
+    box-sizing: border-box;
+    padding: 10px;
+}</style>

+ 90 - 0
src/components/pages/test/add/components/choice/choice.vue

@@ -0,0 +1,90 @@
+<template>
+    <div class="c_box">
+        <div class="mask"></div>
+        <div v-if="!cJson">暂未设置题目</div>
+        <div v-else class="choice_box">
+            <div class="title">{{ `(${option[cJson.type].name})` + cJson.title }}</div>
+            <div class="choices">
+                <div class="choice" v-for="(item, index) in cJson.array" :key="index">
+                    <div class="choice_c" v-if="cJson.type == 2"><el-checkbox v-model="cJson.answer" :label="index"></el-checkbox><span :class="{right:cJson.answer.indexOf(index) != -1}">{{ item.option }}</span></div>
+                    <div class="choice_c" v-if="cJson.type == 1"><el-radio v-model="cJson.answer[0]" :label="index"></el-radio><span :class="{right:cJson.answer.indexOf(index) != -1}">{{ item.option }}</span></div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    props: {
+        cJson: {
+            type: Object,
+        },
+    },
+    data() {
+        return {
+            option: {
+                1: { name: '单选题' },
+                2: { name: '多选题' }
+            }
+        }
+    },
+}
+</script>
+
+<style scoped>
+.c_box {
+    width: 100%;
+    position: relative;
+}
+.mask{
+    position: absolute;
+    height: 100%;
+    width: 100%;
+    z-index: 2;
+}
+.choice_box {}
+
+.choice_box>.title {
+    font-weight: bold;
+    width: 100%;
+    word-break: break-all;
+}
+.choice_box>.choices {
+   margin-top:10px;
+}
+.choice_box>.choices >.choice{
+    word-break: break-all;
+}
+.choice_box>.choices >.choice + .choice{
+    margin-top: 5px;
+}
+.choice_box>.choices >.choice > .choice_c{
+    display: flex;
+}
+.choice_box>.choices >.choice > .choice_c > span{
+    /* margin-left: 10px; */
+}
+.choice_box>.choices >.choice > .choice_c > .el-checkbox{
+    margin-top: 4px;
+    margin-right: 10px;
+}
+.choice_box>.choices >.choice > .choice_c > .el-radio{
+    margin-top: 4px;
+    margin-right: 10px;
+}
+.choice_c>>>.el-checkbox__label {
+    display: none;
+}
+
+.choice_c>>>.el-radio__label {
+    display: none;
+}
+
+.choice_c .right{
+    color: #efa030;
+}
+.choice_c .right::after{
+    content: '(正确答案)';
+}
+</style>

+ 214 - 0
src/components/pages/test/add/components/choice/index.vue

@@ -0,0 +1,214 @@
+<template>
+    <div class="choice_box" @click.stop="">
+        <div class="title">设置选择题</div>
+        <div class="box">
+            <div class="set_type">
+                <span>选择题类型:</span>
+                <el-select v-model="checkJson.type" @change="changeAnswer">
+                    <el-option v-for="item in options" :key="item.type" :label="item.name" :value="item.type">
+                    </el-option>
+                </el-select>
+            </div>
+            <div class="set_title">
+                <span>选择题标题:</span><el-input v-model="checkJson.title" class="input" placeholder="请输入标题"></el-input>
+            </div>
+            <div class="set_options">
+                <div class="title">选择题选项:</div>
+                <div class="xuan_body">
+                    <div class="xuan_title">
+                        <span class="xuan_1">选项文字</span>
+                        <!-- <span class="xuan_2">图片</span> -->
+                        <span class="xuan_3">正确答案</span>
+                        <!-- <span class="xuan_4">上移下移</span> -->
+                    </div>
+                    <div v-for="(item, index) in checkJson.array" :key="index" class="xuan_box">
+                        <div class="xuan_1">
+                            <el-input v-model="item.option" placeholder="请输入选项" size="normal"></el-input>
+                            <el-button type="primary" size="mini" @click="addOption2(index)"
+                                style="margin-left: 10px;">+</el-button>
+                            <el-button type="primary" size="mini" @click="deleteOption(index)">-</el-button>
+                        </div>
+                        <!-- <div class="xuan_2"><span></span></div> -->
+                        <div class="xuan_3"><el-checkbox v-model="checkJson.answer" :label="index"
+                                @change="checkChange(index)"></el-checkbox></div>
+                        <!-- <div class="xuan_4">
+                            <div><span></span><span></span></div>
+                        </div> -->
+                    </div>
+                </div>
+                <div class="btn">
+                    <el-button type="primary" size="mini" @click="addOption">添加选项</el-button>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    props: {
+        cJson: {
+            type: Object,
+        },
+    },
+    data() {
+        return {
+            ctype: 1,
+            options: [
+                { type: 1, name: '单选题' },
+                { type: 2, name: '多选题' }
+            ],
+            checkJson: {}
+        }
+    },
+    watch: {
+        checkJson: {
+            handler(newVal) {
+                this.$emit("setJson", newVal)
+            },
+            deep: true
+        }
+    },
+    methods: {
+        depthCopy(s) {
+            return JSON.parse(JSON.stringify(s));
+        },
+        changeAnswer() {
+            this.checkJson.answer = []
+        },
+        checkChange(val) {
+            if (this.checkJson.type == 1) {
+                this.checkJson.answer = [val]
+            }
+        },
+        addOption() {
+            this.checkJson.array.push({ option: "选项" + (this.checkJson.array.length + 1), img: "" })
+        },
+        addOption2(index) {
+            this.checkJson.array.splice(index+1, 0, { option: "选项", img: "" })
+        },
+        deleteOption(index) {
+            this.checkJson.array.splice(index, 1)
+            if (this.checkJson.answer.indexOf(index) != -1) {
+                this.checkJson.answer.splice(this.checkJson.answer.indexOf(index), 1)
+            }
+        }
+    },
+    mounted() {
+        console.log(1);
+        // console.log(this.cJson);
+        if (!this.cJson) {
+            this.checkJson = {
+                title: "标题",
+                type: 1,
+                array: [
+                    { option: "选项1", img: "" },
+                    { option: "选项2", img: "" }
+                ],
+                answer: ""
+            };
+        } else {
+            this.checkJson = this.depthCopy(this.cJson);
+        }
+
+    },
+}
+</script>
+
+<style scoped>
+.choice_box {
+    margin-top: 10px;
+    width: 100%;
+    background: #f6f6f6;
+    padding: 10px;
+    box-sizing: border-box;
+}
+
+.choice_box>.box {}
+
+.set_type {
+    margin-top: 10px;
+    display: flex;
+    align-items: center;
+}
+
+.set_title {
+    margin-top: 10px;
+    display: flex;
+    align-items: center;
+}
+
+.set_type>span,
+.set_title>span {
+    min-width: fit-content;
+    font-size: 15px;
+}
+
+.set_options {
+    margin-top: 10px;
+}
+
+.set_options>.title {
+    font-size: 15px;
+}
+
+.xuan_body {
+    margin-top: 10px;
+    font-size: 14px;
+}
+
+.xuan_body>.xuan_title {
+    display: flex;
+    align-items: center;
+    background: #e1e1e1;
+    height: 40px;
+    padding: 0 10px;
+    box-sizing: border-box;
+    justify-content: space-between;
+}
+
+.xuan_body>.xuan_box {
+    display: flex;
+    align-items: center;
+    min-height: 40px;
+    padding: 0 10px;
+    box-sizing: border-box;
+    justify-content: space-between;
+    margin-top: 10px;
+}
+
+.xuan_1 {
+    display: flex;
+    width: calc(100% - 340px);
+    align-items: center;
+}
+
+.xuan_2 {
+    width: 100px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.xuan_3 {
+    width: 100px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.xuan_3>>>.el-checkbox__label {
+    display: none;
+}
+
+.xuan_4 {
+    width: 100px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.set_options>.btn {
+    margin-top: 10px;
+}
+</style>

+ 315 - 0
src/components/pages/test/add/edit/edit/index.vue

@@ -0,0 +1,315 @@
+<template>
+    <div class="edit_box">
+        <div class="e_add">
+            <div class="title">题目添加</div>
+            <div class="e_add_box">
+                <div class="title">添加题型</div>
+                <div class="e_add_ci">
+                    <div class="title">基础题型</div>
+                    <div class="box">
+                        <div class="btn" v-for="item in options" :key="item.label" @click="addCheck(item.value)"><el-button type="primary"
+                                size="mini">{{ item.label }}</el-button></div>
+                    </div>
+                </div>
+            </div>
+            <div class="e_add_box">
+                <div class="title">添加组件</div>
+                <div class="e_add_ci">
+                    <div class="box">
+                        <div class="btn" v-for="item in buttonOptions" :key="item.name" @click="addQtype(item.type)"><el-button type="primary"
+                                size="mini">{{ item.name }}</el-button></div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="e_content">
+            <div class="title">{{title}}</div>
+            <div class="e_order_box">
+                <checkOrder :checkC.sync="checkC" :checkJson="manualJson" @changeJson="changeJson" etype="edit"></checkOrder>
+            </div>
+        </div>
+        <div class="e_order">
+            <div class="title">题目排序</div>
+            <div class="e_order_box" style="margin-top: 20px;">
+                <checkOrder :checkC.sync="checkC" :checkJson="manualJson" @changeJson="changeJson"></checkOrder>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import checkOrder from '../../components/checkOrder.vue';
+import minxinVue from '../../minxins/minxin';
+export default {
+    components: {
+        checkOrder,
+    },
+    mixins: [minxinVue],
+    props: {
+        checkJson: {
+            type: Array,
+        },
+        title:{
+            type:String
+        }
+    },
+    data() {
+        return {
+            manualJson: [],
+            checkC: "",
+        }
+    },
+    watch: {
+        checkJson:{
+            handler(newVal){
+                this.manualJson = this.depthCopy(newVal);
+            },
+            deep: true
+        }
+    },
+    methods: {
+        changeJson(json) {
+            this.manualJson = json;
+            this.$emit("changeJson", json);
+        },
+        addCheck(topicType) {
+            let type = 1;
+            if (this.manualJson.length > 0) {
+                for (var i = 0; i < this.manualJson.length; i++) {
+                    if (this.manualJson[i].ttype == 2) {
+                        type = 2;
+                    } else if (this.manualJson[i].ttype == 3) {
+                        type = 3;
+                    }
+                }
+            }
+            if (this.checkC) {
+                let _check = this.checkC.replace('x', '').split("-")
+                let _json = this.manualJson[_check[0]]
+                let json = {
+                    ttype: 1,
+                    type: topicType
+                }
+                if (_json.array) {
+                    if (type == 3 && _check.length == 2) {
+                        if (this.manualJson[_check[0]].array[_check[1]].array) {
+                                this.manualJson[_check[0]].array[_check[1]].array.push(json)
+                        } else {
+                                this.manualJson[_check[0]].array.splice(parseInt(_check[1]) + 1, 0, json)
+                        }
+
+                    } else if (type == 3 && _check.length == 3) {
+                            this.manualJson[_check[0]].array[_check[1]].array.splice(parseInt(_check[2]) + 1, 0, json)
+                    } else if (type == 2 && _check.length == 2) {
+                            this.manualJson[_check[0]].array.splice(parseInt(_check[1]) + 1, 0, json)
+                    } else if (type == 2 && _check.length == 1) {
+                            this.manualJson[_check[0]].array.push(json)
+                    } else if (type == 3 && _check.length == 1) {
+                        if(this.manualJson[_check[0]].array[0] && this.manualJson[_check[0]].array[0].array){
+                                this.manualJson[_check[0]].array[0].array.push(json)
+                        }else{
+                                this.manualJson[_check[0]].array.push(json)
+                        }
+                    }
+                } else {
+                        this.manualJson.splice(parseInt(_check[0]) + 1, 0, json);
+                }
+            } else {
+                if (type == 1) {
+                        this.manualJson.push({
+                            ttype: 1,
+                            type: topicType
+                        });
+                } else if (type == 3 || type == 2) {
+                    this.$message.error("请选中分页或者分组添加题目");
+                    return;
+                }
+            }
+            topicType = "";
+            this.$emit("changeJson", this.manualJson);
+        },
+        addQtype(type) {
+            if (type == 1) {
+
+                let type = 1;
+                if (this.manualJson.length > 0) {
+                    for (var i = 0; i < this.manualJson.length; i++) {
+                        if (this.manualJson[i].ttype == 1) {
+                            type = 2;
+                        } else if (this.manualJson[i].ttype == 3) {
+                            type = 3;
+                        }
+                    }
+                }
+                let json = {
+                    ttype: 2,
+                    array: [],
+                    isopen: true
+                }
+                if (type == 1) {
+                    if (this.checkC) {
+                        let _check = this.checkC.replace('x', '').split("-")
+                        this.manualJson.splice(parseInt(_check[0]) + 1, 0, json);
+                    } else {
+                        this.manualJson.push(json);
+                    }
+                } else if (type == 2) {
+                    this.manualJson = [
+                        {
+                            ttype: 2,
+                            array: this.depthCopy(this.manualJson),
+                            isopen: true
+                        }
+                    ];
+                } else if (type == 3) {
+                    if (this.checkC) {
+                        let _check = this.checkC.replace('x', '').split("-")
+
+                        if (_check.length > 1 && this.manualJson[_check[0]].array[0] && this.manualJson[_check[0]].array[0].array) {
+                            this.manualJson[_check[0]].array.splice(parseInt(_check[1]) + 1, 0, json);
+                        } else if (this.manualJson[_check[0]].array[0] && !this.manualJson[_check[0]].array[0].array) {
+                            this.manualJson[_check[0]].array = [
+                                {
+                                    ttype: 2,
+                                    array: this.depthCopy(this.manualJson[_check[0]].array),
+                                    isopen: true
+                                }
+                            ]
+                        } else {
+                            this.manualJson[_check[0]].array.push(json);
+                        }
+                    } else {
+                        this.$message.error("请选中分页添加分组");
+                        return;
+                    }
+                }
+
+            } else if (type == 2) {
+
+                let type = 1;
+                if (this.manualJson.length > 0) {
+                    for (var i = 0; i < this.manualJson.length; i++) {
+                        if (this.manualJson[i].ttype == 1 || this.manualJson[i].ttype == 2) {
+                            type = 2;
+                        }
+                    }
+                }
+                if (type == 1) {
+                    let json = {
+                        ttype: 3,
+                        array: [],
+                        isopen: true
+                    }
+                    if (this.checkC) {
+                        let _check = this.checkC.replace('x', '').split("-")
+
+                        this.manualJson.splice(parseInt(_check[0]) + 1, 0, json);
+                    } else {
+                        this.manualJson.push(json);
+                    }
+                } else {
+                    this.manualJson = [
+                        {
+                            ttype: 3,
+                            array: this.depthCopy(this.manualJson),
+                            isopen: true
+                        }
+                    ];
+                }
+
+            }
+            this.$emit("changeJson", this.manualJson);
+        },
+    },
+    mounted() {
+        this.manualJson = this.depthCopy(this.checkJson);
+    },
+}
+</script>
+
+<style scoped>
+.edit_box {
+    width: 100%;
+    height: 100%;
+    overflow: hidden;
+    display: flex;
+    justify-content: space-between;
+    padding: 10px 0 0;
+    box-sizing: border-box;
+}
+
+.e_add {
+    height: 100%;
+    width: 300px;
+    background: #fff;
+    overflow: auto;
+    padding: 20px 10px;
+    box-sizing: border-box;
+}
+
+.e_content {
+    height: 100%;
+    width: calc(100% - 620px);
+    background: #fff;
+    overflow: auto;
+    padding: 20px 10px;
+    box-sizing: border-box;
+}
+
+.e_content > .title{
+    font-size: 24px;
+    font-weight: bold;
+    text-align: center;
+    width: 100%;
+    margin-bottom: 10px;
+    word-break: break-all;
+}
+
+.e_order {
+    height: 100%;
+    width: 300px;
+    background: #fff;
+    overflow: auto;
+    padding: 20px 10px;
+    box-sizing: border-box;
+}
+
+.e_add>.title,
+.e_order>.title {
+    text-align: center;
+    font-size: 20px;
+}
+
+.e_add_box {
+    width: 100%;
+    border: 1px solid #dcdcdc;
+    margin-top: 20px;
+    border-radius: 3px;
+    background: #f4f4f4;
+    box-sizing: border-box;
+    padding: 10px 20px;
+}
+
+.e_add_box>.title {
+    text-align: center;
+    font-weight: bold;
+}
+
+.e_add_box>.e_add_ci {
+    margin-top: 10px;
+}
+
+.e_add_box>.e_add_ci>.title {
+    font-size: 14px;
+    margin-bottom: 10px;
+}
+
+.e_add_box>.e_add_ci>.box {
+    display: flex;
+    flex-wrap: wrap;
+}
+
+.e_add_box>.e_add_ci>.box>.btn {
+    margin-bottom: 10px;
+    width: 50%;
+}</style>

+ 134 - 0
src/components/pages/test/add/edit/index.vue

@@ -0,0 +1,134 @@
+<template>
+  <div class="rightBox">
+    <div class="edit_top">
+      <div class="edit_btn">
+        <span :class="{ active: type == 1 }" @click="type = 1">编辑</span>
+        <span :class="{ active: type == 2 }" @click="type = 2">预览</span>
+        <span :class="{ active: type == 3 }" @click="type = 3">回答</span>
+        <span :class="{ active: type == 4 }" @click="type = 4">统计</span>
+      </div>
+      <div class="op_btn">
+        <el-button type="primary" size="small" @click="lastSteps">上一步</el-button>
+        <el-button type="primary" size="small" @click="save">保存</el-button>
+        <el-button type="primary" size="small" @click="publish">发布</el-button>
+
+      </div>
+    </div>
+    <div class="e_box">
+      <editBox v-if="type == 1" :checkJson="checkJson"  @changeJson="changeJson" :title="title"></editBox>
+    </div>
+  </div>
+</template>
+
+<script>
+import editBox from './edit/index.vue'
+export default {
+  components: {
+    editBox,
+  },
+  props: {
+    title: {
+      type: String
+    },
+    testType: {
+      type: Array
+    },
+    see: {
+      type: Boolean
+    },
+    steps: {
+      type: Number
+    },
+    cJson: {
+      type: Array
+    }
+  },
+  data() {
+    return {
+      type: 1,
+      checkJson: [],
+    }
+  },
+  watch: {
+    cJson: {
+      handler: function (newVal, oldVal) { 
+        this.checkJson = this.depthCopy(newVal);
+      },
+      deep: true,
+    },
+  },
+  methods: {
+    lastSteps() {
+      this.$emit('update:steps', this.steps - 1)
+    },
+    save() {
+      this.$emit("save")
+    },
+    publish() {
+      this.$emit("publish")
+    },
+    depthCopy(s) {
+      return JSON.parse(JSON.stringify(s))
+    },
+    changeJson(json) {
+      this.$emit("update:cJson", json);
+    }
+  },
+  mounted() {
+    this.checkJson = this.depthCopy(this.cJson);
+  },
+}
+</script>
+
+<style scoped>
+.rightBox {
+  width: calc(100%);
+  background: #F0F2F5;
+  overflow: auto;
+  height: calc(100%);
+  margin: 0 auto;
+  position: relative;
+  box-sizing: border-box;
+}
+
+.edit_top {
+  height: 50px;
+  background: #fff;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  position: relative;
+}
+
+.edit_top>.edit_btn {
+  display: flex;
+  height: 100%;
+  align-items: center;
+}
+
+.edit_top>.edit_btn>span {
+  cursor: pointer;
+  padding-bottom: 5px;
+  display: block;
+}
+
+.edit_top>.edit_btn>.active {
+  color: #3e88f4;
+  border-bottom: 2px solid #2f80f3;
+}
+
+.edit_top>.edit_btn>span+span {
+  margin-left: 35px;
+}
+
+.edit_top>.op_btn {
+  position: absolute;
+  right: 30px;
+}
+
+.e_box {
+  height: calc(100% - 50px);
+  width: 100%;
+  overflow: hidden;
+  background: rgb(196, 226, 241);
+}</style>

+ 44 - 0
src/components/pages/test/add/minxins/minxin.js

@@ -0,0 +1,44 @@
+const minxin = {
+  data() {
+    return {
+      options: [
+        {
+          value: 1,
+          label: "选择题"
+        },
+        {
+          value: 2,
+          label: "问答题"
+        },
+        {
+          value: 3,
+          label: "填空题"
+        },
+        {
+          value: 4,
+          label: "添加文档"
+        }
+      ],
+      options2: {
+        1: "选择题",
+        2: "问答题",
+        3: "填空题",
+        4: "添加文档"
+      },
+      buttonOptions: [
+        { name: "分组", type: 1 },
+        { name: "分页", type: 2 }
+      ]
+    };
+  },
+  computed: {},
+  mounted() {},
+  activated() {},
+  methods: {
+    depthCopy(s) {
+      return JSON.parse(JSON.stringify(s));
+    }
+  }
+};
+
+export default minxin;

+ 412 - 0
src/components/pages/test/add/setInfo/index.vue

@@ -0,0 +1,412 @@
+<template>
+    <div class="rightBox">
+        <div class="whiteBg" style="background:unset;padding: 0;">
+            <div>
+                <div class="basic_box" style="padding: 0;">
+                    <div class="big_box">
+                        <div class="left_first">
+                            <div class="c_info_title" style="padding: 0 0 15px;margin: 0 auto 0 0;">设置基础信息</div>
+                            <div>
+                                <div style="width: 100%;">
+                                    <div class="course_input_box">
+                                        <div class="bb_courseIcon"><img src="../../../../../assets/icon/new/course.png" />
+                                        </div>
+                                        <input @input="titleChange" type="text" placeholder="请输入课程名称" class="binfo_input" v-model="courseName"
+                                            style="border: 1.5px solid rgb(202, 209, 220);margin: 0px 10px 0px 0px;border-radius: 5px;font-weight: 600;padding: 12px 14px 12px 71px;" />
+                                        <el-switch v-model="isTeacherSee" active-text="允许学生回答后查看正确答案"
+                                            style="justify-content: center;" @change="seeChange"></el-switch>
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="both">
+                                <div class="choose">
+                                    <div class="all_choose" v-for="(item, index) in CourseType[0]" :key="index" @change="typeChange">
+                                        <span v-if="CourseTypeJson[item.id].length > 0">{{ item.name }}:</span>
+                                        <el-checkbox-group v-model="courseTypeId" v-if="CourseTypeJson[item.id].length > 0">
+                                            <el-checkbox v-for="item1 in CourseTypeJson[item.id]" :key="item1.id"
+                                                :label="item1.id">{{
+                                                    item1.name }}</el-checkbox>
+                                        </el-checkbox-group>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="whiteBg" style="background:#fff;margin: 10px 0;min-height: 300px;">
+            <div class="whiteBg" style="border-radius: 0">
+                <div class="c_info_title">创建评测内容</div>
+                <div class="c_info_box">
+                    <div class="c_info_tab">
+                        <!-- <span :class="{ active: type == 1 }" @click="type = 1">智能创建</span> -->
+                        <span :class="{ active: type == 2 }" @click="type = 2">手动创建</span>
+                        <!-- <span :class="{ active: type == 3 }" @click="type = 3">题库导入</span> -->
+                    </div>
+                    <div class="c_info_tab_box">
+                        <manualCreate v-if="type == 2" :manualJson.sync="manualJson" @nextSteps="nextSteps"></manualCreate>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import manualCreate from './manualCreated.vue';
+export default {
+    components: {
+        manualCreate
+    },
+    props: {
+        title:{
+            type: String
+        },
+        testType:{
+            type: Array
+        },
+        see:{
+            type: Boolean
+        },
+        steps:{
+            type: Number
+        },
+        cJson:{
+            type:Array
+        }
+    },
+    data() {
+        return {
+            CourseType: [],
+            courseTypeId: [],
+            CourseTypeJson: {},
+            courseName: "",
+            isTeacherSee: false,
+            type: 2,
+            manualJson:[]
+        }
+    },
+    methods: {
+        selectAllType() {
+            let params = {
+                org: this.org && this.org != "" ? this.org : "",
+                oid: this.oid && this.oid != "" ? this.oid : "",
+            };
+            this.ajax
+                .get(this.$store.state.api + "selectAllTypeT", params)
+                .then((res) => {
+                    this.CourseType = res.data;
+                    for (var cti = 0; cti < res.data[0].length; cti++) {
+                        if (res.data[0][cti].id == "34628934-d02f-11ec-8c78-005056b86db5" || res.data[0][cti].id == "34628934-d02f-11ec-8c78-005056b86ac5") {
+                            res.data[0][cti].name = "年级";
+                        } else if (res.data[0][cti].id == "34629907-d02f-11ec-8c78-005056b86db5" || res.data[0][cti].id == "34629907-d02f-11ec-8c78-005056b86ac5") {
+                            res.data[0][cti].name = "学科";
+                        }
+                    }
+                    let _courseTypeId = [];
+                    for (var i = 0; i < res.data[0].length; i++) {
+                        if (!this.cid) {
+                            this.courseTypeId[res.data[0][i].id] = [];
+                        }
+                        // if (!this.CourseTypeJson[res.data[0][i].id]) {
+                        // }
+                        this.CourseTypeJson[res.data[0][i].id] = [];
+
+                        if (res.data[2].length == 0 && res.data[3].length == 0) {
+                            for (var j = 0; j < res.data[1].length; j++) {
+                                if (
+                                    this.courseTypeId.indexOf(res.data[1][j].id) != -1 &&
+                                    _courseTypeId.indexOf(res.data[1][j].id) == -1
+                                ) {
+                                    _courseTypeId.push(res.data[1][j].id);
+                                }
+                                if (res.data[0][i].id == res.data[1][j].pid) {
+                                    this.CourseTypeJson[res.data[0][i].id].push(res.data[1][j]); // 去除公共分类
+                                }
+                            }
+                        } else {
+                            if (res.data[2].length > 0) {
+                                for (var j = 0; j < res.data[2].length; j++) {
+                                    if (
+                                        this.courseTypeId.indexOf(res.data[2][j].id) != -1 &&
+                                        _courseTypeId.indexOf(res.data[2][j].id) == -1
+                                    ) {
+                                        _courseTypeId.push(res.data[2][j].id);
+                                    }
+                                    if (res.data[0][i].id == res.data[2][j].pid) {
+                                        this.CourseTypeJson[res.data[0][i].id].push(res.data[2][j]); // 去除公共分类
+                                    }
+                                }
+                            }
+                            if (res.data[3].length > 0) {
+                                for (var j = 0; j < res.data[3].length; j++) {
+                                    if (
+                                        this.courseTypeId.indexOf(res.data[3][j].id) != -1 &&
+                                        _courseTypeId.indexOf(res.data[3][j].id) == -1
+                                    ) {
+                                        _courseTypeId.push(res.data[3][j].id);
+                                    }
+                                    if (res.data[0][i].id == res.data[3][j].pid) {
+                                        this.CourseTypeJson[res.data[0][i].id].push(res.data[3][j]); // 去除公共分类
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    this.courseTypeId = _courseTypeId;
+                })
+                .catch((err) => {
+                    console.error(err);
+                });
+        },
+        titleChange(){
+            this.$emit("update:title", this.courseName)
+        },
+        typeChange(){
+            this.$emit("update:testType", this.courseTypeId)
+        },
+        seeChange(){
+            this.$emit("update:see", this.isTeacherSee)
+        },
+        depthCopy(s){
+            return JSON.parse(JSON.stringify(s))
+        },
+        nextSteps(){
+            if(this.type == 2){
+                this.$emit("update:cJson", this.manualJson)
+            }
+            this.$emit('update:steps',this.steps+1)
+            console.log(this.cJson);
+            console.log(this.manualJson);
+        }
+    },
+    mounted() {
+        this.courseTypeId = this.depthCopy(this.testType)
+        this.courseName = this.depthCopy(this.title)
+        this.isTeacherSee = this.depthCopy(this.see)
+        this.manualJson = this.depthCopy(this.cJson)
+        this.$forceUpdate()
+        this.selectAllType();
+    }
+}
+</script>
+
+<style scoped>
+.rightBox {
+    width: calc(100%);
+    background: #F0F2F5;
+    overflow: auto;
+    height: calc(100%);
+    margin: 0 auto;
+    position: relative;
+    box-sizing: border-box;
+}
+
+.whiteBg {
+    /* background: #fff; */
+    border-radius: 10px;
+}
+
+.basic_box {
+    margin: 0 auto;
+    position: relative;
+    padding: 0 20px 0 20px;
+}
+
+.big_box {
+    /* margin-top: 20px; */
+    display: flex;
+    justify-content: space-between;
+    /* border-bottom: 1px solid #E0E2ED; */
+}
+
+.left_first {
+    display: flex;
+    flex-direction: column;
+    flex-wrap: nowrap;
+    width: calc(100%);
+    padding: 20px;
+    box-sizing: border-box;
+    background: #fff;
+    border-radius: 5px;
+}
+
+.course_input_box {
+    display: flex;
+    margin-right: 20px;
+    width: 100%;
+    align-items: center;
+    position: relative;
+}
+
+.course_input_box>.binfo_input {
+    width: calc(100% - 290px);
+    margin: 0 10px;
+}
+
+.bb_courseIcon {
+    width: 57px;
+    height: 45px;
+    background: #F0F4FA;
+    border-radius: 5px 0px 0px 5px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    border-right: 1.5px solid rgb(202, 209, 220);
+    box-sizing: border-box;
+    position: absolute;
+    left: 1.5px
+}
+
+.bb_courseIcon>img {
+    width: 25px;
+    height: auto
+}
+
+.all_choose {
+    display: flex;
+    flex-direction: row;
+    align-items: flex-start;
+    width: 100%;
+}
+
+.all_choose+.all_choose {
+    /* margin-top: 10px */
+}
+
+.all_choose>span {
+    min-width: fit-content;
+    display: block;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    margin-right: 20px;
+    font-weight: bold;
+    font-size: 14px;
+}
+
+.all_choose>>>.el-checkbox-group {
+    display: flex;
+    flex-direction: row;
+    width: 100%;
+    flex-wrap: wrap;
+    align-content: center;
+    justify-content: flex-start;
+    align-items: center;
+    margin-top: 3px;
+}
+
+.all_choose>.el-checkbox-group>>>.el-checkbox {
+    margin-bottom: 10px;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    margin-right: 10px;
+}
+
+.all_choose>.el-checkbox-group>.el-checkbox>>>.el-checkbox__label {
+    min-width: 80px;
+    overflow: hidden;
+    width: 80px;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+}
+
+.all_choose>.el-checkbox-group>.el-checkbox>>>.el-checkbox__label:hover {
+    width: auto;
+}
+
+.choose>div:nth-child(3)>span {
+    /* letter-spacing: 0 !important; */
+}
+
+.choose {
+    display: flex;
+    flex-direction: column;
+    flex-wrap: nowrap;
+    height: 100%;
+    justify-content: space-evenly;
+    align-items: flex-start;
+}
+
+.both {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: wrap;
+    width: 100%;
+    align-items: center;
+    justify-content: flex-start;
+    margin: 15px 0;
+}
+
+.binfo_input {
+    width: 100%;
+    margin: 0;
+    padding: 12px 14px;
+    display: block;
+    min-width: 0;
+    outline: none;
+    box-sizing: border-box;
+    background: none;
+    border: none;
+    border-radius: 4px;
+    background: #fff;
+    font-size: 16px;
+    resize: none;
+    font-family: 'Microsoft YaHei';
+    min-height: 48px;
+    border: 1.5px solid #CAD1DC;
+}
+
+.c_info_title {
+    padding: 15px 0 15px 0;
+    font-size: 16px;
+    font-weight: bold;
+    margin: 0 0 0 20px;
+    box-sizing: border-box;
+    display: flex;
+    align-items: center;
+    line-height: 20px;
+}
+
+.c_info_title::before {
+    content: '';
+    display: block;
+    width: 3px;
+    height: 20px;
+    background: #0061FF;
+    border-radius: 3px;
+    margin: 0 5px 0 0;
+}
+
+.c_info_box {
+    width: 100%;
+}
+
+.c_info_tab {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.c_info_tab>span {
+    cursor: pointer;
+    padding-bottom: 10px;
+    font-weight: bold;
+}
+
+.c_info_tab>span+span {
+    margin-left: 20px;
+}
+
+.c_info_tab>.active {
+    color: #3e88f4;
+    border-bottom: 2px solid #2f80f3;
+}
+
+
+.c_info_tab_box {
+    overflow: hidden;
+}
+</style>

+ 335 - 0
src/components/pages/test/add/setInfo/manualCreated.vue

@@ -0,0 +1,335 @@
+<template>
+    <div class="mc_box">
+        <div class="mc_addBox">
+            <div class="mc_addBox_add">
+                <div class="title">请添加题目类型与数量</div>
+                <div class="select">
+                    <el-select v-model="topicType" placeholder="题目类型" clearable class="e-select">
+                        <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
+                        </el-option>
+                    </el-select>
+                    <el-input v-model="number" placeholder="请输入题目数量" size="normal" clearable @change="numberPan"
+                        class="e-input"></el-input>
+                    <img src="@/assets/icon/new/addStage.png" class="e-img" @click="addCheck" />
+                </div>
+            </div>
+            <div class="mc_addBox_add">
+                <div class="title">请添加题目类型与数量</div>
+                <div class="btnBox">
+                    <el-button type="primary" size="mini" v-for="item in buttonOptions" :key="item.type" class="e-button"
+                        @click="addQtype(item.type)">{{ item.name }}</el-button>
+                </div>
+            </div>
+        </div>
+        <div class="mc_checkBox">
+            <checkOrder :checkC.sync="checkC" :checkJson="checkJson" @changeJson="changeJson"></checkOrder>
+            <div class="e_btn">
+                <el-button type="primary" size="mini" @click="nextSteps()">下一步</el-button>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import checkOrder from '../components/checkOrder.vue';
+import minxinVue from '../minxins/minxin';
+
+export default {
+    mixins:[minxinVue],
+    components: {
+        checkOrder,
+    },
+    props: {
+        manualJson: {
+            type: Array
+        }
+    },
+    data() {
+        return {
+            topicType: "",
+            number: "",
+            checkJson: [
+                // {
+                //     ttype: 1, //题目分类 1普通题目 2分组 3分页
+                //     type: 1, //题型分类 1选择题, 2问答题 3填空题 4添加文档
+                //     array:[] //题目
+                // }
+            ],
+            checkC: "",
+        };
+    },
+    watch: {
+        manualJson :{
+            handler: function (newVal, oldVal) { 
+                this.checkJson = this.depthCopy(newVal);
+            },
+            deep: true,
+        }
+    },
+    methods: {
+        numberPan() {
+            if (/[^\d]/.test(this.number)) {
+                this.$message.error("请填写数字");
+                this.number = "";
+            }
+        },
+        changeJson(json) {
+            this.checkJson = json;
+            this.$emit("update:cJson", json);
+        },
+        addCheck() {
+            if (!this.topicType) {
+                this.$message.error("请选择题目类型");
+                return;
+            }
+            if (!this.number) {
+                this.$message.error("请填写题目数量");
+                return;
+            }
+            let type = 1;
+            if (this.checkJson.length > 0) {
+                for (var i = 0; i < this.checkJson.length; i++) {
+                    if (this.checkJson[i].ttype == 2) {
+                        type = 2;
+                    } else if (this.checkJson[i].ttype == 3) {
+                        type = 3;
+                    }
+                }
+            }
+            if (this.checkC) {
+                let _check = this.checkC.replace('x', '').split("-")
+                let _json = this.checkJson[_check[0]]
+                let json = {
+                    ttype: 1,
+                    type: this.topicType
+                }
+                if (_json.array) {
+                    if (type == 3 && _check.length == 2) {
+                        if (this.checkJson[_check[0]].array[_check[1]].array) {
+                            for (var i = 0; i < this.number; i++) {
+                                this.checkJson[_check[0]].array[_check[1]].array.push(json)
+                            }
+                        } else {
+                            for (var i = 0; i < this.number; i++) {
+                                this.checkJson[_check[0]].array.splice(parseInt(_check[1]) + 1, 0, json)
+                            }
+                        }
+
+                    } else if (type == 3 && _check.length == 3) {
+                        for (var i = 0; i < this.number; i++) {
+                            this.checkJson[_check[0]].array[_check[1]].array.splice(parseInt(_check[2]) + 1, 0, json)
+                        }
+                    } else if (type == 2 && _check.length == 2) {
+                        for (var i = 0; i < this.number; i++) {
+                            this.checkJson[_check[0]].array.splice(parseInt(_check[1]) + 1, 0, json)
+                        }
+                    } else if (type == 2 && _check.length == 1) {
+                        for (var i = 0; i < this.number; i++) {
+                            this.checkJson[_check[0]].array.push(json)
+                        }
+                    } else if (type == 3 && _check.length == 1) {
+                        if(this.checkJson[_check[0]].array[0] && this.checkJson[_check[0]].array[0].array){
+                            for (var i = 0; i < this.number; i++) {
+                                this.checkJson[_check[0]].array[0].array.push(json)
+                            }
+                        }else{
+                            for (var i = 0; i < this.number; i++) {
+                                this.checkJson[_check[0]].array.push(json)
+                            }
+                        }
+                    }
+                } else {
+                    for (var i = 0; i < this.number; i++) {
+                        this.checkJson.splice(parseInt(_check[0]) + 1, 0, json);
+                    }
+                }
+            } else {
+                if (type == 1) {
+                    for (var i = 0; i < this.number; i++) {
+                        this.checkJson.push({
+                            ttype: 1,
+                            type: this.topicType
+                        });
+                    }
+                } else if (type == 3 || type == 2) {
+                    this.$message.error("请选中分页或者分组添加题目");
+                    return;
+                }
+            }
+            this.topicType = "";
+            this.number = "";
+            this.$emit("update:manualJson", this.checkJson);
+        },
+        addQtype(type) {
+            if (type == 1) {
+
+                let type = 1;
+                if (this.checkJson.length > 0) {
+                    for (var i = 0; i < this.checkJson.length; i++) {
+                        if (this.checkJson[i].ttype == 1) {
+                            type = 2;
+                        } else if (this.checkJson[i].ttype == 3) {
+                            type = 3;
+                        }
+                    }
+                }
+                let json = {
+                    ttype: 2,
+                    array: [],
+                    isopen: true
+                }
+                if (type == 1) {
+                    if (this.checkC) {
+                        let _check = this.checkC.replace('x', '').split("-")
+                        this.checkJson.splice(parseInt(_check[0]) + 1, 0, json);
+                    } else {
+                        this.checkJson.push(json);
+                    }
+                } else if (type == 2) {
+                    this.checkJson = [
+                        {
+                            ttype: 2,
+                            array: this.depthCopy(this.checkJson),
+                            isopen: true
+                        }
+                    ];
+                } else if (type == 3) {
+                    if (this.checkC) {
+                        let _check = this.checkC.replace('x', '').split("-")
+
+                        if (_check.length > 1 && this.checkJson[_check[0]].array[0] && this.checkJson[_check[0]].array[0].array) {
+                            this.checkJson[_check[0]].array.splice(parseInt(_check[1]) + 1, 0, json);
+                        } else if (this.checkJson[_check[0]].array[0] && !this.checkJson[_check[0]].array[0].array) {
+                            this.checkJson[_check[0]].array = [
+                                {
+                                    ttype: 2,
+                                    array: this.depthCopy(this.checkJson[_check[0]].array),
+                                    isopen: true
+                                }
+                            ]
+                        } else {
+                            this.checkJson[_check[0]].array.push(json);
+                        }
+                    } else {
+                        this.$message.error("请选中分页添加分组");
+                        return;
+                    }
+                }
+
+            } else if (type == 2) {
+
+                let type = 1;
+                if (this.checkJson.length > 0) {
+                    for (var i = 0; i < this.checkJson.length; i++) {
+                        if (this.checkJson[i].ttype == 1 || this.checkJson[i].ttype == 2) {
+                            type = 2;
+                        }
+                    }
+                }
+                if (type == 1) {
+                    let json = {
+                        ttype: 3,
+                        array: [],
+                        isopen: true
+                    }
+                    if (this.checkC) {
+                        let _check = this.checkC.replace('x', '').split("-")
+
+                        this.checkJson.splice(parseInt(_check[0]) + 1, 0, json);
+                    } else {
+                        this.checkJson.push(json);
+                    }
+                } else {
+                    this.checkJson = [
+                        {
+                            ttype: 3,
+                            array: this.depthCopy(this.checkJson),
+                            isopen: true
+                        }
+                    ];
+                }
+
+            }
+            this.$emit("update:manualJson", this.checkJson);
+        },
+        depthCopy(s) {
+            return JSON.parse(JSON.stringify(s));
+        },
+        
+        nextSteps(){
+            this.$emit("nextSteps")
+        }
+    },
+    mounted() {
+        this.checkJson = this.depthCopy(this.manualJson);
+        this.$forceUpdate()
+    }
+};
+</script>
+
+<style scoped>
+.mc_box {
+    width: 90%;
+    margin: 10px auto;
+    display: flex;
+}
+
+.mc_addBox {
+    width: 400px;
+    border: 1px solid #898989;
+    border-radius: 8px;
+    padding: 20px 20px;
+    box-sizing: border-box;
+    height: 350px;
+}
+
+.mc_addBox_add {}
+
+.mc_addBox_add+.mc_addBox_add {
+    margin-top: 10px;
+}
+
+.mc_addBox_add .title {
+    margin-bottom: 10px;
+}
+
+.mc_addBox_add .select {
+    display: flex;
+    align-items: center;
+}
+
+.mc_addBox_add .btnBox {}
+
+.mc_addBox_add .select .e-select {}
+
+.mc_addBox_add .select .e-input {
+    margin-left: 10px;
+}
+
+.mc_addBox_add .select .e-img {
+    cursor: pointer;
+    width: 20px;
+    margin-left: 10px;
+}
+
+.mc_addBox_add .btnBox .e-button {}
+
+.mc_checkBox {
+    width: calc(100% - 420px);
+    margin-left: 20px;
+    border: 1px solid #898989;
+    border-radius: 8px;
+    padding: 20px;
+    box-sizing: border-box;
+    display: flex;
+    flex-direction: column;
+}
+
+
+.e_btn{
+    width: 100%;
+    margin-top: auto;
+    display: flex;
+    justify-content: flex-end;
+}
+</style>

+ 1170 - 0
src/components/pages/test/index.vue

@@ -0,0 +1,1170 @@
+<template>
+    <div class="pb_content" style="height: auto">
+        <div class="pb_head top">
+            <div>
+                <span>评测管理</span>
+            </div>
+            <div class="student_button">
+                <el-button type="primary" class="bgColor" @click="goToCourse()">新建评测</el-button>
+            </div>
+        </div>
+        <div class="pb_content_body" style="height: 100%">
+            <div class="student_head">
+                <div class="choose">
+                    <div class="all_choose" v-for="(item, index) in CourseType[0]" :key="index">
+                        <span v-if="CourseTypeJson[item.id].length">{{ item.name }}</span>
+                        <el-select v-if="CourseTypeJson[item.id].length" v-model="courseTypeId[item.id]" placeholder="请选择"
+                            @change="getTypeName">
+                            <el-option label="全部" value="1">全部</el-option>
+                            <el-option v-for="item1 in CourseTypeJson[item.id]" :key="item1.id" :label="item1.name"
+                                :value="item1.id">
+                            </el-option>
+                        </el-select>
+                    </div>
+                    <div class="student_search">
+                        <span>所有者</span>
+                        <el-select v-model="groupA" @change="search">
+                            <el-option value="0" label="我的"></el-option>
+                            <!-- <el-option value="4" label="全部"></el-option> -->
+                            <!-- <el-option value="2" label="他人"
+                                v-if="oid != '1c3b9def-8fbe-11ed-b13d-005056b86db5'"></el-option> -->
+                        </el-select>
+                        <!-- <el-select v-model="groupA" @change="search" v-else>
+                <el-option value="4" label="全部"></el-option>
+              </el-select> -->
+                    </div>
+                    <div @click="clear" class="clear" v-if="CourseType.length">重置</div>
+                </div>
+
+                <div class="student_right">
+                    <div class="head_left">
+                        <el-input v-model="courseName" class="student_input" placeholder="请输入项目名称"></el-input>
+                        <el-button class="course_button" @click="searchCourse">查询</el-button>
+                    </div>
+                </div>
+            </div>
+            <div class="student_table" v-loading="isLoading">
+                <div class="course_box">
+                    <div class="out_box" v-for="(item, index) in course" :key="index">
+                        <div class="myCourse" v-if="item.userid == userid">
+                            我的项目
+                        </div>
+                        <div class="myCourse" style="background:#4187f0" v-else-if="!item.course_teacher ||
+                            (item.course_teacher &&
+                                item.course_teacher.indexOf(userid) == -1)">
+                            他人项目
+                        </div>
+                        <div class="xtCourse" v-else>协同项目</div>
+                       
+                        <div class="bottom_box">
+                            <div><span>{{ item.title }}</span><span>{{ item.look == '1' ? '未发布' : '已发布' }}</span></div>
+                            <div class="kc_t">
+                                创建人:{{ item.uname }}
+                            </div>
+                            <div class="kc_time">
+                                <span style="color: #4b4b4b">创建日期:</span>{{ item.time }}
+                            </div>
+                            <div class="kc_time">
+                                <span style="color: #4b4b4b">修改日期:</span>{{ item.utime }}
+                            </div>
+                        </div>
+                        <div class="three_bottom">
+                            <div @click="goToCourse2(item.courseId)" v-if="((item.userid == userid) ||
+                                (item.course_teacher &&
+                                    item.course_teacher.indexOf(userid) !== -1) || role == '1')">编辑</div>
+                            <!-- <div @click="get(item.courseId)">预览</div> -->
+                            <!-- 项目进展 -->
+                            <!-- <div @click="copyCourse(item.courseId)">复制</div> -->
+                            <!-- <div v-if="(item.userid == userid || role == '1')" @click="deleteCourse(item.courseId)">
+                                删除
+                            </div> -->
+                        </div>
+                    </div>
+                    <div class="course_empty" v-if="course.length == 0">暂无数据</div>
+                </div>
+            </div>
+        </div>
+        <div class="student_page">
+            <el-pagination background layout="prev, pager, next" :page-size="pageSize" :total="total"
+                v-if="page && course.length" style="padding-bottom: 20px"
+                @current-change="handleCurrentChange"></el-pagination>
+        </div>
+        <el-dialog :visible.sync="dialogVisible1" size="tiny">
+            <img width="100%" :src="dialogImageUrl" alt />
+        </el-dialog>
+        <el-dialog title="查看提问" :visible.sync="dialogVisible" :append-to-body="true" width="750px"
+            :before-close="handleClose" class="dialog_diy">
+            <div>
+                <div class="a_addBox">
+                    <CourseProblem :problemCourse="problemCourse"></CourseProblem>
+                </div>
+            </div>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="dialogVisible = false">关 闭</el-button>
+            </span>
+        </el-dialog>
+        <el-dialog title="查看协同项目" :visible.sync="dialogVisibleCourse" :append-to-body="true" width="850px"
+            :before-close="handleClose" class="dialog_diy">
+            <div class="ct_box">
+                <div class="out_box" v-for="(item, index) in courseTeam" :key="index" style="margin-left: 15px">
+                    <div class="tup">
+                        <img :src="item.cover != null && item.cover != ''
+                                ? JSON.parse(item.cover).length > 0
+                                    ? JSON.parse(item.cover)[0].url
+                                    : mr
+                                : mr
+                            " alt />
+                    </div>
+                    <div class="bottom_box">
+                        <div>{{ item.title }}</div>
+                        <div class="kc_t">创建人:{{ item.uname }}</div>
+                        <div class="kc_time">{{ item.time }}</div>
+                    </div>
+                    <div class="three_bottom">
+                        <!-- <div @click="jump(item.courseId)">查看内容</div> -->
+                        <div @click="
+                            goTo(
+                                '/studentAddCourse?cid=' +
+                                item.courseId +
+                                '&userid=' +
+                                userid +
+                                '&oid=' +
+                                oid +
+                                '&org=' +
+                                org +
+                                '&role=' +
+                                role
+                            )
+                            ">
+                            编辑
+                        </div>
+                    </div>
+                </div>
+                <div class="course_empty" v-if="courseTeam.length == 0">暂无数据</div>
+            </div>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="dialogVisibleCourse = false">关 闭</el-button>
+            </span>
+        </el-dialog>
+    </div>
+</template>
+  
+<script>
+import "../../../common/aws-sdk-2.235.1.min";
+import EditorBar from "../../../components/tools/wangEnduit";
+import CourseProblem from "../components/courseProblem";
+export default {
+    components: { EditorBar, CourseProblem },
+    data() {
+        return {
+            itemCount: 1,
+            courseTitle: "",
+            courseText: "",
+            courseTime: "",
+            isLoading: false,
+            fileList: [],
+            fileList1: [],
+            homeworkList: [{ name: "" }],
+            formLabelWidth: "100px",
+            dialogVisible: false,
+            dialogVisible1: false,
+            dialogVisibleCourse: false,
+            dialogImageUrl: "",
+            group: "",
+            userid: this.$route.query.userid,
+            oid: this.$route.query.oid,
+            org: this.$route.query.org,
+            role: this.$route.query.role,
+            orgArray: ["150e3120-9195-11ed-b13d-005056b86db5"],
+            oidArray: [],
+            Juri: "",
+            groupList: [],
+            JuriList: [],
+            page: 1,
+            total: 0,
+            pageSize: 20,
+            tableData: [],
+            now: "",
+            courseDetail: {},
+            addCourse: {},
+            groupA: "3",
+            classX: "",
+            course: [],
+            courseName: "",
+            mr: require("../../../assets/icon/kc1.png"),
+            CourseType: [],
+            CourseTypeJson: {},
+            courseTypeId: {},
+            courseTypeSon: [],
+            isChoose: 0,
+            problemCourse: null, //查看提问的项目
+            courseTeam: [],
+        };
+    },
+    methods: {
+        change(val) {
+            console.log(val);
+        },
+        time() {
+            if (!this.now) {
+                this.now = new Date().getTime();
+                return true;
+            } else {
+                let time = new Date().getTime();
+                if (time - this.now > 3000) {
+                    this.now = time;
+                    return true;
+                } else {
+                    return false;
+                }
+            }
+        },
+        addHomeworkBox() {
+            this.homeworkList.push({ name: "" });
+            this.itemCount++;
+        },
+        reduceHomeworkBox() {
+            var a = this.homeworkList;
+            a.splice(a.length - 1);
+            this.itemCount--;
+        },
+        goTo(path) {
+            this.$router.push(path);
+        },
+        goToCourse(courseId) {
+            if (courseId) {
+                this.$router.push(
+                    "/addTest?cid=" +
+                    courseId +
+                    "&userid=" +
+                    this.userid +
+                    "&oid=" +
+                    this.oid +
+                    "&org=" +
+                    this.org +
+                    "&role=" +
+                    this.role
+                );
+            } else {
+                this.$router.push(
+                    "/addTest?userid=" +
+                    this.userid +
+                    "&oid=" +
+                    this.oid +
+                    "&org=" +
+                    this.org +
+                    "&role=" +
+                    this.role
+                );
+            }
+            // this.$router.push(path);
+        },
+        goToCourse2(cid) {
+            this.$router.push(
+                "/addTest?cid=" +
+                cid +
+                "&userid=" +
+                this.userid +
+                "&oid=" +
+                this.oid +
+                "&org=" +
+                this.org +
+                "&type=2" +
+                "&role=" +
+                this.role
+            );
+        },
+        tableRowClassName({ row, rowIndex }) {
+            if ((rowIndex + 1) % 2 === 0) {
+                return "even_row";
+            } else {
+                return "";
+            }
+        },
+        jump(cid) {
+            // window.open(
+            //   "//pbl.cocorobo.cn/pbl-student-table/dist/#/courseDetail?courseId=" +
+            //     cid +
+            //     "&userid=" +
+            //     this.userid
+            // );
+            window.parent.postMessage({ cid: cid, screenType: "2s" }, "*");
+        },
+        get(cid) {
+            window.parent.postMessage({ cid: cid, screenType: "3s" }, "*");
+        },
+        getA(cid) {
+            this.$router.push("/courseProgress?cid=" + cid + "&userid=" +
+                this.userid +
+                "&oid=" +
+                this.oid +
+                "&org=" +
+                this.org)
+        },
+        handle_remove(file, fileList) {
+            var _tmp = this.fileList;
+            for (var i = 0, len = _tmp.length; i < len; i++) {
+                if (_tmp[i].uid == file.uid) {
+                    _tmp.splice(i, 1);
+                    break;
+                }
+                this.fileList = _tmp;
+            }
+        },
+        handle_remove1(file, fileList) {
+            var _tmp = this.fileList1;
+            for (var i = 0, len = _tmp.length; i < len; i++) {
+                if (_tmp[i].uid == file.uid) {
+                    _tmp.splice(i, 1);
+                    break;
+                }
+                this.fileList1 = _tmp;
+            }
+        },
+        handleCurrentChange(val) {
+            // console.log(`当前页: ${val}`);
+            this.page = val;
+            this.getCourse();
+        },
+        init() { },
+        handleClose(done) {
+            done();
+        },
+        handleRemove(file, fileList) {
+            console.log(file, fileList);
+        },
+        handlePictureCardPreview(file) {
+            this.dialogImageUrl = file.url;
+            this.dialogVisible1 = true;
+        },
+        onExceed() {
+            this.$message.error("项目海报仅支持上传一张,请删除后再进行上传");
+        },
+        //uuid生成
+        guid() {
+            return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
+                /[xy]/g,
+                function (c) {
+                    var r = (Math.random() * 16) | 0,
+                        v = c == "x" ? r : (r & 0x3) | 0x8;
+                    return v.toString(16);
+                }
+            );
+        },
+        time() {
+            if (!this.now) {
+                this.now = new Date().getTime();
+                return true;
+            } else {
+                let time = new Date().getTime();
+                if (time - this.now > 3000) {
+                    this.now = time;
+                    return true;
+                } else {
+                    return false;
+                }
+            }
+        },
+        searchCourse() {
+            this.page = 1;
+            this.getCourse();
+        },
+        clear() {
+            if (this.CourseType.length) {
+                for (var i = 0; i < this.CourseType[0].length; i++) {
+                    this.courseTypeId[this.CourseType[0][i].id] = "";
+                }
+            }
+            this.getCourse();
+        },
+        getCourse() {
+            var typeE = [];
+            var typea, typeb, typec, typed, typef;
+            if (this.isChoose == 1) {
+                for (var i = 0; i < this.CourseType[0].length; i++) {
+                    if (this.courseTypeId[this.CourseType[0][i].id] == "1") {
+                        typeE.push(this.CourseType[0][i].id);
+                    } else if (this.courseTypeId[this.CourseType[0][i].id] != "") {
+                        if (this.CourseType[0][i].name == "年级") {
+                            typea = this.courseTypeId[this.CourseType[0][i].id];
+                        } else if (this.CourseType[0][i].name == "学科") {
+                            typeb = this.courseTypeId[this.CourseType[0][i].id];
+                        } else if (this.CourseType[0][i].name == "栏目") {
+                            typeb = this.courseTypeId[this.CourseType[0][i].id];
+                        } else if (this.CourseType[0][i].name == "学院") {
+                            typeb = this.courseTypeId[this.CourseType[0][i].id];
+                        } else if (this.CourseType[0][i].name == "新技能") {
+                            typec = this.courseTypeId[this.CourseType[0][i].id];
+                        } else if (this.CourseType[0][i].name == "赛道") {
+                            typed = this.courseTypeId[this.CourseType[0][i].id];
+                        } else if (this.CourseType[0][i].name == "项目类型") {
+                            typed = this.courseTypeId[this.CourseType[0][i].id];
+                        } else if (this.CourseType[0][i].name == "主题") {
+                            typef = this.courseTypeId[this.CourseType[0][i].id];
+                        }
+                        this.courseTypeSon.push(
+                            this.courseTypeId[this.CourseType[0][i].id]
+                        );
+                    }
+                }
+            }
+            this.isLoading = true;
+            let params = {
+                type: this.groupA,
+                uid: this.userid,
+                oid: this.oid,
+                org: this.org,
+                typea: typea != undefined ? typea : "",
+                typeb: typeb != undefined ? typeb : "",
+                typec: typec != undefined ? typec : "",
+                typed: typed != undefined ? typed : "",
+                typef: typef != undefined ? typef : "",
+                typeE: typeE.join(","),
+                cu: "",
+                cn: this.courseName,
+                page: this.page,
+                pageSize: this.pageSize,
+            };
+            this.ajax
+                .get(this.$store.state.api + "selectTesttCourse", params)
+                .then((res) => {
+                    this.isLoading = false;
+                    this.total = res.data[0].length > 0 ? res.data[0][0].num : 0;
+                    this.course = res.data[0];
+                })
+                .catch((err) => {
+                    console.error(err);
+                });
+        },
+        getTypeName() {
+            this.$forceUpdate();
+            this.page = 1;
+            this.isChoose = 1;
+            this.getCourse();
+        },
+        // searchCourse() {
+        //   this.isLoading = true;
+        //   let params = {
+        //     cu: "",
+        //     cn: this.courseName,
+        //     page: this.page,
+        //   };
+        //   this.ajax
+        //     .get(this.$store.state.api + "searchCourse", params)
+        //     .then((res) => {
+        //       this.isLoading = false;
+        //       this.total = res.data[0].length > 0 ? res.data[0][0].num : 0;
+        //       this.course = res.data[0];
+        //     })
+        //     .catch((err) => {
+        //       this.isLoading = false;
+        //       console.error(err);
+        //     });
+        // },
+        deleteCourse(cid) {
+            // if (this.time()) {
+            this.$confirm("确定删除此项目吗?", "提示", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning",
+            })
+                .then(() => {
+                    this.isLoading = true;
+                    let params = {
+                        cid: cid,
+                    };
+                    this.ajax
+                        .get(this.$store.state.api + "deleteStudentCourse", params)
+                        .then((res) => {
+                            this.isLoading = false;
+                            this.$message.success("删除成功");
+                            this.getCourse();
+                        })
+                        .catch((err) => {
+                            console.error(err);
+                        });
+                })
+                .catch(() => {
+                    loading.close();
+                    this.isLoading = false;
+                    return;
+                });
+            // }
+        },
+        selectAllType() {
+            let params = {
+                org: this.org && this.org != "" ? this.org : "",
+                oid: this.oid && this.oid != "" ? this.oid : "",
+            };
+            this.ajax
+                .get(this.$store.state.api + "selectAllTypeT", params)
+                .then((res) => {
+                    this.CourseType = res.data;
+
+                    for (var i = 0; i < res.data[0].length; i++) {
+                        if (res.data[0][i].id == "34629907-d02f-11ec-8c78-005056b86db5") {
+                            res.data[0][i].name = "学科";
+                        } else if (res.data[0][i].id == "34628934-d02f-11ec-8c78-005056b86db5") {
+                            res.data[0][i].name = "年级";
+                        }
+                        if (!this.cid) {
+                            this.courseTypeId[res.data[0][i].id] = '';
+                        }
+                        if (!this.CourseTypeJson[res.data[0][i].id]) {
+                            this.CourseTypeJson[res.data[0][i].id] = [];
+                        }
+
+                        if (res.data[2].length == 0 && res.data[3].length == 0) {
+                            // for (var j = 0; j < res.data[1].length; j++) {
+                            //   if (res.data[0][i].id == res.data[1][j].pid) {
+                            //     this.CourseTypeJson[res.data[0][i].id].push(res.data[1][j]); // 去除公共分类
+                            //   }
+                            // }
+                            // if(this.org == '150e3120-9195-11ed-b13d-005056b86db5'){
+                            for (var j = 0; j < res.data[1].length; j++) {
+                                if (res.data[0][i].id == res.data[1][j].pid) {
+                                    this.CourseTypeJson[res.data[0][i].id].push(res.data[1][j]); // 去除公共分类
+                                }
+                            }
+                            // }else{
+                            //   this.CourseType = []
+                            // }
+                        } else {
+                            if (res.data[2].length > 0) {
+                                for (var j = 0; j < res.data[2].length; j++) {
+                                    if (res.data[0][i].id == res.data[2][j].pid) {
+                                        this.CourseTypeJson[res.data[0][i].id].push(res.data[2][j]); // 去除公共分类
+                                    }
+                                }
+                            }
+                            if (res.data[3].length > 0) {
+                                for (var j = 0; j < res.data[3].length; j++) {
+                                    if (res.data[0][i].id == res.data[3][j].pid) {
+                                        this.CourseTypeJson[res.data[0][i].id].push(res.data[3][j]); // 去除公共分类
+                                    }
+                                }
+                            }
+                        }
+                    }
+                })
+                .catch((err) => {
+                    console.error(err);
+                });
+        },
+        selectType() {
+            this.ajax
+                .get(this.$store.state.api + "selectStudentType")
+                .then((res) => {
+                    this.CourseType = res.data;
+                    for (var i = 0; i < res.data[0].length; i++) {
+                        if (!this.cid) {
+                            this.courseTypeId[res.data[0][i].id] = "";
+                        }
+                        if (this.oid == "69893dca-1d47-11ed-8c78-005056b86db5") {
+                            if (res.data[0][i].name == "栏目") {
+                                this.CourseType[0][i].name = "主题";
+                            }
+                        }
+                        for (var j = 0; j < res.data[1].length; j++) {
+                            if (res.data[0][i].id == res.data[1][j].pid) {
+                                if (!this.CourseTypeJson[res.data[0][i].id]) {
+                                    this.CourseTypeJson[res.data[0][i].id] = [];
+                                }
+                                this.CourseTypeJson[res.data[0][i].id].push(res.data[1][j]); //去除公共分类
+                            }
+                        }
+                    }
+                    this.selectTypeByOid();
+                    this.selectTypeByOrg();
+                })
+                .catch((err) => {
+                    console.error(err);
+                });
+        },
+        selectTypeByOid() {
+            let params = {
+                oid: this.oid,
+            };
+            this.ajax
+                .get(this.$store.state.api + "selectStudentTypeByOid", params)
+                .then((res) => {
+                    for (var i = 0; i < res.data[0].length; i++) {
+                        for (var j = 0; j < res.data[1].length; j++) {
+                            if (res.data[0][i].id == res.data[1][j].pid) {
+                                if (!this.CourseTypeJson[res.data[0][i].id]) {
+                                    this.CourseTypeJson[res.data[0][i].id] = [];
+                                }
+                                this.CourseTypeJson[res.data[0][i].id].push(res.data[1][j]);
+                            }
+                        }
+                    }
+                    this.$forceUpdate();
+                })
+                .catch((err) => {
+                    console.error(err);
+                });
+        },
+        selectTypeByOrg() {
+            let params = {
+                oid: this.org,
+            };
+            this.ajax
+                .get(this.$store.state.api + "selectStudentTypeByOid", params)
+                .then((res) => {
+                    for (var i = 0; i < res.data[0].length; i++) {
+                        for (var j = 0; j < res.data[1].length; j++) {
+                            if (res.data[0][i].id == res.data[1][j].pid) {
+                                if (!this.CourseTypeJson[res.data[0][i].id]) {
+                                    this.CourseTypeJson[res.data[0][i].id] = [];
+                                }
+                                this.CourseTypeJson[res.data[0][i].id].push(res.data[1][j]);
+                            }
+                        }
+                    }
+                    this.$forceUpdate();
+                })
+                .catch((err) => {
+                    console.error(err);
+                });
+        },
+        openCourse() {
+            this.dialogVisibleCourse = true;
+            this.getTeamCourse();
+        },
+        getTeamCourse() {
+            let params = {
+                uid: this.userid,
+                oid: this.oid,
+            };
+            this.ajax
+                .get(this.$store.state.api + "selectCourseTeam", params)
+                .then((res) => {
+                    this.courseTeam = res.data[0];
+                })
+                .catch((err) => {
+                    console.error(err);
+                });
+        },
+        search() {
+            this.page = 1;
+            this.getCourse();
+        },
+        checkProblem(res) {
+            this.problemCourse = res;
+            this.dialogVisible = true;
+        },
+        copyCourse(cid) {
+            let params = [{
+                cid: cid,
+                uid: this.userid
+            }]
+            this.ajax
+                .post(this.$store.state.api + "copySCourse", params)
+                .then((res) => {
+                    this.page = 1
+                    if (this.role == "1") {
+                        this.groupA = "0";
+                    } else {
+                        this.groupA = "0";
+                    }
+                    this.$message.success("复制成功")
+                    this.clear()
+                })
+                .catch((err) => {
+                    console.error(err);
+                });
+        }
+    },
+    created() {
+        if (this.role == '1') {
+            this.groupA = '0'
+        }
+        this.page = 1;
+        this.selectAllType();
+        this.getCourse();
+    },
+};
+</script>
+  
+<style scoped>
+.dialog_diy>>>.el-dialog__header {
+    background: #3d67bc !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;
+}
+
+.student_head>>>.el-button--primary {
+    background-color: #2268bc;
+}
+
+.xls_button {
+    font-size: 14px;
+    cursor: pointer;
+    text-decoration: underline;
+    color: rgb(34, 104, 188);
+}
+
+.student_head {
+    display: flex;
+    justify-content: space-between;
+    align-items: baseline;
+    flex-direction: row;
+    flex-wrap: wrap;
+}
+
+.top {
+    display: flex;
+    justify-content: space-between;
+}
+
+.bgColor {
+    background: #466b99;
+}
+
+.student_search {
+    display: flex;
+    align-items: center;
+    /* width: calc(100% / 3); */
+    width: 190px;
+}
+
+.student_search span {
+    margin: 0 10px 0 0;
+    min-width: 65px;
+}
+
+.student_button {
+    display: flex;
+    overflow: hidden;
+    height: 40px;
+}
+
+.upload-demo {
+    display: flex;
+    flex-direction: column;
+    align-items: end;
+    /* position: relative; */
+    width: 100px;
+    overflow: hidden;
+}
+
+.student_table {
+    padding: 20px 0;
+    height: 100%;
+    /* overflow: auto; */
+    min-height: 360px;
+}
+
+.student_empty {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+.el-table>>>.even_row {
+    background-color: #f1f1f1;
+}
+
+.time {
+    font-size: 13px;
+    color: #999;
+}
+
+.course_button {
+    padding: 10px 20px;
+}
+
+.course_button_box {
+    display: flex;
+    margin-top: 5px;
+    justify-content: space-between;
+}
+
+.course_rate {
+    margin-top: 5px;
+}
+
+.course_view {
+    display: flex;
+    align-items: center;
+    margin: 5px 0 0 0;
+}
+
+.course_view i {
+    background-image: url("../../../assets/liulan.png");
+    width: 25px;
+    height: 25px;
+    background-size: 100% 100%;
+    /* margin-top: 1px; */
+    line-height: 25px;
+    vertical-align: text-top;
+    background-repeat: no-repeat;
+}
+
+.image {
+    width: 100%;
+    height: 150px;
+    display: block;
+}
+
+.course_box {
+    display: flex;
+    flex-wrap: wrap;
+}
+
+.student_page {
+    width: 95%;
+    margin: 0 auto;
+}
+
+.course_create_box {
+    font-size: 18px;
+}
+
+.course_name {
+    margin-top: 10px;
+}
+
+.course_name span {
+    margin-bottom: 10px;
+    display: block;
+}
+
+.homework_box {
+    display: flex;
+    align-items: center;
+    flex-wrap: wrap;
+}
+
+.course_homework {
+    width: 130px;
+    display: flex;
+    justify-content: center;
+    flex-direction: column;
+    align-items: center;
+    margin: 0 10px 10px 0;
+}
+
+.course_type {
+    margin-top: 10px;
+    display: flex;
+}
+
+.course_type1 span {
+    margin-bottom: 10px;
+    display: block;
+}
+
+.course_type2 {
+    margin-left: 20px;
+}
+
+.course_type2 span {
+    margin-bottom: 10px;
+    display: block;
+}
+
+.course_empty {
+    color: rgb(110, 110, 110);
+    width: 100%;
+    height: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.el_cards>>>.el-card__body {
+    height: 100%;
+}
+
+.courseBtnBox {
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+    height: calc(100% - 170px);
+    padding: 10px;
+}
+
+.wordUpload {
+    display: flex;
+}
+
+.wordUpload>.buttonUp {
+    margin-right: 5px;
+}
+
+.out_box {
+    display: flex;
+    flex-direction: column;
+    flex-wrap: nowrap;
+    width: 250px;
+    background: #fff;
+    margin-right: 25px;
+    border: 1px solid #ccc;
+    height: fit-content;
+    box-sizing: border-box;
+    border-radius: 0px 0px 5px 5px;
+    /* overflow: hidden; */
+    margin-bottom: 15px;
+    position: relative;
+    padding-top: 30px;
+}
+
+.bottom_box {
+    display: flex;
+    padding: 0 0 10px 10px;
+    flex-direction: column;
+    box-sizing: border-box;
+    height: 140px;
+    flex-wrap: nowrap;
+    justify-content: space-evenly;
+}
+
+.bottom_box>div:nth-child(1) {
+    width: 230px;
+    overflow: hidden;
+    display: flex;
+    align-items: center;
+}
+.bottom_box>div:nth-child(1) span:nth-child(1){
+    font-weight: bold;
+    font-size: 18px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    max-width: 100%;
+}
+.bottom_box>div:nth-child(1) span:nth-child(2){
+    font-size: 14px;
+    min-width: fit-content;
+    margin-left: 5px;
+    color: #0074ff;
+}
+
+.tup {
+    width: 100%;
+    height: 141.06px;
+    margin: 0 auto;
+    overflow: hidden;
+    display: flex;
+    align-items: center;
+}
+
+.tup>img {
+    width: 100%;
+    height: 100%;
+    object-fit: contain;
+}
+
+.kc_time {
+    margin-top: 8px;
+    font-size: 14px;
+    color: #999;
+}
+
+.kc_t {
+    margin-top: 5px;
+    width: 100%;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+
+.three_bottom {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-around;
+    height: 40px;
+    align-items: center;
+    background: #f5f4f4;
+    font-size: 14px;
+}
+
+.three_bottom>div {
+    cursor: pointer;
+}
+
+.three_bottom>div:hover {
+    color: #79a2ff;
+}
+
+.head_left {
+    display: flex;
+}
+
+.student_input>>>.el-input__inner {
+    height: 40px;
+    width: 190px;
+    font-size: 13px;
+    padding: 0 10px;
+}
+
+.course_button {
+    color: #fff;
+    background: #2268bc;
+    width: 75px;
+    height: 40px;
+    padding: 0 !important;
+    font-size: 12px;
+    line-height: 40px;
+}
+
+.all_choose {
+    margin: 15px 0 10px;
+    height: 20%;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    max-width: calc(100% / 3 - 50px);
+}
+
+.all_choose>span {
+    min-width: 75px;
+    display: block;
+    margin-right: 10px;
+    text-align-last: justify;
+}
+
+.choose {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: wrap;
+    align-content: space-between;
+    height: 100%;
+    justify-content: flex-start;
+    width: 60%;
+    min-width: 868px;
+    align-items: center;
+}
+
+.choose>div:nth-child(2) {
+    margin-left: 1%;
+    width: 32.33333%;
+}
+
+.choose>div:nth-child(3) {
+    margin-left: 1%;
+    width: 32.33333%;
+}
+
+.choose>div:nth-child(5) {
+    margin: 5px 0 0 1%;
+}
+
+.choose>div:nth-child(4)>span {
+    /* width: 74px !important;
+    min-width: 74px; */
+}
+
+.choose>div:nth-child(4)>>>.el-select {
+    /* width: 217.5px;
+    min-width: 215.06px; */
+}
+
+.clear {
+    width: 70px;
+    max-width: 70px;
+    height: 35px;
+    background: #2268bc;
+    color: #fff;
+    text-align: center;
+    border-radius: 5px;
+    line-height: 35px;
+    cursor: pointer;
+    margin-left: 20px;
+}
+
+.ct_box {
+    height: 500px;
+    overflow: auto;
+    display: flex;
+    flex-wrap: wrap;
+}
+
+.myCourse {
+    position: absolute;
+    background: #3c3c3c;
+    width: 65px;
+    height: 25px;
+    color: #fff;
+    font-size: 12px;
+    text-align: center;
+    line-height: 25px;
+    top: 0;
+    right: 0;
+}
+
+.xtCourse {
+    position: absolute;
+    background: #466b99;
+    width: 70px;
+    height: 30px;
+    border-radius: 30px;
+    color: #fff;
+    font-size: 14px;
+    text-align: center;
+    line-height: 30px;
+    top: 5px;
+    left: 5px;
+}
+
+.subClick {
+    font-size: 16px;
+    cursor: pointer;
+    margin-left: 10px;
+    /* color: #ab582f; */
+    color: #409eff;
+}
+
+.more {
+    position: relative;
+
+}
+
+.more:hover div {
+    display: block;
+    color: #000;
+}
+
+.more div {
+    position: absolute;
+    bottom: 0px;
+    transform: translate(-50%, 100%);
+    background: #f5f4f4;
+    padding: 10px 20px;
+    z-index: 99;
+    width: 40px;
+    border-radius: 5px;
+    box-shadow: 0 0 3px 3px #80808020;
+    display: none;
+}
+
+.more div>span+span {
+    margin-top: 10px;
+}
+
+.more div>span {
+    display: block;
+    width: 100%;
+    text-align: center;
+}
+
+.more div>span:hover {
+    color: #79a2ff;
+}</style>
+  

+ 1139 - 0
src/components/pages/testStudent/index.vue

@@ -0,0 +1,1139 @@
+<template>
+    <div class="pb_content" style="height: auto">
+        <div class="pb_head top">
+            <div>
+                <span>学生评测</span>
+            </div>
+            <!-- <div class="student_button">
+                <el-button type="primary" class="bgColor" @click="goToCourse()">新建评测</el-button>
+            </div> -->
+        </div>
+        <div class="pb_content_body" style="height: 100%">
+            <div class="student_head">
+                <div class="choose">
+                    <div class="all_choose" v-for="(item, index) in CourseType[0]" :key="index">
+                        <span v-if="CourseTypeJson[item.id].length">{{ item.name }}</span>
+                        <el-select v-if="CourseTypeJson[item.id].length" v-model="courseTypeId[item.id]" placeholder="请选择"
+                            @change="getTypeName">
+                            <el-option label="全部" value="1">全部</el-option>
+                            <el-option v-for="item1 in CourseTypeJson[item.id]" :key="item1.id" :label="item1.name"
+                                :value="item1.id">
+                            </el-option>
+                        </el-select>
+                    </div>
+                    <div class="student_search">
+                        <span>所有者</span>
+                        <el-select v-model="groupA" @change="search">
+                            <el-option value="0" label="我的"></el-option>
+                            <!-- <el-option value="4" label="全部"></el-option> -->
+                            <!-- <el-option value="2" label="他人"
+                                v-if="oid != '1c3b9def-8fbe-11ed-b13d-005056b86db5'"></el-option> -->
+                        </el-select>
+                        <!-- <el-select v-model="groupA" @change="search" v-else>
+                <el-option value="4" label="全部"></el-option>
+              </el-select> -->
+                    </div>
+                    <div @click="clear" class="clear" v-if="CourseType.length">重置</div>
+                </div>
+
+                <div class="student_right">
+                    <div class="head_left">
+                        <el-input v-model="courseName" class="student_input" placeholder="请输入项目名称"></el-input>
+                        <el-button class="course_button" @click="searchCourse">查询</el-button>
+                    </div>
+                </div>
+            </div>
+            <div class="student_table" v-loading="isLoading">
+                <div class="course_box">
+                    <div class="out_box" v-for="(item, index) in course" :key="index">
+                        <div class="bottom_box">
+                            <div>{{ item.title }}</div>
+                            <div class="kc_t">
+                                创建人:{{ item.uname }}
+                            </div>
+                            <div class="kc_time">
+                                <span style="color: #4b4b4b">创建日期:</span>{{ item.time }}
+                            </div>
+                            <div class="kc_time">
+                                <span style="color: #4b4b4b">修改日期:</span>{{ item.utime }}
+                            </div>
+                        </div>
+                        <div class="three_bottom">
+                            <div @click="goToCourse2(item.courseId)">进入答题</div>
+                        </div>
+                    </div>
+                    <div class="course_empty" v-if="course.length == 0">暂无数据</div>
+                </div>
+            </div>
+        </div>
+        <div class="student_page">
+            <el-pagination background layout="prev, pager, next" :page-size="pageSize" :total="total"
+                v-if="page && course.length" style="padding-bottom: 20px"
+                @current-change="handleCurrentChange"></el-pagination>
+        </div>
+        <el-dialog :visible.sync="dialogVisible1" size="tiny">
+            <img width="100%" :src="dialogImageUrl" alt />
+        </el-dialog>
+        <el-dialog title="查看提问" :visible.sync="dialogVisible" :append-to-body="true" width="750px"
+            :before-close="handleClose" class="dialog_diy">
+            <div>
+                <div class="a_addBox">
+                    <CourseProblem :problemCourse="problemCourse"></CourseProblem>
+                </div>
+            </div>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="dialogVisible = false">关 闭</el-button>
+            </span>
+        </el-dialog>
+        <el-dialog title="查看协同项目" :visible.sync="dialogVisibleCourse" :append-to-body="true" width="850px"
+            :before-close="handleClose" class="dialog_diy">
+            <div class="ct_box">
+                <div class="out_box" v-for="(item, index) in courseTeam" :key="index" style="margin-left: 15px">
+                    <div class="tup">
+                        <img :src="item.cover != null && item.cover != ''
+                                ? JSON.parse(item.cover).length > 0
+                                    ? JSON.parse(item.cover)[0].url
+                                    : mr
+                                : mr
+                            " alt />
+                    </div>
+                    <div class="bottom_box">
+                        <div>{{ item.title }}</div>
+                        <div class="kc_t">创建人:{{ item.uname }}</div>
+                        <div class="kc_time">{{ item.time }}</div>
+                    </div>
+                    <div class="three_bottom">
+                        <!-- <div @click="jump(item.courseId)">查看内容</div> -->
+                        <div @click="
+                            goTo(
+                                '/studentAddCourse?cid=' +
+                                item.courseId +
+                                '&userid=' +
+                                userid +
+                                '&oid=' +
+                                oid +
+                                '&org=' +
+                                org +
+                                '&role=' +
+                                role
+                            )
+                            ">
+                            编辑
+                        </div>
+                    </div>
+                </div>
+                <div class="course_empty" v-if="courseTeam.length == 0">暂无数据</div>
+            </div>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="dialogVisibleCourse = false">关 闭</el-button>
+            </span>
+        </el-dialog>
+    </div>
+</template>
+  
+<script>
+import "../../../common/aws-sdk-2.235.1.min";
+import EditorBar from "../../../components/tools/wangEnduit";
+import CourseProblem from "../components/courseProblem";
+export default {
+    components: { EditorBar, CourseProblem },
+    data() {
+        return {
+            itemCount: 1,
+            courseTitle: "",
+            courseText: "",
+            courseTime: "",
+            isLoading: false,
+            fileList: [],
+            fileList1: [],
+            homeworkList: [{ name: "" }],
+            formLabelWidth: "100px",
+            dialogVisible: false,
+            dialogVisible1: false,
+            dialogVisibleCourse: false,
+            dialogImageUrl: "",
+            group: "",
+            userid: this.$route.query.userid,
+            oid: this.$route.query.oid,
+            org: this.$route.query.org,
+            role: this.$route.query.role,
+            classid: this.$route.query.classid,
+            Juri: "",
+            groupList: [],
+            JuriList: [],
+            page: 1,
+            total: 0,
+            pageSize: 20,
+            tableData: [],
+            now: "",
+            courseDetail: {},
+            addCourse: {},
+            groupA: "3",
+            classX: "",
+            course: [],
+            courseName: "",
+            mr: require("../../../assets/icon/kc1.png"),
+            CourseType: [],
+            CourseTypeJson: {},
+            courseTypeId: {},
+            courseTypeSon: [],
+            isChoose: 0,
+            problemCourse: null, //查看提问的项目
+            courseTeam: [],
+        };
+    },
+    methods: {
+        change(val) {
+            console.log(val);
+        },
+        time() {
+            if (!this.now) {
+                this.now = new Date().getTime();
+                return true;
+            } else {
+                let time = new Date().getTime();
+                if (time - this.now > 3000) {
+                    this.now = time;
+                    return true;
+                } else {
+                    return false;
+                }
+            }
+        },
+        addHomeworkBox() {
+            this.homeworkList.push({ name: "" });
+            this.itemCount++;
+        },
+        reduceHomeworkBox() {
+            var a = this.homeworkList;
+            a.splice(a.length - 1);
+            this.itemCount--;
+        },
+        goTo(path) {
+            this.$router.push(path);
+        },
+        goToCourse(courseId) {
+            if (courseId) {
+                this.$router.push(
+                    "/studentAddCourse?cid=" +
+                    courseId +
+                    "&userid=" +
+                    this.userid +
+                    "&oid=" +
+                    this.oid +
+                    "&org=" +
+                    this.org +
+                    "&role=" +
+                    this.role
+                );
+            } else {
+                this.$router.push(
+                    "/addTest?userid=" +
+                    this.userid +
+                    "&oid=" +
+                    this.oid +
+                    "&org=" +
+                    this.org +
+                    "&role=" +
+                    this.role
+                );
+            }
+            // this.$router.push(path);
+        },
+        goToCourse2(cid) {
+            this.$router.push(
+                "/doTest?cid=" +
+                cid +
+                "&userid=" +
+                this.userid +
+                "&oid=" +
+                this.oid +
+                "&org=" +
+                this.org +
+                "&type=2" +
+                "&role=" +
+                this.role
+            );
+        },
+        tableRowClassName({ row, rowIndex }) {
+            if ((rowIndex + 1) % 2 === 0) {
+                return "even_row";
+            } else {
+                return "";
+            }
+        },
+        jump(cid) {
+            // window.open(
+            //   "//pbl.cocorobo.cn/pbl-student-table/dist/#/courseDetail?courseId=" +
+            //     cid +
+            //     "&userid=" +
+            //     this.userid
+            // );
+            window.parent.postMessage({ cid: cid, screenType: "2s" }, "*");
+        },
+        get(cid) {
+            window.parent.postMessage({ cid: cid, screenType: "3s" }, "*");
+        },
+        getA(cid) {
+            this.$router.push("/courseProgress?cid=" + cid + "&userid=" +
+                this.userid +
+                "&oid=" +
+                this.oid +
+                "&org=" +
+                this.org)
+        },
+        handle_remove(file, fileList) {
+            var _tmp = this.fileList;
+            for (var i = 0, len = _tmp.length; i < len; i++) {
+                if (_tmp[i].uid == file.uid) {
+                    _tmp.splice(i, 1);
+                    break;
+                }
+                this.fileList = _tmp;
+            }
+        },
+        handle_remove1(file, fileList) {
+            var _tmp = this.fileList1;
+            for (var i = 0, len = _tmp.length; i < len; i++) {
+                if (_tmp[i].uid == file.uid) {
+                    _tmp.splice(i, 1);
+                    break;
+                }
+                this.fileList1 = _tmp;
+            }
+        },
+        handleCurrentChange(val) {
+            // console.log(`当前页: ${val}`);
+            this.page = val;
+            this.getCourse();
+        },
+        init() { },
+        handleClose(done) {
+            done();
+        },
+        handleRemove(file, fileList) {
+            console.log(file, fileList);
+        },
+        handlePictureCardPreview(file) {
+            this.dialogImageUrl = file.url;
+            this.dialogVisible1 = true;
+        },
+        onExceed() {
+            this.$message.error("项目海报仅支持上传一张,请删除后再进行上传");
+        },
+        //uuid生成
+        guid() {
+            return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
+                /[xy]/g,
+                function (c) {
+                    var r = (Math.random() * 16) | 0,
+                        v = c == "x" ? r : (r & 0x3) | 0x8;
+                    return v.toString(16);
+                }
+            );
+        },
+        time() {
+            if (!this.now) {
+                this.now = new Date().getTime();
+                return true;
+            } else {
+                let time = new Date().getTime();
+                if (time - this.now > 3000) {
+                    this.now = time;
+                    return true;
+                } else {
+                    return false;
+                }
+            }
+        },
+        searchCourse() {
+            this.page = 1;
+            this.getCourse();
+        },
+        clear() {
+            if (this.CourseType.length) {
+                for (var i = 0; i < this.CourseType[0].length; i++) {
+                    this.courseTypeId[this.CourseType[0][i].id] = "";
+                }
+            }
+            this.getCourse();
+        },
+        getCourse() {
+            var typeE = [];
+            var typea, typeb, typec, typed, typef;
+            if (this.isChoose == 1) {
+                for (var i = 0; i < this.CourseType[0].length; i++) {
+                    if (this.courseTypeId[this.CourseType[0][i].id] == "1") {
+                        typeE.push(this.CourseType[0][i].id);
+                    } else if (this.courseTypeId[this.CourseType[0][i].id] != "") {
+                        if (this.CourseType[0][i].name == "年级") {
+                            typea = this.courseTypeId[this.CourseType[0][i].id];
+                        } else if (this.CourseType[0][i].name == "学科") {
+                            typeb = this.courseTypeId[this.CourseType[0][i].id];
+                        } else if (this.CourseType[0][i].name == "栏目") {
+                            typeb = this.courseTypeId[this.CourseType[0][i].id];
+                        } else if (this.CourseType[0][i].name == "学院") {
+                            typeb = this.courseTypeId[this.CourseType[0][i].id];
+                        } else if (this.CourseType[0][i].name == "新技能") {
+                            typec = this.courseTypeId[this.CourseType[0][i].id];
+                        } else if (this.CourseType[0][i].name == "赛道") {
+                            typed = this.courseTypeId[this.CourseType[0][i].id];
+                        } else if (this.CourseType[0][i].name == "项目类型") {
+                            typed = this.courseTypeId[this.CourseType[0][i].id];
+                        } else if (this.CourseType[0][i].name == "主题") {
+                            typef = this.courseTypeId[this.CourseType[0][i].id];
+                        }
+                        this.courseTypeSon.push(
+                            this.courseTypeId[this.CourseType[0][i].id]
+                        );
+                    }
+                }
+            }
+            this.isLoading = true;
+            let params = {
+                type: this.groupA,
+                uid: this.userid,
+                oid: this.oid,
+                org: this.org,
+                typea: typea != undefined ? typea : "",
+                typeb: typeb != undefined ? typeb : "",
+                typec: typec != undefined ? typec : "",
+                typed: typed != undefined ? typed : "",
+                typef: typef != undefined ? typef : "",
+                typeE: typeE.join(","),
+                cu: "",
+                cn: this.courseName,
+                page: this.page,
+                pageSize: this.pageSize,
+            };
+            this.ajax
+                .get(this.$store.state.api + "selectTesttCourseCenter", params)
+                .then((res) => {
+                    this.isLoading = false;
+                    this.total = res.data[0].length > 0 ? res.data[0][0].num : 0;
+                    this.course = res.data[0];
+                })
+                .catch((err) => {
+                    console.error(err);
+                });
+        },
+        getTypeName() {
+            this.$forceUpdate();
+            this.page = 1;
+            this.isChoose = 1;
+            this.getCourse();
+        },
+        // searchCourse() {
+        //   this.isLoading = true;
+        //   let params = {
+        //     cu: "",
+        //     cn: this.courseName,
+        //     page: this.page,
+        //   };
+        //   this.ajax
+        //     .get(this.$store.state.api + "searchCourse", params)
+        //     .then((res) => {
+        //       this.isLoading = false;
+        //       this.total = res.data[0].length > 0 ? res.data[0][0].num : 0;
+        //       this.course = res.data[0];
+        //     })
+        //     .catch((err) => {
+        //       this.isLoading = false;
+        //       console.error(err);
+        //     });
+        // },
+        deleteCourse(cid) {
+            // if (this.time()) {
+            this.$confirm("确定删除此项目吗?", "提示", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning",
+            })
+                .then(() => {
+                    this.isLoading = true;
+                    let params = {
+                        cid: cid,
+                    };
+                    this.ajax
+                        .get(this.$store.state.api + "deleteStudentCourse", params)
+                        .then((res) => {
+                            this.isLoading = false;
+                            this.$message.success("删除成功");
+                            this.getCourse();
+                        })
+                        .catch((err) => {
+                            console.error(err);
+                        });
+                })
+                .catch(() => {
+                    loading.close();
+                    this.isLoading = false;
+                    return;
+                });
+            // }
+        },
+        selectAllType() {
+            let params = {
+                org: this.org && this.org != "" ? this.org : "",
+                oid: this.oid && this.oid != "" ? this.oid : "",
+            };
+            this.ajax
+                .get(this.$store.state.api + "selectAllTypeT", params)
+                .then((res) => {
+                    this.CourseType = res.data;
+
+                    for (var i = 0; i < res.data[0].length; i++) {
+                        if (res.data[0][i].id == "34629907-d02f-11ec-8c78-005056b86db5") {
+                            res.data[0][i].name = "学科";
+                        } else if (res.data[0][i].id == "34628934-d02f-11ec-8c78-005056b86db5") {
+                            res.data[0][i].name = "年级";
+                        }
+                        if (!this.cid) {
+                            this.courseTypeId[res.data[0][i].id] = '';
+                        }
+                        if (!this.CourseTypeJson[res.data[0][i].id]) {
+                            this.CourseTypeJson[res.data[0][i].id] = [];
+                        }
+
+                        if (res.data[2].length == 0 && res.data[3].length == 0) {
+                            // for (var j = 0; j < res.data[1].length; j++) {
+                            //   if (res.data[0][i].id == res.data[1][j].pid) {
+                            //     this.CourseTypeJson[res.data[0][i].id].push(res.data[1][j]); // 去除公共分类
+                            //   }
+                            // }
+                            // if(this.org == '150e3120-9195-11ed-b13d-005056b86db5'){
+                            for (var j = 0; j < res.data[1].length; j++) {
+                                if (res.data[0][i].id == res.data[1][j].pid) {
+                                    this.CourseTypeJson[res.data[0][i].id].push(res.data[1][j]); // 去除公共分类
+                                }
+                            }
+                            // }else{
+                            //   this.CourseType = []
+                            // }
+                        } else {
+                            if (res.data[2].length > 0) {
+                                for (var j = 0; j < res.data[2].length; j++) {
+                                    if (res.data[0][i].id == res.data[2][j].pid) {
+                                        this.CourseTypeJson[res.data[0][i].id].push(res.data[2][j]); // 去除公共分类
+                                    }
+                                }
+                            }
+                            if (res.data[3].length > 0) {
+                                for (var j = 0; j < res.data[3].length; j++) {
+                                    if (res.data[0][i].id == res.data[3][j].pid) {
+                                        this.CourseTypeJson[res.data[0][i].id].push(res.data[3][j]); // 去除公共分类
+                                    }
+                                }
+                            }
+                        }
+                    }
+                })
+                .catch((err) => {
+                    console.error(err);
+                });
+        },
+        selectType() {
+            this.ajax
+                .get(this.$store.state.api + "selectStudentType")
+                .then((res) => {
+                    this.CourseType = res.data;
+                    for (var i = 0; i < res.data[0].length; i++) {
+                        if (!this.cid) {
+                            this.courseTypeId[res.data[0][i].id] = "";
+                        }
+                        if (this.oid == "69893dca-1d47-11ed-8c78-005056b86db5") {
+                            if (res.data[0][i].name == "栏目") {
+                                this.CourseType[0][i].name = "主题";
+                            }
+                        }
+                        for (var j = 0; j < res.data[1].length; j++) {
+                            if (res.data[0][i].id == res.data[1][j].pid) {
+                                if (!this.CourseTypeJson[res.data[0][i].id]) {
+                                    this.CourseTypeJson[res.data[0][i].id] = [];
+                                }
+                                this.CourseTypeJson[res.data[0][i].id].push(res.data[1][j]); //去除公共分类
+                            }
+                        }
+                    }
+                    this.selectTypeByOid();
+                    this.selectTypeByOrg();
+                })
+                .catch((err) => {
+                    console.error(err);
+                });
+        },
+        selectTypeByOid() {
+            let params = {
+                oid: this.oid,
+            };
+            this.ajax
+                .get(this.$store.state.api + "selectStudentTypeByOid", params)
+                .then((res) => {
+                    for (var i = 0; i < res.data[0].length; i++) {
+                        for (var j = 0; j < res.data[1].length; j++) {
+                            if (res.data[0][i].id == res.data[1][j].pid) {
+                                if (!this.CourseTypeJson[res.data[0][i].id]) {
+                                    this.CourseTypeJson[res.data[0][i].id] = [];
+                                }
+                                this.CourseTypeJson[res.data[0][i].id].push(res.data[1][j]);
+                            }
+                        }
+                    }
+                    this.$forceUpdate();
+                })
+                .catch((err) => {
+                    console.error(err);
+                });
+        },
+        selectTypeByOrg() {
+            let params = {
+                oid: this.org,
+            };
+            this.ajax
+                .get(this.$store.state.api + "selectStudentTypeByOid", params)
+                .then((res) => {
+                    for (var i = 0; i < res.data[0].length; i++) {
+                        for (var j = 0; j < res.data[1].length; j++) {
+                            if (res.data[0][i].id == res.data[1][j].pid) {
+                                if (!this.CourseTypeJson[res.data[0][i].id]) {
+                                    this.CourseTypeJson[res.data[0][i].id] = [];
+                                }
+                                this.CourseTypeJson[res.data[0][i].id].push(res.data[1][j]);
+                            }
+                        }
+                    }
+                    this.$forceUpdate();
+                })
+                .catch((err) => {
+                    console.error(err);
+                });
+        },
+        openCourse() {
+            this.dialogVisibleCourse = true;
+            this.getTeamCourse();
+        },
+        getTeamCourse() {
+            let params = {
+                uid: this.userid,
+                oid: this.oid,
+            };
+            this.ajax
+                .get(this.$store.state.api + "selectCourseTeam", params)
+                .then((res) => {
+                    this.courseTeam = res.data[0];
+                })
+                .catch((err) => {
+                    console.error(err);
+                });
+        },
+        search() {
+            this.page = 1;
+            this.getCourse();
+        },
+        checkProblem(res) {
+            this.problemCourse = res;
+            this.dialogVisible = true;
+        },
+        copyCourse(cid) {
+            let params = [{
+                cid: cid,
+                uid: this.userid
+            }]
+            this.ajax
+                .post(this.$store.state.api + "copySCourse", params)
+                .then((res) => {
+                    this.page = 1
+                    if (this.role == "1") {
+                        this.groupA = "0";
+                    } else {
+                        this.groupA = "0";
+                    }
+                    this.$message.success("复制成功")
+                    this.clear()
+                })
+                .catch((err) => {
+                    console.error(err);
+                });
+        }
+    },
+    created() {
+        if (this.role == '1') {
+            this.groupA = '0'
+        }
+        this.page = 1;
+        this.selectAllType();
+        this.getCourse();
+    },
+};
+</script>
+  
+<style scoped>
+.dialog_diy>>>.el-dialog__header {
+    background: #3d67bc !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;
+}
+
+.student_head>>>.el-button--primary {
+    background-color: #2268bc;
+}
+
+.xls_button {
+    font-size: 14px;
+    cursor: pointer;
+    text-decoration: underline;
+    color: rgb(34, 104, 188);
+}
+
+.student_head {
+    display: flex;
+    justify-content: space-between;
+    align-items: baseline;
+    flex-direction: row;
+    flex-wrap: wrap;
+}
+
+.top {
+    display: flex;
+    justify-content: space-between;
+}
+
+.bgColor {
+    background: #466b99;
+}
+
+.student_search {
+    display: flex;
+    align-items: center;
+    /* width: calc(100% / 3); */
+    width: 190px;
+}
+
+.student_search span {
+    margin: 0 10px 0 0;
+    min-width: 65px;
+}
+
+.student_button {
+    display: flex;
+    overflow: hidden;
+    height: 40px;
+}
+
+.upload-demo {
+    display: flex;
+    flex-direction: column;
+    align-items: end;
+    /* position: relative; */
+    width: 100px;
+    overflow: hidden;
+}
+
+.student_table {
+    padding: 20px 0;
+    height: 100%;
+    /* overflow: auto; */
+    min-height: 360px;
+}
+
+.student_empty {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+.el-table>>>.even_row {
+    background-color: #f1f1f1;
+}
+
+.time {
+    font-size: 13px;
+    color: #999;
+}
+
+.course_button {
+    padding: 10px 20px;
+}
+
+.course_button_box {
+    display: flex;
+    margin-top: 5px;
+    justify-content: space-between;
+}
+
+.course_rate {
+    margin-top: 5px;
+}
+
+.course_view {
+    display: flex;
+    align-items: center;
+    margin: 5px 0 0 0;
+}
+
+.course_view i {
+    background-image: url("../../../assets/liulan.png");
+    width: 25px;
+    height: 25px;
+    background-size: 100% 100%;
+    /* margin-top: 1px; */
+    line-height: 25px;
+    vertical-align: text-top;
+    background-repeat: no-repeat;
+}
+
+.image {
+    width: 100%;
+    height: 150px;
+    display: block;
+}
+
+.course_box {
+    display: flex;
+    flex-wrap: wrap;
+}
+
+.student_page {
+    width: 95%;
+    margin: 0 auto;
+}
+
+.course_create_box {
+    font-size: 18px;
+}
+
+.course_name {
+    margin-top: 10px;
+}
+
+.course_name span {
+    margin-bottom: 10px;
+    display: block;
+}
+
+.homework_box {
+    display: flex;
+    align-items: center;
+    flex-wrap: wrap;
+}
+
+.course_homework {
+    width: 130px;
+    display: flex;
+    justify-content: center;
+    flex-direction: column;
+    align-items: center;
+    margin: 0 10px 10px 0;
+}
+
+.course_type {
+    margin-top: 10px;
+    display: flex;
+}
+
+.course_type1 span {
+    margin-bottom: 10px;
+    display: block;
+}
+
+.course_type2 {
+    margin-left: 20px;
+}
+
+.course_type2 span {
+    margin-bottom: 10px;
+    display: block;
+}
+
+.course_empty {
+    color: rgb(110, 110, 110);
+    width: 100%;
+    height: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.el_cards>>>.el-card__body {
+    height: 100%;
+}
+
+.courseBtnBox {
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+    height: calc(100% - 170px);
+    padding: 10px;
+}
+
+.wordUpload {
+    display: flex;
+}
+
+.wordUpload>.buttonUp {
+    margin-right: 5px;
+}
+
+.out_box {
+    display: flex;
+    flex-direction: column;
+    flex-wrap: nowrap;
+    width: 250px;
+    background: #fff;
+    margin-right: 25px;
+    border: 1px solid #ccc;
+    height: fit-content;
+    box-sizing: border-box;
+    border-radius: 0px 0px 5px 5px;
+    /* overflow: hidden; */
+    margin-bottom: 15px;
+    position: relative;
+    padding-top: 10px;
+}
+
+.bottom_box {
+    display: flex;
+    padding: 0 0 10px 10px;
+    flex-direction: column;
+    box-sizing: border-box;
+    height: 140px;
+    flex-wrap: nowrap;
+    justify-content: space-evenly;
+}
+
+.bottom_box>div:nth-child(1) {
+    width: 230px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    font-weight: bold;
+    font-size: 18px;
+}
+
+.tup {
+    width: 100%;
+    height: 141.06px;
+    margin: 0 auto;
+    overflow: hidden;
+    display: flex;
+    align-items: center;
+}
+
+.tup>img {
+    width: 100%;
+    height: 100%;
+    object-fit: contain;
+}
+
+.kc_time {
+    margin-top: 8px;
+    font-size: 14px;
+    color: #999;
+}
+
+.kc_t {
+    margin-top: 5px;
+    width: 100%;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+
+.three_bottom {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-around;
+    height: 40px;
+    align-items: center;
+    background: #f5f4f4;
+    font-size: 14px;
+}
+
+.three_bottom>div {
+    cursor: pointer;
+}
+
+.three_bottom>div:hover {
+    color: #79a2ff;
+}
+
+.head_left {
+    display: flex;
+}
+
+.student_input>>>.el-input__inner {
+    height: 40px;
+    width: 190px;
+    font-size: 13px;
+    padding: 0 10px;
+}
+
+.course_button {
+    color: #fff;
+    background: #2268bc;
+    width: 75px;
+    height: 40px;
+    padding: 0 !important;
+    font-size: 12px;
+    line-height: 40px;
+}
+
+.all_choose {
+    margin: 15px 0 10px;
+    height: 20%;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    max-width: calc(100% / 3 - 50px);
+}
+
+.all_choose>span {
+    min-width: 75px;
+    display: block;
+    margin-right: 10px;
+    text-align-last: justify;
+}
+
+.choose {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: wrap;
+    align-content: space-between;
+    height: 100%;
+    justify-content: flex-start;
+    width: 60%;
+    min-width: 868px;
+    align-items: center;
+}
+
+.choose>div:nth-child(2) {
+    margin-left: 1%;
+    width: 32.33333%;
+}
+
+.choose>div:nth-child(3) {
+    margin-left: 1%;
+    width: 32.33333%;
+}
+
+.choose>div:nth-child(5) {
+    margin: 5px 0 0 1%;
+}
+
+.choose>div:nth-child(4)>span {
+    /* width: 74px !important;
+    min-width: 74px; */
+}
+
+.choose>div:nth-child(4)>>>.el-select {
+    /* width: 217.5px;
+    min-width: 215.06px; */
+}
+
+.clear {
+    width: 70px;
+    max-width: 70px;
+    height: 35px;
+    background: #2268bc;
+    color: #fff;
+    text-align: center;
+    border-radius: 5px;
+    line-height: 35px;
+    cursor: pointer;
+    margin-left: 20px;
+}
+
+.ct_box {
+    height: 500px;
+    overflow: auto;
+    display: flex;
+    flex-wrap: wrap;
+}
+
+.myCourse {
+    position: absolute;
+    background: #3c3c3c;
+    width: 65px;
+    height: 25px;
+    color: #fff;
+    font-size: 12px;
+    text-align: center;
+    line-height: 25px;
+    top: 0;
+    right: 0;
+}
+
+.xtCourse {
+    position: absolute;
+    background: #466b99;
+    width: 70px;
+    height: 30px;
+    border-radius: 30px;
+    color: #fff;
+    font-size: 14px;
+    text-align: center;
+    line-height: 30px;
+    top: 5px;
+    left: 5px;
+}
+
+.subClick {
+    font-size: 16px;
+    cursor: pointer;
+    margin-left: 10px;
+    /* color: #ab582f; */
+    color: #409eff;
+}
+
+.more {
+    position: relative;
+
+}
+
+.more:hover div {
+    display: block;
+    color: #000;
+}
+
+.more div {
+    position: absolute;
+    bottom: 0px;
+    transform: translate(-50%, 100%);
+    background: #f5f4f4;
+    padding: 10px 20px;
+    z-index: 99;
+    width: 40px;
+    border-radius: 5px;
+    box-shadow: 0 0 3px 3px #80808020;
+    display: none;
+}
+
+.more div>span+span {
+    margin-top: 10px;
+}
+
+.more div>span {
+    display: block;
+    width: 100%;
+    text-align: center;
+}
+
+.more div>span:hover {
+    color: #79a2ff;
+}</style>
+  

+ 110 - 0
src/components/pages/testStudent/view/component/choice.vue

@@ -0,0 +1,110 @@
+<template>
+    <div class="c_box">
+        <!-- <div class="mask"></div> -->
+        <div v-if="!checkJson">暂未设置题目</div>
+        <div v-else class="choice_box">
+            <div class="title">{{ `(${option[checkJson.type].name})` + checkJson.title }}</div>
+            <div class="choices">
+                <div class="choice" v-for="(item, index) in checkJson.array" :key="index">
+                    <div class="choice_c" v-if="checkJson.type == 2"><el-checkbox v-model="checkJson.answer2" :label="index"></el-checkbox><span>{{ item.option }}</span></div>
+                    <div class="choice_c" v-if="checkJson.type == 1"><el-radio v-model="checkJson.answer2[0]" :label="index"></el-radio><span>{{ item.option }}</span></div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    props: {
+        cJson: {
+            type: Object,
+        },
+    },
+    data() {
+        return {
+            option: {
+                1: { name: '单选题' },
+                2: { name: '多选题' }
+            },
+            checkJson:undefined
+        }
+    },
+    watch: {
+        checkJson: {
+            handler(newValue){
+                this.$emit('update:cJson', newValue)
+            },
+            deep: true
+        }
+    },
+    methods: {
+        depthCopy(s) {
+            return JSON.parse(JSON.stringify(s));
+        },
+    },
+    mounted(){
+        this.checkJson = this.cJson ? this.depthCopy(this.cJson) : undefined
+    }
+}
+</script>
+
+<style scoped>
+.c_box {
+    width: 100%;
+    position: relative;
+}
+.mask{
+    position: absolute;
+    height: 100%;
+    width: 100%;
+    z-index: 2;
+}
+.choice_box {
+    
+}
+
+.choice_box>.title {
+    font-weight: bold;
+    width: 100%;
+    word-break: break-all;
+}
+.choice_box>.choices {
+   margin-top:10px;
+   padding: 0 10px;
+}
+.choice_box>.choices >.choice{
+    word-break: break-all;
+}
+.choice_box>.choices >.choice + .choice{
+    margin-top: 5px;
+}
+.choice_box>.choices >.choice > .choice_c{
+    display: flex;
+}
+.choice_box>.choices >.choice > .choice_c > span{
+    /* margin-left: 10px; */
+}
+.choice_box>.choices >.choice > .choice_c > .el-checkbox{
+    margin-top: 4px;
+    margin-right: 10px;
+}
+.choice_box>.choices >.choice > .choice_c > .el-radio{
+    margin-top: 4px;
+    margin-right: 10px;
+}
+.choice_c>>>.el-checkbox__label {
+    display: none;
+}
+
+.choice_c>>>.el-radio__label {
+    display: none;
+}
+
+.choice_c .right{
+    color: #efa030;
+}
+.choice_c .right::after{
+    content: '(正确答案)';
+}
+</style>

+ 195 - 0
src/components/pages/testStudent/view/component/topic.vue

@@ -0,0 +1,195 @@
+<template>
+  <div class="c_box">
+    <div class="c_box_title">{{ title }}</div>
+    <div class="c_body">
+      <div v-if="type == 3">
+        <div v-for="(item, index) in checkArray[page].array" :key="index" class="check_box">
+          <div class="title">{{ selectType(item, index) }}</div>
+          <div v-if="item.ttype == 1" class="answerBox"><choiceV :cJson.sync="item.json"></choiceV></div>
+          <div v-for="(item2, index2) in item.array" :key="`${index}-${index2}`" class="check_box_xia">
+            <div class="title">{{ selectType(item2, index2) }}</div>
+            <div v-if="item2.ttype == 1" class="answerBox"><choiceV :cJson.sync="item2.json"></choiceV></div>
+          </div>
+        </div>
+      </div>
+      <div v-else>
+        <div v-for="(item, index) in checkArray" :key="index" class="check_box">
+          <div class="title">{{ selectType(item, index) }}</div>
+          <div v-if="item.ttype == 1" class="answerBox"><choiceV :cJson.sync="item.json"></choiceV></div>
+          <div v-for="(item2, index2) in item.array" :key="`${index}-${index2}`" class="check_box_xia">
+            <div class="title">{{ selectType(item2, index2) }}</div>
+            <div v-if="item2.ttype == 1" class="answerBox"><choiceV :cJson.sync="item2.json"></choiceV></div>
+          </div>
+        </div>
+      </div>
+
+      <div v-if="checkArray.length > 1 && type == 3" class="page">
+        <el-button type="primary" size="mini" :disabled="page == 0" @click="page--">上一页</el-button>
+        <div class="p_page"><span>{{ page + 1 }}</span><span>/</span><span>{{ checkArray.length }}</span></div>
+        <el-button type="primary" size="mini" :disabled="page == (checkArray.length - 1)" @click="page++">下一页</el-button>
+
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import choiceV from './choice.vue';
+export default {
+  props: {
+    cJson: {
+      type: Array,
+    },
+    title: {
+      type: String,
+    }
+  },
+  components: {
+    choiceV
+  },
+  data() {
+    return {
+      checkArray: [],
+      type: 1,
+      page: 0,
+      options2: {
+        1: "选择题",
+        2: "问答题",
+        3: "填空题",
+        4: "添加文档"
+      },
+    }
+  },
+  computed: {
+    selectType() {
+      return function (item, index) {
+        if (item.ttype == 1) {
+          return index + 1 + "、" + this.options2[item.type];
+        } else if (item.ttype == 2) {
+          return `第${index + 1}组 (共${item.array.length}题)`;
+        } else if (item.ttype == 3) {
+          return `分页${index + 1}`;
+        }
+      };
+    }
+  },
+  watch: {
+    cJson: {
+      handler(newVal, oldVal) {
+        console.log(newVal);
+        console.log(oldVal);
+        this.checkArray = this.setJson(this.depthCopy(newVal))
+      },
+      deep: true
+    }
+  },
+  methods: {
+    depthCopy(s) {
+      return JSON.parse(JSON.stringify(s));
+    },
+    setJson(json) {
+      if (json.length > 0) {
+        let _json = this.depthCopy(json)
+        this.type = _json[0].ttype
+        let checkArray = _json.filter(item => {
+          if (item.array) {
+            item.array = item.array.filter(item2 => {
+              if (item2.ttype == 1 && item2.json && !item2.json.answer2) {
+                item2.json.answer2 = []
+              }
+              if (item2.array) {
+                  item2.array = item2.array.filter(item3 => {
+                    if (item3.ttype == 1 && item3.json && !item3.json.answer2) {
+                      item3.json.answer2 = []
+                    }
+                    return item3
+                  })
+                }
+              return (item2.ttype != 1 && item2.array.length > 0) || (item2.ttype == 1)
+            })
+          }
+          if (item.ttype == 1 && item.json && !item.json.answer2) {
+            item.json.answer2 = []
+          }
+          console.log(item.array);
+          return (item.ttype != 1 && item.array.length > 0) || (item.ttype == 1)
+        })
+        console.log(checkArray);
+        return checkArray
+      } else {
+        return []
+      }
+    }
+  },
+  mounted() {
+    this.checkArray = this.setJson(this.depthCopy(this.cJson))
+  },
+}
+</script>
+
+<style scoped>
+.c_box {
+  width: 95%;
+  margin: 0 auto;
+  background: #fff;
+  height: calc(100% - 50px);
+  overflow: auto;
+}
+
+.c_box_title {
+  width: 90%;
+  text-align: center;
+  font-size: 24px;
+  font-weight: bold;
+  word-break: break-all;
+  margin: 20px;
+}
+
+.c_body {
+  width: 90%;
+  margin: 0 auto;
+}
+
+.check_box{
+
+}
+.check_box + .check_box{
+  margin-top: 10px;
+}
+.check_box > .title{
+  font-size:20px;
+  word-break: break-all;
+  font-weight: bold;
+}
+.check_box > .answerBox{
+  margin-top: 10px;
+
+}
+.check_box > .noanswerBox{
+  margin-top: 10px;
+}
+.check_box_xia{
+  margin-top: 10px;
+}
+
+.check_box_xia > .title{
+  font-size: 18px;
+  font-weight: bold;
+}
+.check_box_xia > .answerBox{
+  margin-top: 10px;
+}
+.check_box_xia > .noanswerBox{
+  margin-top: 10px;
+}
+
+.page{
+  margin: 20px;
+  display: flex;
+  align-items: center;
+}
+
+.p_page{
+  margin: 0 10px;
+}
+</style>

+ 212 - 0
src/components/pages/testStudent/view/preview.vue

@@ -0,0 +1,212 @@
+<template>
+  <div class="pb_content" style="background: #F0F2F5;" v-loading="loading">
+    <div class="pb_content_body" style="position: relative; margin: 0">
+      <div class="right">
+        <div class="courseTop">
+          <div class="stepsNav">
+            <el-breadcrumb separator-class="el-icon-arrow-right">
+              <el-breadcrumb-item :to="{
+                path:
+                  '/testStudent?userid=' +
+                  userid +
+                  '&oid=' +
+                  oid +
+                  '&org=' +
+                  org +
+                  '&role=' +
+                  role,
+              }">评测中心</el-breadcrumb-item>
+              <el-breadcrumb-item>
+                <span style="color: rgb(15, 126, 255)">{{ title }}</span>
+              </el-breadcrumb-item>
+            </el-breadcrumb>
+          </div>
+          <div class="r_pub_button_retrun" @click="retrunCourse">返回</div>
+        </div>
+        <div class="step_box">
+          <div class="edit_top">
+            <div class="op_btn">
+              <el-button type="primary" size="small" @click="save">保存</el-button>
+              <el-button type="primary" size="small" @click="publish">提交</el-button>
+            </div>
+          </div>
+          <topicVue :cJson="cJson" :title="title"></topicVue>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import topicVue from './component/topic.vue';
+export default {
+  components: {
+    topicVue
+  },
+  data() {
+    return {
+      userid: this.$route.query.userid,
+      oid: this.$route.query.oid,
+      org: this.$route.query.org,
+      role: this.$route.query.role,
+      cid: this.$route.query.cid,
+      steps: 1,
+      title: "",
+      testType: [],
+      see: false,
+      cJson: [],
+      loading: false,
+      look: "",
+    }
+  },
+  methods: {
+    retrunCourse() {
+      this
+        .$confirm("是否确认返回?", "提示", {
+          confirmButtonText: "确认",
+          cancelButtonText: "取消",
+          distinguishCancelAndClose: true,
+          type: "warning",
+        })
+        .then(() => {
+          this.goTo(
+            "/testStudent?userid=" +
+            this.userid +
+            "&oid=" +
+            this.oid +
+            "&org=" +
+            this.org +
+            "&role=" +
+            this.role
+          );
+        })
+        .catch((v) => {
+
+        });
+    },
+    goTo(path) {
+      this.$router.push(path);
+    },
+
+    getData() {
+      this.loading = true
+      let params = {
+        cid: this.cid,
+      };
+      this.ajax
+        .get(this.$store.state.api + "getTestCourseDetail", params)
+        .then((res) => {
+          this.cJson = JSON.parse(res.data[0][0].chapters);
+          this.$forceUpdate();
+          this.title = res.data[0][0].title;
+
+          this.see = res.data[0][0].open == 1 ? true : false;
+
+
+          this.testType = [];
+          for (var i = 0; i < res.data[1].length; i++) {
+            this.testType.push(res.data[1][i].typeid);
+          }
+          console.log(this.testType);
+          this.look = res.data[0][0].look
+          this.loading = false
+
+        })
+        .catch((err) => {
+          console.error(err);
+        });
+    },
+    save(){
+      this.$message.success('保存成功')
+      this.goTo(
+            "/testStudent?userid=" +
+            this.userid +
+            "&oid=" +
+            this.oid +
+            "&org=" +
+            this.org +
+            "&role=" +
+            this.role
+          );
+    },
+    publish(){
+      this.$message.success('提交成功')
+      this.goTo(
+            "/testStudent?userid=" +
+            this.userid +
+            "&oid=" +
+            this.oid +
+            "&org=" +
+            this.org +
+            "&role=" +
+            this.role
+          );
+    },
+
+  },
+  mounted() {
+    this.getData();
+  },
+}
+</script>
+
+<style scoped>
+.pb_content {
+  height: 100% !important;
+  /* margin: 0 20px 0 20px; */
+}
+
+.pb_content_body {
+  width: 100% !important;
+  height: 100%;
+}
+
+.right {
+  height: 100%;
+  width: 100%;
+  display: flex;
+  overflow: hidden;
+  flex-direction: column;
+}
+
+.basic_box {
+  margin: 0 auto;
+  position: relative;
+  padding: 0 20px 0 20px;
+}
+
+.courseTop {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  align-items: center;
+  width: calc(100% - 40px);
+  margin: 0 auto;
+  padding: 10px 0;
+}
+
+.stepsNav {
+  display: flex;
+  flex-direction: row;
+  justify-content: flex-start;
+  align-items: center;
+}
+
+.step_box {
+  width: calc(100%);
+  margin: 0 auto;
+  height: calc(100% - 38px);
+}
+
+.edit_top {
+  height: 50px;
+  background: #fff;
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+  position: relative;
+  padding: 0 30px;
+  border-top: 2px solid #eee;
+  border-bottom: 2px solid #eee;
+}
+</style>

+ 36 - 8
src/components/tools/sunburst.vue

@@ -4,11 +4,7 @@
       <img src="../../assets/nominddata.png" alt />
     </div>
     <!-- <img src="../../assets/dataimage/1.png" style="width:90%" /> -->
-    <div
-      id="charts_canvas"
-      class="echart"
-      style="width: 100%; height: 100%"
-    ></div>
+    <div id="charts_canvas" class="echart" style="width: 100%; height: 100%"></div>
   </div>
 </template>
 
@@ -22,12 +18,43 @@ export default {
       timer: null,
       ooption: [],
       option: {
+        tooltip: {
+          formatter: function (params) {
+            var newParamsName = "";
+            var paramsNameNumber = params.name.length;
+            var provideNumber = 20;  //一行显示几个字
+            var rowNumber = Math.ceil(paramsNameNumber / provideNumber);
+            if (paramsNameNumber > provideNumber) {
+              for (var p = 0; p <rowNumber; p++) {
+                var tempStr = "";
+                var start = p * provideNumber;
+                var end = start + provideNumber;
+                if (p == rowNumber - 1) {
+                  tempStr = params.name.substring(start, paramsNameNumber);
+                } else {
+                  tempStr = params.name.substring(start, end) + "</br>";
+                }
+                newParamsName += tempStr;
+              }
+
+            } else {
+              newParamsName = params.name;
+            }
+            return newParamsName
+          }
+        },
         series: {
           type: "sunburst",
           data: [],
           radius: [30, "90%"],
           label: {
             rotate: "radial",
+            formatter: function (val) {
+              // console.log(val);
+              return val.name.length > 5
+                ? val.name.substring(0, 6) + '...'
+                : val.name;
+            }
           },
         },
       },
@@ -69,7 +96,7 @@ export default {
         _array.push({ name: _item.name, value: count, children: [] });
         let j = 0;
         for (var item2 in _item.child) {
-          let num2 = Object.keys( _item.child);
+          let num2 = Object.keys(_item.child);
           let count2 = count / num2.length;
           let _item2 = _item.child[item2];
           _array[i].children.push({
@@ -78,7 +105,7 @@ export default {
             children: [],
           });
           for (var item3 in _item2.child) {
-            let num3 = Object.keys( _item2.child);
+            let num3 = Object.keys(_item2.child);
             let count3 = count2 / num3.length;
             let _item3 = _item2.child[item3];
             _array[i].children[j].children.push({
@@ -108,7 +135,7 @@ export default {
       deep: true,
     },
     Josn: {
-      handler: function (newVal, oldVal) {},
+      handler: function (newVal, oldVal) { },
       deep: true,
     },
   },
@@ -146,6 +173,7 @@ export default {
   flex-shrink: 0;
   position: relative;
 }
+
 .noMind {
   position: absolute;
   display: flex;

+ 37 - 5
src/router/index.js

@@ -97,6 +97,10 @@ import addCourseT from '@/components/pages/task/addCourse'
 import dataBoard from '@/components/pages/dataBoard'
 import addSynergyCourse from '@/components/pages/synergyCourse/addCourse'
 import synergyCourse from '@/components/pages/synergyCourse/course'
+import test from '@/components/pages/test/index'
+import addTest from '@/components/pages/test/add/addTest'
+import testStudent from '@/components/pages/testStudent/index'
+import doTest from '@/components/pages/testStudent/view/preview'
 
 
 // 全局修改默认配置,点击空白处不能关闭弹窗
@@ -111,7 +115,7 @@ export default new Router({
             meta: {
                 requireAuth: ''
             }
-        }, 
+        },
         {
             path: '/grade',
             name: 'grade',
@@ -119,14 +123,14 @@ export default new Router({
             meta: {
                 requireAuth: ''
             }
-        },{
+        }, {
             path: '/teacherOffice',
             name: 'teacherOffice',
             component: teacherOffice,
             meta: {
                 requireAuth: ''
             }
-        }, 
+        },
         {
             path: '/classGM',
             name: 'classGM',
@@ -497,14 +501,14 @@ export default new Router({
             meta: {
                 requireAuth: '' // 不需要鉴权
             }
-        },{
+        }, {
             path: '/Ttype2Studio',
             name: 'Ttype2Studio',
             component: Ttype2Studio,
             meta: {
                 requireAuth: '' // 不需要鉴权
             }
-        },{
+        }, {
             path: '/TtypeOrg',
             name: 'TtypeOrg',
             component: TtypeOrg,
@@ -832,6 +836,34 @@ export default new Router({
                 requireAuth: '' // 是否需要判断是否登录,这里是需要判断
             }
         },
+        {
+            path: '/test',
+            component: test,
+            meta: {
+                requireAuth: '' // 是否需要判断是否登录,这里是需要判断
+            }
+        },
+        {
+            path: '/testStudent',
+            component: testStudent,
+            meta: {
+                requireAuth: '' // 是否需要判断是否登录,这里是需要判断
+            }
+        },
+        {
+            path: '/doTest',
+            component: doTest,
+            meta: {
+                requireAuth: '' // 是否需要判断是否登录,这里是需要判断
+            }
+        },
+        {
+            path: '/addTest',
+            component: addTest,
+            meta: {
+                requireAuth: '' // 是否需要判断是否登录,这里是需要判断
+            }
+        },
         {
             path: '/synergyCourse/add',
             component: addSynergyCourse,

Some files were not shown because too many files changed in this diff