SanHQin 11 月之前
父節點
當前提交
d01b8a4f12
共有 2 個文件被更改,包括 715 次插入475 次删除
  1. 1 1
      src/components/pages/aiAddCourse/addCourse.vue
  2. 714 474
      src/components/pages/aiAddCourse/aiBox.vue

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

@@ -1029,7 +1029,7 @@
                   </div>
                 </div>
                 <div class="rb_c_ai_box" v-if="stepsNav == 2">
-                  <aiBox @setUnitJson="setUnitJson" :unitJson="unitJson"></aiBox>
+                  <aiBox @setUnitJson="setUnitJson" :courseId="courseId" :unitJson="unitJson"></aiBox>
                 </div>
               </div>
               <div class="rb_c_box_right">

+ 714 - 474
src/components/pages/aiAddCourse/aiBox.vue

@@ -1,573 +1,813 @@
 <template>
-    <div class="ai_body">
-        <div class="ai_body_dialog" v-loading="loading">
-            <div class="dialog_content" :class="{ right: item.role == 2 }" v-for="(item, index) in array" :key="index">
-                <div class="role">
-                    <img src="../../../assets/icon/new/role1.png" v-if="item.role == 1">
-                    <img src="../../../assets/icon/new/role2.png" v-else>
-                </div>
-                <div class="content" :class="{ content2: item.role == 2 }">{{ item.text }}</div>
-            </div>
+  <div class="ai_body">
+    <div class="ai_body_dialog" v-loading="loading" ref="chatDialog">
+      <div
+        class="dialog_content"
+        v-for="(item, index) in array"
+        :key="item.uid"
+      >
+        <div v-if="item.content">
+          <div class="content content2" v-html="item.content"></div>
+          <div class="role">
+            <img src="../../../assets/icon/new/role2.png" />
+          </div>
+        </div>
+        <div style="margin-top:10px ;">
+          <div class="role">
+            <img src="../../../assets/icon/new/role1.png" />
+          </div>
+          <div
+            class="content"
+            v-loading="item.loading"
+            v-html="item.aiContent"
+          ></div>
+        </div>
+        <!-- <div class="role">
+          <img src="../../../assets/icon/new/role1.png"/>
+          <img src="../../../assets/icon/new/role2.png"/>
+        </div>
+        <div class="content content2" :class="{ content2: item.role == 2 }">
+          {{ item.text }}
+        </div>
+				<div class="role">
+          <img src="../../../assets/icon/new/role1.png"/>
         </div>
-        <div class="ai_body_select">
-            <div class="checkBox" v-if="checkBool">
-                <div class="task">
-                    <div class="title">选择需要优化的任务:</div>
-                    <div class="content">
-                        <div class="span" @click="addAllTask()">
-                            <div class="check">
-                                <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="check">
-                                <img :src="checkImg" alt="" v-if="checkArray.indexOf(index) === -1">
-                                <img :src="checkIsImg" alt="" v-else>
-                            </div>
-                            <span>任务{{ index + 1 }}</span>
-                        </div>
-                    </div>
-                </div>
-                <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)">
-                            {{ item.name }}
-                        </div>
-                    </div>
-                </div>
+        <div class="content">
+          {{ item.text }}
+        </div> -->
+      </div>
+    </div>
+    <div class="ai_body_select">
+      <div class="checkBox" v-if="checkBool">
+        <div class="task">
+          <div class="title">选择需要优化的任务:</div>
+          <div class="content">
+            <div class="span" @click="addAllTask()">
+              <div class="check">
+                <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="check">
+                <img
+                  :src="checkImg"
+                  alt=""
+                  v-if="checkArray.indexOf(index) === -1"
+                />
+                <img :src="checkIsImg" alt="" v-else />
+              </div>
+              <span>任务{{ index + 1 }}</span>
             </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>
-                <el-tooltip :content="taskName" placement="top" effect="dark">
-                    <!-- content to trigger tooltip here -->
-                    <span>{{ taskName }}</span>
-                </el-tooltip>
-
-            </span>
+          </div>
         </div>
-        <div class="ai_body_input">
-            <textarea rows="3" @keyup.enter="addContent" class="binfo_input binfo_textarea" cols v-model.trim="courseText" placeholder="在此输入您想了解的内容"
-            ></textarea>
-            <div class="c_pub_button_confirm" v-if="!loading && courseText"  @click="addContent">发送</div>
-            <div class="c_pub_button_confirm" @click="promptTit" v-else>发送</div>
+        <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)"
+            >
+              {{ 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
+      >
+        <el-tooltip :content="taskName" placement="top" effect="dark">
+          <!-- content to trigger tooltip here -->
+          <span>{{ taskName }}</span>
+        </el-tooltip>
+      </span>
+    </div>
+    <div class="ai_body_input">
+      <textarea
+        rows="3"
+        @keyup.enter="addContent"
+        class="binfo_input binfo_textarea"
+        cols
+        v-model.trim="courseText"
+        placeholder="在此输入您想了解的内容"
+      ></textarea>
+      <div
+        class="c_pub_button_confirm"
+        v-if="!loading && courseText"
+        @click="addContent"
+      >
+        发送
+      </div>
+      <div class="c_pub_button_confirm" @click="promptTit" v-else>发送</div>
     </div>
+  </div>
 </template>
 
 <script>
-import checkImg from '../../../assets/icon/sourceFile/check.png'
-import checkIsImg from '../../../assets/icon/sourceFile/check_is.png'
-
+import checkImg from "../../../assets/icon/sourceFile/check.png";
+import checkIsImg from "../../../assets/icon/sourceFile/check_is.png";
+import { v4 as uuidv4 } from "uuid";
+import MarkdownIt from "markdown-it";
 export default {
-    props: {
-        unitJson: {
-            type: Array,
-        },
+  props: {
+    unitJson: {
+      type: Array
     },
-    data() {
-        return {
-            array: [
-                { text: '你好,有说么可以帮你', role: 1 },
-
-            ],
-            courseText: '',
-            checkImg: checkImg,
-            checkIsImg: checkIsImg,
-            checkArray: [],
-            course: [
-                { title: '任务1' },
-                { title: '任务2' },
-                { title: '任务3' }
-            ],
-            partArray: [{ name: '全部内容' }, { name: '任务设计' }, { name: '评价设计' }],
-            part: '',
-            checkBool: false,
-            loading: false
-        }
+		courseId:{
+			type:String,
+			default:""
+		},
+  },
+  data() {
+    return {
+      array: [],
+      courseText: "",
+      checkImg: checkImg,
+      checkIsImg: checkIsImg,
+			userid: this.$route.query.userid,
+      checkArray: [],
+      course: [{ title: "任务1" }, { title: "任务2" }, { title: "任务3" }],
+      partArray: [
+        { name: "全部内容" },
+        { name: "任务设计" },
+        { name: "评价设计" }
+      ],
+      part: "",
+      checkBool: false,
+      loading: false
+    };
+  },
+  watch: {
+    unitJson: {
+      immediate: true,
+      deep: true,
+      handler(newValue, oldValue) {
+        this.course = this.unitJson[0].chapterInfo[0].taskJson;
+      }
+    }
+  },
+  methods: {
+    promptTit() {
+      if (!this.loading && !this.courseText) {
+        this.$message({
+          message: "请输入您想要了解的内容",
+          type: "warning"
+        });
+      } else {
+        this.$message({
+          message: "请回答完毕后再次发送",
+          type: "warning"
+        });
+      }
     },
-    watch: {
-        unitJson: {
-            immediate: true,
-            deep: true,
-            handler(newValue, oldValue) {
-               this.course = this.unitJson[0].chapterInfo[0].taskJson
+    addContent() {
+      if (this.courseText) {
+        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,
+          loading: true
+        });
+        this.$nextTick(() => {
+          this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
+        });
+        let params = JSON.stringify({
+          model: "gpt-3.5-turbo",
+          temperature: 0,
+          max_tokens: 4096,
+          top_p: 1,
+          frequency_penalty: 0,
+          presence_penalty: 0,
+          messages: [{ role: "user", content: this.courseText }],
+          uid: _uuid,
+          mind_map_question: ""
+        });
+        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);
+      }
+      //             if (this.courseText) {
+
+      //                 this.loading = true
+      //                 this.array.push({ text: this.courseText, role: 2 })
+      //                 this.courseText = ''
+
+      //                 setTimeout(() => {
+      //                     this.loading = false
+      //                     if (this.courseText == '请告诉我任务四该具体如何实施?') {
+      //                         this.array.push({
+      //                             text: `任务四:设计保温杯的初步方案
+
+      // 教学目标:
+      // •学会应用热传递原理设计保温杯。
+      // •掌握基本的设计思维和创新方法。
+      // •理解材料选择对保温效果的影响。
+
+      // 教学过程:
+      // 1.复习:回顾热传递的基本原理和不同材料的导热性能。
+      // 2.需求分析:讨论保温杯的使用场景和功能需求,如保温时间、容量、便携性等。
+      // 3.设计指导:教师介绍设计原则和考虑因素,如材料的导热性能、结构设计、成本和环保等。
+      // 4.创意发散:学生团队进行头脑风暴,提出多种设计方案,并选出最可行的方案。
+      // 5.方案绘制:学生绘制保温杯的设计图,包括尺寸、形状、结构和所用材料。
+
+      // 师生研讨:
+      // •分享各组的设计方案,讨论设计的创新点和实用性。
+      // •教师提供专业意见和建议,帮助学生完善设计方案。
+      // •讨论如何将设计方案转化为实际操作的步骤。
+
+      // 拓展:
+      // •学生研究市场上不同类型保温杯的设计和功能。
+      // •分析保温杯的改进空间和潜在的创新点。
+
+      // 学生任务单:
+      // •列出保温杯的功能需求和设计目标。
+      // •绘制保温杯的设计方案图,并标注所用材料和尺寸。
+      // •简述所选材料的导热性能和对保温效果的影响。
+
+      // 知识点练习:
+      // 1.为什么保温杯通常使用不锈钢或陶瓷作为内胆材料?
+      // 2.描述一个创新的保温杯设计方案,并解释其工作原理。
+      // 3.讨论在设计保温杯时需要考虑的环境因素。
+
+      // 答案:
+      // 1.保温杯通常使用不锈钢或陶瓷作为内胆材料,因为这些材料是热的不良导体,可以有效减缓热量的散失。
+      // 2.一个创新的保温杯设计方案可能是采用多层结构,内层为不锈钢,中间层为真空隔热层,外层为塑料保护层。这种设计可以有效隔绝外界温度对热水温度的影响。
+      // 在设计保温杯时,需要考虑的环境因素包括材料的可回收性、生产过程中的能源消耗和废弃物处理等。`, role: 1
+      //                         })
+      //                     }else if(this.courseText == '请你重新设计该任务,我没有感温粉末。'){
+      //                         this.array.push({text:`任务一:探究热的传递方式
+
+      // 任务名: 观察热在水中的传递
+
+      // 任务描述:
+      // 同学们,今天我们将通过一个有趣的实验来探究热是如何在水中传递的。你将需要加热水并观察温度是如何分布的。请准备好实验器材,并按照安全指南进行操作。在实验过程中,请注意观察热水和冷水之间的相互作用,以及水温是如何随时间和空间变化的。你将需要记录你的观察结果,并思考热是如何从一个地方传递到另一个地方的。
+
+      // 工具名字: 电子白板
+
+      // 工具指引:
+      // 使用电子白板工具来绘制你的实验设置和观察到的热传递过程。你可以使用电子白板的绘图功能来创建一个温度分布图,展示热水和冷水相遇时的情况。同时,你可以用它来记录实验步骤和关键观察点,以便于你和同学们进行讨论和分享。
+
+      // 评价维度:
+      // •实验观察和记录:学生应该能够准确地记录实验过程中的观察结果,包括水温变化和热传递的现象。
+      // •数据分析和解释:学生应该能够分析实验数据,解释热在水中的传递方式,并能够用自己的话描述热对流的原理。
+      // •实验报告撰写:学生应该能够撰写一份清晰的实验报告,包括实验目的、方法、结果和结论,以及对实验过程的反思。`,role: 1})
+      //                             this.$emit('setUnitJson')
+      //                     }else if(this.checkArray.indexOf(0) !== -1 && this.courseText == '请告诉该具体如何实施?'){
+      //                         this.array.push({text:`教学活动1:探究热的传递方式
+      // 教学目标:
+      // •理解热的三种传递方式:传导、对流和辐射。
+      // •掌握热对流现象的基本概念。
+      // •学会通过实验观察和分析热在水中的传递过程。
+      // 教学过程:
+      // 1.引入:讨论日常生活中的热现象,如热水变凉、金属勺柄变热等,引出热传递的概念。
+      // 2.实验准备:介绍实验材料(试管、大烧杯、滴管、三脚架、石棉网、酒精灯、火柴、铁架台、试管架、感温粉末、红墨水、清水等)和安全注意事项。
+      // 3.实验操作:学生分组进行实验,加热试管和烧杯中的水,并加入感温粉末或红墨水以观察热的传递。
+      // 4.观察记录:学生记录实验现象,包括水温的变化、感温粉末或红墨水的颜色变化等。
+      // 5.结果分析:师生共同讨论实验结果,理解热对流的形成机制。
+      // 师生研讨:
+      // •讨论实验中观察到的热在水中的传递方式。
+      // •分析为什么水受热后会产生对流现象。
+      // •探讨热对流在生活中的应用,如暖气系统、热水器等。
+      // 拓展:
+      // •学生研究热在其他物质(如空气)中的传递方式。
+      // •设计并执行一个简单的实验,比较热在不同物质中的传递速度。
+      // 学生任务单:
+      // •描述实验中观察到的热在水中的传递过程。
+      // •解释热对流的形成原理。
+      // •提出一个生活中热对流的应用实例。
+      // 知识点练习:
+      // 1.热传递的三种方式是什么?
+      // 2.为什么加热试管底部的水会使试管上部的水也变热?
+      // 3.描述热对流的一个实际应用,并解释其工作原理。
+      // 答案:
+      // 1.热传递的三种方式是传导、对流和辐射。
+      // 2.加热试管底部的水会使试管上部的水也变热,因为热通过水的对流传递到了上部。
+      // 一个热对流的实际应用是暖气系统。它通过加热空气,使热空气上升,冷空气下降,形成对流循环,从而使房间变暖。`,role:1})
+      //                     }else if(this.checkArray.indexOf(0) !== -1 && this.courseText == '我没有感温粉末怎么办'){
+      //                         this.array.push({text:`如果您没有感温粉末,不用担心,我们仍然可以探究热的传递方式,只是需要采用不同的方法来观察和记录热在水中的传递。以下是几种替代方案:
+
+      // 1. **温度计**:您可以使用普通温度计或数字温度计来测量水在加热过程中的温度变化。通过在不同时间点记录水温,您可以绘制出温度随时间变化的曲线,从而理解热是如何在水中传播的。
+
+      // 2. **红墨水或其他有色液体**:如果家里有红墨水或其他任何有颜色的液体,您可以在水加热前滴入几滴。当红墨水在加热的水中扩散时,您可以观察到颜色的变化,这可以帮助您可视化水的流动和混合。
+
+      // 3. **视频记录**:您可以使用手机或相机录制水加热的过程,特别是观察加热区域与未加热区域之间的界面。通过回放视频,您可以分析和讨论热传递的现象。
+
+      // 4. **实验日志**:在实验过程中,详细记录您的观察和思考。包括您使用的替代方法、观察到的现象、遇到的问题以及您对这些现象的解释。
+
+      // 5. **讨论和交流**:与同学或老师讨论您的发现,即使没有感温粉末,您也可以通过交流想法和观察结果来增进对热传递现象的理解。
+
+      // 记住,科学探究的本质在于提出问题、设计实验、收集数据、分析结果和得出结论。即使缺少某些工具或材料,创新和适应性也是科学探究的重要部分。`,role:1})
+      //                     } else {
+      //                         this.array.push({ text: '请输入正确的文案', role: 1 })
+      //                     }
+      //                     // this.array.push({text: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', role: 1})
+      //                 }, 5000);
+      //             }
     },
-    methods: {
-        promptTit(){
-            if (!this.loading && !this.courseText) {
-                this.$message({
-                    message: '请输入您想要了解的内容',
-                    type: 'warning'
-                });
-            }else{
-                this.$message({
-                    message: '请回答完毕后再次发送',
-                    type: 'warning'
+    getAiContent(_uid) {
+      let _source = new EventSource(`https://gpt4.cocorobo.cn/stream/${_uid}`); //http://gpt4.cocorobo.cn:8011/stream/     https://gpt4.cocorobo.cn/stream/
+      let _allText = "";
+      let _mdText = "";
+      const md = new MarkdownIt();
+      _source.onmessage = _e => {
+        if (_e.data.replace("'", "").replace("'", "") == "[DONE]") {
+          //对话已经完成
+          _mdText = _mdText.replace("_", "");
+          _source.close();
+          this.$nextTick(() => {
+            this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
+          });
+          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.insertChat(_uid);
+          return;
+        } else {
+          //对话还在继续
+          let _text = "";
+          _text = _e.data.replaceAll("'", "");
+          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);
+      if (!_data) return;
+      let params = {
+        userId: this.userid,
+        userName: "qgt",
+        groupId: "602def61-005d-11ee-91d8-005056b8q12w",
+        answer: _data.aiContent,
+        problem: _data.content,
+        file_id: _data.fileid ? _data.fileid : "",
+        alltext: _data.aiContent,
+        type: "chat",
+        filename: _data.filename,
+        session_name: `${this.courseId}-addCourse` //这是对话记录位置
+      };
+      this.ajax
+        .post("https://gpt4.cocorobo.cn/insert_chat", params)
+        .then(res => {});
+    },
+    // 获取对应的聊天记录
+    getChatList() {
+      return new Promise((resolve, reject) => {
+        if (this.loading) return this.$message.info("请稍等...");
+        this.chatList = [];
+        this.loading = true;
+        let params = {
+          userid: this.userid,
+          groupid: "602def61-005d-11ee-91d8-005056b8q12w",
+          // session_name:``
+          session_name: `${this.courseId}-addCourse`
+        };
+        this.ajax
+          .post("https://gpt4.cocorobo.cn/get_agent_park_chat", params)
+          .then(res => {
+            let _data = JSON.parse(res.data.FunctionResponse);
+            if (_data.length > 0) {
+              let _chatList = [];
+              for (let i = 0; i < _data.length; i++) {
+                _chatList.push({
+                  loading: false,
+                  role: "user",
+                  content: _data[i].problem,
+                  uid: _data[i].id,
+                  AI: "AI",
+                  aiContent: _data[i].answer,
+                  oldContent: _data[i].answer,
+                  isShowSynchronization: false,
+                  filename: _data[i].filename,
+                  index: i,
+                  is_mind_map: false,
+                  fileid: _data[i].fileid
                 });
-            }
-        },
-        addContent() {
-            if (this.courseText) {
-
-                this.loading = true
-                this.array.push({ text: this.courseText, role: 2 })
-                this.courseText = ''
-
-                setTimeout(() => {
-                    this.loading = false
-                    if (this.courseText == '请告诉我任务四该具体如何实施?') {
-                        this.array.push({
-                            text: `任务四:设计保温杯的初步方案
-
-教学目标:
-•学会应用热传递原理设计保温杯。
-•掌握基本的设计思维和创新方法。
-•理解材料选择对保温效果的影响。
-
-教学过程:
-1.复习:回顾热传递的基本原理和不同材料的导热性能。
-2.需求分析:讨论保温杯的使用场景和功能需求,如保温时间、容量、便携性等。
-3.设计指导:教师介绍设计原则和考虑因素,如材料的导热性能、结构设计、成本和环保等。
-4.创意发散:学生团队进行头脑风暴,提出多种设计方案,并选出最可行的方案。
-5.方案绘制:学生绘制保温杯的设计图,包括尺寸、形状、结构和所用材料。
-
-师生研讨:
-•分享各组的设计方案,讨论设计的创新点和实用性。
-•教师提供专业意见和建议,帮助学生完善设计方案。
-•讨论如何将设计方案转化为实际操作的步骤。
-
-拓展:
-•学生研究市场上不同类型保温杯的设计和功能。
-•分析保温杯的改进空间和潜在的创新点。
-
-学生任务单:
-•列出保温杯的功能需求和设计目标。
-•绘制保温杯的设计方案图,并标注所用材料和尺寸。
-•简述所选材料的导热性能和对保温效果的影响。
-
-知识点练习:
-1.为什么保温杯通常使用不锈钢或陶瓷作为内胆材料?
-2.描述一个创新的保温杯设计方案,并解释其工作原理。
-3.讨论在设计保温杯时需要考虑的环境因素。
-
-答案:
-1.保温杯通常使用不锈钢或陶瓷作为内胆材料,因为这些材料是热的不良导体,可以有效减缓热量的散失。
-2.一个创新的保温杯设计方案可能是采用多层结构,内层为不锈钢,中间层为真空隔热层,外层为塑料保护层。这种设计可以有效隔绝外界温度对热水温度的影响。
-在设计保温杯时,需要考虑的环境因素包括材料的可回收性、生产过程中的能源消耗和废弃物处理等。`, role: 1
-                        })
-                    }else if(this.courseText == '请你重新设计该任务,我没有感温粉末。'){
-                        this.array.push({text:`任务一:探究热的传递方式
-
-任务名: 观察热在水中的传递
-
-任务描述:
-同学们,今天我们将通过一个有趣的实验来探究热是如何在水中传递的。你将需要加热水并观察温度是如何分布的。请准备好实验器材,并按照安全指南进行操作。在实验过程中,请注意观察热水和冷水之间的相互作用,以及水温是如何随时间和空间变化的。你将需要记录你的观察结果,并思考热是如何从一个地方传递到另一个地方的。
-
-工具名字: 电子白板
-
-工具指引:
-使用电子白板工具来绘制你的实验设置和观察到的热传递过程。你可以使用电子白板的绘图功能来创建一个温度分布图,展示热水和冷水相遇时的情况。同时,你可以用它来记录实验步骤和关键观察点,以便于你和同学们进行讨论和分享。
-
-评价维度:
-•实验观察和记录:学生应该能够准确地记录实验过程中的观察结果,包括水温变化和热传递的现象。
-•数据分析和解释:学生应该能够分析实验数据,解释热在水中的传递方式,并能够用自己的话描述热对流的原理。
-•实验报告撰写:学生应该能够撰写一份清晰的实验报告,包括实验目的、方法、结果和结论,以及对实验过程的反思。`,role: 1})
-                            this.$emit('setUnitJson')
-                    }else if(this.checkArray.indexOf(0) !== -1 && this.courseText == '请告诉该具体如何实施?'){
-                        this.array.push({text:`教学活动1:探究热的传递方式
-教学目标:
-•理解热的三种传递方式:传导、对流和辐射。
-•掌握热对流现象的基本概念。
-•学会通过实验观察和分析热在水中的传递过程。
-教学过程:
-1.引入:讨论日常生活中的热现象,如热水变凉、金属勺柄变热等,引出热传递的概念。
-2.实验准备:介绍实验材料(试管、大烧杯、滴管、三脚架、石棉网、酒精灯、火柴、铁架台、试管架、感温粉末、红墨水、清水等)和安全注意事项。
-3.实验操作:学生分组进行实验,加热试管和烧杯中的水,并加入感温粉末或红墨水以观察热的传递。
-4.观察记录:学生记录实验现象,包括水温的变化、感温粉末或红墨水的颜色变化等。
-5.结果分析:师生共同讨论实验结果,理解热对流的形成机制。
-师生研讨:
-•讨论实验中观察到的热在水中的传递方式。
-•分析为什么水受热后会产生对流现象。
-•探讨热对流在生活中的应用,如暖气系统、热水器等。
-拓展:
-•学生研究热在其他物质(如空气)中的传递方式。
-•设计并执行一个简单的实验,比较热在不同物质中的传递速度。
-学生任务单:
-•描述实验中观察到的热在水中的传递过程。
-•解释热对流的形成原理。
-•提出一个生活中热对流的应用实例。
-知识点练习:
-1.热传递的三种方式是什么?
-2.为什么加热试管底部的水会使试管上部的水也变热?
-3.描述热对流的一个实际应用,并解释其工作原理。
-答案:
-1.热传递的三种方式是传导、对流和辐射。
-2.加热试管底部的水会使试管上部的水也变热,因为热通过水的对流传递到了上部。
-一个热对流的实际应用是暖气系统。它通过加热空气,使热空气上升,冷空气下降,形成对流循环,从而使房间变暖。`,role:1})
-                    }else if(this.checkArray.indexOf(0) !== -1 && this.courseText == '我没有感温粉末怎么办'){
-                        this.array.push({text:`如果您没有感温粉末,不用担心,我们仍然可以探究热的传递方式,只是需要采用不同的方法来观察和记录热在水中的传递。以下是几种替代方案:
-
-1. **温度计**:您可以使用普通温度计或数字温度计来测量水在加热过程中的温度变化。通过在不同时间点记录水温,您可以绘制出温度随时间变化的曲线,从而理解热是如何在水中传播的。
-
-2. **红墨水或其他有色液体**:如果家里有红墨水或其他任何有颜色的液体,您可以在水加热前滴入几滴。当红墨水在加热的水中扩散时,您可以观察到颜色的变化,这可以帮助您可视化水的流动和混合。
-
-3. **视频记录**:您可以使用手机或相机录制水加热的过程,特别是观察加热区域与未加热区域之间的界面。通过回放视频,您可以分析和讨论热传递的现象。
-
-4. **实验日志**:在实验过程中,详细记录您的观察和思考。包括您使用的替代方法、观察到的现象、遇到的问题以及您对这些现象的解释。
-
-5. **讨论和交流**:与同学或老师讨论您的发现,即使没有感温粉末,您也可以通过交流想法和观察结果来增进对热传递现象的理解。
-
-记住,科学探究的本质在于提出问题、设计实验、收集数据、分析结果和得出结论。即使缺少某些工具或材料,创新和适应性也是科学探究的重要部分。`,role:1})
-                    } else {
-                        this.array.push({ text: '请输入正确的文案', role: 1 })
-                    }
-                    // this.array.push({text: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', role: 1})
-                }, 5000);
-            }
-        },
-        addTask(index) {
-            if (this.checkArray.indexOf(index) !== -1) {
-                this.checkArray.splice(this.checkArray.indexOf(index), 1)
-            } else {
-                this.checkArray.push(index)
-            }
-            console.log(index);
-        },
-        addAllTask() {
-            if (this.checkArray.length === this.course.length) {
-                this.checkArray = []
+              }
+              this.array = _chatList;
+              this.loading = false;
             } else {
-                this.checkArray = []
-                this.course.forEach((item, index) => {
-                    this.checkArray.push(index)
-                })
+              //没有对话记录
+              this.loading = false;
             }
-        },
-        checkPart(name) {
-            this.part = name
-        }
+            resolve();
+          })
+          .catch(err => {
+            console.log(err);
+            this.$message.error("获取对话记录失败");
+            this.loading = false;
+            resolve();
+          });
+      });
     },
-    computed: {
-        courseTextLength() {
-            return this.courseText.length
-        },
-        taskName() {
-            let task = ''
-            if (this.checkArray.length) {
-                task = '任务'
-                this.checkArray = this.checkArray.sort((a, b) => a - b)
-                let a = JSON.parse(JSON.stringify(this.checkArray))
-                for (let index = 0; index < a.length; index++) {
-                    a[index]++;
-                }
-                task += a.join('/')
-            }
-            return task + ' ' + this.part
-        }
+    addTask(index) {
+      if (this.checkArray.indexOf(index) !== -1) {
+        this.checkArray.splice(this.checkArray.indexOf(index), 1);
+      } else {
+        this.checkArray.push(index);
+      }
+      console.log(index);
     },
-}
+    addAllTask() {
+      if (this.checkArray.length === this.course.length) {
+        this.checkArray = [];
+      } else {
+        this.checkArray = [];
+        this.course.forEach((item, index) => {
+          this.checkArray.push(index);
+        });
+      }
+    },
+    checkPart(name) {
+      this.part = name;
+    }
+  },
+  computed: {
+    courseTextLength() {
+      return this.courseText.length;
+    },
+    taskName() {
+      let task = "";
+      if (this.checkArray.length) {
+        task = "任务";
+        this.checkArray = this.checkArray.sort((a, b) => a - b);
+        let a = JSON.parse(JSON.stringify(this.checkArray));
+        for (let index = 0; index < a.length; index++) {
+          a[index]++;
+        }
+        task += a.join("/");
+      }
+      return task + " " + this.part;
+    }
+  },
+  mounted() {
+    this.getChatList().then(_ => {
+      this.$nextTick(() => {
+				console.log(this.$refs.chatDialog.scrollHeight)
+        this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
+      });
+    });
+  }
+};
 </script>
 
 <style scoped>
 .ai_body {
-    height: 100%;
-    width: calc(100% - 20px);
-    margin: 0 auto;
+  height: 100%;
+  width: calc(100% - 20px);
+  margin: 0 auto;
 }
 
 .binfo_input {
-    width: 100%;
-    margin: 0;
-    padding: 12px 14px;
-    display: block;
-    min-width: 0;
-    outline: none;
-    box-sizing: border-box;
-    background: none;
-    border: none;
-    border-radius: 4px;
-    background: #fff;
-    font-size: 14px;
-    resize: none;
-    font-family: "Microsoft YaHei";
-    min-height: 48px;
-    /* border: 1px solid #3682fc00; */
-    border: 1.5px solid #cad1dc;
+  width: 100%;
+  margin: 0;
+  padding: 12px 14px;
+  display: block;
+  min-width: 0;
+  outline: none;
+  box-sizing: border-box;
+  background: none;
+  border: none;
+  border-radius: 4px;
+  background: #fff;
+  font-size: 14px;
+  resize: none;
+  font-family: "Microsoft YaHei";
+  min-height: 48px;
+  /* border: 1px solid #3682fc00; */
+  border: 1.5px solid #cad1dc;
 }
 
 .binfo_textarea {
-    border: 1.5px solid #cad1dc;
-    font-size: 14px;
-    resize: none;
-    /* background: #f6f6f6; */
-    font-family: "Microsoft YaHei";
+  border: 1.5px solid #cad1dc;
+  font-size: 14px;
+  resize: none;
+  /* background: #f6f6f6; */
+  font-family: "Microsoft YaHei";
 }
 
 .binfo_textarea::-webkit-scrollbar {
-    /*滚动条整体样式*/
-    width: 6px;
-    /*高宽分别对应横竖滚动条的尺寸*/
-    height: 6px;
+  /*滚动条整体样式*/
+  width: 6px;
+  /*高宽分别对应横竖滚动条的尺寸*/
+  height: 6px;
 }
 
 /*定义滚动条轨道 内阴影+圆角*/
 .binfo_textarea::-webkit-scrollbar-track {
-    border-radius: 10px;
-    background-color: rgba(0, 0, 0, 0.1);
+  border-radius: 10px;
+  background-color: rgba(0, 0, 0, 0.1);
 }
 
 /*定义滑块 内阴影+圆角*/
 .binfo_textarea::-webkit-scrollbar-thumb {
-    border-radius: 10px;
-    -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
-    background-color: rgba(0, 0, 0, 0.1);
+  border-radius: 10px;
+  -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
+  background-color: rgba(0, 0, 0, 0.1);
 }
 
 .binfo_input:focus-visible {
-    border: 1.5px solid #3681fc !important;
+  border: 1.5px solid #3681fc !important;
 }
 
 .ai_body_input {
-    /* position: relative; */
-    display: flex;
-    flex-direction: column;
-    justify-content: center;
-    align-items: end;
+  /* position: relative; */
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: end;
 }
 
 .c_pub_button_confirm {
-    /* position: absolute;
+  /* position: absolute;
     bottom: 13px;
     right: 13px; */
-    margin-top: 10px;
-    width: 80px;
-    display: flex;
-    justify-content: center;
+  margin-top: 10px;
+  width: 80px;
+  display: flex;
+  justify-content: center;
 }
 
-
 .ai_body_dialog {
-    padding: 10px 0;
-    box-sizing: border-box;
-    height: calc(100% - 180px);
-    overflow: auto;
-    margin-bottom: 10px;
+  padding: 10px 0;
+  box-sizing: border-box;
+  height: calc(100% - 180px);
+  overflow: auto;
+  margin-bottom: 10px;
 }
 
-
 .dialog_content {
-    width: 100%;
-    display: flex;
+  width: 100%;
+  display: flex;
+  flex-direction: column;
 }
 
-.dialog_content+.dialog_content {
-    margin: 15px 0;
+.dialog_content > div {
+  display: flex;
+  align-items: flex-start;
 }
 
-.dialog_content.right {
-    flex-direction: row-reverse;
+.dialog_content + .dialog_content {
+  margin: 15px 0;
 }
 
-.dialog_content.right .role {
-    margin-right: 0;
-    margin-left: 10px;
+.dialog_content > div .right {
+  flex-direction: row-reverse;
 }
 
-.dialog_content .role {
-    min-width: 30px;
-    width: 30px;
-    height: 30px;
-    margin-right: 10px;
-    border-radius: 50%;
+.dialog_content > div .right .role {
+  margin-right: 0;
+  margin-left: 10px;
 }
 
-.dialog_content .role>img {
-    height: 100%;
-    width: 100%;
+.dialog_content > div .role {
+  min-width: 30px;
+  width: 30px;
+  height: 30px;
+  margin-right: 10px;
+  border-radius: 50%;
 }
 
-.dialog_content .content {
-    padding: 10px 5px;
-    border-radius: 5px;
-    width: 100%;
-    word-break: break-word;
-    box-sizing: border-box;
-    white-space: pre-line;
-    max-width: 100%;
-    background: #F7F7F7;
-    overflow: hidden;
+.dialog_content > div .role > img {
+  height: 100%;
+  width: 100%;
 }
 
-.dialog_content .content2 {
-    background: #3681fc;
-    color: #fff;
+.dialog_content > div .content {
+  padding: 10px 5px;
+  border-radius: 5px;
+  width: 100%;
+  word-break: break-word;
+  box-sizing: border-box;
+  /* white-space: pre-line; */
+  max-width: 100%;
+  background: #f7f7f7;
+  overflow: hidden;
+  margin: 0 10px;
 }
 
+.dialog_content > div .content2 {
+  background: #3681fc;
+  color: #fff;
+}
 
 .ai_body_select {
-    position: relative;
-}
-
-.ai_body_select>.check {
-    background: #e7e7e7;
-    display: flex;
-    width: fit-content;
-    padding: 0 10px;
-    height: 30px;
-    border-radius: 21px;
-    font-size: 14px;
-    align-items: center;
-    justify-content: center;
-    color: #0061FF;
-    font-weight: 700;
-    margin: 10px 0;
-    cursor: pointer;
-}
-
-.ai_body_select>.check::before {
-    content: '';
-    width: 15px;
-    height: 15px;
-    display: block;
-    background-image: url('../../../assets/icon/course/aiPart.png');
-    background-size: 100% 100%;
-    margin-right: 5px;
-}
-
-.ai_body_select>.check::after {
-    content: '';
-    width: 15px;
-    height: 15px;
-    display: block;
-    background-image: url('../../../assets/icon/course/aiPart_arrow.png');
-    background-size: 100% 100%;
-    margin-right: 5px;
-}
-
-.ai_body_select>.isCheck {
-    background: #0061FF;
-    display: flex;
-    width: fit-content;
-    padding: 0 10px;
-    height: 30px;
-    border-radius: 21px;
-    font-size: 14px;
-    align-items: center;
-    justify-content: center;
-    color: #fff;
-    font-weight: 700;
-    margin: 10px 0;
-    cursor: pointer;
-    max-width: 100%;
-    box-sizing: border-box;
-}
-
-.ai_body_select>.isCheck>span {
-    width: calc(100% - 40px);
-    display: block;
-    overflow: hidden;
-    white-space: nowrap;
-    text-overflow: ellipsis;
+  position: relative;
+}
+
+.ai_body_select > .check {
+  background: #e7e7e7;
+  display: flex;
+  width: fit-content;
+  padding: 0 10px;
+  height: 30px;
+  border-radius: 21px;
+  font-size: 14px;
+  align-items: center;
+  justify-content: center;
+  color: #0061ff;
+  font-weight: 700;
+  margin: 10px 0;
+  cursor: pointer;
+}
+
+.ai_body_select > .check::before {
+  content: "";
+  width: 15px;
+  height: 15px;
+  display: block;
+  background-image: url("../../../assets/icon/course/aiPart.png");
+  background-size: 100% 100%;
+  margin-right: 5px;
+}
+
+.ai_body_select > .check::after {
+  content: "";
+  width: 15px;
+  height: 15px;
+  display: block;
+  background-image: url("../../../assets/icon/course/aiPart_arrow.png");
+  background-size: 100% 100%;
+  margin-right: 5px;
+}
+
+.ai_body_select > .isCheck {
+  background: #0061ff;
+  display: flex;
+  width: fit-content;
+  padding: 0 10px;
+  height: 30px;
+  border-radius: 21px;
+  font-size: 14px;
+  align-items: center;
+  justify-content: center;
+  color: #fff;
+  font-weight: 700;
+  margin: 10px 0;
+  cursor: pointer;
+  max-width: 100%;
+  box-sizing: border-box;
+}
+
+.ai_body_select > .isCheck > span {
+  width: calc(100% - 40px);
+  display: block;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
 }
 
-.ai_body_select>.isCheck::before {
-    content: '';
-    width: 15px;
-    height: 15px;
-    display: block;
-    background-image: url('../../../assets/icon/course/aiPart_active.png');
-    background-size: 100% 100%;
-    margin-right: 5px;
+.ai_body_select > .isCheck::before {
+  content: "";
+  width: 15px;
+  height: 15px;
+  display: block;
+  background-image: url("../../../assets/icon/course/aiPart_active.png");
+  background-size: 100% 100%;
+  margin-right: 5px;
 }
 
-.ai_body_select>.isCheck::after {
-    content: '';
-    width: 15px;
-    height: 15px;
-    display: block;
-    background-image: url('../../../assets/icon/course/aiPart_arrow_active.png');
-    background-size: 100% 100%;
-    margin-right: 5px;
+.ai_body_select > .isCheck::after {
+  content: "";
+  width: 15px;
+  height: 15px;
+  display: block;
+  background-image: url("../../../assets/icon/course/aiPart_arrow_active.png");
+  background-size: 100% 100%;
+  margin-right: 5px;
 }
 
-
-.ai_body_select>.checkBox {
-    position: absolute;
-    bottom: 40px;
-    border: 1px solid #E0EAFB;
-    width: 100%;
-    height: 300px;
-    background: #fff;
-    border-radius: 5px;
-    padding: 10px;
-    box-sizing: border-box;
+.ai_body_select > .checkBox {
+  position: absolute;
+  bottom: 40px;
+  border: 1px solid #e0eafb;
+  width: 100%;
+  height: 300px;
+  background: #fff;
+  border-radius: 5px;
+  padding: 10px;
+  box-sizing: border-box;
 }
 
-.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 {
-    height: calc(100% - 60px);
-}
-
-.ai_body_select>.checkBox>.part {}
+.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 {
+  height: calc(100% - 60px);
+}
+
+.ai_body_select > .checkBox > .part {
+}
 
-.ai_body_select>.checkBox>.task>.content {
-    height: calc(100% - 40px);
-    overflow: auto;
+.ai_body_select > .checkBox > .task > .content {
+  height: calc(100% - 40px);
+  overflow: auto;
 }
 
-.ai_body_select>.checkBox>.task>.content>.span+.span {
-    margin-top: 5px;
+.ai_body_select > .checkBox > .task > .content > .span + .span {
+  margin-top: 5px;
 }
 
-.ai_body_select>.checkBox>.task>.content>.span {
-    display: flex;
-    align-items: center;
-    font-size: 14px;
-    cursor: pointer;
+.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 {
-    width: 13px;
-    height: 13px;
-    display: flex;
-    align-items: center;
-    margin-right: 5px;
+.ai_body_select > .checkBox > .task > .content > .span > .check {
+  width: 13px;
+  height: 13px;
+  display: flex;
+  align-items: center;
+  margin-right: 5px;
 }
 
-.ai_body_select>.checkBox>.task>.content>.span>.check>img {
-    width: 100%;
-    height: 100%;
+.ai_body_select > .checkBox > .task > .content > .span > .check > img {
+  width: 100%;
+  height: 100%;
 }
 
-.ai_body_select>.checkBox>.part>.content {
-    display: flex;
-    align-items: center;
-    font-size: 14px;
-    justify-content: space-between;
+.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 {
-    padding: 3px 6px;
-    border: 1px solid #E0EAFB;
-    border-radius: 40px;
-    cursor: pointer;
+.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 {
-    color: #0061ff;
-    border-color: #0061ff;
+.ai_body_select > .checkBox > .part > .content > .span.active {
+  color: #0061ff;
+  border-color: #0061ff;
 }
-</style>
+</style>