Kaynağa Gözat

Merge branch 'beta' of https://git.cocorobo.cn/CocoRoboLabs/pbl-teacher-table into beta

lsc 6 ay önce
ebeveyn
işleme
282ae4ed6a

+ 1 - 1
dist/index.html

@@ -32,7 +32,7 @@
       width: 100%;
       background: #e6eaf0;
       font-family: '黑体';
-    }</style><link href=./static/css/app.3af7c0f3a17e8254bfebe42e961ac035.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.5a298b1b16b7a18c1575.js></script></body></html><script>function stopSafari() {
+    }</style><link href=./static/css/app.a4dbeca4d87c56dce0acbc4d76439dbb.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.00bfcafc8431113801f1.js></script><script type=text/javascript src=./static/js/vendor.a54a39a7efbf3fedeee2.js></script><script type=text/javascript src=./static/js/app.2581c1e76795629baeac.js></script></body></html><script>function stopSafari() {
     //阻止safari浏览器双击放大功能
     let lastTouchEnd = 0  //更新手指弹起的时间
     document.documentElement.addEventListener("touchstart", function (event) {

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/static/css/app.3af7c0f3a17e8254bfebe42e961ac035.css


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/static/css/app.3af7c0f3a17e8254bfebe42e961ac035.css.map


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/static/css/app.a4dbeca4d87c56dce0acbc4d76439dbb.css


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/static/css/app.a4dbeca4d87c56dce0acbc4d76439dbb.css.map


+ 0 - 0
dist/static/img/videoFile.8b2406f.svg → dist/static/img/videoFile.2273786.svg


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/static/js/0.4f3b05586c3acc102a54.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/static/js/0.4f3b05586c3acc102a54.js.map


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/static/js/0.7da288988865a9378b49.js.map


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/static/js/app.2581c1e76795629baeac.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/static/js/app.2581c1e76795629baeac.js.map


+ 2 - 2
dist/static/js/manifest.571c38d63f24b1ae9e16.js → dist/static/js/manifest.00bfcafc8431113801f1.js

@@ -1,2 +1,2 @@
-!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,a,c){for(var i,u,f,s=0,l=[];s<r.length;s++)u=r[s],t[u]&&l.push(t[u][0]),t[u]=0;for(i in a)Object.prototype.hasOwnProperty.call(a,i)&&(e[i]=a[i]);for(n&&n(r,a,c);l.length;)l.shift()();if(c)for(s=0;s<c.length;s++)f=o(o.s=c[s]);return f};var r={},t={6:0};function o(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,o){n=t[e]=[r,o]});n[2]=r;var a=document.getElementsByTagName("head")[0],c=document.createElement("script");c.type="text/javascript",c.charset="utf-8",c.async=!0,c.timeout=12e4,o.nc&&c.setAttribute("nonce",o.nc),c.src=o.p+"static/js/"+e+"."+{0:"7da288988865a9378b49",1:"d8d4e9b1fe43bbb0a681",2:"94e1427bfc7ef0b4c685",3:"3a9f53a78da16650e6b8"}[e]+".js";var i=setTimeout(u,12e4);function u(){c.onerror=c.onload=null,clearTimeout(i);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),t[e]=void 0)}return c.onerror=c.onload=u,a.appendChild(c),r},o.m=e,o.c=r,o.d=function(e,n,r){o.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},o.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(n,"a",n),n},o.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},o.p="./",o.oe=function(e){throw console.error(e),e}}([]);
-//# sourceMappingURL=manifest.571c38d63f24b1ae9e16.js.map
+!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,c,a){for(var i,u,f,s=0,l=[];s<r.length;s++)u=r[s],t[u]&&l.push(t[u][0]),t[u]=0;for(i in c)Object.prototype.hasOwnProperty.call(c,i)&&(e[i]=c[i]);for(n&&n(r,c,a);l.length;)l.shift()();if(a)for(s=0;s<a.length;s++)f=o(o.s=a[s]);return f};var r={},t={6:0};function o(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,o){n=t[e]=[r,o]});n[2]=r;var c=document.getElementsByTagName("head")[0],a=document.createElement("script");a.type="text/javascript",a.charset="utf-8",a.async=!0,a.timeout=12e4,o.nc&&a.setAttribute("nonce",o.nc),a.src=o.p+"static/js/"+e+"."+{0:"4f3b05586c3acc102a54",1:"d8d4e9b1fe43bbb0a681",2:"94e1427bfc7ef0b4c685",3:"3a9f53a78da16650e6b8"}[e]+".js";var i=setTimeout(u,12e4);function u(){a.onerror=a.onload=null,clearTimeout(i);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),t[e]=void 0)}return a.onerror=a.onload=u,c.appendChild(a),r},o.m=e,o.c=r,o.d=function(e,n,r){o.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},o.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(n,"a",n),n},o.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},o.p="./",o.oe=function(e){throw console.error(e),e}}([]);
+//# sourceMappingURL=manifest.00bfcafc8431113801f1.js.map

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/static/js/manifest.00bfcafc8431113801f1.js.map


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/static/js/vendor.a54a39a7efbf3fedeee2.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/static/js/vendor.a54a39a7efbf3fedeee2.js.map


+ 509 - 82
src/components/pages/aiAddCourse/aiBoxRight.vue

@@ -1,10 +1,6 @@
 <template>
   <div class="ai_body" v-loading="loading">
-    <div
-      class="ai_body_dialog"
-      
-      ref="chatDialog"
-    >
+    <div class="ai_body_dialog" ref="chatDialog">
       <div class="dialog_content" v-for="item in array" :key="item.uid">
         <div v-if="item.content" style="margin-left: auto;">
           <div class="content content2" v-html="item.content"></div>
@@ -14,7 +10,7 @@
         </div>
         <div style="margin-top:20px;margin-bottom:20px ; margin-right: auto;">
           <div class="role">
-            <img src="../../../assets/icon/new/role1.png" />
+            <img :src="item.fileid?item.fileid:require('../../../assets/icon/new/role1.png')" />
           </div>
           <div
             element-loading-background="#f6f9ff"
@@ -24,7 +20,10 @@
             }"
             class="content"
             v-loading="item.loading"
-          ><span v-html="item.aiContent"></span><span class="createTime" v-text="item.createtime"></span></div>
+          >
+            <span v-html="item.aiContent"></span
+            ><span class="createTime" v-text="item.createtime"></span>
+          </div>
         </div>
       </div>
     </div>
@@ -130,6 +129,47 @@
           <span>清屏</span>
         </span>
       </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_rlb_itemTop">
+            <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>
+            </div>
+          </div>
+          <div class="ai_b_i_rlb_itemBottom">
+            {{ item.prologue }}
+          </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> -->
       <textarea
         class="ai_body_input_textarea"
         @input="inputChange"
@@ -138,7 +178,14 @@
         v-model.trim="courseText"
         placeholder="在此输入您想了解的内容"
       ></textarea>
-      <div class="c_pub_button_confirm" v-if="!loading" @click="addContent">
+      <div
+        :class="[
+          'c_pub_button_confirm',
+          courseText ? '' : 'c_pub_button_confirmDisabled'
+        ]"
+        v-if="!loading"
+        @click="addContent"
+      >
         发送
       </div>
     </div>
@@ -186,6 +233,8 @@ export default {
       checkImg: checkImg,
       checkIsImg: checkIsImg,
       userid: this.$route.query.userid,
+      oid: this.$route.query.oid,
+      org: this.$route.query.org,
       checkArray: [],
       course: [{ title: "任务1" }, { title: "任务2" }, { title: "任务3" }],
       partArray: [
@@ -196,7 +245,37 @@ export default {
       part: "全部内容",
       checkBool: false,
       loading: false,
-      textareaHeight: 50
+      textareaHeight: 50,
+      publicRoleList: [],
+      roleList: [],
+			textList:[
+				{
+					title:"项目式学习",
+					dataList:['请给我一些学生开展项目式学习可以使用的主题或问题参考,请说出学生将要解决的问题,以及学生要经历怎样的学习活动。','请将一个关于生态保护项目的项目式学习展开描述,你需要描述学生如何解决这个问题,你需要至少写出四个活动,这些活动需要按照前后逻辑关系排列。','请对驱动问题为“如何为学校建造一个富有特色的花坛?”的项目式学习进行子问题拆解,至少拆解为5个子问题,并根据子问题对应写出各环节的主要活动。']
+				},{
+					title:"教学评价",
+					dataList:['如果需要给学生的社区服务进行评价,给出评价维度和至少3个等级的表现描述。','为6年级学生设计一份关于梧桐山研究报告的评估任务表,并给出参考的报告流程,至少包含8个步骤,并包括地图、图片和至少300个词。','创建一个给5年级学生使用的课堂小测试,包含5道多选题,评价学生对于太阳能这个概念的理解。你需要给出题目和正确答案。']
+				},{
+					title:"教学设计",
+					dataList:['如果需要5年级学生感受“移步换景”的景观写作手法,你有什么合适的阅读材料推荐?你需要给出材料名称,以及材料的哪部分内容。','设计一个针对8年级学生且关于人类迁徙主题的地理课,并在课程中设计至少1项小组活动。','设计一个针对5年级学生的课程,课程综合科学和信息技术领域,解决生物与环境领域的生活问题,你需要给出完整的课程框架和活动。','如果3年级的学生不能理解光合作用的实现过程,需要你帮我设计一个支持他们理解的教学活动,需要包含活动的形式、实施材料和清单。','请基于贝叶斯定理为8年级学生出三道题目。','如果需要八年级学生了解尼罗河流域的文化发展史,你有哪些推荐的网站或参考书籍?']
+				},{
+					title:"班级管理",
+					dataList:['创建一组给一年级学生使用的班级口号,要求大家注意卫生、保护环境,口号需要对仗工整,符合一年级学生的理解水平。',' 设计一套用于6年级学生的班级管理规章制度,内容需要包括学习、纪律、卫生、思想品德方面。']
+				},{
+					title:"课堂组织",
+					dataList:['请为“制作垃圾分类宣传单”的小组活动设计小组分工表,每个小组的成员为4-6人。','请给5年级“校园植物图鉴”社团课程设计一份小组合作公约,需包含小组成员信息、小组项目目标、填写日期,总长度不超过300字,并且提供至少3处学生自行填写的部分。','请用苏格拉底提问的方式,引导5年级学生拆解驱动问题:如何解决教室黑板反光的问题?其中需包含对于反光原因的分析与实验探究。']
+				},{
+					title:"教师发展",
+					dataList:['教师需要理解项目式学习的理论基础和基础概念,你需要生成一份阅读清单,要求内容为中文书籍或文献。','设计一个教师进行个人学期总结的框架,需要体现在教学、教研、个人学习方面的进步。']
+				},{
+					title:"代码分析",
+					dataList:['这段代码实现了什么效果?','请描述这段代码。','根据这段代码,给我一些修改意见。']
+				},
+			],
+			showTextList:false,
+      showRoleList: false,
+      choseRoleItem: 0,
+			choseTextItem:0,
     };
   },
   watch: {
@@ -273,59 +352,154 @@ export default {
           `;
           message = msg;
         }
-        let _uuid = uuidv4();
-        this.array.push({
-          role: "user",
-          content: `${this.courseText}`,
-          uid: _uuid,
-          AI: "AI",
-          aiContent: "",
-          oldContent: "",
-          isShowSynchronization: false,
-          filename: "",
-          index: this.array.length,
-          is_mind_map: false,
-          createtime: new Date().toLocaleString().replaceAll("/", "-"),
-          loading: true
-        });
 
-        let history = [];
-        this.array.forEach(i => {
-          if (i.content) history.push({ role: "user", content: i.content });
-          if (i.aiContent)
-            history.push({ role: "assistant", content: i.aiContent });
+        // 这里处理@的角色
+        let _atRoleList = [];
+        let _roleList = [...this.roleList, ...this.publicRoleList];
+        _roleList.forEach(i => {
+          if (message.indexOf(`@${i.assistantName}`) != -1) {
+            _atRoleList.push(i);
+          }
         });
 
-        history.push({ role: "user", content: message });
-        this.$nextTick(() => {
-          this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
-        });
-        let params = JSON.stringify({
-          // model: "gpt-3.5-turbo",
-          model: "gpt-4o-2024-08-06",
-          temperature: 0,
-          max_tokens: 4096,
-          top_p: 1,
-          frequency_penalty: 0,
-          presence_penalty: 0,
-          messages: history,
-          uid: _uuid,
-          mind_map_question: ""
-        });
-        this.courseText = "";
+        if (_atRoleList.length > 0) {
+          //有@角色
+          let _replaceText = message;
+          let _htmlText = message;
+          _atRoleList.forEach(_i => {
+            _replaceText = _replaceText.replaceAll(`@${_i.assistantName}`, ``);
+            _htmlText = _htmlText.replaceAll(
+              `@${_i.assistantName}`,
+              `<span class='aite-name'>@${_i.assistantName}</span>`
+            );
+          });
 
-        this.ajax
-          .post("https://gpt4.cocorobo.cn/chat", params)
-          .then(res => {
-            if (res.data.FunctionResponse.result == "发送成功") {
+          _atRoleList.forEach((_item, _index) => {
+            const _uid = uuidv4();
+            if (_index == 0) {
+              this.array.push({
+                loading: true,
+                role: "user",
+                content: _htmlText,
+                uid: _uid,
+                AI: "AI",
+                aiContent: "",
+                oldContent: "",
+                isShowSynchronization: false,
+                filename: _item.assistantName,
+                index: this.array.length,
+                is_mind_map: false,
+                fileid: _item.headUrl,
+                createtime: new Date().toLocaleString().replaceAll("/", "-")
+              });
             } else {
-              this.$message.warning(res.data.FunctionResponse.result);
+              this.array.push({
+                loading: true,
+                role: "user",
+                content: "",
+                uid: _uid,
+                AI: "AI",
+                aiContent: "",
+                oldContent: "",
+                isShowSynchronization: false,
+                filename: _item.assistantName,
+                index: this.array.length,
+                is_mind_map: false,
+                fileid: _item.headUrl,
+                createtime: new Date().toLocaleString().replaceAll("/", "-")
+              });
             }
-          })
-          .catch(e => {
-            console.log(e);
+            this.$nextTick(() => {
+              this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
+            });
+
+            let params = {
+              assistant_id: _item.assistant_id,
+              userId: this.userid,
+              message: _replaceText,
+              session_name: `${this.courseId}-addCourseA`,
+              uid: _uid,
+              file_ids: [],
+              model: "gpt-4o-2024-08-06"
+            };
+            var OpenCC = require("opencc-js");
+            let converter = OpenCC.Converter({
+              from: "cn",
+              to: "hk"
+            });
+						
+            this.ajax
+              .post("https://gpt4.cocorobo.cn/ai_agent_park_chat_new", params)
+              .then(res => {
+                if (
+                  converter(res.data.FunctionResponse.result) ==
+                  converter("发送成功")
+                ) {
+                } else {
+                  this.$message.warning(res.data.FunctionResponse.result);
+                }
+              })
+              .catch(err => {
+                console.log(err);
+              });
+            this.getAtAuContent(_uid);
+          });
+					this.courseText = "";
+        } else {
+          let _uuid = uuidv4();
+          this.array.push({
+            role: "user",
+            content: `${this.courseText}`,
+            uid: _uuid,
+            AI: "AI",
+            aiContent: "",
+            oldContent: "",
+            isShowSynchronization: false,
+            filename: "",
+            index: this.array.length,
+            is_mind_map: false,
+            createtime: new Date().toLocaleString().replaceAll("/", "-"),
+            loading: true
+          });
+
+          let history = [];
+          this.array.forEach(i => {
+            if (i.content) history.push({ role: "user", content: i.content });
+            if (i.aiContent)
+              history.push({ role: "assistant", content: i.aiContent });
+          });
+
+          history.push({ role: "user", content: message });
+          this.$nextTick(() => {
+            this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
+          });
+          let params = JSON.stringify({
+            // model: "gpt-3.5-turbo",
+            model: "gpt-4o-2024-08-06",
+            temperature: 0,
+            max_tokens: 4096,
+            top_p: 1,
+            frequency_penalty: 0,
+            presence_penalty: 0,
+            messages: history,
+            uid: _uuid,
+            mind_map_question: ""
           });
-        this.getAiContent(_uuid);
+          this.courseText = "";
+
+          this.ajax
+            .post("https://gpt4.cocorobo.cn/chat", params)
+            .then(res => {
+              if (res.data.FunctionResponse.result == "发送成功") {
+              } else {
+                this.$message.warning(res.data.FunctionResponse.result);
+              }
+            })
+            .catch(e => {
+              console.log(e);
+            });
+          this.getAiContent(_uuid);
+        }
       }
     },
     getAiContent(_uid) {
@@ -374,6 +548,54 @@ export default {
         }
       };
     },
+		getAtAuContent(_uid){
+			let _source = new EventSource(
+        `https://gpt4.cocorobo.cn/question/${_uid}`
+      ); //http://gpt4.cocorobo.cn:8011/question/   https://gpt4.cocorobo.cn/question/
+      let _allText = "";
+      let _mdText = "";
+      const md = new MarkdownIt();
+      _source.onmessage = _e => {
+        let _eData = JSON.parse(_e.data);
+        if (_eData.content.replace("'", "").replace("'", "") == "[DONE]") {
+          let _result = [];
+          if ("result" in _eData) {
+            _result = _eData.result;
+            for (let i = 0; i < _result.length; i++) {
+              _mdText = _mdText.replace(_result[i].text, _result[i].fileName);
+            }
+          }
+          _mdText = _mdText.replace("_", "");
+          this.array.find(i => i.uid == _uid).aiContent = _mdText;
+          this.array.find(i => i.uid == _uid).isalltext = true;
+          this.array.find(i => i.uid == _uid).isShowSynchronization = true;
+          this.array.find(i => i.uid == _uid).loading = false;
+          this.$nextTick(() => {
+            this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
+          });
+          this.insertChat(_uid);
+        } else {
+          let _text = _eData.content.replace("'", "").replace("'", "");
+          if (_allText == "") {
+            _allText = _text.replace(/^\n+/, ""); //去掉回复消息中偶尔开头就存在的连续换行符
+          } else {
+            _allText += _text;
+          }
+          _mdText = _allText + "_";
+          _mdText = _mdText.replace(/\\n/g, "\n");
+          _mdText = _mdText.replace(/\\/g, "");
+          if (_allText.split("```").length % 2 == 0) _mdText += "\n```\n";
+          //转化返回的回复流数据
+          _mdText = md.render(_mdText);
+          this.array.find(i => i.uid == _uid).aiContent = _mdText;
+          this.array.find(i => i.uid == _uid).loading = false;
+          this.$nextTick(() => {
+            this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
+          });
+          // 处理流数据
+        }
+      };
+		},
     //保存消息
     insertChat(_uid) {
       let _data = this.array.find(i => i.uid == _uid);
@@ -426,7 +648,7 @@ export default {
                   index: i,
                   is_mind_map: false,
                   fileid: _data[i].fileid,
-									createtime:_data[i].createtime
+                  createtime: _data[i].createtime
                 });
               }
               this.array = _chatList;
@@ -490,7 +712,7 @@ export default {
     },
     inputChange() {
       if (this.courseText.at(-1) == "@") {
-        console.log("哇咔咔");
+        this.showRoleList = true;
       }
       if (this.courseText.at(-1) == "/") {
         console.log("哇卡ka2");
@@ -504,9 +726,41 @@ export default {
       });
     },
     textareaKeydown(_e) {
-			
-      if (_e.key === "Enter") {
-				_e.preventDefault();
+      if (this.showRoleList && this.choseRoleList.length > 0) {
+        console.log(_e.keyCode);
+        switch (_e.keyCode) {
+          case 38: //小键盘上
+            _e.preventDefault();
+            if (this.choseRoleItem == 0) return;
+            this.choseRoleItem--;
+            // 修改滚动条高度
+            this.$refs.roleListRef.scrollTo({
+              top:
+                this.$refs[`roleItem${this.choseRoleItem}Ref`][0].offsetTop -
+                10,
+              behavior: "smooth"
+            });
+            // this.$refs.roleListRef.scrollTop = this.choseRoleItem * 107;
+            break;
+          case 40: //小键盘下
+            _e.preventDefault();
+            if (this.choseRoleItem == this.choseRoleList.length - 1) return;
+            this.choseRoleItem++;
+            this.$refs.roleListRef.scrollTo({
+              top:
+                this.$refs[`roleItem${this.choseRoleItem}Ref`][0].offsetTop -
+                10,
+              behavior: "smooth"
+            });
+            // this.$refs.roleListRef.scrollTop = this.choseRoleItem * 107;
+            break;
+          case 13: //回车
+            _e.preventDefault();
+            this.choseRole(this.choseRoleList[this.choseRoleItem]);
+            break;
+        }
+      } else if (_e.key === "Enter") {
+        _e.preventDefault();
         if (_e.shiftKey) {
           this.courseText += "\n";
         } else {
@@ -514,8 +768,8 @@ export default {
         }
       }
     },
-		clear(){
-			this.$confirm("确定清空聊天记录吗?", "提示", {
+    clear() {
+      this.$confirm("确定清空聊天记录吗?", "提示", {
         confirmButtonText: "确定",
         cancelButtonText: "取消",
         type: "warning"
@@ -541,7 +795,57 @@ export default {
             });
         })
         .catch(_ => {});
-		}
+    },
+    getRoleList() {
+      this.roleList = [];
+      let params = {
+        userId: this.userid
+      };
+      this.ajax
+        .post("https://gpt4.cocorobo.cn/get_ai_agent_assistant_list", params)
+        .then(res => {
+          let _data = res.data.FunctionResponse.result;
+          if (_data) {
+            this.roleList = JSON.parse(_data);
+          }
+        })
+        .catch(e => {
+          console.log(e);
+          // this.$message.error("获取角色列表失败");
+          this.roleList = [];
+        });
+    },
+    getPublicRoleList() {
+      this.publicRoleList = [];
+      let params = {
+        userId: this.userid,
+        organizeid: this.oid
+      };
+      this.ajax
+        .post(
+          "https://gpt4.cocorobo.cn/get_ai_agent_assistant_share_list",
+          params
+        )
+        .then(res => {
+          let _data = res.data.FunctionResponse.result;
+          if (_data) {
+            this.publicRoleList = JSON.parse(_data);
+          }
+        })
+        .catch(e => {
+          this.publicRoleList = [];
+          console.log(e);
+          // console.log("获取公共角色失败", e);
+        });
+    },
+    choseRole(item) {
+      let _lastAtIndex = this.courseText.lastIndexOf("@");
+      this.courseText = `${this.courseText.slice(0, _lastAtIndex)}@${
+        item.assistantName
+      } `;
+      this.$refs.textareaRef.focus();
+      this.showRoleList = false;
+    }
   },
   computed: {
     courseTextLength() {
@@ -559,6 +863,18 @@ export default {
         task += a.join("/");
       }
       return task + " " + this.part;
+    },
+    choseRoleList() {
+      let result = [...this.roleList, ...this.publicRoleList];
+      const _index = this.courseText.lastIndexOf("@");
+      if (_index !== -1) {
+        let roleName = this.courseText.substring(_index + 1);
+        result = result.filter(i => i.assistantName.indexOf(roleName) != -1);
+      } else {
+        return [];
+      }
+      this.choseRoleItem = 0;
+      return result;
     }
   },
   mounted() {
@@ -568,6 +884,8 @@ export default {
         this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
       });
     });
+    this.getRoleList();
+    this.getPublicRoleList();
   }
 };
 </script>
@@ -666,7 +984,7 @@ export default {
   border: solid 1px #3781fb;
   border-radius: 15px;
   display: flex;
-	font-size: 15px;
+  font-size: 15px;
   align-items: center;
   justify-content: center;
   background-color: #fff;
@@ -676,7 +994,7 @@ export default {
   width: 17px;
   height: 17px;
   margin-right: 5px;
-	fill: black;
+  fill: black;
 }
 
 .ai_b_i_btnArea > span:hover {
@@ -688,6 +1006,110 @@ export default {
   fill: #409eff;
 }
 
+.ai_b_i_textListBox{
+	width: 100%;
+  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);
+		display: flex;
+}
+
+.ai_b_i_tlb_left{
+	width: 60px;
+	height: 100%;
+	background-color: red;
+}
+
+.ai_b_i_tlb_right{
+	flex: 1;
+	height: 100%;
+	background-color: yellow;
+}
+
+.ai_b_i_roleListBox {
+  width: 100%;
+  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);
+}
+
+.ai_b_i_rlb_item {
+  width: calc(100% - 20px);
+  height: auto;
+  padding: 10px;
+  background-color: #f3f7fd;
+  margin-bottom: 20px;
+  border-radius: 8px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  transition: 0.3s;
+  cursor: pointer;
+}
+
+.ai_b_i_rlb_itemActive {
+  background-color: #d1d5db !important;
+}
+
+/* .ai_b_i_rlb_item:hover{
+	background-color: #d1d5db;
+} */
+
+.ai_b_i_rlb_itemTop {
+  display: flex;
+}
+
+.ai_b_i_rlb_itemTop > img {
+  width: 40px;
+  height: 40px;
+  margin-right: 10px;
+  border-radius: 100%;
+  overflow: hidden;
+}
+
+.ai_b_i_rlb_itemTop > div {
+  display: flex;
+  flex-direction: column;
+}
+
+.ai_b_i_rlb_itemTop > div > span {
+  font-size: 16px;
+  font-weight: bold;
+}
+
+.ai_b_i_rlb_itemTop > div > span:last-child {
+  font-size: 14px;
+  color: #999;
+}
+
+.ai_b_i_rlb_itemBottom {
+  margin-top: 10px;
+  display: flex;
+}
+
+.ai_b_i_rlb_itemBottom > span {
+  width: 60px;
+  height: 30px;
+  border-radius: 15px;
+  display: flex;
+}
+
 .ai_body_input_textarea {
   flex: 1;
   margin: 10px 5px 10px 5px;
@@ -699,7 +1121,7 @@ export default {
   resize: none;
   font-size: 18px;
   overflow: auto;
-	padding-right: 100px;
+  padding-right: 100px;
 }
 
 .ai_body_input_textarea::-webkit-input-placeholder {
@@ -724,22 +1146,21 @@ export default {
   color: grey; /* 修改placeholder文字颜色 */
 }
 
-
 .ai_body_input_textarea::-webkit-scrollbar {
   width: 6px;
 }
 
 .ai_body_input_textarea::-webkit-scrollbar-track {
-  background: #D8D9DC;
+  background: #d8d9dc;
   border-radius: 2px;
 }
 
 .ai_body_input_textarea::-webkit-scrollbar-thumb {
-  background: #C9C9C9;
+  background: #c9c9c9;
   border-radius: 10px;
 }
 .ai_body_input_textarea::-webkit-scrollbar-thumb:hover {
-  background: #C9C9C9;
+  background: #c9c9c9;
 }
 
 .c_pub_button_confirm {
@@ -747,7 +1168,7 @@ export default {
     bottom: 13px;
     right: 13px; */
   /* margin-top: 10px; */
-  width: 80px;
+  width: 60px;
   margin-right: 5px;
   display: flex;
   justify-content: center;
@@ -755,6 +1176,12 @@ export default {
   position: absolute;
   right: 10px;
   bottom: 0px;
+  white-space: nowrap;
+  border-radius: 10px;
+}
+
+.c_pub_button_confirmDisabled {
+  background-color: #aeccfe;
 }
 
 .ai_body_dialog {
@@ -802,6 +1229,7 @@ export default {
 .dialog_content > div .role > img {
   height: 100%;
   width: 100%;
+	border-radius: 100%;
 }
 
 .dialog_content > div .content {
@@ -815,18 +1243,18 @@ export default {
   background: #f6f9ff;
   /* overflow: hidden; */
   margin: 0 10px;
-	position: relative;
+  position: relative;
 }
 
-.createTime{
-	width: 100%;
-	height: 20px;
-	position: absolute;
-	bottom: -25px;
-	left: 0;
-	font-size: 14px;
-	white-space: nowrap;
-	color: #919191;
+.createTime {
+  width: 100%;
+  height: 20px;
+  position: absolute;
+  bottom: -25px;
+  left: 0;
+  font-size: 14px;
+  white-space: nowrap;
+  color: #919191;
 }
 
 .dialog_content > div .content2 {
@@ -995,5 +1423,4 @@ export default {
   color: #0061ff;
   border-color: #0061ff;
 }
-
 </style>

+ 282 - 112
src/components/pages/components/exportWorksDialog.vue

@@ -1,5 +1,15 @@
 <template>
   <div class="pbl">
+    <!-- <el-dialog
+      title="文件预览"
+      :visible.sync="worksDialog"
+      :before-close="handleClose"
+      class="worksDialogCSS"
+      :append-to-body="true"
+    > -->
+      <div slot="title" class="header-title">
+        <div style="color: #fff">导出作业集</div>
+      </div>
     <div ref="reportPdf" v-loading="loading">
       <div
         class="coverPage"
@@ -8,10 +18,10 @@
         }"
       >
         <div class="coverPageLogo">
-          <img :src="schoolImg.logo ? schoolImg.logo : '' " alt="" />
+          <img :src="schoolImg.logo ? schoolImg.logo : ''" alt="" />
         </div>
         <div class="coverPageFrom">
-          <div class="coverPageFromTit">{{ worksDialogCon.course }}</div>
+          <div class="coverPageFromTit">{{ worksDialogCon2.course }}</div>
           <div
             style="
                   font-size: 36px;
@@ -25,15 +35,15 @@
           <div class="fromCss">
             <div>
               <span>姓名:</span>
-              <div class="txt">{{ worksDialogCon.sName }}</div>
+              <div class="txt">{{ worksDialogCon2.sName }}</div>
             </div>
             <div>
               <span>班级:</span>
-              <div class="txt">{{ worksDialogCon.class }}</div>
+              <div class="txt">{{ worksDialogCon2.class }}</div>
             </div>
             <div>
               <span>学校:</span>
-              <div class="txt">{{ worksDialogCon.schName }}</div>
+              <div class="txt">{{ worksDialogCon2.schName }}</div>
             </div>
             <!-- <div>
               <span>指导老师:</span>
@@ -42,7 +52,10 @@
           </div>
         </div>
         <div class="coverPageFrom">
-          <img :src="schoolImg.conImg ? schoolImg.conImg :'../../../assets/icon/exportPdfworks/cocoroboCon.svg'" alt="" />
+          <img
+            src="../../../assets/icon/exportPdfworks/cocoroboCon.svg"
+            alt=""
+          />
         </div>
       </div>
       <div class="coverPageCon">
@@ -371,10 +384,8 @@
                 </div>
               </div>
               <div
-                v-if="
-                  state == 5 && item[0].stage == i.id && item[0].task == k.id
-                "
-                v-for="(item, index) in elist"
+                v-if="item.stage == i.id && item.task == k.id && item.data && item.data.length"
+                v-for="(item, index) in elist[i.id]"
                 :key="index"
               >
                 <div class="taskSco">
@@ -389,7 +400,7 @@
                     <div style="font-weight: 600; color: rgba(0, 0, 0, 0.9)">
                       任务得分:
                       <span style="color: rgba(54, 129, 252, 1)">{{
-                        totalScore(item[0].data)
+                        totalScore(item.data)
                       }}</span
                       >分
                     </div>
@@ -409,7 +420,7 @@
                       <div>
                         <div class="score_boxTit"><span>分数详情</span></div>
                         <div
-                          v-for="(l, ind) in item[0].data"
+                          v-for="(l, ind) in item.data"
                           :key="ind + 's'"
                           class="score_box"
                         >
@@ -435,12 +446,12 @@
                       </div>
                     </div>
                     <div style="width: 49%">
-                      <div class="worksTarget" v-if="isShow(item[0].data)">
+                      <div class="worksTarget" v-if="isShow(item.data)">
                         <span>目标</span>
                       </div>
-                      <div class="worksTargetCon" v-if="isShow(item[0].data)">
+                      <div class="worksTargetCon" v-if="isShow(item.data)">
                         <div
-                          v-for="(r, tarIndex) in item[0].data"
+                          v-for="(r, tarIndex) in item.data"
                           :key="tarIndex"
                         >
                           <span> {{ r.target }}</span>
@@ -455,14 +466,18 @@
         </div>
       </div>
     </div>
+  <!-- </el-dialog> -->
+
   </div>
 </template>
 
 <script>
 import html2canvas from "html2canvas";
 import jspdf from "jspdf";
+import JSZip from "jszip";
+
 export default {
-  props: ["uid", "cid", "worksDialog", "worksDialogCon"],
+  props: ["uid", "cid", "worksDialog", "worksDialogCon","digNum"],
   data() {
     return {
       workList: [],
@@ -472,7 +487,11 @@ export default {
       state: 0,
       oid: this.$route.query.oid,
       org: this.$route.query.org,
+      uid2: this.uid,
+      worksDialogCon2: this.worksDialogCon,
+      courseName:'',
       loading: false,
+      tableData: [],
       imgList: [
         {
           schoolId: "45facc0a-1211-11ec-80ad-005056b86db5",
@@ -485,18 +504,24 @@ export default {
     };
   },
   watch: {
-    uid(newl) {
-        this.getCourseDetail();
-    }
+    // uid(newl) {
+    //     this.getCourseDetail();
+    // }
   },
   mounted() {
-
-      this.getCourseDetail();
-    
+    if (this.digNum == 0) {
+      this.downPdf()
+    }else{
+     this.getWorks1()
+    }
+      // this.getCourseDetail();
   },
   computed: {
     isShow() {
       return function(val) {
+        if (!val) {
+          return 0
+        }
         let num = 0;
         val.forEach(i => {
           if (i.target) {
@@ -508,6 +533,9 @@ export default {
     },
     totalScore() {
       return function(val) {
+        if (!val) {
+          return "0.0"
+        }
         let a = 0;
         val.forEach(e => {
           if (e.sco) {
@@ -521,54 +549,96 @@ export default {
   },
 
   methods: {
-    getPdf() {
+    // 下载pdf文件
+    async getPdf() {
       let domHeight = this.$refs.reportPdf.offsetHeight;
       // console.log('this.$refs.reportPdf',this.$refs.reportPdf.offsetHeight);
       let maxHeight = 64257;
-      html2canvas(this.$refs.reportPdf, {
-        useCORS: true, // 如果截图的内容里有图片,可能会有跨域的情况,加上这个参数,解决文件跨域问题
-        scale: maxHeight / domHeight > 1 ? 1 : maxHeight / domHeight
-      })
-        .then(canvas => {
-          const contentWidth = canvas.width;
-          const contentHeight = canvas.height;
+      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;
 
-          let pageHeight = (contentWidth / 592.28) * 841.89;
-          let leftHeight = contentHeight;
+            var pageData = canvas.toDataURL("image/jpeg", 1.0);
 
-          //页面偏移
-          var position = 0;
-          //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
-          var imgWidth = 595.28; // A4 宽度
-          var imgHeight = (592.28 / contentWidth) * contentHeight; // A4总高度
-          var pageData = canvas.toDataURL("image/jpeg", 1.0);
+            var pdf = new jspdf("", "pt", [contentWidth, contentHeight]);
 
-          var pdf = new jspdf("", "pt", [contentWidth, contentHeight]);
+            //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
+            //当内容未超过pdf一页显示的范围,无需分页
+            // if (leftHeight < pageHeight) {
+            pdf.addImage(pageData, "JPEG", 0, 0, 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);
+          });
+      });
+    },
 
-          pdf.save(
-            this.worksDialogCon.course +
-              "-作业集-" +
-              this.worksDialogCon.sName +
-              ".pdf"
-          );
+    // 压缩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
         })
-        .catch(err => {
-          console.log(err);
-        });
+          .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);
+          });
+      });
     },
 
-     exportPdfSet(uid, con) {
+    // 图片放大查看
+    previewImg(url) {
+      this.$hevueImgPreview(url);
+    },
+    // 获取处理作业信息
+    async exportPdfSet(uid, con) {
       let params = {
-        uid: this.uid,
+        uid: this.uid2,
         cid: this.cid
       };
-     
-      this.ajax
+      return new Promise((resolve, reject) => {
+        this.ajax
           .get(this.$store.state.api + "selectAllWorksDetail", params)
           .then(res => {
             var worksDetail = res.data[1];
@@ -584,41 +654,60 @@ export default {
             var wordInfo = res.data[12]; //文档作业
             this.workEvaList = res.data[13];
 
+            this.elist = [] 
             if (res.data[0].length) {
-              let elistData = JSON.parse(res.data[0][0].chapters)[0]
-                .chapterInfo[0].taskJson;
+              let elistData = JSON.parse(res.data[0][0].chapters);
+
               elistData.forEach((e, i) => {
                 this.elist[i] = [];
-                let a = e.id.split("-");
-                this.elist[i].push({ stage: a[0], task: a[1], data: e.eList });
+                e.chapterInfo[0].taskJson.forEach((k, kin) => {
+                  this.elist[i].push({ stage: i, task: kin, data: k.eList });
+                });
               });
             }
-            this.elist.forEach(e => {
-              this.workEvaList.forEach(i => {
-                if (e[0].stage == i.stage && e[0].task == i.task) {
-                  e[0].data.forEach(l => {
-                    l.sco = 0;
-
-                    let key2 = l.detail
-                      .match(/[\u4e00-\u9fa5a-zA-Z]+/g)
-                      .join("");
-                    // console.log("key2", key2);
 
-                    let rateCopy = JSON.parse(i.rate);
-                    for (const key in rateCopy) {
-                      // console.log("key", key);
 
-                      // let key3 = key.match(/[\u4e00-\u9fa5a-zA-Z]+/g).join("");
-                      if (key2.indexOf(key) != -1 && key != "content") {
-                        l.sco = rateCopy[key] * 1;
-                      }
+            this.elist.forEach((e) => {
+              e.forEach((m, min) => {
+                this.workEvaList.forEach((i) => {
+                  if (
+                    m.stage == i.stage &&
+                    m.task == i.task &&
+                    this.worksDialogCon2.userid == i.userid &&
+                    m.data && m.data.length
+                  ) {
+                    
+                    if (m.data) {
+                      m.data.forEach((l) => {
+                        l.sco = 0;
+                        console.log('l.detail',l.detail);
+                        
+                        if (isNaN(parseFloat(l.detail)) && l.detail) {
+                          var key2 = l.detail
+                          .match(/[\u4e00-\u9fa5a-zA-Z]+/g)
+                          .join("");
+                        }else{
+                          var key2 = l.detail
+                        }
+                        let rateCopy = JSON.parse(i.rate);
+                        for (const key in rateCopy) {
+                          if (isNaN(parseFloat(l.detail)) && l.detail) {
+                            var key3 = key
+                            .match(/[\u4e00-\u9fa5a-zA-Z]+/g)
+                            .join("");
+                          }else{
+                            var key3 = key
+                          }
+                          if (key2.indexOf(key3) != -1 && key != "content") {
+                            l.sco = rateCopy[key] * 1;
+                          }
+                        }
+                      });
                     }
-                  });
-                }
+                  }
+                });
               });
             });
-            // console.log("this.elist", this.elist);
-            // console.log("this.workEvaList", this.workEvaList);
 
             res.data[3].forEach(e => {
               e.content = JSON.parse(e.content);
@@ -707,59 +796,125 @@ export default {
             // console.log("phaseList", phaseList);
             this.workList = phaseList;
             setTimeout(() => {
-              this.getPdf();
-              return resolve(1);
-              // this.$emit("update:worksDialog", false);
+              return resolve();              
             }, 1000);
           })
           .catch(err => {
             console.error(err);
           });
-      
-    },
-    previewImg(url) {
-      this.$hevueImgPreview(url);
+      });
     },
+    // 获取作业阶段人物信息
     getCourseDetail() {
       this.loading = true;
       let params = {
         cid: this.cid,
         choseClass: ""
       };
-      this.ajax
-        .get(this.$store.state.api + "getCourseWorksReport2", params) //getCourseWorksReport
-        .then(res => {
-          this.state = res.data[0][0].state;
+      return new Promise((resolve, reject) => {
+        this.ajax
+          .get(this.$store.state.api + "getCourseWorksReport2", params) //getCourseWorksReport
+          .then(res => {
+            this.state = res.data[0][0].state;
 
-          var dyJSON = JSON.parse(res.data[0][0].chapters);
+            var dyJSON = JSON.parse(res.data[0][0].chapters);
 
-          let dyList = [];
-          for (var i = 0; i < dyJSON.length; i++) {
-            dyList.push({ name: dyJSON[i].dyName, id: i, taskList: [] });
-            var a = dyJSON[i].chapterInfo[0].taskJson;
-            for (var j = 0; j < a.length; j++) {
-              dyList[i].taskList.push({ name: a[j].task, id: j });
+            let dyList = [];
+            for (var i = 0; i < dyJSON.length; i++) {
+              dyList.push({ name: dyJSON[i].dyName, id: i, taskList: [] });
+              var a = dyJSON[i].chapterInfo[0].taskJson;
+              for (var j = 0; j < a.length; j++) {
+                dyList[i].taskList.push({ name: a[j].task, id: j });
+              }
             }
-          }
-          this.dyList = dyList;
+            this.dyList = dyList;
 
-          this.imgList.forEach(e => {
-            console.log(e.schoolId, this.oid);
-            if (e.schoolId == this.oid) {
-              this.schoolImg = e;
-            }
+            this.imgList.forEach(e => {
+              if (e.schoolId == this.oid) {
+                this.schoolImg = e;
+              }
+            });
+
+            return resolve();
+          })
+          .catch(err => {
+            console.error(err);
           });
+      });
+    },
+
+    // 一键打包所有作业
+    async circulatePdf() {
+      let _this = this
+      var zip = new JSZip();
+      let pdfList = [];
+      for (let i = 0; i < this.tableData.length; i++) {
+        this.uid2 = this.tableData[i].userid;
+        this.worksDialogCon2 = this.tableData[i];
+        await this.getCourseDetail();
+        await this.exportPdfSet();
+        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.courseName + "-作业集汇总.zip");
+      });
+
+    this.$emit('update:worksDialog', false);
+      // this.worksDialog = false;
+    },
+    handleClose(done) {
+      done();
+    },
+    // 下载单个文件
+    async downPdf() {
+       
+        await this.getCourseDetail();
+        await this.exportPdfSet();
+        await this.getPdf();
+    },
+
+
+
+    // 获取所有作业然后一键打包压缩包
+    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.isLoading = false;
+          // this.total = res.data[0].length > 0 ? res.data[0][0].num : 0;
+          this.tableData = res.data[0];
+          if (!this.tableData.length){
+            this.loading = false;
 
-          this.exportPdfSet();
+            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);
         });
-      
-
-    },
-    
-   
+    }
   }
 };
 </script>
@@ -1036,4 +1191,19 @@ export default {
 .worksTargetCon > div:last-child {
   margin: 0 !important;
 }
+.dialog_diy >>> .el-dialog__header {
+  padding: 9px 20px 10px;
+  background: #32455b !important;
+}
+.worksDialogCSS >>> .el-dialog__header {
+  /* padding: 9px 20px 10px; */
+  background: #32455b !important;
+}
+
+.worksDialogCSS >>> .el-dialog__body {
+  width: 850px !important;
+}
+.worksDialogCSS >>> .el-dialog {
+  width: 888px !important;
+}
 </style>

+ 3 - 1
src/components/pages/components/studentWorksDetail.vue

@@ -4389,7 +4389,9 @@ export default {
 .max_diy >>> .el-dialog__body {
   height: 800px;
 }
-
+.dialog_diy2 {
+  overflow: hidden;
+}
 .dialog_diy2 >>> .el-dialog__header {
   padding: 9px 20px 10px;
   background: #32455b !important;

+ 2 - 2
src/components/pages/components/workData.vue

@@ -172,9 +172,9 @@
             <div class="JsonTit">
               <div style="width:94%;margin: 0 auto;font-size: 26px;">{{ dataJson.title }}</div>
               <div class="JsonTitBtn" v-if="dialogVisible">
-                <!-- <el-button @click="exportWorkPdf" type="primary" size="small"
+                <el-button @click="exportWorkPdf" type="primary" size="small"
                   >一键导出</el-button
-                > -->
+                >
                 <el-button @click="exportData" type="primary" size="small"
                   >自定义导出</el-button
                 >

+ 26 - 15
src/components/pages/components/worksDetail2.vue

@@ -1558,7 +1558,7 @@
       <div slot="title" class="header-title">
         <div style="color: #fff">导出作业集</div>
       </div>
-      <exportWorksDialog ref="exportW"  :oid="oid" :worksDialog.sync="worksDialog" :worksDialogCon="worksDialogCon" :uid="exportPdfSetUid" :cid="id"></exportWorksDialog>
+      <exportWorksDialog  :key="exportW" :digNum="digNum" :oid="oid" :worksDialog.sync="worksDialog" :worksDialogCon="worksDialogCon" :uid="exportPdfSetUid" :cid="id"></exportWorksDialog>
     </el-dialog>
   </div>
 </template>
@@ -1813,7 +1813,9 @@ export default {
       allWorkData:[],
       worksDialog : false,
       worksDialogCon : {},
-      exportPdfSetUid:''
+      exportPdfSetUid:'',
+      exportW:0,
+      digNum:0
     };
   },
   computed: {
@@ -1896,6 +1898,23 @@ export default {
     });
   },
   methods: {
+    // 导出所有作业
+    exportPdfSetAllWork(){
+      this.worksDialog = true;
+      this.digNum = 1
+      this.exportW++
+      
+    },
+   
+    // 按任务查看导出作业集
+    exportPdfSetBtn(uid, con) {
+      this.worksDialog = true;
+      this.worksDialogCon = con;
+      this.exportPdfSetUid = uid;
+      this.digNum = 0
+
+      this.exportW++
+    },
     cutTabData(val){
       this.cutTabNum = val;
       this.page = 1;
@@ -2883,18 +2902,7 @@ export default {
           console.error(err);
         });
     },
-    // 导出所有作业
-    exportPdfSetAllWork(){
-      this.worksDialog = true;
-    },
-   
-    // 按任务查看导出作业集
-    exportPdfSetBtn(uid, con) {
-      // console.log('con',con);
-      this.worksDialog = true;
-      this.worksDialogCon = con;
-      this.exportPdfSetUid = uid;
-    },
+  
     checkAsk(askJson) {
       this.askJson = askJson;
       this.dialogVisible4 = true;
@@ -4605,7 +4613,7 @@ export default {
   background: #32455b !important;
 }
 .worksDialogCSS >>> .el-dialog__header {
-  padding: 9px 20px 10px;
+  /* padding: 9px 20px 10px; */
   background: #32455b !important;
 }
 
@@ -4646,6 +4654,9 @@ export default {
 .max_diy >>> .el-dialog__body {
   height: 800px;
 }
+.dialog_diy2 {
+  overflow: hidden;
+}
 
 .dialog_diy2 >>> .el-dialog__header {
   padding: 9px 20px 10px;

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor