瀏覽代碼

Merge branch 'beta' into HK

lsc 10 月之前
父節點
當前提交
04ed01f03b
共有 38 個文件被更改,包括 5536 次插入1568 次删除
  1. 4 0
      dist/index.html
  2. 0 0
      dist/static/css/app.eca8c790dce1209ec8667c6b5b52d134.css
  3. 0 0
      dist/static/css/app.eca8c790dce1209ec8667c6b5b52d134.css.map
  4. 二進制
      dist/static/img/aiImage.c4ce77d.png
  5. 二進制
      dist/static/img/aiImage2.13de0f5.png
  6. 6 0
      dist/static/img/logo2.4f91689.svg
  7. 1 0
      dist/static/js/app.837c34481b28b3e9e385.js
  8. 0 0
      dist/static/js/app.837c34481b28b3e9e385.js.map
  9. 1 0
      dist/static/js/app.ddad82df5f4e10f122b5.js
  10. 1 0
      dist/static/js/app.ddad82df5f4e10f122b5.js.map
  11. 0 0
      dist/static/js/manifest.0ad6c5648a38a6d1fa8f.js.map
  12. 8 0
      src/App.vue
  13. 二進制
      src/assets/icon/classroomObservation/aiImage2.png
  14. 5 0
      src/assets/icon/classroomObservation/courseIcon.svg
  15. 6 0
      src/assets/icon/classroomObservation/del2.svg
  16. 4 0
      src/assets/icon/classroomObservation/editIcon2.svg
  17. 5 0
      src/assets/icon/classroomObservation/moreIcon.svg
  18. 二進制
      src/assets/icon/classroomObservation/startPageIcon1.png
  19. 二進制
      src/assets/icon/classroomObservation/startPageIcon2.png
  20. 5 0
      src/assets/icon/exportPdfworks/infocircle.svg
  21. 二進制
      src/assets/icon/exportPdfworks/title.png
  22. 585 48
      src/components/pages/aiAddCourse/addCourse.vue
  23. 370 191
      src/components/pages/aiAddCourse/aiBoxRight.vue
  24. 861 28
      src/components/pages/classroomObservation/components/addNewAnalysisDialog.vue
  25. 169 0
      src/components/pages/classroomObservation/components/addNewTeacherVoiceprintDialog.vue
  26. 265 18
      src/components/pages/classroomObservation/components/analysis.vue
  27. 130 9
      src/components/pages/classroomObservation/components/analysisItem.vue
  28. 102 7
      src/components/pages/classroomObservation/components/analysisSpecialItem.vue
  29. 7 4
      src/components/pages/classroomObservation/components/analysisTemplateDialog.vue
  30. 33 8
      src/components/pages/classroomObservation/components/baseMessage.vue
  31. 110 9
      src/components/pages/classroomObservation/components/chatArea.vue
  32. 81 0
      src/components/pages/classroomObservation/components/editNameDialog.vue
  33. 956 1087
      src/components/pages/classroomObservation/components/messageArea.vue
  34. 213 127
      src/components/pages/classroomObservation/components/startPage.vue
  35. 5 5
      src/components/pages/classroomObservation/index.vue
  36. 1505 0
      src/components/pages/components/exportDataDialog.vue
  37. 10 3
      src/components/pages/components/exportWorksDialog.vue
  38. 88 24
      src/components/pages/works.vue

+ 4 - 0
dist/index.html

@@ -32,7 +32,11 @@
       width: 100%;
       background: #e6eaf0;
       font-family: '黑体';
+<<<<<<< HEAD
     }</style><link href=./static/css/app.028f680cc9289ff688aa089a80bc9952.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.0ad6c5648a38a6d1fa8f.js></script><script type=text/javascript src=./static/js/vendor.a82b79982b082928b294.js></script><script type=text/javascript src=./static/js/app.837c34481b28b3e9e385.js></script></body></html><script>function stopSafari() {
+=======
+    }</style><link href=./static/css/app.eca8c790dce1209ec8667c6b5b52d134.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.571c38d63f24b1ae9e16.js></script><script type=text/javascript src=./static/js/vendor.a82b79982b082928b294.js></script><script type=text/javascript src=./static/js/app.ddad82df5f4e10f122b5.js></script></body></html><script>function stopSafari() {
+>>>>>>> beta
     //阻止safari浏览器双击放大功能
     let lastTouchEnd = 0  //更新手指弹起的时间
     document.documentElement.addEventListener("touchstart", function (event) {

文件差異過大導致無法顯示
+ 0 - 0
dist/static/css/app.eca8c790dce1209ec8667c6b5b52d134.css


文件差異過大導致無法顯示
+ 0 - 0
dist/static/css/app.eca8c790dce1209ec8667c6b5b52d134.css.map


二進制
dist/static/img/aiImage.c4ce77d.png


二進制
dist/static/img/aiImage2.13de0f5.png


文件差異過大導致無法顯示
+ 6 - 0
dist/static/img/logo2.4f91689.svg


文件差異過大導致無法顯示
+ 1 - 0
dist/static/js/app.837c34481b28b3e9e385.js


文件差異過大導致無法顯示
+ 0 - 0
dist/static/js/app.837c34481b28b3e9e385.js.map


文件差異過大導致無法顯示
+ 1 - 0
dist/static/js/app.ddad82df5f4e10f122b5.js


文件差異過大導致無法顯示
+ 1 - 0
dist/static/js/app.ddad82df5f4e10f122b5.js.map


文件差異過大導致無法顯示
+ 0 - 0
dist/static/js/manifest.0ad6c5648a38a6d1fa8f.js.map


+ 8 - 0
src/App.vue

@@ -517,4 +517,12 @@ html::-webkit-scrollbar-thumb {
   display: flex;
   justify-content: flex-end;
 }
+
+.el-message-box__wrapper{
+  z-index: 9999999 !important;
+}
+.el-message-box__wrapper + .v-modal{
+  z-index: 9999998 !important;
+
+}
 </style>

二進制
src/assets/icon/classroomObservation/aiImage2.png


+ 5 - 0
src/assets/icon/classroomObservation/courseIcon.svg

@@ -0,0 +1,5 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M2.5 14.5V5.5V4H5.5H8.5H13.5V14.5H2.5Z" fill="#3681FC"/>
+<path d="M13.5 1.5H3.5C2.94771 1.5 2.5 1.94772 2.5 2.5V4M2.5 4H5.5M2.5 4L2.5 5.5V14.5H13.5V4H8.5M5.5 4V9.5L7 8.5L8.5 9.5V4M5.5 4H8.5" stroke="#3681FC" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M8.5 4.5H5.5V9.5L7 8.5L8.5 9.5V4.5Z" fill="white"/>
+</svg>

+ 6 - 0
src/assets/icon/classroomObservation/del2.svg

@@ -0,0 +1,6 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M6.25 3.125C6.25 2.77982 6.52982 2.5 6.875 2.5H13.125C13.4702 2.5 13.75 2.77982 13.75 3.125C13.75 3.47018 13.4702 3.75 13.125 3.75H6.875C6.52982 3.75 6.25 3.47018 6.25 3.125Z" fill="black" fill-opacity="0.6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M2.5 5.625C2.5 5.26481 2.77982 5 3.125 5H16.875C17.2202 5 17.5 5.26481 17.5 5.625C17.5 6.03952 17.2202 6.25 16.875 6.25L15.625 6.30435V17.5H4.375V6.25H3.125C2.77982 6.25 2.5 6.03952 2.5 5.625ZM5.625 6.25V16.1957L14.375 16.25V6.30435L5.625 6.25Z" fill="black" fill-opacity="0.6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M8.125 8.06838C8.47018 8.06838 8.75 8.32276 8.75 8.63656V13.7502C8.75 14.064 8.47018 14.3184 8.125 14.3184C7.77982 14.3184 7.5 14.064 7.5 13.7502V8.63656C7.5 8.32276 7.77982 8.06838 8.125 8.06838Z" fill="black" fill-opacity="0.6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M11.875 8.06838C12.2202 8.06838 12.5 8.32276 12.5 8.63656V13.7502C12.5 14.064 12.2202 14.3184 11.875 14.3184C11.5298 14.3184 11.25 14.064 11.25 13.7502V8.63656C11.25 8.32276 11.5298 8.06838 11.875 8.06838Z" fill="black" fill-opacity="0.6"/>
+</svg>

+ 4 - 0
src/assets/icon/classroomObservation/editIcon2.svg

@@ -0,0 +1,4 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M2 2.5C2 2.22386 2.22386 2 2.5 2H8.5C8.77614 2 9 2.22386 9 2.5C9 2.77614 8.77614 3 8.5 3H3V13H13V8.5C13 8.22386 13.2239 8 13.5 8C13.7761 8 14 8.22386 14 8.5V13.5C14 13.7761 13.7761 14 13.5 14H2.5C2.22386 14 2 13.7761 2 13.5V2.5Z" fill="black" fill-opacity="0.4"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M13.8536 2.14645C14.0488 2.34171 14.0488 2.65829 13.8536 2.85355L7.85355 8.85355C7.65829 9.04882 7.34171 9.04882 7.14645 8.85355C6.95118 8.65829 6.95118 8.34171 7.14645 8.14645L13.1464 2.14645C13.3417 1.95118 13.6583 1.95118 13.8536 2.14645Z" fill="black" fill-opacity="0.4"/>
+</svg>

+ 5 - 0
src/assets/icon/classroomObservation/moreIcon.svg

@@ -0,0 +1,5 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M5.25 11.9997C5.25 12.3975 5.40802 12.779 5.6893 13.0603C5.97058 13.3416 6.35208 13.4996 6.74987 13.4996C7.14766 13.4996 7.52915 13.3416 7.81043 13.0603C8.09171 12.779 8.24973 12.3975 8.24973 11.9997C8.24973 11.6019 8.09171 11.2204 7.81043 10.9392C7.52915 10.6579 7.14766 10.4999 6.74987 10.4999C6.35208 10.4999 5.97058 10.6579 5.6893 10.9392C5.40802 11.2204 5.25 11.6019 5.25 11.9997Z" fill="black" fill-opacity="0.9"/>
+<path d="M10.5 11.9997C10.5 12.3975 10.658 12.779 10.9393 13.0603C11.2206 13.3416 11.6021 13.4996 11.9999 13.4996C12.3977 13.4996 12.7792 13.3416 13.0604 13.0603C13.3417 12.779 13.4997 12.3975 13.4997 11.9997C13.4997 11.6019 13.3417 11.2204 13.0604 10.9392C12.7792 10.6579 12.3977 10.4999 11.9999 10.4999C11.6021 10.4999 11.2206 10.6579 10.9393 10.9392C10.658 11.2204 10.5 11.6019 10.5 11.9997Z" fill="black" fill-opacity="0.9"/>
+<path d="M15.75 11.9997C15.75 12.3975 15.908 12.779 16.1893 13.0603C16.4706 13.3416 16.8521 13.4996 17.2499 13.4996C17.6477 13.4996 18.0292 13.3416 18.3104 13.0603C18.5917 12.779 18.7497 12.3975 18.7497 11.9997C18.7497 11.6019 18.5917 11.2204 18.3104 10.9392C18.0292 10.6579 17.6477 10.4999 17.2499 10.4999C16.8521 10.4999 16.4706 10.6579 16.1893 10.9392C15.908 11.2204 15.75 11.6019 15.75 11.9997Z" fill="black" fill-opacity="0.9"/>
+</svg>

二進制
src/assets/icon/classroomObservation/startPageIcon1.png


二進制
src/assets/icon/classroomObservation/startPageIcon2.png


+ 5 - 0
src/assets/icon/exportPdfworks/infocircle.svg

@@ -0,0 +1,5 @@
+<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M5.62921 8.99982V4.875H6.37921V8.99982H5.62921Z" fill="black" fill-opacity="0.6"/>
+<path d="M6.44989 3H5.54993V3.89996H6.44989V3Z" fill="black" fill-opacity="0.6"/>
+<path d="M0.75 6C0.75 8.89948 3.10052 11.25 6 11.25C8.89948 11.25 11.25 8.89948 11.25 6C11.25 3.10052 8.89948 0.75 6 0.75C3.10052 0.75 0.75 3.10052 0.75 6ZM1.5 6C1.5 3.51471 3.51471 1.5 6 1.5C8.48529 1.5 10.5 3.51471 10.5 6C10.5 8.48529 8.48529 10.5 6 10.5C3.51471 10.5 1.5 8.48529 1.5 6Z" fill="black" fill-opacity="0.6"/>
+</svg>

二進制
src/assets/icon/exportPdfworks/title.png


文件差異過大導致無法顯示
+ 585 - 48
src/components/pages/aiAddCourse/addCourse.vue


+ 370 - 191
src/components/pages/aiAddCourse/aiBoxRight.vue

@@ -10,25 +10,17 @@
         </div>
         <div style="margin-top:20px;margin-bottom:20px ; margin-right: auto;">
           <div class="role">
-            <img
-              :src="
-                item.fileid
-                  ? item.fileid
-                  : require('../../../assets/icon/new/role1.png')
-              "
-            />
+            <img :src="item.fileid
+                ? item.fileid
+                : require('../../../assets/icon/new/role1.png')
+              " />
           </div>
-          <div
-            element-loading-background="#f6f9ff"
-            :style="{
-              minHeight: item.loading ? '50px' : 'unset',
-              minWidth: item.loading ? '50px' : 'unset'
-            }"
-            class="content"
-            v-loading="item.loading"
-          >
-            <span class="vditor-reset" v-html="item.aiContent"></span
-            ><span class="createTime" v-text="item.createtime"></span>
+          <div element-loading-background="#f6f9ff" :style="{
+            minHeight: item.loading ? '50px' : 'unset',
+            minWidth: item.loading ? '50px' : 'unset'
+          }" class="content" v-loading="item.loading">
+            <span class="vditor-reset" v-html="item.aiContent"></span><span class="createTime"
+              v-text="item.createtime"></span>
           </div>
         </div>
       </div>
@@ -40,27 +32,14 @@
           <div class="content">
             <div class="span" @click="addAllTask()">
               <div class="check">
-                <img
-                  :src="checkImg"
-                  alt=""
-                  v-if="checkArray.length !== course.length"
-                />
+                <img :src="checkImg" alt="" v-if="checkArray.length !== course.length" />
                 <img :src="checkIsImg" alt="" v-else />
               </div>
               <span>全选</span>
             </div>
-            <div
-              class="span"
-              v-for="(item, index) in course"
-              :key="index"
-              @click="addTask(index)"
-            >
+            <div class="span" v-for="(item, index) in course" :key="index" @click="addTask(index)">
               <div class="check">
-                <img
-                  :src="checkImg"
-                  alt=""
-                  v-if="checkArray.indexOf(index) === -1"
-                />
+                <img :src="checkImg" alt="" v-if="checkArray.indexOf(index) === -1" />
                 <img :src="checkIsImg" alt="" v-else />
               </div>
               <span>任务{{ index + 1 }}</span>
@@ -70,31 +49,16 @@
         <div class="part">
           <div class="title">选择优化的部分:</div>
           <div class="content">
-            <div
-              class="span"
-              v-for="(item, index) in partArray"
-              :key="index"
-              :class="{ active: part == item.name }"
-              @click="checkPart(item.name)"
-            >
+            <div class="span" v-for="(item, index) in partArray" :key="index" :class="{ active: part == item.name }"
+              @click="checkPart(item.name)">
               {{ item.name }}
             </div>
           </div>
         </div>
       </div>
-      <span
-        class="check"
-        :class="{ isCheck: checkBool }"
-        v-if="!checkArray.length && !part"
-        @click="checkBool = !checkBool"
-        >选择优化内容</span
-      >
-      <span
-        class="check"
-        :class="{ isCheck: checkBool }"
-        @click="checkBool = !checkBool"
-        v-else
-      >
+      <span class="check" :class="{ isCheck: checkBool }" v-if="!checkArray.length && !part"
+        @click="checkBool = !checkBool">选择优化内容</span>
+      <span class="check" :class="{ isCheck: checkBool }" @click="checkBool = !checkBool" v-else>
         <el-tooltip :content="taskName" placement="top" effect="dark">
           <!-- content to trigger tooltip here -->
           <span>{{ taskName }}</span>
@@ -103,68 +67,39 @@
     </div>
     <div class="ai_body_input">
       <div class="ai_b_i_btnArea">
-        <span @click.stop="clear()">
-          <svg
-            width="20"
-            height="20"
-            viewBox="0 0 20 20"
-            fill="none"
-            xmlns="http://www.w3.org/2000/svg"
-          >
-            <path
-              fill-rule="evenodd"
-              clip-rule="evenodd"
-              d="M2.5 3.125C2.5 2.77982 2.77982 2.5 3.125 2.5H16.875C17.2202 2.5 17.5 2.77982 17.5 3.125V8.02715C17.5 8.37233 17.2202 8.65215 16.875 8.65215C16.5298 8.65215 16.25 8.37233 16.25 8.02715V3.75H3.75V16.25H8.125C8.47018 16.25 8.75 16.5298 8.75 16.875C8.75 17.2202 8.47018 17.5 8.125 17.5H3.125C2.77982 17.5 2.5 17.2202 2.5 16.875V3.125Z"
-            />
-            <path
-              fill-rule="evenodd"
-              clip-rule="evenodd"
-              d="M5.625 6.1521C5.625 5.80692 5.90482 5.5271 6.25 5.5271H13.125C13.4702 5.5271 13.75 5.80692 13.75 6.1521C13.75 6.49728 13.4702 6.7771 13.125 6.7771H6.25C5.90482 6.7771 5.625 6.49728 5.625 6.1521Z"
-            />
-            <path
-              fill-rule="evenodd"
-              clip-rule="evenodd"
-              d="M5.625 9.2771C5.625 8.93192 5.90482 8.6521 6.25 8.6521H9.37496C9.72014 8.6521 9.99996 8.93192 9.99996 9.2771C9.99996 9.62228 9.72014 9.9021 9.37496 9.9021H6.25C5.90482 9.9021 5.625 9.62228 5.625 9.2771Z"
-            />
-            <path
-              fill-rule="evenodd"
-              clip-rule="evenodd"
-              d="M12.465 11.507L15.9141 14.9048C16.1279 14.5365 16.25 14.1088 16.25 13.6521C16.25 12.2714 15.1307 11.1521 13.75 11.1521C13.2799 11.1521 12.8406 11.2815 12.465 11.507ZM15.0374 15.7957L11.5873 12.397C11.3726 12.7659 11.25 13.1944 11.25 13.6521C11.25 15.0328 12.3693 16.1521 13.75 16.1521C14.2211 16.1521 14.6613 16.0222 15.0374 15.7957ZM11.0797 11.0192C11.759 10.3303 12.7051 9.9021 13.75 9.9021C15.8211 9.9021 17.5 11.581 17.5 13.6521C17.5 14.6767 17.0882 15.6064 16.4226 16.2827C15.7431 16.9729 14.7961 17.4021 13.75 17.4021C11.6789 17.4021 10 15.7232 10 13.6521C10 12.6263 10.4127 11.6957 11.0797 11.0192Z"
-            />
+        <span class="clear" @click.stop="clear()">
+          <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+            <path fill-rule="evenodd" clip-rule="evenodd"
+              d="M2.5 3.125C2.5 2.77982 2.77982 2.5 3.125 2.5H16.875C17.2202 2.5 17.5 2.77982 17.5 3.125V8.02715C17.5 8.37233 17.2202 8.65215 16.875 8.65215C16.5298 8.65215 16.25 8.37233 16.25 8.02715V3.75H3.75V16.25H8.125C8.47018 16.25 8.75 16.5298 8.75 16.875C8.75 17.2202 8.47018 17.5 8.125 17.5H3.125C2.77982 17.5 2.5 17.2202 2.5 16.875V3.125Z" />
+            <path fill-rule="evenodd" clip-rule="evenodd"
+              d="M5.625 6.1521C5.625 5.80692 5.90482 5.5271 6.25 5.5271H13.125C13.4702 5.5271 13.75 5.80692 13.75 6.1521C13.75 6.49728 13.4702 6.7771 13.125 6.7771H6.25C5.90482 6.7771 5.625 6.49728 5.625 6.1521Z" />
+            <path fill-rule="evenodd" clip-rule="evenodd"
+              d="M5.625 9.2771C5.625 8.93192 5.90482 8.6521 6.25 8.6521H9.37496C9.72014 8.6521 9.99996 8.93192 9.99996 9.2771C9.99996 9.62228 9.72014 9.9021 9.37496 9.9021H6.25C5.90482 9.9021 5.625 9.62228 5.625 9.2771Z" />
+            <path fill-rule="evenodd" clip-rule="evenodd"
+              d="M12.465 11.507L15.9141 14.9048C16.1279 14.5365 16.25 14.1088 16.25 13.6521C16.25 12.2714 15.1307 11.1521 13.75 11.1521C13.2799 11.1521 12.8406 11.2815 12.465 11.507ZM15.0374 15.7957L11.5873 12.397C11.3726 12.7659 11.25 13.1944 11.25 13.6521C11.25 15.0328 12.3693 16.1521 13.75 16.1521C14.2211 16.1521 14.6613 16.0222 15.0374 15.7957ZM11.0797 11.0192C11.759 10.3303 12.7051 9.9021 13.75 9.9021C15.8211 9.9021 17.5 11.581 17.5 13.6521C17.5 14.6767 17.0882 15.6064 16.4226 16.2827C15.7431 16.9729 14.7961 17.4021 13.75 17.4021C11.6789 17.4021 10 15.7232 10 13.6521C10 12.6263 10.4127 11.6957 11.0797 11.0192Z" />
           </svg>
           <span>清屏</span>
         </span>
-        <div>
+        <span class="clear" @click.stop="showjList = !showjList" v-if="jArray.length">
+          <span>查看</span>
+        </span>
+        <div style="margin-left: auto;">
           <el-switch v-model="continuous"></el-switch>
           <span @click.stop="continuous = !continuous">连续对话</span>
         </div>
       </div>
 
-      <div
-        class="ai_b_i_roleListBox"
-        ref="roleListRef"
-        v-if="showRoleList && choseRoleList.length > 0"
-      >
-        <div
-          :class="[
-            'ai_b_i_rlb_item',
-            index == choseRoleItem ? 'ai_b_i_rlb_itemActive' : ''
-          ]"
-          :ref="`roleItem${index}Ref`"
-          v-for="(item, index) in choseRoleList"
-          :key="item.id"
-          @mouseover="choseRoleItem = index"
-          @click.stop="choseRole(item)"
-        >
+      <div class="ai_b_i_roleListBox" ref="roleListRef" v-if="showRoleList && choseRoleList.length > 0">
+        <div :class="[
+          'ai_b_i_rlb_item',
+          index == choseRoleItem ? 'ai_b_i_rlb_itemActive' : ''
+        ]" :ref="`roleItem${index}Ref`" v-for="(item, index) in choseRoleList" :key="item.id"
+          @mouseover="choseRoleItem = index" @click.stop="choseRole(item)">
           <div class="ai_b_i_rlb_itemTop">
-            <img
-              :src="
-                item.headUrl
-                  ? item.headUrl
-                  : require('../../../assets/icon/new/role1.png')
-              "
-              alt=""
-            />
+            <img :src="item.headUrl
+                ? item.headUrl
+                : require('../../../assets/icon/new/role1.png')
+              " alt="" />
             <div class="ai_b_i_rlb_i_name">
               <span>{{ item.assistantName }}</span>
               <span>作者:{{ item.username }}</span>
@@ -175,28 +110,28 @@
           </div>
         </div>
       </div>
-
+      <div class="ai_b_i_jListPanel" @click="showjList = !showjList" v-if="showjList && jArray.length > 0"></div>
+      <div class="ai_b_i_jListBox" v-if="showjList && jArray.length > 0">
+        <div class="jlist_box" v-for="(item, index) in jArray" :key="index">
+          <el-tooltip :content="item.area + ':' + item.value" placement="top" effect="dark" popper-class="text_tooltip2">
+            <!-- content to trigger tooltip here -->
+            <span>{{ item.area }}:{{ item.value }}</span>
+          </el-tooltip>
+          <div class="cancel" @click="cancelJ(item.string)">×</div>
+        </div>
+      </div>
       <!-- <div class="ai_b_i_textListBox">
 				<div class="ai_b_i_tlb_left"></div>
 				<div class="ai_b_i_tlb_right"></div>
 			</div> -->
       <!-- @input="inputChange" -->
 
-      <textarea
-        class="ai_body_input_textarea"
-        @keydown="textareaKeydown"
-        ref="textareaRef"
-        v-model.trim="courseText"
-        placeholder="在此输入您想了解的内容"
-      ></textarea>
-      <div
-        :class="[
-          'c_pub_button_confirm',
-          courseText ? '' : 'c_pub_button_confirmDisabled'
-        ]"
-        v-if="!loading"
-        @click="addContent"
-      >
+      <textarea class="ai_body_input_textarea" @keydown="textareaKeydown" ref="textareaRef" v-model.trim="courseText"
+        placeholder="在此输入您想了解的内容"></textarea>
+      <div :class="[
+        'c_pub_button_confirm',
+        courseText ? '' : 'c_pub_button_confirmDisabled'
+      ]" v-if="!loading" @click="addContent">
         发送
       </div>
     </div>
@@ -235,11 +170,40 @@ export default {
     courseId: {
       type: String,
       default: ""
-    }
+    },
+    quoteArray: {
+      type: Object,
+      default: function () {
+        return {};
+      }
+    },
+    teacherCourseText: {
+      type: String,
+      default: ""
+    },
+    targetCourseText: {
+      type: String,
+      default: ""
+    },
+    courseText2: {
+      type: String,
+      default: ""
+    },
+    targetCourseText2: {
+      type: String,
+      default: ""
+    },
+    cpote: {
+      type: Object,
+      default: function () {
+        return {};
+      }
+    },
   },
   data() {
     return {
       array: [],
+      jArray: [],
       courseText: "",
       checkImg: checkImg,
       checkIsImg: checkIsImg,
@@ -322,7 +286,8 @@ export default {
       showRoleList: false,
       choseRoleItem: 0,
       choseTextItem: 0,
-      continuous: false
+      continuous: false,
+      showjList: false
     };
   },
   watch: {
@@ -331,6 +296,10 @@ export default {
       deep: true,
       handler(newValue, oldValue) {
         this.course = this.unitJson[0].chapterInfo[0].taskJson;
+        this.jArray = this.getString();
+        if (!this.jArray.length) {
+          this.showjList = false
+        }
       }
     },
     courseId: {
@@ -346,9 +315,135 @@ export default {
           });
         }
       }
-    }
+    },
+    quoteArray: {
+      immediate: true,
+      deep: true,
+      handler(newValue, oldValue) {
+        this.jArray = this.getString();
+        if (!this.jArray.length) {
+          this.showjList = false
+        }
+      }
+    },
+    teacherCourseText: {
+      immediate: true,
+      deep: true,
+      handler(newValue, oldValue) {
+        this.jArray = this.getString();
+        if (!this.jArray.length) {
+          this.showjList = false
+        }
+      }
+    },
+    targetCourseText: {
+      immediate: true,
+      deep: true,
+      handler(newValue, oldValue) {
+        this.jArray = this.getString();
+        if (!this.jArray.length) {
+          this.showjList = false
+        }
+      }
+    },
+    courseText2: {
+      immediate: true,
+      deep: true,
+      handler(newValue, oldValue) {
+        this.jArray = this.getString();
+        if (!this.jArray.length) {
+          this.showjList = false
+        }
+      }
+    },
+    targetCourseText2: {
+      immediate: true,
+      deep: true,
+      handler(newValue, oldValue) {
+        this.jArray = this.getString();
+        if (!this.jArray.length) {
+          this.showjList = false
+        }
+      }
+    },
+    cpote: {
+      immediate: true,
+      deep: true,
+      handler(newValue, oldValue) {
+        this.jArray = this.getString();
+        if (!this.jArray.length) {
+          this.showjList = false
+        }
+      }
+    },
   },
   methods: {
+    cancelJ(string) {
+      this.$emit('setIsQuote', string)
+    },
+    getString() {
+      let quoteArray = []
+      let array = Object.keys(this.quoteArray)
+      array.forEach(item => {
+        if (!this.quoteArray[item]) {
+          return
+        }
+        let string = item
+        let area = ''
+        let text = ''
+        if (string == 'aiteacherTextDetail') {
+          area = '已有教案摘要'
+          text = this.teacherCourseText
+        } else if (string == 'aitargetTextDetail') {
+          area = '课程目标'
+          text = this.targetCourseText
+        } else if (string == 'aiDetail') {
+          area = '课程简要描述'
+          text = this.courseText2
+        } else if (string == 'aitargetTextDetail2') {
+          area = '课程目标'
+          text = this.targetCourseText2
+        } else if (string.indexOf('aiDetail1') != -1) {
+          let index = parseInt(string.split('aiDetail1-')[1])
+          area = `任务${index + 1}课程大纲`
+          text = this.unitJson[0].chapterInfo[0].taskJson[index].taskDetail2
+        } else if (string == 'aiCpote1') {
+          area = '概念群'
+          text = this.cpote.cpote1
+        } else if (string == 'aiCpote2') {
+          area = '问题链'
+          text = this.cpote.cpote2
+        } else if (string == 'aiCpote3') {
+          area = '目标层'
+          text = this.cpote.cpote3
+        } else if (string == 'aiCpote4') {
+          area = '任务簇'
+          text = this.cpote.cpote4
+        } else if (string.indexOf('teacherDetail2') != -1) {
+          let index = parseInt(string.split('teacherDetail2-')[1])
+          area = `任务${index + 1}教案`
+          text = this.unitJson[0].chapterInfo[0].taskJson[index].taskDetail3
+        } else if (string.indexOf('aiDetail2') != -1) {
+          let index = parseInt(string.split('aiDetail2-')[1])
+          area = `任务${index + 1}任务描述`
+          text = this.unitJson[0].chapterInfo[0].taskJson[index].taskDetail
+        } else if (string.indexOf('aiDetail3') != -1) {
+          let index = parseInt(string.split('-')[1])
+          let index2 = parseInt(string.split('-')[2])
+          area = `任务${index + 1}工具${index2 + 1}的工具描述`
+          text = this.unitJson[0].chapterInfo[0].taskJson[index].toolChoose[index2].toolDetail
+        }
+
+        quoteArray.push({
+          string,
+          area,
+          value: text
+        })
+      })
+
+      return quoteArray
+
+    },
     promptTit() {
       if (!this.loading && !this.courseText) {
         this.$message({
@@ -365,9 +460,10 @@ export default {
     addContent() {
       let message = this.courseText;
       if (this.courseText) {
-        let msg = `
-          ATTENTION: Use '##' to SPLIT SECTIONS, not '#'.Output format carefully referenced "Format example".`;
+        let msg = ``;
         if (this.checkArray.length) {
+          msg = `
+ATTENTION: Use '##' to SPLIT SECTIONS, not '#'.Output format carefully referenced "Format example".`
           let task = [];
           if (this.part == "全部内容") {
             for (var i = 0; i < this.checkArray.length; i++) {
@@ -387,19 +483,36 @@ export default {
           }
 
           msg += `
-          --------
           ## 修改内容
           ${JSON.stringify(task)}
           `;
 
           msg += `
-          --------
           ## 要求
           ${this.courseText}
           `;
           message = msg;
         }
 
+        if (this.jArray.length) {
+          let task = [];
+          for (var i = 0; i < this.jArray.length; i++) {
+            let _index = this.jArray[i];
+            task.push(`${_index.area}: ${_index.value.replaceAll('\n', '')}`);
+          }
+
+          msg += `
+          ## 参考资料
+          ${task.join('\n')}
+          `;
+
+          msg += `
+          ## 要求
+          根据<参考资料>中的内容实现以下要求:${this.courseText}
+          `;
+          message = msg;
+        }
+
         // 这里处理@的角色
         let _atRoleList = [];
         let _roleList = [...this.roleList, ...this.publicRoleList];
@@ -664,7 +777,7 @@ export default {
       };
       this.ajax
         .post("https://gpt4.cocorobo.cn/insert_chat", params)
-        .then(res => {});
+        .then(res => { });
     },
     // 获取对应的聊天记录
     getChatList() {
@@ -844,7 +957,7 @@ export default {
               this.$message.error("清除聊天记录失败");
             });
         })
-        .catch(_ => {});
+        .catch(_ => { });
     },
     getRoleList() {
       this.roleList = [];
@@ -890,9 +1003,8 @@ export default {
     },
     choseRole(item) {
       let _lastAtIndex = this.courseText.lastIndexOf("@");
-      this.courseText = `${this.courseText.slice(0, _lastAtIndex)}@${
-        item.assistantName
-      } `;
+      this.courseText = `${this.courseText.slice(0, _lastAtIndex)}@${item.assistantName
+        } `;
       this.$refs.textareaRef.focus();
       this.showRoleList = false;
     }
@@ -936,6 +1048,7 @@ export default {
     });
     this.getRoleList();
     this.getPublicRoleList();
+    this.jArray = this.getString();
   }
 };
 </script>
@@ -1019,29 +1132,32 @@ export default {
 }
 
 .ai_b_i_btnArea {
-  width: 100%;
+  width: calc(100% - 10px);
   position: absolute;
   bottom: calc(100% + 5px);
   height: 30px;
   display: flex;
-  justify-content: space-between;
+  /* justify-content: space-between; */
 }
 
-.ai_b_i_btnArea > div {
+.ai_b_i_btnArea>div {
   display: flex;
   align-items: center;
-	
+
 }
 
-.ai_b_i_btnArea > div > span {
+.ai_b_i_btnArea>div>span {
   margin-left: 5px;
-	cursor: pointer;
+  cursor: pointer;
+}
+
+.ai_b_i_btnArea>.clear+.clear {
+  margin-left: 10px;
 }
 
-.ai_b_i_btnArea > span {
+.ai_b_i_btnArea>.clear {
   box-sizing: border-box;
-  height: 90%;
-  width: 90px;
+  padding: 5px 10px;
   box-sizing: border-box;
   cursor: pointer;
   border: solid 1px #3781fb;
@@ -1053,19 +1169,19 @@ export default {
   background-color: #fff;
 }
 
-.ai_b_i_btnArea > span > svg {
+.ai_b_i_btnArea>.clear>svg {
   width: 17px;
   height: 17px;
   margin-right: 5px;
   fill: black;
 }
 
-.ai_b_i_btnArea > span:hover {
+.ai_b_i_btnArea>.clear:hover {
   background-color: #ebf4fe;
   color: #409eff;
 }
 
-.ai_b_i_btnArea > span:hover > svg {
+.ai_b_i_btnArea>.clear:hover>svg {
   fill: #409eff;
 }
 
@@ -1138,7 +1254,7 @@ export default {
   display: flex;
 }
 
-.ai_b_i_rlb_itemTop > img {
+.ai_b_i_rlb_itemTop>img {
   width: 40px;
   height: 40px;
   margin-right: 10px;
@@ -1146,17 +1262,17 @@ export default {
   overflow: hidden;
 }
 
-.ai_b_i_rlb_itemTop > div {
+.ai_b_i_rlb_itemTop>div {
   display: flex;
   flex-direction: column;
 }
 
-.ai_b_i_rlb_itemTop > div > span {
+.ai_b_i_rlb_itemTop>div>span {
   font-size: 16px;
   font-weight: bold;
 }
 
-.ai_b_i_rlb_itemTop > div > span:last-child {
+.ai_b_i_rlb_itemTop>div>span:last-child {
   font-size: 14px;
   color: #999;
 }
@@ -1166,7 +1282,7 @@ export default {
   display: flex;
 }
 
-.ai_b_i_rlb_itemBottom > span {
+.ai_b_i_rlb_itemBottom>span {
   width: 60px;
   height: 30px;
   border-radius: 15px;
@@ -1188,25 +1304,35 @@ export default {
 }
 
 .ai_body_input_textarea::-webkit-input-placeholder {
-  font-size: 16px; /* 修改placeholder字体大小 */
-  color: grey; /* 修改placeholder文字颜色 */
+  font-size: 16px;
+  /* 修改placeholder字体大小 */
+  color: grey;
+  /* 修改placeholder文字颜色 */
 }
 
 .ai_body_input_textarea::-moz-placeholder {
-  font-size: 16px; /* 修改placeholder字体大小 */
-  color: grey; /* 修改placeholder文字颜色 */
-  opacity: 1; /* 修复Firefox的透明度问题 */
+  font-size: 16px;
+  /* 修改placeholder字体大小 */
+  color: grey;
+  /* 修改placeholder文字颜色 */
+  opacity: 1;
+  /* 修复Firefox的透明度问题 */
 }
 
 .ai_body_input_textarea::-moz-placeholder {
-  font-size: 16px; /* 修改placeholder字体大小 */
-  color: grey; /* 修改placeholder文字颜色 */
-  opacity: 1; /* 修复Firefox的透明度问题 */
+  font-size: 16px;
+  /* 修改placeholder字体大小 */
+  color: grey;
+  /* 修改placeholder文字颜色 */
+  opacity: 1;
+  /* 修复Firefox的透明度问题 */
 }
 
 .ai_body_input_textarea::-ms-input-placeholder {
-  font-size: 16px; /* 修改placeholder字体大小 */
-  color: grey; /* 修改placeholder文字颜色 */
+  font-size: 16px;
+  /* 修改placeholder字体大小 */
+  color: grey;
+  /* 修改placeholder文字颜色 */
 }
 
 .ai_body_input_textarea::-webkit-scrollbar {
@@ -1222,6 +1348,7 @@ export default {
   background: #c9c9c9;
   border-radius: 10px;
 }
+
 .ai_body_input_textarea::-webkit-scrollbar-thumb:hover {
   background: #c9c9c9;
 }
@@ -1262,26 +1389,26 @@ export default {
   flex-direction: column;
 }
 
-.dialog_content > div {
+.dialog_content>div {
   display: flex;
   align-items: flex-start;
   width: 100%;
 }
 
-.dialog_content + .dialog_content {
+.dialog_content+.dialog_content {
   margin: 15px 0;
 }
 
-.dialog_content > div .right {
+.dialog_content>div .right {
   flex-direction: row-reverse;
 }
 
-.dialog_content > div .right .role {
+.dialog_content>div .right .role {
   margin-right: 0;
   margin-left: 10px;
 }
 
-.dialog_content > div .role {
+.dialog_content>div .role {
   min-width: 30px;
   width: 30px;
   height: 30px;
@@ -1289,13 +1416,13 @@ export default {
   border-radius: 50%;
 }
 
-.dialog_content > div .role > img {
+.dialog_content>div .role>img {
   height: 100%;
   width: 100%;
   border-radius: 100%;
 }
 
-.dialog_content > div .content {
+.dialog_content>div .content {
   padding: 10px 10px;
   border-radius: 2px 8px 8px 8px;
   width: auto;
@@ -1320,7 +1447,7 @@ export default {
   color: #919191;
 }
 
-.dialog_content > div .content2 {
+.dialog_content>div .content2 {
   background: #3681fc;
   color: #fff;
   border-radius: 8px 2px 8px 8px;
@@ -1331,7 +1458,7 @@ export default {
   position: relative;
 }
 
-.ai_body_select > .check {
+.ai_body_select>.check {
   background: #e7e7e7;
   display: flex;
   width: fit-content;
@@ -1347,7 +1474,7 @@ export default {
   cursor: pointer;
 }
 
-.ai_body_select > .check::before {
+.ai_body_select>.check::before {
   content: "";
   width: 15px;
   height: 15px;
@@ -1357,7 +1484,7 @@ export default {
   margin-right: 5px;
 }
 
-.ai_body_select > .check::after {
+.ai_body_select>.check::after {
   content: "";
   width: 15px;
   height: 15px;
@@ -1367,7 +1494,7 @@ export default {
   margin-right: 5px;
 }
 
-.ai_body_select > .isCheck {
+.ai_body_select>.isCheck {
   background: #0061ff;
   display: flex;
   width: fit-content;
@@ -1385,7 +1512,7 @@ export default {
   box-sizing: border-box;
 }
 
-.ai_body_select > .isCheck > span {
+.ai_body_select>.isCheck>span {
   width: calc(100% - 40px);
   display: block;
   overflow: hidden;
@@ -1393,7 +1520,7 @@ export default {
   text-overflow: ellipsis;
 }
 
-.ai_body_select > .isCheck::before {
+.ai_body_select>.isCheck::before {
   content: "";
   width: 15px;
   height: 15px;
@@ -1403,7 +1530,7 @@ export default {
   margin-right: 5px;
 }
 
-.ai_body_select > .isCheck::after {
+.ai_body_select>.isCheck::after {
   content: "";
   width: 15px;
   height: 15px;
@@ -1413,7 +1540,7 @@ export default {
   margin-right: 5px;
 }
 
-.ai_body_select > .checkBox {
+.ai_body_select>.checkBox {
   position: absolute;
   bottom: 40px;
   border: 1px solid #e0eafb;
@@ -1425,37 +1552,36 @@ export default {
   box-sizing: border-box;
 }
 
-.ai_body_select > .checkBox > .task > .title,
-.ai_body_select > .checkBox > .part > .title {
+.ai_body_select>.checkBox>.task>.title,
+.ai_body_select>.checkBox>.part>.title {
   font-size: 14px;
   font-weight: 700;
   margin-bottom: 5px;
 }
 
-.ai_body_select > .checkBox > .task {
+.ai_body_select>.checkBox>.task {
   height: calc(100% - 60px);
 }
 
-.ai_body_select > .checkBox > .part {
-}
+.ai_body_select>.checkBox>.part {}
 
-.ai_body_select > .checkBox > .task > .content {
+.ai_body_select>.checkBox>.task>.content {
   height: calc(100% - 40px);
   overflow: auto;
 }
 
-.ai_body_select > .checkBox > .task > .content > .span + .span {
+.ai_body_select>.checkBox>.task>.content>.span+.span {
   margin-top: 5px;
 }
 
-.ai_body_select > .checkBox > .task > .content > .span {
+.ai_body_select>.checkBox>.task>.content>.span {
   display: flex;
   align-items: center;
   font-size: 14px;
   cursor: pointer;
 }
 
-.ai_body_select > .checkBox > .task > .content > .span > .check {
+.ai_body_select>.checkBox>.task>.content>.span>.check {
   width: 13px;
   height: 13px;
   display: flex;
@@ -1463,27 +1589,80 @@ export default {
   margin-right: 5px;
 }
 
-.ai_body_select > .checkBox > .task > .content > .span > .check > img {
+.ai_body_select>.checkBox>.task>.content>.span>.check>img {
   width: 100%;
   height: 100%;
 }
 
-.ai_body_select > .checkBox > .part > .content {
+.ai_body_select>.checkBox>.part>.content {
   display: flex;
   align-items: center;
   font-size: 14px;
   justify-content: space-between;
 }
 
-.ai_body_select > .checkBox > .part > .content > .span {
+.ai_body_select>.checkBox>.part>.content>.span {
   padding: 3px 6px;
   border: 1px solid #e0eafb;
   border-radius: 40px;
   cursor: pointer;
 }
 
-.ai_body_select > .checkBox > .part > .content > .span.active {
+.ai_body_select>.checkBox>.part>.content>.span.active {
   color: #0061ff;
   border-color: #0061ff;
 }
+
+.ai_b_i_jListPanel {
+  width: 400px;
+  height: 100%;
+  top: 0;
+  right: 0;
+  position: fixed;
+  /* background-color: #000; */
+  z-index: 990;
+}
+
+.ai_b_i_jListBox {
+  width: 100%;
+  max-height: 300px;
+  background-color: #fff;
+  position: absolute;
+  bottom: calc(100% + 5px);
+  box-sizing: border-box;
+  padding: 10px;
+  overflow: auto;
+  border-radius: 8px;
+  border: 1px solid #e7e7e7;
+  box-shadow: 0 4px 10px 0 rgba(29, 57, 131, 0.08),
+    1px 1px 20px 4px rgba(29, 57, 131, 0.05);
+  z-index: 999;
+}
+
+.jlist_box {
+  background: #f1f1f1;
+  border-radius: 5px;
+  margin-bottom: 10px;
+  padding: 8px 18px 8px 8px;
+  box-sizing: border-box;
+  width: 100%;
+  position: relative;
+}
+
+.jlist_box .cancel {
+  position: absolute;
+  top: 8px;
+  right: 5px;
+  cursor: pointer;
+  font-size: 14px;
+}
+
+.jlist_box>span {
+  display: -webkit-box;
+  -webkit-box-orient: vertical;
+  -webkit-line-clamp: 3;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  word-break: break-all;
+}
 </style>

+ 861 - 28
src/components/pages/classroomObservation/components/addNewAnalysisDialog.vue

@@ -17,15 +17,15 @@
             clearable
           >
           </el-input>
-
+          <!-- 
           <el-button
-					v-if="canAddNew"
+            v-if="canAddNew"
             style="margin-left: 30px;"
             size="mini"
             @click.stop="addNew()"
             round
             >新建分析模块</el-button
-          >
+          > -->
         </div>
         <div class="a-d-t-right">
           <span @click.stop="close()">×</span>
@@ -33,7 +33,17 @@
       </div>
       <div style="display: flex; height: 100%">
         <div class="a-d-t-left">
-          <!-- <div class="itemTit">我的模块</div> -->
+          <div
+            class="itemTit"
+            :style="
+              tagIndex == -1 || tagIndex == -2
+                ? 'background: rgba(226, 238, 255, 1);color: rgba(54, 129, 252, 1)'
+                : ''
+            "
+            @click.stop="tagIndex = -1"
+          >
+            我的模块
+          </div>
           <div
             :style="
               tagIndex == index
@@ -48,7 +58,7 @@
             {{ item.name }}
           </div>
         </div>
-        <div class="a-d-box">
+        <div class="a-d-box" v-if="[0, 1, 2].includes(tagIndex)">
           <div
             style="
 							font-family: PingFang SC;
@@ -106,7 +116,7 @@
                   <!-- <div class="a-d-b-i-t-btn">详情</div> -->
                   <div
                     class="a-d-b-i-t-btn1"
-                    @click="addAnalysisItem(item.name,item.id)"
+                    @click="addAnalysisItem(item.name, item.id)"
                   >
                     添加
                   </div>
@@ -115,18 +125,388 @@
             </div>
           </div>
         </div>
+        <div class="a-d-box" v-if="[-1, -2].includes(tagIndex)">
+          <div
+            class="d_d_b_type"
+            v-if="[-1].includes(tagIndex)"
+            v-loading="formLoading"
+          >
+            <div class="d_d_b_t_head">
+              <div>我的模块</div>
+              <div @click.stop="addNewAnalysis">新建分析模块</div>
+            </div>
+
+            <div class="a-d-b-subject">
+              <span
+                v-for="(item, index) in tagSubjectList"
+                :class="[
+                  'a_d_b_s_btn',
+                  tagSubject == item ? 'a_d_b_s_ActiveBtn' : ''
+                ]"
+                :key="index + '-' + tagIndex"
+                @click.stop="
+                  tagSubject == item ? (tagSubject = '') : (tagSubject = item)
+                "
+                >{{ item }}</span
+              >
+            </div>
+
+            <div style="display: flex; flex-wrap: wrap">
+              <div
+                class="a-d-b-item"
+                v-for="(item, index) in searchMyselfDataList"
+                :key="index"
+              >
+                <div class="a-d-b-i-top">
+                  <img
+                    style="height: 22px; width: 22px"
+                    :src="
+                      require('../../../../assets/icon/classroomObservation/digImg.svg')
+                    "
+                  />
+                  <div
+                    class="a-d-b-i-t-title"
+                    style="width: calc(100% - 40px);"
+                  >
+                    {{ item.name }}
+                  </div>
+                  <div class="a_d_b_i_t_t_editIcon">
+                    <span @click.stop="showModelDialog = item.id">
+                      <svg
+                        width="16"
+                        height="16"
+                        viewBox="0 0 16 16"
+                        fill="none"
+                        xmlns="http://www.w3.org/2000/svg"
+                      >
+                        <path
+                          d="M2.25 8C2.25 8.33152 2.3817 8.64946 2.61612 8.88388C2.85054 9.1183 3.16848 9.25 3.5 9.25C3.83152 9.25 4.14946 9.1183 4.38388 8.88388C4.6183 8.64946 4.75 8.33152 4.75 8C4.75 7.66848 4.6183 7.35054 4.38388 7.11612C4.14946 6.8817 3.83152 6.75 3.5 6.75C3.16848 6.75 2.85054 6.8817 2.61612 7.11612C2.3817 7.35054 2.25 7.66848 2.25 8ZM6.75 8C6.75 8.33152 6.8817 8.64946 7.11612 8.88388C7.35054 9.1183 7.66848 9.25 8 9.25C8.33152 9.25 8.64946 9.1183 8.88388 8.88388C9.1183 8.64946 9.25 8.33152 9.25 8C9.25 7.66848 9.1183 7.35054 8.88388 7.11612C8.64946 6.8817 8.33152 6.75 8 6.75C7.66848 6.75 7.35054 6.8817 7.11612 7.11612C6.8817 7.35054 6.75 7.66848 6.75 8ZM11.25 8C11.25 8.33152 11.3817 8.64946 11.6161 8.88388C11.8505 9.1183 12.1685 9.25 12.5 9.25C12.8315 9.25 13.1495 9.1183 13.3839 8.88388C13.6183 8.64946 13.75 8.33152 13.75 8C13.75 7.66848 13.6183 7.35054 13.3839 7.11612C13.1495 6.8817 12.8315 6.75 12.5 6.75C12.1685 6.75 11.8505 6.8817 11.6161 7.11612C11.3817 7.35054 11.25 7.66848 11.25 8Z"
+                          fill="black"
+                        />
+                      </svg>
+                    </span>
+
+                    <div
+                      class="a_d_b_i_t_t_editDialog"
+                      v-if="showModelDialog == item.id"
+                      v-click-outside="() => (showModelDialog = '')"
+                    >
+                      <div
+                        v-if="['0'].includes(item.open)"
+                        @click.stop="editAnalysis(0, item)"
+                      >
+                        <svg
+                          width="16"
+                          height="16"
+                          viewBox="0 0 16 16"
+                          fill="none"
+                          xmlns="http://www.w3.org/2000/svg"
+                        >
+                          <path
+                            fill-rule="evenodd"
+                            clip-rule="evenodd"
+                            d="M2 2.5C2 2.22386 2.22386 2 2.5 2H6.5C6.77614 2 7 2.22386 7 2.5C7 2.77614 6.77614 3 6.5 3H3V13H13V8.5C13 8.22386 13.2239 8 13.5 8C13.7761 8 14 8.22386 14 8.5V13.5C14 13.7761 13.7761 14 13.5 14H2.5C2.22386 14 2 13.7761 2 13.5V2.5Z"
+                            fill="black"
+                            fill-opacity="0.9"
+                          />
+                          <path
+                            fill-rule="evenodd"
+                            clip-rule="evenodd"
+                            d="M12.0849 2.06707C11.8458 1.929 11.54 2.01094 11.4019 2.25008C11.2639 2.48923 11.3458 2.79503 11.5849 2.9331L12.1204 3.24226C9.77846 3.65788 8 5.70382 8 8.16515V8.66515C8 8.94129 8.22386 9.16515 8.5 9.16515C8.77614 9.16515 9 8.94129 9 8.66515V8.16515C9 6.09309 10.5755 4.38901 12.5939 4.18551L12.134 4.98213C11.9959 5.22128 12.0778 5.52708 12.317 5.66515C12.5561 5.80322 12.8619 5.72128 13 5.48213L14 3.75008C14.1381 3.51094 14.0561 3.20514 13.817 3.06707L12.0849 2.06707Z"
+                            fill="black"
+                            fill-opacity="0.9"
+                          />
+                        </svg>
+                        <span>公开到社区</span>
+                      </div>
+                      <div
+                        v-if="!['0'].includes(item.open)"
+                        @click.stop="editAnalysis(1, item)"
+                      >
+                        <svg
+                          width="16"
+                          height="16"
+                          viewBox="0 0 16 16"
+                          fill="none"
+                          xmlns="http://www.w3.org/2000/svg"
+                        >
+                          <path
+                            fill-rule="evenodd"
+                            clip-rule="evenodd"
+                            d="M4.5 5C4.5 3.61929 5.61929 2.5 7 2.5C8.38071 2.5 9.5 3.61929 9.5 5C9.5 6.38071 8.38071 7.5 7 7.5C5.61929 7.5 4.5 6.38071 4.5 5ZM7 8.5C8.933 8.5 10.5 6.933 10.5 5C10.5 3.067 8.933 1.5 7 1.5C5.067 1.5 3.5 3.067 3.5 5C3.5 6.19029 4.09418 7.24181 5.0021 7.87412C2.95231 8.67365 1.5 10.6672 1.5 13V14.5C1.5 14.7761 1.72386 15 2 15C2.27614 15 2.5 14.7761 2.5 14.5V13C2.5 10.5147 4.51472 8.5 7 8.5Z"
+                            fill="black"
+                            fill-opacity="0.9"
+                          />
+                          <path
+                            fill-rule="evenodd"
+                            clip-rule="evenodd"
+                            d="M9.5 10.5C9.5 10.2239 9.72386 10 10 10H11C11.2761 10 11.5 10.2239 11.5 10.5V11H9.5V10.5ZM8.5 11V10.5C8.5 9.67157 9.17157 9 10 9H11C11.8284 9 12.5 9.67157 12.5 10.5V11H13C13.2761 11 13.5 11.2239 13.5 11.5V14.5C13.5 14.7761 13.2761 15 13 15H8C7.72386 15 7.5 14.7761 7.5 14.5V11.5C7.5 11.2239 7.72386 11 8 11H8.5ZM8.5 14V12H12.5V14H8.5Z"
+                            fill="black"
+                            fill-opacity="0.9"
+                          />
+                        </svg>
+
+                        <span>恢复隐私</span>
+                      </div>
+                      <span></span>
+                      <div @click.stop="editAnalysis(2, item)">
+                        <svg
+                          width="16"
+                          height="16"
+                          viewBox="0 0 16 16"
+                          fill="none"
+                          xmlns="http://www.w3.org/2000/svg"
+                        >
+                          <path
+                            fill-rule="evenodd"
+                            clip-rule="evenodd"
+                            d="M8.00001 1.5C8.1894 1.5 8.36253 1.61128 8.44723 1.78745L10.3276 5.69853L14.062 6.18401C14.2515 6.20865 14.411 6.34338 14.4729 6.53124C14.5349 6.71909 14.4886 6.92726 14.3536 7.06769L11.5537 9.9795L12.4851 13.8539C12.5302 14.0413 12.4715 14.2393 12.3329 14.368C12.1942 14.4967 11.9984 14.5347 11.8245 14.4669L8.00001 12.9754L4.17558 14.4669C4.0016 14.5347 3.80578 14.4967 3.66714 14.368C3.52849 14.2393 3.46988 14.0413 3.51494 13.8539L4.44628 9.9795L1.64646 7.06769C1.51143 6.92726 1.4651 6.71909 1.52708 6.53124C1.58905 6.34338 1.7485 6.20865 1.938 6.18401L5.67247 5.69853L7.5528 1.78745C7.6375 1.61128 7.81063 1.5 8.00001 1.5ZM8.00001 3.18275L6.44723 6.41255C6.37246 6.56806 6.22792 6.67442 6.06203 6.69598L3.07646 7.08411L5.35357 9.4523C5.47776 9.58146 5.52768 9.76891 5.48509 9.94611L4.71603 13.1454L7.82445 11.9331C7.93764 11.889 8.06238 11.889 8.17558 11.9331L11.284 13.1454L10.5149 9.94611C10.4723 9.76891 10.5223 9.58146 10.6465 9.4523L12.9236 7.08411L9.938 6.69598C9.77211 6.67442 9.62756 6.56806 9.5528 6.41255L8.00001 3.18275Z"
+                            fill="black"
+                            fill-opacity="0.9"
+                          />
+                        </svg>
+                        <span>收藏</span>
+                      </div>
+                      <div @click.stop="editAnalysis(3, item)">
+                        <svg
+                          width="16"
+                          height="16"
+                          viewBox="0 0 16 16"
+                          fill="none"
+                          xmlns="http://www.w3.org/2000/svg"
+                        >
+                          <path
+                            fill-rule="evenodd"
+                            clip-rule="evenodd"
+                            d="M2 2.5C2 2.22386 2.22386 2 2.5 2H8.5C8.77614 2 9 2.22386 9 2.5C9 2.77614 8.77614 3 8.5 3H3V13H13V8.5C13 8.22386 13.2239 8 13.5 8C13.7761 8 14 8.22386 14 8.5V13.5C14 13.7761 13.7761 14 13.5 14H2.5C2.22386 14 2 13.7761 2 13.5V2.5Z"
+                            fill="black"
+                            fill-opacity="0.9"
+                          />
+                          <path
+                            fill-rule="evenodd"
+                            clip-rule="evenodd"
+                            d="M13.8536 2.14645C14.0488 2.34171 14.0488 2.65829 13.8536 2.85355L7.85355 8.85355C7.65829 9.04882 7.34171 9.04882 7.14645 8.85355C6.95118 8.65829 6.95118 8.34171 7.14645 8.14645L13.1464 2.14645C13.3417 1.95118 13.6583 1.95118 13.8536 2.14645Z"
+                            fill="black"
+                            fill-opacity="0.9"
+                          />
+                        </svg>
+                        <span>编辑</span>
+                      </div>
+                      <div @click.stop="editAnalysis(4, item)">
+                        <svg
+                          width="16"
+                          height="16"
+                          viewBox="0 0 16 16"
+                          fill="none"
+                          xmlns="http://www.w3.org/2000/svg"
+                        >
+                          <path
+                            fill-rule="evenodd"
+                            clip-rule="evenodd"
+                            d="M5 2.5C5 2.22386 5.22386 2 5.5 2H10.5C10.7761 2 11 2.22386 11 2.5C11 2.77614 10.7761 3 10.5 3H5.5C5.22386 3 5 2.77614 5 2.5Z"
+                            fill="black"
+                            fill-opacity="0.9"
+                          />
+                          <path
+                            fill-rule="evenodd"
+                            clip-rule="evenodd"
+                            d="M2 4.5C2 4.21185 2.22386 4 2.5 4H13.5C13.7761 4 14 4.21185 14 4.5C14 4.83161 13.7761 5 13.5 5L12.5 5.04348V14H3.5V5H2.5C2.22386 5 2 4.83161 2 4.5ZM4.5 5V12.9565L11.5 13V5.04348L4.5 5Z"
+                            fill="black"
+                            fill-opacity="0.9"
+                          />
+                          <path
+                            fill-rule="evenodd"
+                            clip-rule="evenodd"
+                            d="M6.5 6.45461C6.77614 6.45461 7 6.65811 7 6.90915V11.0001C7 11.2511 6.77614 11.4546 6.5 11.4546C6.22386 11.4546 6 11.2511 6 11.0001V6.90915C6 6.65811 6.22386 6.45461 6.5 6.45461Z"
+                            fill="black"
+                            fill-opacity="0.9"
+                          />
+                          <path
+                            fill-rule="evenodd"
+                            clip-rule="evenodd"
+                            d="M9.5 6.45461C9.77614 6.45461 10 6.65811 10 6.90915V11.0001C10 11.2511 9.77614 11.4546 9.5 11.4546C9.22386 11.4546 9 11.2511 9 11.0001V6.90915C9 6.65811 9.22386 6.45461 9.5 6.45461Z"
+                            fill="black"
+                            fill-opacity="0.9"
+                          />
+                        </svg>
+                        <span>删除</span>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+                <div class="a-d-b-i-bottom">{{ item.detail }}</div>
+                <div class="a-d-b-i-bottomPer" style="display: block">
+                  {{ item.count }}人已使用
+                </div>
+                <div class="a-d-b-i-bottomBtn" style="display: none">
+                  <div
+                    style="
+										display: flex;
+										width: 100%;
+										justify-content: space-around;
+									"
+                  >
+                    <!-- <div class="a-d-b-i-t-btn">详情</div> -->
+                    <div
+                      class="a-d-b-i-t-btn1"
+                      @click="addAnalysisItem(item.name, item.id)"
+                    >
+                      添加
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div
+            class="d_d_b_addType"
+            v-if="[-2].includes(tagIndex)"
+            v-loading="formLoading"
+          >
+            <div>新建模块</div>
+
+            <el-form
+              :model="form"
+              :rules="rules"
+              ref="ruleForm"
+              label-position="top"
+            >
+              <div class="d_d_b_at_inputArea">
+                <el-form-item
+                  label="模板名称"
+                  prop="name"
+                  style="margin-right: 50px;"
+                  class="d_d_b_at_input"
+                >
+                  <el-input
+                    v-model="form.name"
+                    placeholder="请输入模板名称"
+                  ></el-input>
+                </el-form-item>
+
+                <el-form-item
+                  label="所属分类"
+                  prop="type"
+                  style="margin-right: 50px;"
+                  class="d_d_b_at_input"
+                >
+                  <el-select v-model="form.type" placeholder="请选择所属分类">
+                    <el-option
+                      v-for="item in dialogTagList"
+                      :key="item.id"
+                      :label="item.name"
+                      :value="item.id"
+                    >
+                    </el-option>
+                  </el-select>
+                  <!-- <el-input v-model="form.subject" placeholder="请输入所属学科" style="width: 300px;"></el-input> -->
+                </el-form-item>
+
+                <el-form-item
+                  label="所属学科"
+                  prop="subject"
+                  style="margin-right: 50px;"
+                  class="d_d_b_at_input"
+                >
+                  <el-select
+                    v-model="form.subject"
+                    placeholder="请选择所属学科"
+                  >
+                    <el-option
+                      v-for="item in subjectList"
+                      :key="item.value"
+                      :label="item.label"
+                      :value="item.label"
+                    >
+                    </el-option>
+                  </el-select>
+                  <!-- <el-input v-model="form.subject" placeholder="请输入所属学科" style="width: 300px;"></el-input> -->
+                </el-form-item>
+              </div>
+              <el-form-item
+                label="模板简介"
+                prop="detail"
+                class="d_d_b_at_input"
+              >
+                <el-input
+                  type="textarea"
+                  v-model="form.detail"
+                  :rows="3"
+                  :maxlength="30"
+                  resize="none"
+                  placeholder="请输入内容,不超过30字"
+                ></el-input>
+              </el-form-item>
+
+              <el-form-item label="提示词" prop="tips" class="d_d_b_at_input">
+                <el-input
+                  type="textarea"
+                  v-model="form.tips"
+                  :rows="6"
+                  resize="none"
+                  placeholder="请输入提示词"
+                ></el-input>
+              </el-form-item>
+
+              <el-form-item label="是否公开" prop="open" class="d_d_b_at_input">
+                <el-switch v-model="form.open"></el-switch>
+                <!-- <el-select v-model="form.open" placeholder="请选择是否公开">
+  					  <el-option
+  					    v-for="item in openList"
+  					    :key="item.value"
+  					    :label="item.label"
+  					    :value="item.value">
+  					  </el-option>
+  					</el-select> -->
+                <!-- <el-input v-model="form.subject" placeholder="请输入所属学科" style="width: 300px;"></el-input> -->
+              </el-form-item>
+            </el-form>
+            <div class="d_d_b_at_btnArea">
+              <el-button @click.stop="cancelSubmit()">取消</el-button>
+              <el-button type="primary" @click.stop="submitForm('ruleForm')"
+                >确认</el-button
+              >
+            </div>
+          </div>
+        </div>
       </div>
       <!-- </div> -->
     </el-dialog>
-    <newAnalysisModule v-if="canAddNew" ref="newAnalysisModuleRef" @success="successNew"/>
+    <!-- <newAnalysisModule
+      v-if="canAddNew"
+      ref="newAnalysisModuleRef"
+      @success="successNew"
+    /> -->
   </div>
 </template>
 
 <script>
-import newAnalysisModule from "./newAnalysisModule.vue";
+// import newAnalysisModule from "./newAnalysisModule.vue";
+// 自定义指令,用于处理点击外部区域的事件
+const clickOutside = {
+  bind(el, binding) {
+    // 在元素上绑定一个点击事件监听器
+    el.clickOutsideEvent = function(event) {
+      // 检查点击事件是否发生在元素的内部
+      if (!(el === event.target || el.contains(event.target))) {
+        // 如果点击事件发生在元素的外部,则触发指令绑定的方法,将点击的event数据传过去
+        binding.value(event);
+      }
+    };
+    // 在文档上添加点击事件监听器
+    document.addEventListener("click", el.clickOutsideEvent);
+  },
+  unbind(el) {
+    // 在元素上解除点击事件监听器
+    document.removeEventListener("click", el.clickOutsideEvent);
+  }
+};
 export default {
   components: {
-    newAnalysisModule
+    // newAnalysisModule
+  },
+  directives: {
+    "click-outside": clickOutside // 注册自定义指令
   },
   props: {
     dialogTagDataList: {
@@ -143,15 +523,53 @@ export default {
   data() {
     return {
       dialogVisible: false,
+      userId: this.$route.query["userid"],
       input2: "",
+
       tagIndex: 0,
       tagSubject: "",
+      boxType: 0, //0 新建  1修改
       dialogTagList: [
         { id: 0, name: "通用课堂分析" },
         { id: 1, name: "学科课堂分析" },
         { id: 2, name: "扩展分析" }
         //{ id: 3, name: "增值性分析" },
-      ]
+      ],
+      subjectList: [
+        { value: "1", label: "语文" },
+        { value: "2", label: "数学" },
+        { value: "3", label: "英语" },
+        { value: "4", label: "科学" },
+        { value: "5", label: "物理" },
+        { value: "6", label: "化学" },
+        { value: "7", label: "生物" },
+        { value: "8", label: "历史" },
+        { value: "9", label: "地理" },
+        { value: "10", label: "政治" },
+        { value: "11", label: "其它" }
+      ],
+      form: {
+        name: "",
+        detail: "",
+        tips: "",
+        type: "",
+        subject: "",
+        open: false
+      },
+      showModelDialog: "",
+      formLoading: false,
+      rules: {
+        name: [{ required: true, message: "请输入模块名称", trigger: "blur" }],
+        tips: [
+          { required: true, message: "请输入模块提示词", trigger: "blur" }
+        ],
+        type: [
+          { required: true, message: "请选择模块所属分类", trigger: "change" }
+        ],
+        subject: [
+          { required: true, message: "请选择模块所属学科", trigger: "change" }
+        ]
+      }
     };
   },
   computed: {
@@ -166,24 +584,61 @@ export default {
 
       return _result;
     },
+    searchMyselfDataList() {
+      let _result = this.dialogTagDataList.filter(i => i.userid == this.userId);
+      if (this.input2) {
+        _result = _result.filter(i => i.name.indexOf(this.input2) > -1);
+      }
+      if (this.tagSubject) {
+        _result = _result.filter(i => i.subject == this.tagSubject);
+      }
+      return _result;
+    },
     tagSubjectList() {
       let _result = [];
-      this.dialogTagDataList
-        .filter(i => i.type == this.tagIndex)
-        .forEach(i => {
-          if (i.subject && !_result.includes(i.subject)) {
-            _result.push(i.subject);
-          }
-        });
+      if ([-1, -2].includes(this.tagIndex)) {
+        this.dialogTagDataList
+          .filter(i => i.userid == this.userId)
+          .forEach(i => {
+            if (i.subject && !_result.includes(i.subject)) {
+              _result.push(i.subject);
+            }
+          });
+      } else {
+        this.dialogTagDataList
+          .filter(i => i.type == this.tagIndex)
+          .forEach(i => {
+            if (i.subject && !_result.includes(i.subject)) {
+              _result.push(i.subject);
+            }
+          });
+      }
+
       return _result;
     }
   },
+	watch:{
+		tagIndex(val){
+			if(val !=-2){
+				this.tagSubject = "";
+			}
+		}
+	},
   methods: {
     open(type) {
       this.tagIndex = type;
       this.input2 = "";
       this.tagSubject = "";
       this.dialogVisible = true;
+      this.form = {
+        name: "",
+        detail: "",
+        tips: "",
+        type: "",
+        subject: "",
+        open: false
+      };
+      this.$emit("update");
     },
     close() {
       this.dialogVisible = false;
@@ -191,15 +646,240 @@ export default {
       this.input2 = "";
       this.tagSubject = "";
     },
-    addAnalysisItem(title,id) {
-      this.$emit("success", title,id);
+    addAnalysisItem(title, id) {
+      this.$emit("success", title, id);
     },
     addNew() {
       this.$refs.newAnalysisModuleRef.open();
     },
-		successNew(){
-			this.$emit("update");
-		}
+    successNew() {
+      this.$emit("update");
+    },
+    addNewAnalysis() {
+      this.boxType = 0;
+      this.tagIndex = -2;
+      this.form = {
+        name: "",
+        detail: "",
+        tips: "",
+        type: "",
+        subject: "",
+        open: false
+      };
+      //新建模块
+    },
+    editAnalysis(mid) {
+      console.log(mid);
+    },
+    submitForm(ref) {
+      this.$refs[ref].validate(valid => {
+        if (valid) {
+          if (this.boxType == 0) {
+            let params = [
+              {
+                nuid: this.userId,
+                nname: this.form.name,
+                ndetail: this.form.detail,
+                nsubject: this.form.subject,
+                ntype: this.form.type,
+                nopen: this.form.open ? 2 : 0,
+                nagentid: "",
+                ntips: this.form.tips
+              }
+            ];
+
+            this.formLoading = true;
+            this.ajax
+              .post(this.$store.state.api + "insert_smodel", params)
+              .then(res => {
+                if (typeof res.data == "object") {
+                  this.$message.warning("该新建的模块名称已存在,请重新输入");
+                } else if (res.data == 1) {
+                  this.boxType = 0;
+                  this.tagIndex = -1;
+                  this.form = {
+                    name: "",
+                    detail: "",
+                    tips: "",
+                    type: "",
+                    subject: "",
+                    open: false
+                  };
+                  this.$message.success("创建成功");
+                } else {
+                  this.$message.error("新建失败");
+                }
+								this.successNew();
+                this.formLoading = false;
+              })
+              .catch(e => {
+                console.log(e);
+                this.loading = false;
+                this.$message.error("新建失败");
+								this.successNew();
+              });
+          } else if (this.boxType == 1) {
+            let params = [
+              {
+                nuid: this.userId,
+                mid: this.form.id,
+                nname: this.form.name,
+                ndetail: this.form.detail,
+                nsubject: this.form.subject,
+                ntype: this.form.type,
+                nopen: this.form.open ? 2 : 0,
+                nagentid: this.form.agentid,
+                ntips: this.form.tips
+              }
+            ];
+            this.ajax
+              .post(this.$store.state.api + "update_smodel", params)
+              .then(res => {
+                if (res.data == 1) {
+                  this.$message.success("修改成功");
+									this.tagIndex = -1;
+									this.boxType = 0; 
+                } else {
+                  this.$message.error("修改失败");
+                }
+                this.successNew();
+                this.formLoading = false;
+              })
+              .catch(e => {
+                console.log(e);
+                this.$message.error("修改失败");
+                this.successNew();
+              });
+          }
+        }
+      });
+      // });
+    },
+    cancelSubmit() {
+      this.formLoading = false;
+      this.tagIndex = -1;
+      this.boxType = 0;
+      this.form = {
+        name: "",
+        detail: "",
+        tips: "",
+        type: "",
+        subject: "",
+        open: false
+      };
+    },
+    editAnalysis(type, data) {
+      if (type == 0) {
+        let params = [
+          {
+            nuid: data.userid,
+            mid: data.id,
+            nname: data.name,
+            ndetail: data.detail,
+            nsubject: data.subject,
+            ntype: data.type,
+            nopen: 2,
+            nagentid: data.agentid,
+            ntips: data.tips
+          }
+        ];
+        this.formLoading = true;
+        this.ajax
+          .post(this.$store.state.api + "update_smodel", params)
+          .then(res => {
+            if (res.data == 1) {
+              this.$message.success("公开成功");
+            } else {
+              this.$message.error("公开失败");
+            }
+            this.successNew();
+            this.formLoading = false;
+          })
+          .catch(e => {
+            console.log(e);
+            this.$message.error("公开失败");
+            this.successNew();
+          });
+        this.showModelDialog = "";
+      } else if (type == 1) {
+        let params = [
+          {
+            nuid: data.userid,
+            mid: data.id,
+            nname: data.name,
+            ndetail: data.detail,
+            nsubject: data.subject,
+            ntype: data.type,
+            nopen: 0,
+            nagentid: data.agentid,
+            ntips: data.tips
+          }
+        ];
+        this.formLoading = true;
+        this.ajax
+          .post(this.$store.state.api + "update_smodel", params)
+          .then(res => {
+            if (res.data == 1) {
+              this.$message.success("设为隐私成功");
+            } else {
+              this.$message.error("设为隐私失败");
+            }
+            this.successNew();
+            this.formLoading = false;
+          })
+          .catch(e => {
+            console.log(e);
+            this.$message.error("设为隐私失败");
+            this.successNew();
+          });
+        this.showModelDialog = "";
+      } else if (type == 2) {
+        console.log("收藏");
+      } else if (type == 3) {
+        this.boxType = 1;
+        this.tagIndex = -2;
+        this.form = {
+          id: data.id,
+          name: data.name,
+          detail: data.detail,
+          tips: data.tips,
+          type: data.type,
+          subject: data.subject,
+          agentid: data.agentid,
+          open: data.open == 0 ? false : true
+        };
+        this.showModelDialog = "";
+      } else if (type == 4) {
+        this.$confirm("该操作会永远删除该分析,确定删除?", "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        })
+          .then(() => {
+            this.formLoading = true;
+            this.ajax
+              .post(this.$store.state.api + "delete_smodelById", [
+                { uid: this.userId, mid: data.id }
+              ])
+              .then(res => {
+                let data = res.data;
+                if (data == 1) {
+                  this.$message.success("删除成功");
+                } else {
+                  this.$message.error("删除失败");
+                }
+                this.successNew();
+                this.formLoading = false;
+              })
+              .catch(e => {
+                this.$message.error("删除失败");
+              });
+          })
+          .catch(_ => {
+            console.log("取消");
+          });
+      }
+    }
   }
 };
 </script>
@@ -309,8 +989,7 @@ export default {
   width: 100%;
   height: 100%;
   background-color: #f0f2f5;
-  overflow: scroll;
-  overflow-x: hidden;
+  overflow: auto;
   box-sizing: border-box;
   padding: 15px;
   padding-bottom: 50px;
@@ -446,14 +1125,32 @@ export default {
   display: none;
 }
 .itemTit {
-  width: 136px;
-  height: 32px;
+  width: calc(136px - 10px);
+  height: auto;
   padding: 5px 8px 5px 8px;
   gap: 8px;
-  opacity: 0px;
   margin: 20px 0;
   margin-bottom: 10px;
-  border-bottom: 1px #ccc solid;
+  /* border-bottom: 1px #ccc solid; */
+  cursor: pointer;
+  font-size: 14px;
+  border-radius: 5px;
+  display: flex;
+  padding: 8px 5px;
+  /* justify-content: center; */
+  align-items: center;
+  position: relative;
+  font-weight: bold;
+}
+
+.itemTit::after {
+  content: "";
+  width: 100%;
+  height: 1px;
+  background-color: #ccc;
+  position: absolute;
+  bottom: -10px;
+  left: 0;
 }
 
 .a-d-b-subject {
@@ -480,4 +1177,140 @@ export default {
   background-color: rgba(54, 129, 252, 1);
   color: #fff;
 }
+
+.d_d_b_type {
+  width: 100%;
+  height: auto;
+}
+
+.d_d_b_t_head {
+  width: 100%;
+  height: auto;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 0;
+  margin: 20px 0;
+  box-sizing: border-box;
+}
+
+.d_d_b_t_head > div:nth-of-type(1) {
+  font-family: PingFang SC;
+  font-size: 16px;
+  font-weight: 600;
+  /* line-height: 22px; */
+  text-align: left;
+  margin-bottom: 10px;
+}
+
+.d_d_b_t_head > div:nth-of-type(2) {
+  padding: 10px 20px;
+  background-color: #3681fc;
+  color: #fff;
+  border-radius: 4px;
+  cursor: pointer;
+}
+
+.d_d_b_addType {
+  width: 100%;
+  height: 100%;
+  background-color: #fff;
+  border-radius: 4px;
+  box-sizing: border-box;
+  padding: 20px;
+  position: relative;
+}
+
+.d_d_b_addType > div {
+  font-size: 20px;
+  font-weight: bold;
+}
+
+.d_d_b_at_inputArea {
+  display: flex;
+}
+
+.d_d_b_at_btnArea {
+  position: absolute;
+  bottom: 20px;
+  right: 20px;
+}
+
+.d_d_b_at_input >>> .el-form-item__label {
+  padding: 0;
+}
+.a_d_b_i_t_t_editIcon {
+  width: 30px;
+  height: 30px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  position: relative;
+}
+
+.a_d_b_i_t_t_editIcon > span {
+  width: 30px;
+  height: 30px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.a_d_b_i_t_t_editIcon > span > svg {
+  width: 100%;
+  height: 100%;
+  cursor: pointer;
+}
+
+.a_d_b_i_t_t_editDialog {
+  width: auto;
+  background: #ffffff;
+  height: auto;
+  padding: 10px;
+  border-radius: 8px;
+  position: absolute;
+  top: 100%;
+  right: 0;
+  box-shadow: 0px 8px 10px -5px #00000014;
+
+  box-shadow: 0px 16px 24px 2px #0000000a;
+
+  box-shadow: 0px 6px 30px 5px #0000000d;
+}
+
+.a_d_b_i_t_t_editDialog > div {
+  width: 100%;
+  height: auto;
+  padding: 5px 0;
+  display: flex;
+  white-space: nowrap;
+  align-items: center;
+  background-color: #fff;
+  margin-bottom: 10px;
+  border-radius: 4px;
+  transition: 0.3s;
+  cursor: pointer;
+}
+
+.a_d_b_i_t_t_editDialog > span {
+  width: 100%;
+  height: 1px;
+  display: flex;
+  margin-bottom: 10px;
+  background-color: #e7e7e7;
+}
+
+.a_d_b_i_t_t_editDialog > div:hover {
+  background-color: #f0f2f5;
+}
+
+.a_d_b_i_t_t_editDialog > div > svg {
+  width: 20px;
+  height: 20px;
+  margin-left: 10px;
+}
+
+.a_d_b_i_t_t_editDialog > div > span {
+  margin: 0 5px 0 10px;
+}
 </style>

+ 169 - 0
src/components/pages/classroomObservation/components/addNewTeacherVoiceprintDialog.vue

@@ -0,0 +1,169 @@
+<template>
+  <div>
+    <el-dialog
+      :center="true"
+      :visible.sync="dialogVisible"
+      width="600px"
+      class="addTemplateDialog"
+    >
+      <!-- <div v-if="showDialog == true" class="a-dialog" v-el-drag-dialog> -->
+      <div class="a-d-top">
+        <div class="a-d-topTit"><div>新增声纹</div></div>
+  
+        <div class="a-d-t-right">
+          <span @click.stop="close()">×</span>
+        </div>
+      </div>
+      <div class="a_box">
+				<div class="a_b_form">
+					<div class="a_b_f_item"></div>
+				</div>
+				<div class="a_b_bottom">
+					<div class="a_b_b_top">
+						<span>请使用正常语速朗读以上内容</span>
+					</div>
+					<div class="a_b_b_bottom">
+						<div class="a_b_b_b_btn">
+							<svg width="16" height="22" viewBox="0 0 16 22" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M8.00009 13.8098C10.5962 13.8098 12.6876 11.6655 12.6876 9.00351V5.30633C12.6876 2.64436 10.5962 0.5 8.00009 0.5C5.40393 0.5 3.31259 2.64436 3.31259 5.30633V9.00351C3.31259 11.6655 5.40393 13.8098 8.00009 13.8098ZM4.75489 5.30633C4.75489 3.45774 6.1972 1.97887 8.00009 1.97887C9.80297 1.97887 11.2453 3.45774 11.2453 5.30633V9.00351C11.2453 10.8521 9.80297 12.331 8.00009 12.331C6.1972 12.331 4.75489 10.8521 4.75489 9.00351V5.30633ZM15.5 10.1132C15.5 9.70651 15.1755 9.37377 14.7788 9.37377C14.4183 9.37377 14.0938 9.66954 14.0577 10.0393C13.5529 13.034 11.0288 15.2892 8 15.2892C4.97115 15.2892 2.44712 13.034 1.94231 10.0393C1.90625 9.66954 1.58173 9.37377 1.22115 9.37377C0.824519 9.37377 0.5 9.70651 0.5 10.1132V10.2241C1.07692 13.6995 3.85337 16.3984 7.27885 16.7311V19.9223H4.15379C3.72896 19.9223 3.38456 20.2755 3.38456 20.7111C3.38456 21.1467 3.72896 21.4998 4.15379 21.4998H11.8461C12.2709 21.4998 12.6153 21.1467 12.6153 20.7111C12.6153 20.2755 12.2709 19.9223 11.8461 19.9223H8.72115V16.7311C12.1466 16.3984 14.9231 13.6995 15.4639 10.2611C15.4639 10.2426 15.473 10.2149 15.482 10.1872L15.482 10.1871C15.491 10.1594 15.5 10.1317 15.5 10.1132Z" fill="white"/>
+</svg>
+点击录制
+						</div>
+					</div>
+				</div>
+      </div>
+      <!-- </div> -->
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+
+export default {
+  data() {
+    return {
+      dialogVisible: false,
+      userId: this.$route.query["userid"],
+			form: {
+				name: "",
+			},
+			textAreaVale:"夏天来喽,又能吃上西瓜啦!我真的太喜欢在空调房吃西瓜了,这种感觉真的超爽!红彤彤的果肉和黑色的籽,西瓜就是夏天的标志。每次切开一个大大的西瓜,忍不住就想大口大口地吃,尤其在炎热的午后,这时候来一块冰镇西瓜,简直是人间美味,清凉透底!我也喜欢把西瓜切成小块,用小叉子一块一块品尝,仿佛在享受一场夏日盛宴,每一口都充满了甜蜜和清凉,仿佛所有的烦恼都被这清爽的滋味一扫而空。有时候我也会呼朋唤友,让朋友们来家里玩,大家围坐在一起吃着瓜,聊着天,笑声不断,再没有比这更惬意的日子了!这样的时光总让人觉得生活是如此美好。夏天来喽,又能吃上西瓜了,这种简单的快乐,真是让人难以抗拒!",
+		}
+  },
+
+
+  methods:{
+		open(){
+			this.dialogVisible = true;
+		},
+	}
+};
+</script>
+
+<style scoped>
+.a-d-top {
+  /* background: #adadad; */
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  align-items: center;
+  justify-content: space-between;
+  height: 54px;
+  border-radius: 8px 8px 0 0;
+  user-select: none;
+  border-bottom: 1px #ccc solid;
+}
+
+.a-d-topTit {
+  width: auto;
+  height: 32px;
+  display: flex;
+  align-items: center;
+  font-family: PingFang SC;
+  box-sizing: border-box;
+  /* padding: 5px; */
+  line-height: 22px;
+	font-size: 18px;
+  justify-content: center;
+  /* text-align: left; */
+}
+.a-d-t-right {
+  width: 40px;
+  height: 40px;
+  margin-right: 10px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  color: black !important;
+}
+
+.a-d-t-right > span {
+  width: 25px;
+  height: 25px;
+  border-radius: 25px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  /* align-items: center; */
+  font-size: 22px;
+  color: #fff;
+  /* background-color: #adadad; */
+  cursor: pointer;
+  /* background-color: #e6e6e6; */
+  color: #adadad;
+}
+
+.addTemplateDialog >>> .el-dialog {
+  min-width: 600px;
+
+  height: 700px;
+  box-shadow: 0px 0 8px 0px #555555;
+  border-radius: 8px;
+  background-color: #fff;
+  /* top: 0px; */
+  /* margin: 0 auto; */
+  overflow: hidden;
+}
+.addTemplateDialog >>> .el-dialog__body {
+  height: 100%;
+  min-width: 600px;
+  flex-shrink: 0;
+  box-sizing: border-box;
+  padding-bottom: 50px;
+  padding-top: 10px;
+}
+.addTemplateDialog >>> .el-dialog__header {
+  display: none;
+}
+
+.a_box{
+	width: 100%;
+	height: 100%;
+	box-sizing: border-box;
+	padding: 20px 0;
+}
+
+.a_b_form{
+	width: 100%;
+	height: calc(100% - 70px);
+	background-color: yellow;
+}
+
+.a_b_bottom{
+	width: 100%;
+	height: 70px;
+	background-color: red;
+}
+
+.a_b_b_top{
+	width: 100%;
+	height: 15px;
+	background-color: blue;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	font-size: 14px;
+}
+
+
+</style>

+ 265 - 18
src/components/pages/classroomObservation/components/analysis.vue

@@ -1,15 +1,92 @@
 <template>
   <div class="analysis">
-    <div class="a-header">
-      <div class="a-h-left" @click.stop="changeShowItem(!showItem)">
+    <div class="a-header" :style="showItem ? '' : 'border-radius:5px'">
+      <div class="a-h-left" @click="changeShowItem(!showItem)">
         <span :class="['a-h-l-icon', showItem ? 'a-h-l-showIcon' : '']"></span>
-        <span class="a-h-l-title">{{ title }}</span>
+        <span class="a-h-l-title" v-if="!editTitle">{{ title }}</span>
+        <div class="a_h_l_t_input" v-if="editTitle" @click.stop="() => {}">
+          <el-form ref="form" :model="form" :rules="rules" label-position="top">
+            <el-form-item prop="name">
+              <el-input
+                v-model="form.name"
+               	@blur="editNameCheckFn()"
+                ref="editNameInputRef"
+                placeholder="请输入新的名称"
+              ></el-input>
+            </el-form-item>
+						<!--   @blur="editNameCheckFn()" -->
+          </el-form>
+        </div>
+        <el-tooltip
+          v-if="!editTitle"
+          class="item"
+          effect="light"
+          content="修改名称"
+          placement="top"
+        >
+          <span class="a_h_l_edit" @click.stop="editTitleFn()">
+            <img
+              src="../../../../assets/icon/classroomObservation/editIcon2.svg"
+            /> </span
+          >>
+        </el-tooltip>
       </div>
       <div class="a-h-right">
-        <div class="a-h-r-btn" @click.stop="addTemplate">
+        <!-- <el-popover placement="bottom-end" width="150" v-model="visible" trigger="manual">
+          <div class="a_h_r_boxList" v-click-outside="()=>visible = false">
+					</div> -->
+        <div
+          class="a_h_r_more"
+          slot="reference"
+          @click.stop="visible = !visible"
+        >
+          <img src="@/assets/icon/classroomObservation/moreIcon.svg" alt="" />
+        </div>
+
+        <div
+          class="a_h_r_boxList"
+          v-if="visible"
+          v-click-outside="() => (visible = false)"
+        >
+          <div @click="addTemplate">
+            <svg
+              width="16"
+              height="16"
+              viewBox="0 0 16 16"
+              fill="none"
+              xmlns="http://www.w3.org/2000/svg"
+            >
+              <path
+                fill-rule="evenodd"
+                clip-rule="evenodd"
+                d="M2.00003 4C2.00003 3.72386 2.22389 3.5 2.50003 3.5H4C4.27614 3.5 4.5 3.72386 4.5 4C4.5 4.27614 4.27614 4.5 4 4.5H3.00003L3 14H11V11C11 10.7239 11.2239 10.5 11.5 10.5C11.7762 10.5 12 10.7239 12 11V14.5C12 14.7761 11.7762 15 11.5 15H2.5C2.36739 15 2.24021 14.9473 2.14645 14.8536C2.05268 14.7598 2 14.6326 2 14.5L2.00003 4Z"
+                fill="black"
+                fill-opacity="0.9"
+              />
+              <path
+                fill-rule="evenodd"
+                clip-rule="evenodd"
+                d="M5 5.5C5 5.22386 5.22386 5 5.5 5H13.5C13.7761 5 14 5.22386 14 5.5C14 5.77614 13.7761 6 13.5 6H5.5C5.22386 6 5 5.77614 5 5.5Z"
+                fill="black"
+                fill-opacity="0.9"
+              />
+              <path
+                fill-rule="evenodd"
+                clip-rule="evenodd"
+                d="M9.5 1C9.77614 1 10 1.22386 10 1.5V9.5C10 9.77614 9.77614 10 9.5 10C9.22386 10 9 9.77614 9 9.5V1.5C9 1.22386 9.22386 1 9.5 1Z"
+                fill="black"
+                fill-opacity="0.9"
+              />
+            </svg>
+
+            添加模块
+          </div>
+        </div>
+        <!-- </el-popover> -->
+        <!-- <div class="a-h-r-btn" @click.stop="addTemplate">
           <img src="@/assets/icon/classroomObservation/newcon.svg" alt="" />
           添加模块
-        </div>
+        </div> -->
       </div>
     </div>
     <div class="a-main" v-show="showItem">
@@ -26,7 +103,7 @@
           "
           :dialogTagDataList="dialogTagDataList"
           :bmData="bmData"
-          :key="item.id + item.Type"
+          :key="item.id + item.Type + '-'+index"
           :data="item"
           :tid="tid"
           :fileId="fileId"
@@ -47,7 +124,7 @@
           :dialogTagDataList="dialogTagDataList"
           ref="analysisItemRef"
           :bmData="bmData"
-          :key="item.id + item.Type"
+          :key="item.id + item.Type+'-' + index"
           :data="item"
           :tid="tid"
           :fileId="fileId"
@@ -62,19 +139,45 @@
         暂无模块...
       </div>
     </div>
+    <editNameDialog ref="editNameDialogRef" @success="editNameSuccess" />
   </div>
 </template>
 
 <script>
 import analysisItem from "./analysisItem";
 import analysisSpecialItem from "./analysisSpecialItem";
+import editNameDialog from "./editNameDialog.vue";
 var OpenCC = require("opencc-js");
 let converter2 = OpenCC.Converter({
-		from:'cn',
-		to:'hk'
-})
+  from: "cn",
+  to: "hk"
+});
+
+// 自定义指令,用于处理点击外部区域的事件
+const clickOutside = {
+  bind(el, binding) {
+    // 在元素上绑定一个点击事件监听器
+    el.clickOutsideEvent = function(event) {
+      // 检查点击事件是否发生在元素的内部
+      if (!(el === event.target || el.contains(event.target))) {
+        // 如果点击事件发生在元素的外部,则触发指令绑定的方法,将点击的event数据传过去
+        binding.value(event);
+      }
+    };
+    // 在文档上添加点击事件监听器
+    document.addEventListener("click", el.clickOutsideEvent);
+  },
+  unbind(el) {
+    // 在元素上解除点击事件监听器
+    document.removeEventListener("click", el.clickOutsideEvent);
+  }
+};
+
 export default {
   emits: ["delItem", "editItem", "saveItem"],
+  directives: {
+    "click-outside": clickOutside // 注册自定义指令
+  },
   props: {
     bmData: {
       type: Object,
@@ -117,7 +220,8 @@ export default {
   },
   components: {
     analysisItem,
-    analysisSpecialItem
+    analysisSpecialItem,
+    editNameDialog
   },
   computed: {
     converter() {
@@ -129,12 +233,29 @@ export default {
   data() {
     return {
       showDialog: false,
-      showItem: true
+      showItem: true,
+      visible: false,
+      form: {
+        name: ""
+      },
+      editTitle: false,
+      rules: {
+        name: [
+          { required: true, trigger: "change", message: "请输入新的名称" },
+          {
+            min: 1,
+            max: 20,
+            trigger: "change",
+            message: "长度需在1-20个字符之间"
+          }
+        ]
+      }
     };
   },
   methods: {
     addTemplate() {
       if (!this.tid) return this.$message.error("请新建课堂,或选择历史课堂");
+      this.visible = false;
       this.$emit("updateMessage", this.type);
     },
     changeShowItem(newValue) {
@@ -163,6 +284,32 @@ export default {
           ].editBtn(false);
         });
       }
+    },
+    editTitleFn() {
+      if (!this.tid) return this.$message.info("请新建课堂,或选择历史课堂");
+      this.form.name = this.title;
+      this.editTitle = true;
+      this.$nextTick(() => {
+        this.$refs.editNameInputRef.focus();
+      });
+      // this.$refs.editNameDialogRef.open(this.title)
+    },
+    editNameCheckFn() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          this.editTitle = false;
+          this.editNameSuccess(this.form.name);
+        } else {
+          this.$nextTick(() => {
+            this.$refs.editNameInputRef.focus();
+						this.$message.error("该名称不符合规则")
+          });
+        }
+      });
+    },
+    editNameSuccess(name) {
+      this.$emit("changeAnalysisName", { name: name, type: this.type });
+      // this.$refs.editNameDialogRef.close()
     }
   }
 };
@@ -182,27 +329,32 @@ export default {
 .analysis {
   width: 100%;
   height: auto;
+  margin-top: 20px;
 }
 
 .a-header {
-  width: 100%;
-  height: 50px;
+  width: calc(100% - 10px);
+  height: 60px;
   display: flex;
   align-items: center;
   justify-content: space-between;
   box-sizing: border-box;
-  padding-right: 10px;
+  padding: 0 10px;
+  background-color: #f8f9fa;
+  border-radius: 5px 5px 0 0;
 }
 
 .a-h-left {
   display: flex;
   align-items: center;
   cursor: pointer;
+  flex: 1;
+  height: 100%;
 }
 
 .a-h-l-icon {
-  width: 16px;
-  height: 16px;
+  width: 18px;
+  height: 18px;
   background: url("../../../../assets/icon/classroomObservation/right.svg")
     no-repeat;
   background-size: 100% 100%;
@@ -216,6 +368,7 @@ export default {
 
 .a-h-l-title {
   font-size: 18px;
+  font-weight: bold;
 }
 
 .a-h-r-btn {
@@ -241,8 +394,11 @@ export default {
 }
 
 .a-main {
-  width: calc(100%);
+  width: calc(100% - 10px - 30px);
   height: auto;
+  background-color: #fff;
+  border-radius: 0 0 5px 5px;
+  padding: 15px;
 }
 
 .a-dialog {
@@ -488,4 +644,95 @@ export default {
   font-size: 14px;
   color: #555555;
 }
+
+.a_h_r_more {
+  margin-right: 10px;
+  width: 35px;
+  height: 35px;
+}
+
+.a_h_r_more > img {
+  width: 35px;
+  height: 35px;
+  cursor: pointer;
+}
+
+.a_h_r_boxList {
+  width: auto;
+  height: auto;
+  position: absolute;
+  top: calc(100% - 10px);
+  right: 0;
+  border: 1px solid #e7e7e7;
+  box-shadow: 0px 8px 10px -5px #00000014;
+
+  box-shadow: 0px 16px 24px 2px #0000000a;
+
+  box-shadow: 0px 6px 30px 5px #0000000d;
+  border-radius: 8px;
+  background-color: #fff;
+  padding: 10px;
+  z-index: 10;
+}
+
+.a_h_r_boxList > div {
+  width: auto;
+  white-space: nowrap;
+  display: flex;
+  align-items: center;
+  box-sizing: border-box;
+  padding: 10px;
+  font-size: 14px;
+  background-color: #fff;
+  border-radius: 8px;
+  transition: 0.3s;
+  cursor: pointer;
+}
+
+.a_h_r_boxList > div:hover {
+  background-color: #f0f2f5;
+}
+
+.a_h_r_boxList > div > svg {
+  width: 16px;
+  height: 16px;
+  margin-right: 4px;
+}
+
+.a-h-right {
+  height: 100%;
+  display: flex;
+  align-items: center;
+  position: relative;
+}
+
+.a_h_l_edit {
+  width: 20px;
+  height: 20px;
+  margin-left: 10px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.a_h_l_edit > img {
+  width: 100%;
+  height: 100%;
+}
+.a_h_l_t_input {
+	width: 25%;
+	min-width: 220px;
+  height: 100%;
+  display: flex;
+  align-items: center;
+}
+
+.a_h_l_t_input>>>.el-form{
+	width: 100%;
+	min-width: 220px;
+}
+
+.a_h_l_t_input>>>.el-form-item{
+	margin-bottom: 0;
+}
 </style>

+ 130 - 9
src/components/pages/classroomObservation/components/analysisItem.vue

@@ -1,11 +1,29 @@
 <template>
 	<div class="analysisItem">
 		<div class="ai-header" v-show="data.jsonData.name != '词频词汇分析'">
-			<div class="ai-h-left" @click.stop="changeOpenItem(!openItem)">
+			<div class="ai-h-left" @click="changeOpenItem(!openItem)">
 				<span
 					:class="['ai-h-l-icon', openItem ? 'ai-h-l-iconActive' : '']"
 				></span>
-				<span class="ai-h-l-text">{{ data.jsonData.name }}</span>
+				<span class="ai-h-l-text" v-if="!editTitle">{{ data.jsonData.anotherName?data.jsonData.anotherName:data.jsonData.name }}</span>
+				<div class="a_h_l_t_input" v-if="editTitle" @click.stop="() => {}">
+          <el-form ref="form" :model="form" :rules="rules" label-position="top">
+            <el-form-item prop="name">
+              <el-input
+                v-model="form.name"
+               	@blur="editNameCheckFn()"
+                ref="editNameInputRef"
+                placeholder="请输入新的名称"
+              ></el-input>
+            </el-form-item>
+						<!--   @blur="editNameCheckFn()" -->
+          </el-form>
+        </div>
+				<el-tooltip v-if="!editTitle" class="item" effect="light" content="修改名称" placement="top">
+    		  <span class="a_h_l_edit" @click.stop="editTitleFn()">
+						<img src="../../../../assets/icon/classroomObservation/editIcon2.svg">
+					</span>
+    		</el-tooltip>
 			</div>
 			<div class="ai-h-right">
 				<span style="width: 100px;" class="generateError" v-if="loadNum == 2"
@@ -27,7 +45,7 @@
 				<span
 					v-if="loadNum == 0 && !openItem && tid"
 					class="ai-h-r-icon4"
-					@click.stop="delBtn()"
+					@click="delBtn()"
 				>
 					<el-tooltip
 						class="item"
@@ -46,7 +64,7 @@
 				<span
 					v-if="loadNum == 0 && openItem"
 					:class="['ai-h-r-icon1', showIndex <= 0 ? 'ai_h_r_iconOpacity' : '']"
-					@click.stop="changeShowIndex(-1)"
+					@click="changeShowIndex(-1)"
 				>
 					<el-tooltip
 						class="item"
@@ -67,7 +85,7 @@
 					:class="[
 						showIndex >= historyResult.length - 1 ? 'ai_h_r_iconOpacity' : '',
 					]"
-					@click.stop="changeShowIndex(1)"
+					@click="changeShowIndex(1)"
 				>
 					<el-tooltip
 						class="item"
@@ -83,7 +101,7 @@
 					</el-tooltip>
 				</span>
 
-				<span v-if="loadNum != 1 && openItem && tid" @click.stop="editBtn()">
+				<span v-if="loadNum != 1 && openItem && tid" @click="editBtn()">
 					<el-tooltip
 						class="item"
 						effect="light"
@@ -107,7 +125,9 @@
 				<!-- <mdView :text="data.jsonData.result" /> -->
 				<!-- {{ data.jsonData.result }} -->
 			</div>
-			<mdView :text="data.jsonData.content" />
+
+			<eChartTemplate style="width: 100%;height: 400px;" :data="data.jsonData.eChartData" v-if="data.jsonData.eChartData"/>
+			<mdView :text="data.jsonData.content"/>
 			<div v-for="(item, index) in data.jsonData.dataFileList" :key="item.uid">
 				<div v-if="imgTypeList.includes(checkFileType(item.url))">
 					<img style="max-width: 100%" :src="item.url" alt="" />
@@ -132,6 +152,7 @@
 				</div>
 			</div>
 		</div>
+		<!-- <editNameDialog ref="editNameDialogRef" @success="changeNameSuccess"/> -->
 	</div>
 </template>
 
@@ -139,11 +160,15 @@
 import mdView from "./mdView.vue";
 import pieChart from "./pieChart.vue";
 import { v4 as uuidv4 } from "uuid";
+import eChartTemplate from "./eChartTemplate";
+// import editNameDialog from './editNameDialog.vue'
 export default {
 	emits: ["delItem", "editItem", "saveItem"],
 	components: {
 		mdView,
 		pieChart,
+		eChartTemplate
+		// editNameDialog
 	},
 	props: {
 		data: {
@@ -201,6 +226,21 @@ export default {
 				"tiff",
 			],
 			oldData: {},
+			form: {
+        name: ""
+      },
+      editTitle: false,
+      rules: {
+        name: [
+          { required: true, trigger: "change", message: "请输入新的名称" },
+          {
+            min: 1,
+            max: 20,
+            trigger: "change",
+            message: "长度需在1-20个字符之间"
+          }
+        ]
+      }
 		};
 	},
 	computed: {
@@ -232,6 +272,8 @@ export default {
 				this.loadNum = 1;
 				let type = 0;//0 用agentId  1:用提示词 3:啥都没有
 				let assistant = this.dialogTagDataList.find(
+					(i) => i.id == this.data.jsonData.mId
+				) || this.dialogTagDataList.find(
 					(i) => i.name == this.data.jsonData.name
 				);
 
@@ -417,6 +459,39 @@ export default {
 			this.$emit("editItem", this.data.id, _copyData);
 			this.$emit("saveItem", this.data.id, _copyData);
 		},
+		// editTitle(){
+		// 	this.$refs.editNameDialogRef.open(this.data.jsonData.anotherName?this.data.jsonData.anotherName:this.data.jsonData.name)
+		// },
+		changeNameSuccess(newName){
+			let _copyData = JSON.parse(JSON.stringify(this.data));
+			_copyData.jsonData.anotherName = newName;
+			_copyData.json_data = JSON.stringify(_copyData.jsonData);
+			this.$emit("editItem", this.data.id, _copyData);
+			this.$emit("saveItem", this.data.id, _copyData);
+			// this.$refs.editNameDialogRef.close();
+		},
+		editTitleFn() {
+      if (!this.tid) return this.$message.info("请新建课堂,或选择历史课堂");
+      this.form.name = this.data.jsonData.anotherName?this.data.jsonData.anotherName:this.data.jsonData.name;
+      this.editTitle = true;
+      this.$nextTick(() => {
+        this.$refs.editNameInputRef.focus();
+      });
+      // this.$refs.editNameDialogRef.open(this.title)
+    },
+    editNameCheckFn() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          this.editTitle = false;
+          this.changeNameSuccess(this.form.name);
+        } else {
+          this.$nextTick(() => {
+            this.$refs.editNameInputRef.focus();
+						this.$message.error("该名称不符合规则")
+          });
+        }
+      });
+    },
 	},
 	mounted() {
 		if (this.data.jsonData.content) {
@@ -431,10 +506,18 @@ export default {
 	width: 100%;
 	height: auto;
 
-	margin: 11.7px 0px;
+	/* margin: 11.7px 0px; */
 
 	padding-right: 10px;
 	box-sizing: border-box;
+	margin-bottom:10px ;
+	border: 1px solid #E7E7E7;
+	border-radius: 4px;
+	transition: .3s;
+}
+
+.analysisItem:hover{
+	border: 1px solid #3681FC;
 }
 .text1 {
 	color: rgba(54, 129, 252, 1);
@@ -520,13 +603,16 @@ export default {
 
 .ai-header:hover .ai-h-r-icon4 {
 	display: block;
+	/* opacity: 1; */
 }
 
 .ai-h-r-icon4 {
-	background: url("../../../../assets/icon/classroomObservation/del.svg");
+	background: url("../../../../assets/icon/classroomObservation/del2.svg");
 	/* position: absolute; */
 	/* right: -40px; */
 	display: none;
+	/* opacity: 0; */
+	/* transition: .3s; */
 }
 
 .analysisItem:hover .ai-h-r-icon4 {
@@ -588,4 +674,39 @@ th {
 	display: flex;
 	align-items: center;
 }
+
+.a_h_l_edit{
+	width: 16px;
+	height: 16px;
+	margin-left: 10px;
+	display: none;
+	align-items: center;
+	justify-content: center;
+}
+
+.a_h_l_edit>img{
+	width: 100%;
+	height: 100%;
+}
+
+.ai-h-left:hover .a_h_l_edit{
+	display: flex;
+}
+
+.a_h_l_t_input {
+	width: 25%;
+	min-width: 220px;
+  height: 100%;
+  display: flex;
+  align-items: center;
+}
+
+.a_h_l_t_input>>>.el-form{
+	width: 100%;
+	min-width: 220px;
+}
+
+.a_h_l_t_input>>>.el-form-item{
+	margin-bottom: 0;
+}
 </style>

+ 102 - 7
src/components/pages/classroomObservation/components/analysisSpecialItem.vue

@@ -5,7 +5,26 @@
 				<span
 					:class="['ai-h-l-icon', openItem ? 'ai-h-l-iconActive' : '']"
 				></span>
-				<span class="ai-h-l-text">{{ data.jsonData.name }}</span>
+				<span class="ai-h-l-text" v-if="!editTitle">{{ data.jsonData.anotherName?data.jsonData.anotherName:data.jsonData.name }}</span>
+
+				<div class="a_h_l_t_input" v-if="editTitle" @click.stop="() => {}">
+          <el-form ref="form" :model="form" :rules="rules" label-position="top">
+            <el-form-item prop="name">
+              <el-input
+                v-model="form.name"
+               	@blur="editNameCheckFn()"
+                ref="editNameInputRef"
+                placeholder="请输入新的名称"
+              ></el-input>
+            </el-form-item>
+						<!--   @blur="editNameCheckFn()" -->
+          </el-form>
+        </div>
+				<el-tooltip v-if="!editTitle" class="item" effect="light" content="修改名称" placement="top">
+    		  <span class="a_h_l_edit" @click.stop="editTitleFn()">
+						<img src="../../../../assets/icon/classroomObservation/editIcon2.svg">
+					</span>
+    		</el-tooltip>
 			</div>
 			<div class="ai-h-right">
 				<span style="width: 100px" class="generateError" v-if="loadNum == 2"
@@ -134,6 +153,7 @@
 			</div>
 			<mdView :text="data.jsonData.content" />
 		</div>
+		<!-- <editNameDialog ref="editNameDialogRef" @success="changeNameSuccess"/> -->
 	</div>
 </template>
 
@@ -145,12 +165,13 @@ let converter2 = OpenCC.Converter({
 })
 import mdView from "./mdView.vue";
 import eChartTemplate from "./eChartTemplate";
-
+// import editNameDialog from './editNameDialog.vue'
 export default {
 	emits: ["delItem", "editItem", "saveItem"],
 	components: {
 		mdView,
 		eChartTemplate,
+		// editNameDialog
 	},
 	props: {
 		data: {
@@ -209,6 +230,21 @@ export default {
 				"tiff",
 			],
 			oldData: {},
+			form: {
+        name: ""
+      },
+      editTitle: false,
+      rules: {
+        name: [
+          { required: true, trigger: "change", message: "请输入新的名称" },
+          {
+            min: 1,
+            max: 20,
+            trigger: "change",
+            message: "长度需在1-20个字符之间"
+          }
+        ]
+      }
 		};
 	},
 	computed: {
@@ -335,7 +371,8 @@ export default {
 			};
 		},
 		getData() {
-			if (this.bmData.editorBarData.type != 0) {
+			if (!this.bmData.editorBarData || this.bmData.editorBarData.type != 0) {
+				this.loadNum = 2;
 				return this.$message.info("请上传表格形式的转录文稿");
 			}
 			try {
@@ -352,8 +389,8 @@ export default {
 						endTime: i.cells[2].textContent,
 						message: i.cells[3].textContent,
 						time: i.cells[4].textContent,
-						role: i.cells[5].textContent,
-						behavior: i.cells[6].textContent,
+						role: i.cells[5]?i.cells[5].textContent:'',
+						behavior: i.cells[6]?i.cells[6].textContent:'',
 					};
 					_result.push(obj);
 				});
@@ -601,7 +638,38 @@ export default {
 		  let parts = time.split(':');
 		  let seconds = (+parts[0]) * 3600 + (+parts[1]) * 60 + (+parts[2]);
 		  return seconds;
-		}
+		},
+		
+		changeNameSuccess(newName){
+			let _copyData = JSON.parse(JSON.stringify(this.data));
+			_copyData.jsonData.anotherName = newName;
+			_copyData.json_data = JSON.stringify(_copyData.jsonData);
+			this.$emit("editItem", this.data.id, _copyData);
+			this.$emit("saveItem", this.data.id, _copyData);
+			// this.$refs.editNameDialogRef.close();
+		},
+		editTitleFn() {
+      if (!this.tid) return this.$message.info("请新建课堂,或选择历史课堂");
+      this.form.name = this.data.jsonData.anotherName?this.data.jsonData.anotherName:this.data.jsonData.name;
+      this.editTitle = true;
+      this.$nextTick(() => {
+        this.$refs.editNameInputRef.focus();
+      });
+      // this.$refs.editNameDialogRef.open(this.title)
+    },
+    editNameCheckFn() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          this.editTitle = false;
+          this.changeNameSuccess(this.form.name);
+        } else {
+          this.$nextTick(() => {
+            this.$refs.editNameInputRef.focus();
+						this.$message.error("该名称不符合规则")
+          });
+        }
+      });
+    },
 	},
 	mounted() {
 		if (this.data.jsonData.content) {
@@ -616,10 +684,18 @@ export default {
 	width: 100%;
 	height: auto;
 
-	margin: 11.7px 0px;
+	/* margin: 11.7px 0px; */
 
 	padding-right: 10px;
 	box-sizing: border-box;
+	margin-bottom:10px ;
+	border: 1px solid #E7E7E7;
+	border-radius: 4px;
+	transition: .3s;
+}
+
+.analysisItem:hover{
+	border: 1px solid #3681FC;
 }
 .text1 {
 	color: rgba(54, 129, 252, 1);
@@ -799,4 +875,23 @@ th {
 	/* 斜体字 */
 	font-style: italic;
 }
+
+
+.a_h_l_edit{
+	width: 16px;
+	height: 16px;
+	margin-left: 10px;
+	display: none;
+	align-items: center;
+	justify-content: center;
+}
+
+.a_h_l_edit>img{
+	width: 100%;
+	height: 100%;
+}
+
+.ai-h-left:hover .a_h_l_edit{
+	display: flex;
+}
 </style>

+ 7 - 4
src/components/pages/classroomObservation/components/analysisTemplateDialog.vue

@@ -719,8 +719,12 @@ export default {
 			this.$refs.addNewAnalysisDialogRef.open(type);
 		},
 		//添加某条
-		addNewAnalysisItem(name) {
-			let _data = this.dataList.find((i) => i.name == name);
+		addNewAnalysisItem(name,id) {
+			let _data = this.dataList.find(
+					(i) => i.id == id
+				) || this.dataList.find(
+					(i) => i.name == name
+				);
 			console.log(_data)
 			this.analysisDetail.tips.push({
 				id: "",
@@ -968,8 +972,7 @@ export default {
 	width: 100%;
 	height: 100%;
 	background-color: #f0f2f5;
-	overflow: scroll;
-	overflow-x: hidden;
+	overflow: auto;
 	box-sizing: border-box;
 	padding: 15px;
 	padding-bottom: 50px;

+ 33 - 8
src/components/pages/classroomObservation/components/baseMessage.vue

@@ -1,6 +1,6 @@
 <template>
 	<div class="message">
-		<div class="m-header" @click.stop="changeShowMain(!showMain)">
+		<div class="m-header" :style="showMain?'':'border-radius:5px'" @click.stop="changeShowMain(!showMain)">
 			<span :class="['m-h-icon', showMain ? 'm-h-icon-active' : '']"></span>
 			<span class="m-h-title">{{ title }}</span>
 		</div>
@@ -30,17 +30,21 @@
 
 				<div class="m-m-formItem" style="width: clamp(22%,22%,22%)"">
 					<div class="m-m-fi-label">授课时间</div>
-					<div class="m-m-fi-input">
+					<div class="m-m-fi-input" style="position: relative;">
 						<el-date-picker
 							v-model="data.time"
 							type="datetime"
 							format="yyyy-MM-dd HH:mm:ss"
 							value-format="yyyy-MM-dd HH:mm:ss"
-							style="width: 100%"
+							style="width: 100%;"
+							class="m_m_fi_inputDisabledIcon"
+							prefix-icon="none"
 							@change="changeData()"
 							placeholder="请选择授课时间"
 						>
+						
 						</el-date-picker>
+						<i class="el-icon-date" style="position: absolute; right: 10px; top: 50%; transform: translateY(-50%); pointer-events: none;"></i>
 					</div>
 				</div>
 
@@ -787,6 +791,7 @@ ${this.data.editorBarData?this.data.editorBarData.content:""}
 .message {
 	width: 100%;
 	height: auto;
+	/* background-color: red; */
 }
 .imgTit {
 	height: 40px;
@@ -834,16 +839,20 @@ ${this.data.editorBarData?this.data.editorBarData.content:""}
 }
 
 .m-header {
-	width: 100%;
-	height: 50px;
+	width: calc(100% - 10px);
+	height: 60px;
 	display: flex;
 	align-items: center;
 	cursor: pointer;
+	border-radius: 5px 5px 0 0;
+	box-sizing: border-box;
+	padding: 0 10px;
+	background-color: #F8F9FA;
 }
 
 .m-h-icon {
-	width: 16px;
-	height: 16px;
+	width: 18px;
+	height: 18px;
 	background: url("../../../../assets/icon/classroomObservation/right.svg")
 		no-repeat;
 	background-size: 100% 100%;
@@ -857,12 +866,13 @@ ${this.data.editorBarData?this.data.editorBarData.content:""}
 
 .m-h-title {
 	font-size: 18px;
+	font-weight: bold;
 }
 
 .m-main {
 	width: calc(100% - 10px);
 	height: auto;
-	border-radius: 5px;
+	border-radius:0 0 5px 5px;
 	background-color: #ffffff;
 	padding: 20px 20px 0 20px;
 	box-sizing: border-box;
@@ -893,6 +903,14 @@ ${this.data.editorBarData?this.data.editorBarData.content:""}
 	max-width: 100%;
 }
 
+.m_m_fi_inputDisabledIcon>>> .el-input__prefix{
+	display: none;
+}
+
+.m_m_fi_inputDisabledIcon>>>.el-input__inner{
+	padding-left: 15px;
+}
+
 .m-m-fi-label {
 	font-size: 16px;
 	display: flex;
@@ -938,6 +956,9 @@ ${this.data.editorBarData?this.data.editorBarData.content:""}
 	cursor: pointer;
 	position: relative;
 	margin-bottom: 10px;
+	border-radius: 4px;
+	border: dashed 1px #DCDCDC;
+	overflow: hidden;
 }
 .m-m-fi-imageItem > .itemUrl {
 	width: 100%;
@@ -1081,6 +1102,10 @@ ${this.data.editorBarData?this.data.editorBarData.content:""}
 	cursor: pointer;
 	position: relative;
 	margin-bottom: 10px;
+	border-radius: 4px;
+	border: dashed 1px #DCDCDC;
+	overflow: hidden;
+
 }
 .m-m-fi-nephogramItem> .itemUrl {
 	width: 100%;

+ 110 - 9
src/components/pages/classroomObservation/components/chatArea.vue

@@ -149,6 +149,29 @@
               </div>
             </div>
 
+            <!-- <div class="ca-b-o-h-l-btn">
+              <div class="ca-b-o-h-b-l-text" @click.stop="showTeacherVoiceprintBox = !showTeacherVoiceprintBox">{{choseTeacherVoiceprint?choseTeacherVoiceprint.name+'的':'教师'}}声纹</div>
+              <div class="ca_teacherVoiceprintBox" style="cursor: default;" v-click-outside="()=>showTeacherVoiceprintBox = !showTeacherVoiceprintBox" v-if="showTeacherVoiceprintBox">
+                <div class="ca_tvb_itemHead" @click.stop="test()">
+                  <svg
+                    width="12"
+                    height="12"
+                    viewBox="0 0 12 12"
+                    fill="none"
+                    xmlns="http://www.w3.org/2000/svg"
+                  >
+                    <path d="M5.33337 2H6.66671V10H5.33337V2Z" fill="#3681FC" />
+                    <path
+                      d="M10 5.33301V6.66634H2V5.33301H10Z"
+                      fill="#3681FC"
+                    />
+                  </svg>
+                  添加声纹
+                </div>
+                <div :class="['ca_tvb_item',(choseTeacherVoiceprint&&choseTeacherVoiceprint.id==item.id)?'ca_tvb_itemActive':'']" v-for="item in teacherVoiceprintList" :key="item.id" @click.stop="choseTeacherVoiceprintFn(item)">{{ item.name }}</div>
+              </div>
+            </div> -->
+
             <div
               class="ca-b-o-h-l-btn"
               @click.stop="uploadRecording()"
@@ -441,6 +464,7 @@
       </div>
       <!-- <el-progress style="width:80%" :text-inside="true" :stroke-width="24" :percentage="progressData.value"></el-progress> -->
     </div>
+		<addNewTeacherVoiceprintDialog ref="addNewTeacherVoiceprintDialogRef"/>
   </div>
 </template>
 
@@ -456,6 +480,7 @@ const lamejs = require("lamejs");
 import vpdf from "./vpdf";
 import _ from "lodash";
 import Papa from "papaparse";
+import addNewTeacherVoiceprintDialog from "./addNewTeacherVoiceprintDialog.vue";
 // const recorder = new Recorder({
 // 	sampleBits: 16, // 采样位数,支持 8 或 16,默认是16
 // 	sampleRate: 48000, // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
@@ -578,7 +603,8 @@ export default {
     transcription,
     tape,
     EditorBar,
-    vpdf
+    vpdf,
+		addNewTeacherVoiceprintDialog
   },
   directives: {
     "click-outside": clickOutside // 注册自定义指令
@@ -664,7 +690,18 @@ export default {
       },
       chatList: [],
       actionTypesMap: {},
-      jobContext: null
+      jobContext: null,
+			showTeacherVoiceprintBox:false,
+			choseTeacherVoiceprint:null,
+			teacherVoiceprintList:[
+				{id:0,name:"李正红"},
+				{id:1,name:"李大壮"},
+				{id:2,name:"李小米"},
+				{id:3,name:"李儒文"},
+				{id:4,name:"覃某某"},
+				{id:5,name:"覃彤彤"},
+
+			],
     };
   },
   computed: {
@@ -1728,11 +1765,11 @@ ${JSON.stringify(_list)}
       }
       let iiframe = this.$refs["iiframe"];
       let _this = this;
-			// this.uploadFile(_file,{changeText:false,flag:true})
+      // this.uploadFile(_file,{changeText:false,flag:true})
       // return console.log(_file);
-			
-			console.log("将转录的文件👇")
-			console.log(_file)
+
+      console.log("将转录的文件👇");
+      console.log(_file);
 
       iiframe.contentWindow.window.document.getElementById(
         "languageOptions"
@@ -1885,7 +1922,7 @@ ${JSON.stringify(_list)}
               // 	console.log("这hi是一个txt文件")
               // } else if(otherRegex.test(data.Location)){
               //
-							console.log(data.Location)
+              console.log(data.Location);
               if (audioRegex.test(data.Location)) {
                 if (changeText) _this.wavFileGetText(file);
                 _this.$emit("changeAudioUrl", data);
@@ -2150,7 +2187,7 @@ ${JSON.stringify(_list)}
             while (i.cells.length > 7) {
               i.removeChild(i.lastElementChild);
             }
-            const actionTypeCell = i.cells[6] && i.removeChild(i.cells[6]);
+            const actionTypeCell = i.cells[6];
             _editorBarDataContentRows.push(i.outerHTML);
             if (index == 0) return;
             if (i.cells[3].textContent != "") {
@@ -2335,6 +2372,7 @@ ${JSON.stringify(_list)}
         url: ""
       };
       this.audioUrl = "";
+			this.choseTeacherVoiceprint = null;
     },
     async loadActionTypesMap() {
       const res = await this.ajax.post(
@@ -2597,7 +2635,20 @@ ${JSON.stringify(_list)}
       for (let i = 0; i < string.length; i++) {
         view.setUint8(offset + i, string.charCodeAt(i));
       }
-    }
+    },
+		addNewTeacherVoiceprintBtn(){
+			this.showTeacherVoiceprintBox = false;
+			this.$refs.addNewTeacherVoiceprintDialogRef.open();
+		},
+		choseTeacherVoiceprintFn(item){
+			if(this.choseTeacherVoiceprint && item.id == this.choseTeacherVoiceprint.id)return this.choseTeacherVoiceprint = null;
+			this.showTeacherVoiceprintBox = false;
+			this.choseTeacherVoiceprint = item;
+			console.log("选择声纹")
+		},
+		test(){
+			console.log(this.editorBarData)
+		}
   },
   mounted() {}
 };
@@ -2817,6 +2868,56 @@ ${JSON.stringify(_list)}
   border-radius: 15px;
   background-color: white;
   cursor: pointer;
+  position: relative;
+}
+
+.ca_teacherVoiceprintBox {
+  width: auto;
+  height: auto;
+  background-color: #fff;
+  padding: 10px;
+  position: absolute;
+  bottom: calc(100% + 5px);
+  border-radius: 4px;
+  left: 0;
+  box-shadow: 0px 2px 4px -1px #0000001f;
+
+  box-shadow: 0px 4px 5px 0px #00000014;
+
+  box-shadow: 0px 1px 10px 0px #0000000d;
+}
+
+.ca_teacherVoiceprintBox > div {
+  width: 100px;
+  padding: 8px;
+  margin-top: 10px;
+  border-radius: 4px;
+  background-color: #fff;
+  transition: 0.3s;
+  cursor: pointer;
+}
+
+.ca_teacherVoiceprintBox > div:hover {
+  background-color: #f3f7fd;
+}
+
+.ca_tvb_itemHead{
+	width: 100%;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	color: #3681FC;
+	margin-top: 0 !important;
+	border: solid 1px #3681FC;
+}
+
+.ca_tvb_itemHead>svg{
+	margin-right: 5px;
+}
+
+.ca_tvb_itemActive{
+	color: #3681FC;
+	background-color: #f3f7fd !important;
 }
 
 .ca-b-o-h-right {

+ 81 - 0
src/components/pages/classroomObservation/components/editNameDialog.vue

@@ -0,0 +1,81 @@
+<template>
+	<div class="addNewCourse">
+		<el-dialog title="修改名称" :visible.sync="dialogVisible" width="500px">
+			<div>
+				<el-form ref="form" :model="form" :rules="rules" label-position="top">
+					<el-form-item label="名称" prop="name">
+						<el-input
+							v-model="form.name"
+							placeholder="请输入新的名称"
+						></el-input>
+					</el-form-item>
+				</el-form>
+			</div>
+			<span slot="footer" class="dialog-footer">
+				<el-button @click="dialogVisible = false">取 消</el-button>
+				<el-button type="primary" @click="submit('form')">确 定</el-button>
+			</span>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+export default {
+	emits: ["success"],
+	props: {
+	
+	},
+	data() {
+		// let validateNo = (rule, value, callback) => {
+		// 	if (value.trim().length == 0) {
+		// 		callback(new Error("请输入课堂编号"));
+		// 	}else if(this.courseList.findIndex(i=>i.value==value.trim())!=-1){
+		// 		callback(new Error("该课堂编号已存在"));
+		// 	} else {
+		// 		callback();
+		// 	}
+		// };
+		// let validateName = (rule, value, callback) => {
+		// 	if (value.trim().length == 0) {
+		// 		callback(new Error("请输入课堂名称"));
+		// 	} else {
+		// 		callback();
+		// 	}
+		// };
+		return {
+			dialogVisible: false,
+			form: {
+				name: "",
+			},
+			rules: {
+				name: [
+					{ required:true,trigger: "change",message:"请输入新的名称"},
+					{min:1,max:20,trigger: "change",message:"长度需在1-20个字符之间"}
+			],
+			},
+		};
+	},
+	methods: {
+		open(name='新的名称') {
+			this.form.name = name;
+			this.dialogVisible = true;
+		},
+		close(){
+			this.dialogVisible = false;
+		},
+		submit(formName) {
+			this.$refs[formName].validate((valid) => {
+				if (valid) {
+					this.$emit("success", this.form.name);
+				} else {
+					return false;
+				}
+			});
+		},
+	},
+};
+</script>
+
+<style scoped>
+
+</style>

文件差異過大導致無法顯示
+ 956 - 1087
src/components/pages/classroomObservation/components/messageArea.vue


+ 213 - 127
src/components/pages/classroomObservation/components/startPage.vue

@@ -1,21 +1,42 @@
 <template>
-	<div class="startPage">
-		<div class="sp-introduce" v-if="showIntroduce">
-			<span class="sp-i-personIcon"></span>
-			<div class="sp-i-p-p">
-				<div class="sp-i-title">您好,我是 CocoClass 课堂观察</div>
-				<div class="sp-i-brief">
-					基于课堂录音和实录文稿进行分析,为您提供不同启发。
-				</div>
-			</div>
+  <div class="startPage">
+    <div class="sp-introduce" v-if="showIntroduce">
+      <!-- <span class="sp-i-personIcon"></span> -->
+      <img
+        src="../../../../assets/icon/classroomObservation/aiImage2.png"
+        alt=""
+      />
+      <div class="sp-i-p-p">
+        <div class="sp-i-title">您好,欢迎来到课堂观察</div>
+        <div class="sp-i-brief">
+          <!-- 基于课堂录音和实录文稿进行分析,为您提供不同启发。 -->
+          实时将会议录音转为文字,AI 自动生成会议纪要。
+        </div>
+      </div>
 
-			<!-- <span class="sp-i-icon1"></span>
+      <!-- <span class="sp-i-icon1"></span>
 			<span class="sp-i-icon2"></span> -->
-			<div class="sp-i-btn" @click="showIntroduce = false">我已了解并关闭</div>
-		</div>
-		<div class="sp-main">
-			<div class="sp-m-item" @click.stop="$emit('startTape')">
-				<!-- <span class="sp-m-i-icon1"></span> -->
+      <div class="sp-i-btn" @click="showIntroduce = false">我已了解并关闭</div>
+    </div>
+    <div class="sp-main">
+      <div class="sp_m_box">
+        <div class="sp_m_b_top"></div>
+        <div class="sp_m_b_bottom">
+          <div  @click.stop="$emit('startTape')">
+						<div>开始录音</div>
+						<span>实时语音转录文字</span>
+						<span>智能课堂观察</span>
+						<img src="../../../../assets/icon/classroomObservation/startPageIcon2.png">
+					</div>
+          <div  @click.stop="$emit('uploadTape')">
+						<div>上传文件</div>
+						<span>录音复盘</span>
+						<span>一键分析课堂情况</span>
+						<img src="../../../../assets/icon/classroomObservation/startPageIcon1.png">
+					</div>
+        </div>
+      </div>
+      <!-- <div class="sp-m-item" @click.stop="$emit('startTape')">
 				<div class="sp-m-item1">开始录音</div>
 				<div class="sp-m-item2">
 					<p>实时语音转录文字</p>
@@ -37,7 +58,6 @@
 				</div>
 			</div>
 			<div class="sp-m-item" @click.stop="$emit('uploadTape')">
-				<!-- <span class="sp-m-i-icon2"></span> -->
 				<div class="sp-m-item1">上传文件</div>
 				<div class="sp-m-item2">
 					<p>上传录音或实录文稿</p>
@@ -50,170 +70,236 @@
 							alt=""
 						/>
 				</div>
-			</div>
-		</div>
-	</div>
+			</div> -->
+    </div>
+  </div>
 </template>
 
 <script>
 export default {
-	emits: ["startTape", "uploadTape"],
-	data() {
-		return {
-			showIntroduce: true,
-		};
-	},
-	methods: {},
+  emits: ["startTape", "uploadTape"],
+  data() {
+    return {
+      showIntroduce: true
+    };
+  },
+  methods: {}
 };
 </script>
 
 <style scoped>
 .startPage {
-	width: 100%;
-	height: calc(100vh - 290px);
-	position: relative;
-	display: flex;
-	flex-direction: column;
-	overflow: auto;
+  width: 100%;
+  height: calc(100vh - 290px);
+  position: relative;
+  display: flex;
+  flex-direction: column;
+  overflow: auto;
 }
 
 .sp-introduce {
-	width: 100%;
-	min-height: 116px;
-	height: 116px;
-	background-color: #e2eeff;
-	display: flex;
-	flex-direction: column;
-	box-sizing: border-box;
-	padding-left: 220px;
-	padding-top: 20px;
-	position: relative;
-	margin-top: 7%;
+  width: 100%;
+  min-height: 116px;
+  height: 116px;
+  background-color: #e2eeff;
+  display: flex;
+  flex-direction: column;
+  box-sizing: border-box;
+  padding-left: 220px;
+  padding-top: 20px;
+  position: relative;
+  margin-top: 7%;
+}
+
+.sp-introduce > img {
+  width: 200px;
+  position: absolute;
+  left: 0px;
+  bottom: 0;
 }
 
 .sp-i-title {
-	font-size: 24px;
-	font-weight: 600;
-	color: #3681fc;
+  font-size: 24px;
+  font-weight: 600;
+  color: #3681fc;
 }
 
 .sp-i-p-p {
-	position: absolute;
-	bottom: 30%;
+  position: absolute;
+  bottom: 30%;
 }
 
 .sp-i-title > span {
-	margin: 0 10px;
-	white-space: nowrap;
+  margin: 0 10px;
+  white-space: nowrap;
 }
 
 .sp-i-brief {
-	font-size: 14px;
-	margin-top: 10px;
+  font-size: 14px;
+  margin-top: 10px;
 }
 
 .sp-i-personIcon {
-	width: 200px;
-	height: 200px;
-	position: absolute;
-	left: 0px;
-	bottom: 0;
-	background: url("../../../../assets/icon/classroomObservation/aiImage.png")
-		no-repeat;
-	background-size: 100% 100%;
-	background-position: center 20px;
+  width: 200px;
+  /* height: 200px; */
+  position: absolute;
+  left: 0px;
+  bottom: 0;
+  background: url("../../../../assets/icon/classroomObservation/aiImage2.png")
+    no-repeat;
+  background-size: 100% 100%;
+  background-position: center 20px;
 }
 
 .sp-i-btn {
-	width: auto;
-	height: auto;
-	padding: 5px 10px;
-	position: absolute;
-	right: 10px;
-	bottom: 10px;
-	background-color: #3a76fc;
-	font-size: 12px;
-	border-radius: 20px;
-	cursor: pointer;
-	color: white;
+  width: auto;
+  height: auto;
+  padding: 5px 10px;
+  position: absolute;
+  right: 10px;
+  bottom: 10px;
+  background-color: #3a76fc;
+  font-size: 12px;
+  border-radius: 20px;
+  cursor: pointer;
+  color: white;
 }
 
 .sp-main {
-	width: 80%;
-	margin: 10px auto;
-	flex: 1;
-	display: flex;
-	/* align-items: flex-end; */
-	align-items: center;
-	/* align-content: center; */
-	justify-content: space-around;
-	box-sizing: border-box;
-	/* padding-bottom: 15%; */
+  width: 80%;
+  margin: 10px auto;
+  flex: 1;
+  display: flex;
+  align-items: flex-end;
+  /* align-content: center; */
+  justify-content: space-around;
+  box-sizing: border-box;
+  /* padding-bottom: 15%; */
 }
 
-.sp-m-item {
-	width: 220px;
-	height: 330px;
-	gap: 0px;
-	display: flex;
+.sp_m_box {
+  width: 70%;
+  height: 100%;
+	/* max-height: 550px; */
+	max-height: 400px;
+  display: flex;
+  flex-direction: column;
+  margin-bottom: 8%;
+}
+
+.sp_m_b_bottom {
+  width: 100%;
+  flex: 1;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+
+.sp_m_b_bottom > div {
+  height: 100%;
+  flex: 1;
+  display: flex;
+  /* align-items: center; */
+  /* justify-content: center; */
+  box-sizing: border-box;
+  border: 1px solid #aeccfe;
+  box-shadow: 0px 4px 10px 0px #1d398314;
+
+  box-shadow: 1px 1px 20px 4px #1d39830d;
+	background-color: #fff;
+	border-radius: 8px;
+	padding: 40px;
 	flex-direction: column;
-	border-radius: 8px 0px 0px 0px;
-	/* opacity: 0px; */
-	background: rgba(224, 234, 251, 1);
-	box-sizing: border-box;
-	padding: 20px;
-	border-radius: 10px;
 	cursor: pointer;
+	position: relative;
+}
+
+.sp_m_b_bottom > div>img{
+	width: 50%;
+	position: absolute;
+	right: 0;
+	bottom: 0;
+}
+
+.sp_m_b_bottom > div>div{
+	font-size: 30px;
+	font-weight: bold;
+	margin-bottom: 10px;
+}
+
+.sp_m_b_bottom > div>span{
+	margin-top: 5px;
+	color: #00000066;
+}
+
+.sp_m_b_bottom > div:nth-of-type(2) {
+  margin-left: 20px;
+}
+
+.sp-m-item {
+  width: 220px;
+  height: 330px;
+  gap: 0px;
+  display: flex;
+  flex-direction: column;
+  border-radius: 8px 0px 0px 0px;
+  /* opacity: 0px; */
+  background: rgba(224, 234, 251, 1);
+  box-sizing: border-box;
+  padding: 20px;
+  border-radius: 10px;
+  cursor: pointer;
 }
 .sp-m-item1 {
-	font-family: PingFang SC;
-	font-size: 28px;
-	font-weight: 600;
-	line-height: 36px;
-	text-align: left;
+  font-family: PingFang SC;
+  font-size: 28px;
+  font-weight: 600;
+  line-height: 36px;
+  text-align: left;
 }
 .sp-m-item2 {
-	margin: 20px 0;
-	margin: 0;
+  margin: 20px 0;
+  margin: 0;
 }
 .sp-m-item2 {
-	font-size: 14px;
-	font-weight: normal;
-	margin: 20px 0; 
+  font-size: 14px;
+  font-weight: normal;
+  margin: 20px 0;
 }
-.sp-m-item2 > p{
-	margin: 0;
-	margin-bottom: 5px;
+.sp-m-item2 > p {
+  margin: 0;
+  margin-bottom: 5px;
 }
 .sp-m-item3 {
-	width: 100%;
-	flex: 1;
-	display: flex;
-	align-items: center;
-	justify-content: center;
+  width: 100%;
+  flex: 1;
+  display: flex;
+  align-items: center;
+  justify-content: center;
 }
 .img1 {
-	width: 128px;
-	height: 128px;
+  width: 128px;
+  height: 128px;
 }
 .img2 {
-	width: 90px;
-	height: 90px;
-	position: absolute;
-	top: 50%;
-	left: 50%;
-	margin: 0;
-	background-color: #5e9afc;
-	/* overflow: hidden; */
-	border-radius: 50%;
-	transform: translate(-50%, -50%);
+  width: 90px;
+  height: 90px;
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  margin: 0;
+  background-color: #5e9afc;
+  /* overflow: hidden; */
+  border-radius: 50%;
+  transform: translate(-50%, -50%);
 }
 
 .sp-m-item > span {
-	width: 40%;
-	height: 40%;
-	background-size: 100% 100%;
-	margin-bottom: 15px;
+  width: 40%;
+  height: 40%;
+  background-size: 100% 100%;
+  margin-bottom: 15px;
 }
 
 /* .sp-m-i-icon1 {

+ 5 - 5
src/components/pages/classroomObservation/index.vue

@@ -16,8 +16,9 @@
 					class="co-h2-l-icon"
 					@click="$refs.addNewCourseDialogRef.open()"
 				></span> -->
-				<span class="co-h2-l-icon" @click="addNewCourse()"></span>
-				<span class="co-h2-l-hr"></span>
+				<span class="co-h2-l-icon"></span>
+				<!-- @click="addNewCourse()" -->
+				<!--<span class="co-h2-l-hr"></span>-->
 				<span class="co-h2-l-text">
 					<el-select
 						class="co_h2_l_t_select"
@@ -532,7 +533,6 @@ export default {
 			this.ajax
 				.post("https://gpt4.cocorobo.cn/get_classroom_observation_new", pram)
 				.then((res) => {
-					console.log(res);
 					let _data = res.data.FunctionResponse.result.length
 						? JSON.parse(res.data.FunctionResponse.result)
 						: [];
@@ -776,9 +776,9 @@ export default {
 	width: 20px;
 	height: 20px;
 	position: relative;
-	background: url("../../../assets/icon/classroomObservation/close.png")
+	background: url("../../../assets/icon/classroomObservation/courseIcon.svg")
 		no-repeat;
-	transform: rotate(45deg);
+	/* transform: rotate(45deg); */
 	cursor: pointer;
 	background-size: 100% 100%;
 }

+ 1505 - 0
src/components/pages/components/exportDataDialog.vue

@@ -0,0 +1,1505 @@
+<template>
+  <div class="pbl">
+    <!-- <button @click="lookPage">导出</button> -->
+    <!-- <el-dialog
+      title="导出作业集"
+      :visible.sync="worksDialog"
+      :before-close="handleClose"
+      class="full_diy"
+      :append-to-body="true"
+    > -->
+    <!-- :style="{ backgroundColor: schoolImg.bkColor, position: 'relative' }" -->
+    <div ref="reportPdf" v-loading="loading">
+      <div
+        class="coverPage"
+        :style="{
+          backgroundColor: schoolImg.bkColor ? schoolImg.bkColor : '#E5EFFE'
+        }"
+      >
+        <div class="coverPageLogo">
+          <img :src="schoolImg.logo ? schoolImg.logo : ''" alt="" />
+        </div>
+        <div class="coverPageFrom" style="z-index: 10;">
+          <div class="coverPageFromTit">
+            <img src="../../../assets/icon/exportPdfworks/title.png" alt="" />
+          </div>
+
+          <div class="fromCss">
+            <div>
+              <span>姓名:</span>
+              <div class="txt">{{ worksDialogCon2.sName }}</div>
+            </div>
+            <div>
+              <span>班级:</span>
+              <div class="txt">{{ worksDialogCon2.class }}</div>
+            </div>
+            <div>
+              <span>学校:</span>
+              <div class="txt">{{ worksDialogCon2.schName }}</div>
+            </div>
+          </div>
+        </div>
+        <div class="coverPageFrom">
+          <img
+            style="z-index: 10;"
+            src="../../../assets/icon/exportPdfworks/cocoroboCon.svg"
+            alt=""
+          />
+        </div>
+      </div>
+
+      <div class="coverPageCon">
+        <div
+          style="
+                text-align: center;
+                font-weight: 600;
+                font-size: 26px;
+                margin: 10px 0;
+                color: rgba(58, 59, 152, 1);
+              "
+        >
+          {{ courseTit }}
+        </div>
+        <div
+          style="font-weight: 600; font-size: 16px; color: rgba(0, 0, 0, 0.9);margin: 10px 0;"
+        >
+          <li>学习总览</li>
+        </div>
+        <div
+          style="
+                text-align: center;
+                font-weight: 600;
+                font-size: 14px;
+                color: rgba(0, 0, 0, 0.9);
+                margin: 10px 0;
+              "
+        >
+          综合表现
+        </div>
+
+        <div style="display: flex; justify-content: space-between">
+          <div class="zhBlock">
+            <div class="zhBlockTit">
+              <span style="margin-right: 5px">登录时长</span
+              ><img
+                src="../../../assets/icon/exportPdfworks/infocircle.svg"
+                alt=""
+              />
+            </div>
+            <div class="zhBlockCon">{{ loginTime }}</div>
+          </div>
+          <div class="zhBlock">
+            <div class="zhBlockTit">
+              <span style="margin-right: 5px">学习时长</span
+              ><img
+                src="../../../assets/icon/exportPdfworks/infocircle.svg"
+                alt=""
+              />
+            </div>
+            <div class="zhBlockCon">{{ studyTime }}</div>
+          </div>
+          <div class="zhBlock">
+            <div class="zhBlockTit">
+              <span style="margin-right: 5px">学习成绩</span
+              ><img
+                src="../../../assets/icon/exportPdfworks/infocircle.svg"
+                alt=""
+              />
+            </div>
+            <div class="zhBlockCon"><el-rate v-model="star"></el-rate></div>
+          </div>
+          <!-- <div class="zhBlock">
+                <div class="zhBlockTit">
+                  <span style="margin-right: 5px">包含学科</span
+                  ><img src="../assets/img/infocircle.svg" alt="" />
+                </div>
+                <div class="zhBlockCon2">
+                  <span>语文</span>
+                  <span>数学</span>
+                  <span>英语</span>
+                  <span>化学</span>
+                  <span>美术</span>
+                </div>
+              </div> -->
+        </div>
+        <div style="display: flex; height: 370px; margin: 10px 0">
+          <div style="width: 50%">
+            <div ref="chart" style="width: 100%; height: 360px"></div>
+          </div>
+          <div style="width: 50%">
+            <div ref="ringChart" style="height: 360px; width: 100%"></div>
+          </div>
+        </div>
+        <!-- 作业提交率 -->
+        <div class="zxt">
+          <div style="height: 350px; width: 100%" ref="toolSubEcharts"></div>
+        </div>
+
+        <!-- 分组工具使用数量  -->
+        <div class="zxt">
+          <div style="height: 350px; width: 100%" ref="groupingEcharts"></div>
+        </div>
+        <!-- 师生互动次数  -->
+        <div class="zxt">
+          <div
+            style="height: 350px; width: 100%"
+            ref="interactionEcharts"
+          ></div>
+        </div>
+        <!-- 互动次数主动  -->
+        <div class="zxt">
+          <div
+            style="height: 350px; width: 100%"
+            ref="stuInteractZdEcharts"
+          ></div>
+        </div>
+        <!-- 互动次数主动  -->
+        <div class="zxt">
+          <div
+            style="height: 350px; width: 100%"
+            ref="bdStuInteractZdEcharts"
+          ></div>
+        </div>
+        <!-- 课程得分  -->
+        <div class="zxt">
+          <div style="height: 350px; width: 100%" ref="cScoEcharts"></div>
+        </div>
+        <div style="display: flex;justify-content: flex-end;">
+          <img :src="schoolImg.bjLogo ? schoolImg.bjLogo : ''" alt="" />
+        </div>
+      </div>
+    </div>
+
+    <!-- </el-dialog> -->
+  </div>
+</template>
+
+<script>
+import html2canvas from "html2canvas";
+import jspdf from "jspdf";
+import JSZip from "jszip";
+import * as echarts from "echarts";
+
+export default {
+  props: [
+    "multipleSelection",
+    "cid",
+    "worksDialog",
+    "worksDialogCon",
+    "digNum"
+  ],
+
+  data() {
+    return {
+      star: 0,
+      // 课程类型
+      cState: "",
+      // 课程名称
+      courseTit: "",
+      // 学习时长
+      studyTime: "",
+      // 登录时长
+      loginTime: "",
+
+      // 五边形图开始
+      chartData: [
+        [1, 2, 3, 4, 5],
+        [2, 3, 4, 3, 2]
+      ],
+      categories: ["A", "B", "C", "D", "E"],
+      // 五边形图结束
+
+      // 环形图数据开始
+      toolData: [[], [], [], [], [], [], []],
+      toolRatio: [
+        { name: "互动类", value: 0 },
+        { name: "思维类", value: 0 },
+        { name: "协作类", value: 0 },
+        { name: "测评类", value: 0 },
+        { name: "评价类", value: 0 },
+        { name: "编程类", value: 0 },
+        { name: "学科类", value: 0 }
+      ],
+      // 环形图数据结束
+
+      // 作业提交率折线图开始
+      stageList: [], // 阶段
+      stageListPer: [], // 阶段所占百分比
+      toolPercentage: [], // 每个阶段有的工具
+      // 作业提交率折线图结束
+
+      // 作业得分折线图开始
+      taskList: [], //每个阶段下有几个任务
+      scoFoldLineData: [],
+      // 作业得分折线图结束
+
+      // 分数工具柱状图开始
+      columnData: [],
+      // 分数工具柱状图结束
+
+      // 师生在线互动次数开始
+      interact: [], //每个阶段下师生互动工具
+      interactWork: [], //每个工具下提交的作业
+      // 师生在线互动次数结束
+
+      // 生生互动主动开始
+      stuInterAllWork: [],
+      stuInterAllLike: [],
+
+      // 生生互动主动结束
+
+      // 生生互动被动开始
+      bdStuInterAllWork: [],
+      bdStuInterAllLike: [],
+      // 生生互动被动结束
+
+      // 工具类大分类
+      hd: [10, 65],
+      sw: [7, 1, 52, 3, 52],
+      xz: [49],
+      cp: [4, 45, 15, 16, 50, 41, 47],
+      pj: [40],
+      bc: [18, 21, 23, 24, 32, 57, 63, 71],
+      xk: [28, 31, 39, 66, , 68, 69, 70],
+      // 师生互动工具list
+      TeaStuInt: [7, 1, 52, 3, 48, 15, 16, 50, 57],
+      // 处理过的分组
+      TeaStuInt2: [1, 3, 5, 4, 10, 13, 15],
+
+      data3: [],
+      data4: [],
+      data5: [],
+      data6: [],
+      data7: [],
+      data8: [],
+      data9: [],
+      oid: this.$route.query.oid,
+      org: this.$route.query.org,
+      uid2: "",
+      worksDialogCon2: "",
+
+      loading: false,
+      userInfo: "",
+      tableData: [],
+      courseName: "",
+      imgList: [
+        {
+          schoolId: "45facc0a-1211-11ec-80ad-005056b86db5",
+          logo: require("../../../assets/icon/exportPdfworks/cocoroboLogo.svg"),
+          conImg: require("../../../assets/icon/exportPdfworks/cocoroboCon.svg"),
+          bjLogo: require("../../../assets/icon/exportPdfworks/logo2.svg"),
+          bkColor: "#E5EFFE"
+        }
+      ],
+      schoolImg: {}
+    };
+  },
+  mounted() {
+    if (this.digNum == 0) {
+      this.downPdf();
+    } else {
+      this.getWorks1();
+    }
+    // this.getCourseDetail();
+  },
+
+  methods: {
+    // 下载单个文件
+    async downPdf() {
+      this.loading = true;
+      this.tableData = this.multipleSelection;
+      if (!this.tableData.length) {
+        this.loading = false;
+        return this.$message.info("请选择数据后,再进行导出");
+      }
+      if (this.tableData.length == 1) {
+        this.uid2 = this.tableData[0].userid;
+        this.worksDialogCon2 = this.tableData[0];
+        await this.getData();
+        await this.getPdf();
+      } else {
+        this.circulatePdf();
+      }
+    },
+    // 下载pdf文件
+    async getPdf() {
+      let domHeight = this.$refs.reportPdf.offsetHeight;
+      // console.log('this.$refs.reportPdf',this.$refs.reportPdf.offsetHeight);
+      let maxHeight = 64257;
+      return new Promise((resolve, reject) => {
+        html2canvas(this.$refs.reportPdf, {
+          useCORS: true, // 如果截图的内容里有图片,可能会有跨域的情况,加上这个参数,解决文件跨域问题
+          scale: maxHeight / domHeight > 1 ? 1 : maxHeight / domHeight
+        })
+          .then(canvas => {
+            const contentWidth = canvas.width;
+            const contentHeight = canvas.height;
+
+            var pageData = canvas.toDataURL("image/jpeg", 1.0);
+
+            var pdf = new jspdf("", "pt", [contentWidth, contentHeight]);
+
+            //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
+            //当内容未超过pdf一页显示的范围,无需分页
+            // if (leftHeight < pageHeight) {
+            pdf.addImage(pageData, "JPEG", 0, 0, contentWidth, contentHeight);
+
+            pdf.save(
+              this.worksDialogCon2.course +
+                "-作业集-" +
+                this.worksDialogCon2.sName +
+                ".pdf"
+            );
+            return resolve();
+          })
+          .catch(err => {
+            console.log(err);
+          });
+      });
+    },
+    // 获取所有作业然后一键打包压缩包
+    getWorks1() {
+      this.loading = true;
+
+      let params = {
+        cid: this.cid,
+        uname: "",
+        choseClass: "",
+        stage: "",
+        task: ""
+      };
+
+      this.ajax
+        .get(this.$store.state.api + "getCourseWorks6", params) //getCourseWorks4
+        .then(res => {
+          this.tableData = res.data[0];
+
+          if (!this.tableData.length) {
+            this.loading = false;
+            return this.$message.info("课程下未有提交作业");
+          }
+          this.courseName = this.tableData[0].course;
+          this.circulatePdf();
+          // console.log(res.data[0]);
+        })
+        .catch(err => {
+          this.isLoading = false;
+          console.error(err);
+        });
+    },
+    // 一键打包所有作业
+    async circulatePdf() {
+      let _this = this;
+      var zip = new JSZip();
+      let pdfList = [];
+      for (let i = 0; i < this.tableData.length; i++) {
+        this.loading = true;
+
+        this.uid2 = this.tableData[i].userid;
+        this.worksDialogCon2 = this.tableData[i];
+        // await this.getCourseDetail();
+        await this.getData();
+        let a = await this.getPdf2();
+        pdfList.push(a);
+      }
+
+      pdfList.forEach((e, index) => {
+        zip.file(e.pdfName, e.pdfCon);
+      });
+
+      // 生成压缩包并提供下载链接
+      zip.generateAsync({ type: "blob" }).then(function(content) {
+        // 使用FileSaver保存压缩包
+        saveAs(content, _this.courseTit + "-学生报告汇总.zip");
+      });
+
+      //   this.$emit("update:worksDialog", false);
+      // this.worksDialog = false;
+    },
+    // 压缩pdf
+    async getPdf2() {
+      let domHeight = this.$refs.reportPdf.offsetHeight;
+      // console.log('this.$refs.reportPdf',this.$refs.reportPdf.offsetHeight);
+      let maxHeight = 64257;
+      return new Promise((resolve, reject) => {
+        html2canvas(this.$refs.reportPdf, {
+          useCORS: true, // 如果截图的内容里有图片,可能会有跨域的情况,加上这个参数,解决文件跨域问题
+          scale: maxHeight / domHeight > 1 ? 1 : maxHeight / domHeight
+        })
+          .then(canvas => {
+            const contentWidth = canvas.width;
+            const contentHeight = canvas.height;
+
+            var pageData = canvas.toDataURL("image/jpeg", 1.0);
+
+            var pdf = new jspdf("", "pt", [contentWidth, contentHeight]);
+
+            //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
+            //当内容未超过pdf一页显示的范围,无需分页
+            // if (leftHeight < pageHeight) {
+            pdf.addImage(pageData, "JPEG", 0, 0, contentWidth, contentHeight);
+
+            var pdfData = {
+              pdfName:
+                this.worksDialogCon2.course +
+                "-作业集-" +
+                this.worksDialogCon2.sName +
+                ".pdf",
+              pdfCon: pdf.output("blob")
+            };
+            // pdfArray.push(pdfData);
+
+            return resolve(pdfData);
+          })
+          .catch(err => {
+            console.log(err);
+          });
+      });
+    },
+    async getData() {
+      let params = {
+        cid: this.cid,
+        uid: this.worksDialogCon2.userid,
+        cla: ""
+      };
+      return new Promise((resolve, reject) => {
+        this.ajax
+          .get(this.$store.state.api + "selectStuCourseReportPdf", params) //getCourseWorksReport
+          .then(res => {
+            this.cState = res.data[0][0].state;
+            this.courseTit = res.data[0][0].title;
+
+            this.imgList.forEach(e => {
+              if (e.schoolId == this.oid) {
+                this.schoolImg = e;
+              }
+            });
+
+            // 0 课程信息
+            // 1获取登录时长
+            // 3获取学习时长
+            //  4获取学生提交作业
+            //  5获取单个学生作业分数
+            //  6获取教师评价作业
+            //  7获取所有学生提交作业
+            //  8学生点赞评论次数
+            //  9学生被点赞评论次数
+            let oneTime = 0;
+            res.data[1].forEach(e => {
+              oneTime += e.text * 1;
+            });
+            this.loginTime = this.secondsToDhms(oneTime);
+
+            let twoTime = 0;
+            res.data[2].forEach(e => {
+              twoTime += e.text * 1;
+            });
+            this.studyTime = this.secondsToDhms(twoTime);
+
+            this.data3 = res.data[3];
+            this.data4 = res.data[4];
+            this.data5 = res.data[5];
+            this.data6 = res.data[6];
+            this.data7 = res.data[7];
+            this.data8 = res.data[8];
+            this.data9 = res.data[9];
+
+            // 处理这个课程下的工具分类
+            let data = JSON.parse(res.data[0][0].chapters);
+
+            if (this.cState == 1) {
+              this.getDataStageMode(data);
+            } else {
+              this.getDataAiMode(data);
+            }
+
+            // 将课程的所有工具进行分类,然后装在变量里 , 获取所有折线图阶段
+            // console.log("data", data);
+            this.loading = false;
+
+            setTimeout(() => {
+              return resolve();
+            }, 1500);
+          })
+          .catch(err => {
+            console.error(err);
+          });
+      });
+    },
+    // ai模式处理数据
+    getDataAiMode(data) {
+      data.forEach((e, eInd) => {
+        let toolList = e.chapterInfo[0].taskJson;
+        toolList.forEach((i, iInd) => {
+          this.stageList.push("任务" + (iInd * 1 + 1));
+          this.toolPercentage[iInd] = []; // 每个任务有的工具
+          this.stageListPer.push(0); // 作业提交率基础数据折线图
+          // 课程阶段下互动数据工具
+          this.interact[iInd] = [];
+
+          this.interactWork[iInd] = []; //每个工具下提交的作业
+
+          this.stuInterAllWork[iInd] = []; // 生生互动阶段作业分类
+          this.stuInterAllLike[iInd] = []; // 生生互动阶段点赞评论分类
+
+          this.bdStuInterAllWork[iInd] = []; // 生生互动阶段被动作业分类
+          this.bdStuInterAllLike[iInd] = []; // 生生互动阶段被动点赞评论分类
+
+          i.toolChoose.forEach(k => {
+            if (k.tool[0]) {
+              this.toolPercentage[iInd].push(k.tool[0]);
+              if (this.TeaStuInt.indexOf(k.tool[0]) != -1) {
+                this.interact[iInd].push(k.tool[0]);
+              }
+              if (this.hd.indexOf(k.tool[0]) != -1) {
+                this.toolData[0].push(k);
+              }
+              if (this.sw.indexOf(k.tool[0]) != -1) {
+                this.toolData[1].push(k);
+              }
+              if (this.xz.indexOf(k.tool[0]) != -1) {
+                this.toolData[2].push(k);
+              }
+              if (this.cp.indexOf(k.tool[0]) != -1) {
+                this.toolData[3].push(k);
+              }
+              if (this.pj.indexOf(k.tool[0]) != -1) {
+                this.toolData[4].push(k);
+              }
+              if (this.bc.indexOf(k.tool[0]) != -1) {
+                this.toolData[5].push(k);
+              }
+              if (this.xk.indexOf(k.tool[0]) != -1) {
+                this.toolData[6].push(k);
+              }
+            }
+          });
+        });
+      });
+      // console.log("this.toolData", this.toolData);
+
+      // 环形图占比
+      this.toolRatio[0].value = this.toolData[0].length;
+      this.toolRatio[1].value = this.toolData[1].length;
+      this.toolRatio[2].value = this.toolData[2].length;
+      this.toolRatio[3].value = this.toolData[3].length;
+      this.toolRatio[4].value = this.toolData[4].length;
+      this.toolRatio[5].value = this.toolData[5].length;
+      this.toolRatio[6].value = this.toolData[6].length;
+
+      // console.log("this.toolRatio[0]", this.toolRatio);
+      // 作业提交率折线图
+      let repeatWork = this.newArrFn(this.data3);
+      // console.log("repeatWork", repeatWork);
+
+      this.getFoldLineDataAi(repeatWork);
+
+      // 计算任务得分
+      this.getFoldLineSCoDataAi(this.data4);
+
+      // 计算分组工具使用比例
+      this.getColumnData();
+
+      // 师生互动数据
+      let TeaStuHdData = [];
+      repeatWork.forEach(e => {
+        if (this.TeaStuInt2.indexOf(e.type) != -1) {
+          TeaStuHdData.push(e);
+        }
+      });
+      this.getTeaStuHdAi(TeaStuHdData);
+
+      // 生生互动主动
+      this.getStuInterAllWorkAi(this.data6, this.data7);
+
+      // // 生生互动被动
+      this.getBdStuInterAllWorkAi(this.data6, this.data8);
+
+      setTimeout(() => {
+        this.renderChart();
+        this.renderChart2();
+        this.initChart();
+        this.initChart2();
+        this.initChart3();
+        this.initChart4();
+        this.initChart5();
+        this.initChart6();
+      }, 500);
+    },
+    // 阶段模式处理数据
+    getDataStageMode(data) {
+      data.forEach((e, eInd) => {
+        let toolList = e.chapterInfo[0].taskJson;
+        this.toolPercentage[eInd] = [];
+        // X轴数据
+        this.stageList.push("阶段" + (eInd * 1 + 1));
+        // 作业提交率基础数据
+        this.stageListPer.push(0);
+
+        // 课程阶段下互动数据工具
+        this.interact[eInd] = [];
+        //每个工具下提交的作业
+        this.interactWork[eInd] = [];
+
+        this.stuInterAllWork[eInd] = []; // 生生互动阶段作业分类
+        this.stuInterAllLike[eInd] = []; // 生生互动阶段点赞评论分类
+
+        this.bdStuInterAllWork[eInd] = []; // 生生互动阶段被动作业分类
+        this.bdStuInterAllLike[eInd] = []; // 生生互动阶段被动点赞评论分类
+
+        // 每个阶段下有多少个任务
+        this.taskList[eInd] = toolList;
+
+        toolList.forEach(i => {
+          i.toolChoose.forEach(k => {
+            if (k.tool[0]) {
+              this.toolPercentage[eInd].push(k.tool[0]);
+
+              if (this.TeaStuInt.indexOf(k.tool[0]) != -1) {
+                this.interact[eInd].push(k.tool[0]);
+              }
+              if (this.hd.indexOf(k.tool[0]) != -1) {
+                this.toolData[0].push(k);
+              }
+              if (this.sw.indexOf(k.tool[0]) != -1) {
+                this.toolData[1].push(k);
+              }
+              if (this.xz.indexOf(k.tool[0]) != -1) {
+                this.toolData[2].push(k);
+              }
+              if (this.cp.indexOf(k.tool[0]) != -1) {
+                this.toolData[3].push(k);
+              }
+              if (this.pj.indexOf(k.tool[0]) != -1) {
+                this.toolData[4].push(k);
+              }
+              if (this.bc.indexOf(k.tool[0]) != -1) {
+                this.toolData[5].push(k);
+              }
+              if (this.xk.indexOf(k.tool[0]) != -1) {
+                this.toolData[6].push(k);
+              }
+            }
+          });
+        });
+      });
+      // 环形图占比
+      this.toolRatio[0].value = this.toolData[0].length;
+      this.toolRatio[1].value = this.toolData[1].length;
+      this.toolRatio[2].value = this.toolData[2].length;
+      this.toolRatio[3].value = this.toolData[3].length;
+      this.toolRatio[4].value = this.toolData[4].length;
+      this.toolRatio[5].value = this.toolData[5].length;
+      this.toolRatio[6].value = this.toolData[6].length;
+
+      // 作业提交率折线图
+      let repeatWork = this.newArrFn(this.data3);
+      this.getFoldLineData(repeatWork);
+
+      // 计算任务得分
+      this.getFoldLineSCoData(this.data4);
+
+      // 计算分组工具使用比例
+      this.getColumnData();
+
+      // 师生互动数据
+      let TeaStuHdData = [];
+      repeatWork.forEach(e => {
+        if (this.TeaStuInt2.indexOf(e.type) != -1) {
+          TeaStuHdData.push(e);
+        }
+      });
+      this.getTeaStuHd(TeaStuHdData);
+
+      // 生生互动主动
+      this.getStuInterAllWork(this.data6, this.data7);
+
+      // 生生互动被动
+      this.getBdStuInterAllWork(this.data6, this.data8);
+
+      setTimeout(() => {
+        this.renderChart();
+        this.renderChart2();
+        this.initChart();
+        this.initChart2();
+        this.initChart3();
+        this.initChart4();
+        this.initChart5();
+        this.initChart6();
+      }, 500);
+    },
+
+    // 生生互动被动
+    getBdStuInterAllWork(val, likeData) {
+      this.bdStuInterAllWork.forEach((e, index) => {
+        val.forEach(k => {
+          if (k.stage == index) {
+            e.push(k.id);
+          }
+        });
+      });
+      this.bdStuInterAllWork.forEach((e, index) => {
+        likeData.forEach(k => {
+          if (e.indexOf(k.workId) != -1) {
+            this.bdStuInterAllLike[index].push(k);
+          }
+        });
+      });
+    },
+
+    // 生生互动主动
+    getStuInterAllWork(val, likeData) {
+      this.stuInterAllWork.forEach((e, index) => {
+        val.forEach(k => {
+          if (k.stage == index) {
+            e.push(k.id);
+          }
+        });
+      });
+      this.stuInterAllWork.forEach((e, index) => {
+        likeData.forEach(k => {
+          if (e.indexOf(k.workId) != -1) {
+            this.stuInterAllLike[index].push(k);
+          }
+        });
+      });
+    },
+    // 师生互动数据
+    getTeaStuHd(TeaStuHdData) {
+      this.interactWork.forEach((e, index) => {
+        TeaStuHdData.forEach(k => {
+          if (k.stage == index) {
+            e.push(k);
+          }
+        });
+      });
+    },
+    // 计算任务得分
+    getFoldLineSCoData(repeatWork) {
+      // 作业数据e.sco得分
+      repeatWork.forEach(e => {
+        let con = Object.values(JSON.parse(e.rate));
+        e.sco = 0;
+        con.forEach(i => {
+          if (!isNaN(Number(i))) {
+            e.sco += i * 1;
+          }
+        });
+        if (e.sco == 0 || con.length == 0) {
+          e.sco = 0;
+        } else {
+          e.sco = (e.sco / (con.length - 1)).toFixed(1);
+        }
+      });
+
+      let repeatWorkCopy = []; // 阶段分类作业容器
+      let scoList = []; //分数每个阶段的所有任务分的集合
+
+      this.stageList.forEach((e, index) => {
+        repeatWorkCopy[index] = [];
+        scoList[index] = 0;
+      });
+
+      // 将作业进行阶段分类
+      repeatWork.forEach(e => {
+        repeatWorkCopy[e.stage].push(e);
+      });
+
+      repeatWorkCopy.forEach((e, index) => {
+        e.forEach(k => {
+          scoList[index] += k.sco * 1;
+        });
+        scoList[index] = (scoList[index] / this.taskList[index].length).toFixed(
+          1
+        );
+      });
+      this.scoFoldLineData = scoList;
+      // console.log("this.scoFoldLineData", this.scoFoldLineData);
+
+      let zSco = 0;
+      this.scoFoldLineData.forEach(e => {
+        zSco += e * 1;
+      });
+
+      this.star = (zSco / this.scoFoldLineData.length).toFixed(0) * 1;
+      // console.log("this.star", this.star);
+    },
+
+    getFoldLineData(repeatWork) {
+      // 阶段分类作业容器
+      let repeatWorkCopy = [];
+      this.stageList.forEach((e, index) => {
+        repeatWorkCopy[index] = [];
+      });
+
+      // 将作业进行阶段分类
+      repeatWork.forEach(e => {
+        repeatWorkCopy[e.stage].push(e);
+      });
+
+      // 计算阶段工具作业提交率
+      this.toolPercentage.forEach((e, index) => {
+        repeatWorkCopy.forEach((k, kin) => {
+          if (index == kin) {
+            if (k.length == 0 || e.length == 0) {
+              this.stageListPer[index] = 0;
+            } else {
+              this.stageListPer[index] = (k.length / e.length).toFixed(2);
+            }
+          }
+        });
+      });
+    },
+
+    // 非阶段模式
+    // 获取作业提交率折线图
+    getFoldLineDataAi(repeatWork) {
+      // 阶段分类作业容器
+      let repeatWorkCopy = [];
+      this.stageList.forEach((e, index) => {
+        repeatWorkCopy[index] = [];
+      });
+
+      // 将作业进行阶段分类
+      repeatWork.forEach(e => {
+        repeatWorkCopy[e.task].push(e);
+      });
+      // console.log("repeatWorkCopy", repeatWorkCopy);
+
+      // 计算阶段工具作业提交率
+      this.toolPercentage.forEach((e, index) => {
+        repeatWorkCopy.forEach((k, kin) => {
+          if (index == kin) {
+            if (k.length == 0 || e.length == 0) {
+              this.stageListPer[index] = 0;
+            } else {
+              this.stageListPer[index] = (k.length / e.length).toFixed(2);
+            }
+          }
+        });
+      });
+    },
+    // 计算任务得分
+    getFoldLineSCoDataAi(repeatWork) {
+      // 作业数据e.sco得分
+      repeatWork.forEach(e => {
+        let con = Object.values(JSON.parse(e.rate));
+        e.sco = 0;
+        con.forEach(i => {
+          if (!isNaN(Number(i))) {
+            e.sco += i * 1;
+          }
+        });
+        if (e.sco == 0 || con.length == 0) {
+          e.sco = 0;
+        } else {
+          e.sco = (e.sco / (con.length - 1)).toFixed(1);
+        }
+      });
+
+      let repeatWorkCopy = []; // 任务分类作业容器
+      let scoList = []; //分数每个任务的所有任务分的集合
+
+      this.stageList.forEach((e, index) => {
+        repeatWorkCopy[index] = [];
+        scoList[index] = 0;
+      });
+
+      // 将作业进行阶段分类
+      repeatWork.forEach(e => {
+        repeatWorkCopy[e.task].push(e);
+      });
+
+      repeatWorkCopy.forEach((e, index) => {
+        e.forEach(k => {
+          scoList[index] += k.sco * 1;
+        });
+      });
+
+      this.scoFoldLineData = scoList;
+
+      let zSco = 0;
+      this.scoFoldLineData.forEach(e => {
+        zSco += e * 1;
+      });
+
+      this.star = (zSco / this.scoFoldLineData.length).toFixed(0) * 1;
+      // console.log("this.star", this.star);
+    },
+    // 师生互动数据
+    getTeaStuHdAi(TeaStuHdData) {
+      this.interactWork.forEach((e, index) => {
+        TeaStuHdData.forEach(k => {
+          if (k.task == index) {
+            e.push(k);
+          }
+        });
+      });
+    },
+    // 生生互动主动
+    getStuInterAllWorkAi(val, likeData) {
+      this.stuInterAllWork.forEach((e, index) => {
+        val.forEach(k => {
+          if (k.task == index) {
+            e.push(k.id);
+          }
+        });
+      });
+      this.stuInterAllWork.forEach((e, index) => {
+        likeData.forEach(k => {
+          if (e.indexOf(k.workId) != -1) {
+            this.stuInterAllLike[index].push(k);
+          }
+        });
+      });
+    },
+    // 生生互动被动
+    getBdStuInterAllWorkAi(val, likeData) {
+      this.bdStuInterAllWork.forEach((e, index) => {
+        val.forEach(k => {
+          if (k.task == index) {
+            e.push(k.id);
+          }
+        });
+      });
+      this.bdStuInterAllWork.forEach((e, index) => {
+        likeData.forEach(k => {
+          if (e.indexOf(k.workId) != -1) {
+            this.bdStuInterAllLike[index].push(k);
+          }
+        });
+      });
+    },
+
+    // 通用方法
+    // 五边形
+    renderChart() {
+      let chartObj = echarts.init(this.$refs.chart);
+      const seriesData = this.chartData.map((values, index) => ({
+        value: values
+      }));
+
+      const option = {
+        title: {
+          text: "素养发展雷达图",
+          // subtext: '这是一个副标题',
+          top: "bottom", // 标题在底部显示
+          left: "center" // 标题居中显示
+        },
+        tooltip: {},
+        legend: {
+          //   data: this.bLeg.map((series) => series.name),
+          bottom: 0
+        },
+        radar: {
+          indicator: this.categories.map(category => ({
+            name: category,
+            max: 5
+          }))
+        },
+        series: [
+          {
+            type: "radar",
+            data: seriesData
+          }
+        ]
+      };
+      chartObj.setOption(option);
+    },
+    // 环形
+    renderChart2() {
+      let chartObj2 = echarts.init(this.$refs.ringChart);
+
+      const option = {
+        title: {
+          text: "工具使用情况",
+          // subtext: '这是一个副标题',
+          top: "bottom", // 标题在底部显示
+          left: "center" // 标题居中显示
+        },
+        tooltip: {
+          trigger: "item",
+          formatter: "{a} <br/>{b}: {c} ({d}%)"
+        },
+        legend: {
+          orient: "vertical",
+          right: 0,
+          itemWidth: 10, // 控制图例项的宽度
+          itemHeight: 10, // 控制图例项的高度
+          data: this.toolRatio.map(item => item.name)
+        },
+        series: [
+          {
+            name: "工具占比",
+            type: "pie",
+            radius: ["30%", "70%"],
+            avoidLabelOverlap: false,
+            label: {
+              show: true,
+              position: "inside",
+              formatter: " {d}%"
+            },
+            emphasis: {
+              label: {
+                show: true,
+                fontSize: "20"
+                // fontWeight: 'bold'
+              }
+            },
+            labelLine: {
+              show: false
+            },
+            data: this.toolRatio
+          }
+        ]
+      };
+
+      chartObj2.setOption(option);
+    },
+    // 工具提交折线图
+    initChart() {
+      const chart = echarts.init(this.$refs.toolSubEcharts);
+
+      const option = {
+        title: {
+          text: "作业提交率",
+          left: "left",
+          textStyle: {
+            color: "rgba(140, 140, 140, 1)", // 标题颜色
+            fontSize: 10 // 标题字体大小
+          }
+        },
+        tooltip: {
+          trigger: "axis",
+          formatter: "{b} : {c}%"
+        },
+        xAxis: {
+          type: "category",
+          data: this.stageList.map(item => item)
+        },
+        yAxis: {
+          type: "value",
+          axisLabel: {
+            formatter: "{value}%"
+          },
+          max: 100
+        },
+        series: [
+          {
+            data: this.stageListPer.map(item => item * 100),
+            type: "line"
+          }
+        ]
+      };
+
+      chart.setOption(option);
+    },
+    // 课程得分
+    initChart2() {
+      const chart = echarts.init(this.$refs.cScoEcharts);
+      const option = {
+        title: {
+          text: this.cState == 1?'阶段成绩':'任务成绩',
+          left: "left",
+          textStyle: {
+            color: "rgba(140, 140, 140, 1)", // 标题颜色
+            fontSize: 10 // 标题字体大小
+          }
+        },
+        tooltip: {
+          trigger: "axis",
+          formatter: "{b} : {c}"
+        },
+        xAxis: {
+          type: "category",
+          data: this.stageList.map(item => item)
+        },
+        yAxis: {
+          type: "value",
+          axisLabel: {
+            formatter: "{value}"
+          },
+          max: 5
+        },
+        series: [
+          {
+            data: this.scoFoldLineData.map(item => item),
+            type: "line"
+          }
+        ]
+      };
+
+      chart.setOption(option);
+    },
+    // 分组工具占比
+    initChart3() {
+      const chart = echarts.init(this.$refs.groupingEcharts);
+
+      const option = {
+        title: {
+          text: "分组工具占比",
+          left: "left",
+          textStyle: {
+            color: "rgba(140, 140, 140, 1)", // 标题颜色
+            fontSize: 10 // 标题字体大小
+          }
+        },
+        tooltip: {
+          trigger: "axis",
+          axisPointer: {
+            type: "shadow"
+          },
+          formatter: "{b} : {c}%"
+        },
+        xAxis: {
+          type: "category",
+          data: this.stageList.map(item => item)
+        },
+        yAxis: {
+          type: "value",
+          axisLabel: {
+            formatter: "{value}%"
+          },
+          max: 100
+        },
+        series: [
+          {
+            data: this.columnData.map(item => item * 100),
+            type: "bar"
+          }
+        ]
+      };
+
+      chart.setOption(option);
+    },
+    // 师生互动折线图
+    initChart4() {
+      const chart = echarts.init(this.$refs.interactionEcharts);
+
+      const option = {
+        title: {
+          text: "师生互动",
+          left: "left",
+          textStyle: {
+            color: "rgba(140, 140, 140, 1)", // 标题颜色
+            fontSize: 10 // 标题字体大小
+          }
+        },
+        tooltip: {
+          trigger: "axis",
+          formatter: "{b} : {c}"
+        },
+        xAxis: {
+          type: "category",
+          data: this.stageList.map(item => item)
+        },
+        yAxis: {
+          type: "value",
+          axisLabel: {
+            formatter: "{value}"
+          }
+        },
+        series: [
+          {
+            data: this.interactWork.map(item => item.length),
+            type: "line"
+          }
+        ]
+      };
+
+      chart.setOption(option);
+    },
+    // 学生互动主动折线图
+    initChart5() {
+      const chart = echarts.init(this.$refs.stuInteractZdEcharts);
+
+      const option = {
+        title: {
+          text: "生生互动(主动)",
+          left: "left",
+          textStyle: {
+            color: "rgba(140, 140, 140, 1)", // 标题颜色
+            fontSize: 10 // 标题字体大小
+          }
+        },
+        tooltip: {
+          trigger: "axis",
+          formatter: "{b} : {c}"
+        },
+        xAxis: {
+          type: "category",
+          data: this.stageList.map(item => item)
+        },
+        yAxis: {
+          type: "value",
+          axisLabel: {
+            formatter: "{value}"
+          }
+        },
+        series: [
+          {
+            data: this.stuInterAllLike.map(item => item.length),
+            type: "line"
+          }
+        ]
+      };
+
+      chart.setOption(option);
+    },
+    // 学生互动被动折线图
+    initChart6() {
+      const chart = echarts.init(this.$refs.bdStuInteractZdEcharts);
+
+      const option = {
+        title: {
+          text: "生生互动(被动)",
+          left: "left",
+          textStyle: {
+            color: "rgba(140, 140, 140, 1)", // 标题颜色
+            fontSize: 10 // 标题字体大小
+          }
+        },
+        tooltip: {
+          trigger: "axis",
+          formatter: "{b} : {c}"
+        },
+        xAxis: {
+          type: "category",
+          data: this.stageList.map(item => item)
+        },
+        yAxis: {
+          type: "value",
+          axisLabel: {
+            formatter: "{value}"
+          }
+        },
+        series: [
+          {
+            data: this.bdStuInterAllLike.map(item => item.length),
+            type: "line"
+          }
+        ]
+      };
+
+      chart.setOption(option);
+    },
+    // 计算分组工具使用比例
+    getColumnData() {
+      let columnDataCopy = [];
+
+      this.toolPercentage.forEach((e, index) => {
+        columnDataCopy[index] = 0;
+        columnDataCopy[index] = e.filter(item => item === 49).length;
+        if (columnDataCopy[index]) {
+          this.columnData[index] = (columnDataCopy[index] / e.length).toFixed(
+            2
+          );
+        } else {
+          this.columnData[index] = 0;
+        }
+      });
+    },
+    // 计算时长
+    secondsToDhms(seconds) {
+      const days = Math.floor(seconds / (3600 * 24));
+      const hours = Math.floor((seconds % (3600 * 24)) / 3600);
+
+      return days + " 天 " + hours + " 时";
+    },
+    // 判断一个工具下是否提交多个作,有重复的只取一个
+    newArrFn(arr) {
+      // 创建一个新的空数组
+      let newArr = [];
+      for (let i = 0; i < arr.length; i++) {
+        // 设置一个开关,如果是true,就存进去,不是就不存
+        let flag = true;
+        for (let j = 0; j < newArr.length; j++) {
+          // 原数组和新数组作比较,如果一致,开关变为 false
+          if (
+            arr[i].stage == newArr[j].stage &&
+            arr[i].task == newArr[j].task &&
+            arr[i].tool == newArr[j].tool
+          ) {
+            flag = false;
+          }
+        }
+        flag ? newArr.push(arr[i]) : newArr;
+      }
+      return newArr;
+    },
+    handleClose(done) {
+      done();
+    }
+  }
+};
+</script>
+
+<style scoped>
+.pbl {
+  width: 100%;
+  height: 100%;
+  box-sizing: border-box;
+  margin: auto;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  padding: 20px;
+  padding-top: 10px;
+  overflow: auto;
+  border-radius: 10px;
+}
+.pageTit {
+  width: 100%;
+  text-align: left;
+  font-size: 28px;
+  padding: 10px 0;
+  font-weight: bold;
+  border-bottom: 1px solid #ccc;
+  margin-bottom: 10px;
+}
+.full_diy {
+  min-width: 1200px !important;
+}
+.full_diy >>> .el-dialog {
+  height: 80%;
+  width: 598px !important;
+  margin-top: 10vh !important;
+  display: flex;
+  flex-direction: column;
+}
+.full_diy >>> .el-dialog__body {
+  overflow: auto;
+  flex: 1;
+  padding: 0 !important;
+}
+.full_diy >>> .el-dialog__title {
+  color: #fff !important;
+}
+.full_diy >>> .el-dialog__header {
+  padding: 9px 20px 10px;
+  background: #32455b !important;
+}
+.coverPage {
+  min-height: 743px;
+  background-color: #ccc;
+  position: relative;
+  background-image: url("../../../assets/icon/exportPdfworks/bcg1.svg"),
+    url("../../../assets/icon/exportPdfworks/bcg2.svg");
+  /* 设置每个背景的位置和尺寸,可以使用关键字或者具体的像素值,用逗号分隔 */
+  background-position: top left, bottom;
+  /* background-size: cover, cover; */
+
+  /* 设置每个背景图片的重复方式,用逗号分隔 */
+  background-repeat: no-repeat, no-repeat;
+}
+.coverPageLogo {
+  padding: 40px;
+  width: 100%;
+  display: flex;
+  justify-content: flex-end;
+  box-sizing: border-box;
+  margin-bottom: 30px;
+}
+.coverPageFrom {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  width: 70%;
+  margin: 0 auto;
+}
+.coverPageFromTit {
+  display: flex;
+  justify-content: center;
+  width: 100%;
+}
+.fromCss {
+  border: 1.5px dashed rgba(158, 208, 255, 1);
+  border-radius: 16px;
+  background-color: #fff;
+  padding: 24px 32px;
+  width: 300px;
+  margin: 30px;
+  color: rgba(35, 99, 205, 1);
+}
+.fromCss > div {
+  margin-bottom: 10px;
+  display: flex;
+}
+.fromCss > div > span {
+  flex-shrink: 0;
+  margin-right: 5px;
+  font-size: 16px;
+}
+.fromCss > div:last-child {
+  margin-bottom: 0;
+}
+.txt {
+  width: 100%;
+  border-bottom: 1px solid rgba(192, 210, 229, 1);
+  text-align: center;
+  color: #000;
+}
+.coverPageCon {
+  background-color: #e3edfe;
+  display: flex;
+  flex-direction: column;
+  padding: 0 20px;
+  padding-bottom: 30px;
+  box-sizing: border-box;
+}
+.zhBlock {
+  width: 125px;
+  height: 64px;
+  padding: 10px 8px;
+  box-sizing: border-box;
+  background-color: rgba(255, 255, 255, 1);
+  border-radius: 8px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+.zhBlockTit {
+  font-size: 10px;
+  font-weight: 400;
+  color: rgba(0, 0, 0, 0.6);
+  display: flex;
+  align-items: center;
+  margin-bottom: 6px;
+}
+.zhBlockCon {
+  flex: 1;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  font-size: 14px;
+  color: rgba(0, 0, 0, 0.9);
+  font-weight: 400;
+  background-color: rgba(243, 247, 253, 1);
+  border-radius: 5px;
+}
+.zhBlockCon >>> .el-rate__icon {
+  margin: 0 !important;
+}
+.zhBlockCon2 {
+  display: flex;
+  flex-wrap: wrap;
+  overflow: hidden;
+}
+.zhBlockCon2 > span {
+  font-size: 8px;
+  font-weight: 400;
+  color: rgba(0, 0, 0, 0.9);
+  background-color: rgba(243, 247, 253, 1);
+  border-radius: 2px;
+  padding: 1px 4px;
+  box-sizing: border-box;
+  margin-right: 4px;
+  margin-bottom: 2px;
+}
+.zxt {
+  height: 300px;
+  width: 100%;
+  margin: 10px 0;
+  background-color: rgba(255, 255, 255, 1);
+  padding: 10px 0;
+  border-radius: 15px;
+}
+</style>

+ 10 - 3
src/components/pages/components/exportWorksDialog.vue

@@ -7,9 +7,9 @@
       class="worksDialogCSS"
       :append-to-body="true"
     > -->
-      <div slot="title" class="header-title">
+      <!-- <div slot="title" class="header-title">
         <div style="color: #fff">导出作业集</div>
-      </div>
+      </div> -->
     <div ref="reportPdf" v-loading="loading">
       <div
         class="coverPage"
@@ -60,6 +60,8 @@
           />
         </div>
       </div>
+
+
       <div class="coverPageCon">
         <div
           style="
@@ -414,7 +416,7 @@
                             line-height: 21px;
                           "
                     >
-                      <!-- 提交时间: 2024-07-12 17:36:06 -->
+                      <!-- 提交时间: {{ i.taskList[i.taskList.length-1].create_at }} -->
                     </div>
                   </div>
                   <div style="display: flex; justify-content: space-between">
@@ -466,6 +468,10 @@
             </div>
           </div>
         </div>
+        <div style="display: flex;justify-content: flex-end;">
+          <img :src="schoolImg.bjLogo ? schoolImg.bjLogo : ''" alt="" />
+        </div>
+
       </div>
     </div>
   <!-- </el-dialog> -->
@@ -499,6 +505,7 @@ export default {
           schoolId: "45facc0a-1211-11ec-80ad-005056b86db5",
           logo: require("../../../assets/icon/exportPdfworks/cocoroboLogo.svg"),
           conImg: require("../../../assets/icon/exportPdfworks/cocoroboCon.svg"),
+          bjLogo: require("../../../assets/icon/exportPdfworks/logo2.svg"),
           bkColor: "#E5EFFE"
         }
       ],

+ 88 - 24
src/components/pages/works.vue

@@ -354,25 +354,30 @@
       class="dialog_diy check_diy"
     >
       <div>
-        <div class="student_search" style="margin-bottom: 10px">
-          <div>筛选</div>
-          <div style="display: flex; width: 90%">
-            <el-select
-              class="r_select"
-              v-model="uname"
-              placeholder="请选择班级"
-              filterable
-              @change="searchWork2"
-            >
-              <el-option label="所有班级" value></el-option>
-              <el-option
-                v-for="item in userAarray"
-                :key="item.id"
-                :label="item.name"
-                :value="item.id"
-              ></el-option>
-            </el-select>
+        <div class="student_search" style="margin-bottom: 10px;justify-content: space-between;">
+          <div style="display: flex;justify-content: space-between;">
+            <div style="margin-right: 10px;">筛选</div>
+            <div>
+              <el-select
+                class="r_select"
+                v-model="uname"
+                placeholder="请选择班级"
+                filterable
+                @change="searchWork2"
+              >
+                <el-option label="所有班级" value></el-option>
+                <el-option
+                  v-for="item in userAarray"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                ></el-option>
+              </el-select>
+            </div>
           </div>
+          
+          <el-button size="small" @click="exportPdfSetAllBtn" type="primary">一键导出</el-button>
+          
         </div>
         <div>
           <el-table
@@ -385,7 +390,12 @@
             style="width: 100%"
             :row-class-name="tableRowClassName"
             :header-cell-style="{ background: 'rgb(238,238,238)' }"
+              @selection-change="handleSelectionChange"
           >
+            <el-table-column
+              type="selection"
+              width="55">
+            </el-table-column>
             <el-table-column
               prop="sName"
               label="姓名"
@@ -413,7 +423,7 @@
               </template>
             </el-table-column>
           </el-table>
-          <div style="margin-top: 10px">
+          <div style="display: flex;justify-content: space-between; padding:15px 0">
             <el-pagination
               background
               layout="prev, pager, next"
@@ -421,12 +431,15 @@
               :total="total2"
               @current-change="handleCurrentChange2"
             ></el-pagination>
+             <div style="display: flex;"  class="dialog-footer">
+              <el-button @click="exportPdfSetBtn" size="small" style="padding: 6px 18px;" type="primary">导出</el-button>
+
+              <el-button  style="margin-left: 10px;padding: 6px 18px;" size="small" @click="signDialog = false">关闭</el-button>
+            </div>
           </div>
         </div>
       </div>
-      <span slot="footer" class="dialog-footer">
-        <el-button @click="signDialog = false">关闭</el-button>
-      </span>
+     
     </el-dialog>
     <div class="report_box" v-if="reportVisible">
       <studentReport
@@ -436,6 +449,19 @@
         :oid="oid"
       ></studentReport>
     </div>
+
+    <el-dialog
+      title="文件预览"
+      :visible.sync="worksDialog"
+      :before-close="handleClose"
+      class="worksDialogCSSExp"
+      :append-to-body="true"
+    >
+      <div slot="title" class="header-title">
+        <div style="color: #fff">导出作业集</div>
+      </div>
+      <exportDataDialog  :key="exportW" :digNum="digNum" :oid="oid" :multipleSelection="multipleSelection" :worksDialog.sync="worksDialog" :cid="checkCourse"></exportDataDialog>
+    </el-dialog>
     <!-- <div class="cancelbox" v-if="reportVisible">
       <el-button @click="cancelR" type="primary" size="small">返回</el-button>
     </div> -->
@@ -448,16 +474,24 @@ import Report from "./components/report";
 import studentReport from "./components/studentReport";
 import "../../common/aws-sdk-2.235.1.min.js";
 import StudentWorksDetail from "./components/studentWorksDetail.vue";
+import exportDataDialog from "./components/exportDataDialog.vue";
+
 
 export default {
   components: {
     WorkDate,
     Report,
     studentReport,
-    StudentWorksDetail
+    StudentWorksDetail,
+    exportDataDialog
   },
   data() {
     return {
+      worksDialog:false,
+      exportW:0,
+      digNum:0,
+      digCid:'',
+
       tableHeight: "500px",
       isLoading: false,
       formLabelWidth: "100px",
@@ -496,7 +530,8 @@ export default {
       uname: "",
       cutTabNum:0,
       tableData:[],
-      dialogVisibleS:false
+      dialogVisibleS:false,
+      multipleSelection: []
     };
   },
   mounted() {
@@ -518,6 +553,24 @@ export default {
     });
   },
   methods: {
+    handleSelectionChange(val) {
+        this.multipleSelection = val;
+    },
+    // 导出pdf
+    exportPdfSetBtn(){
+      this.worksDialog = true;
+      this.digNum = 0
+      this.exportW++
+      
+    },
+    // 一键导出pdf
+    exportPdfSetAllBtn(){
+      this.worksDialog = true;
+
+      this.digNum = 1
+      this.exportW++
+      
+    },
     goTo(path) {
       this.$router.push(path);
     },
@@ -1010,4 +1063,15 @@ export default {
   text-overflow: ellipsis;
   white-space: nowrap;
 }
+.worksDialogCSSExp>>> .el-dialog__header {
+  /* padding: 9px 20px 10px; */
+  background: #32455b !important;
+}
+
+.worksDialogCSSExp >>> .el-dialog__body {
+  width: 635px !important;
+}
+.worksDialogCSSExp >>> .el-dialog {
+  width: 676px !important;
+}
 </style>

部分文件因文件數量過多而無法顯示