SanHQin преди 11 месеца
родител
ревизия
0f7e3097cc

BIN
src/assets/icon/classroomObservation/isTape.png


BIN
src/assets/icon/classroomObservation/start.png


+ 63 - 0
src/components/pages/classroomObservation/components/addNewCourseDialog.vue

@@ -0,0 +1,63 @@
+<template>
+	<div class="addNewCourse">
+		<el-dialog
+			title="添加课堂"
+			:visible.sync="dialogVisible"
+			width="500px"		>
+		<div>
+			<el-form ref="form" :model="form" label-position="top">
+			  <el-form-item label="课堂编号">
+  			  <el-input v-model="form.no" placeholder="请输入课堂编号"></el-input>
+  			</el-form-item>
+				<el-form-item label="课堂名称">
+  			  <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()"
+					>确 定</el-button
+				>
+			</span>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+export default {
+	emits:["success"],
+	data(){
+		return{
+			dialogVisible:false,
+			form:{
+				no:"",
+				name:"",
+			},
+		}
+	},
+	methods:{
+		open(){
+			this.form = {
+				name:"",
+				no:"",
+			}
+			this.dialogVisible = true;
+		},
+		submit(){
+			if(this.form.no.trim().length==0 || this.form.name.trim().length==0){
+				this.$message.error("请输入课堂编号和课堂名称")
+				return;
+			}
+			this.$emit("success",this.form)
+			this.dialogVisible = false;
+		}
+	}
+};
+</script>
+
+<style  scoped>
+.addNewCourse{
+
+}
+</style>

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

@@ -218,15 +218,15 @@ export default {
 				_copyData.jsonData.fileList = [];
 				_copyData.json_data = JSON.stringify(_copyData.jsonData)
 				this.$emit("editItem",this.data.id,_copyData);
-				let pram2 = {
-					id: _copyData.id,
-					json_data: _copyData.json_data,
-				};
-				this.ajax
-				.post(
-					"https://gpt4.cocorobo.cn/update_classroom_observation",
-					pram2
-				)
+				// let pram2 = {
+				// 	id: _copyData.id,
+				// 	json_data: _copyData.json_data,
+				// };
+				// this.ajax
+				// .post(
+				// 	"https://gpt4.cocorobo.cn/update_classroom_observation",
+				// 	pram2
+				// )
 				this.loading = false;
 			}).catch(err=>{
 				this.$message.error("AI无法识别优化")

+ 509 - 128
src/components/pages/classroomObservation/components/chatArea.vue

@@ -8,11 +8,13 @@
 			<div class="titBarLeft">
 				<div
 					@click="cutBar(index)"
-					:class="barNum == index ? 'titBarBorder' : ''"
+					:class="pageStatus == index ? 'titBarBorder' : ''"
 					v-for="(i, index) in titBarList"
 					:key="index + 'a'"
 				>
-					<img :src="barNum == index ? i.ico : i.ico1" alt="" />{{ i.title }}
+					<img :src="pageStatus == index ? i.ico : i.ico1" alt="" />{{
+						i.title
+					}}
 				</div>
 			</div>
 			<div class="titBarRig">
@@ -23,18 +25,21 @@
 		<div class="ca-top">
 			<!-- 开始页面 -->
 			<startPage
-				v-show="barNum == 0 && !TapeNum"
-				@startTape="judge = 1"
+				v-show="showIndexPage"
+				@startTape="recordedStart"
 				@uploadTape="uploadRecording"
 			/>
-			<!-- 实时转录 -->
-			<transcription v-show="barNum == 1" :data="transcriptionData" />
-			<!-- 上传录音页 -->
-			<tape :chatData="chatList" v-show="barNum == 0 && TapeNum" />
+			<!-- 原文速递 -->
+			<transcription
+				v-show="pageStatus == 1 && !showIndexPage"
+				:data="transcriptionData"
+			/>
+			<!-- ai对话 -->
+			<tape ref="tapeRef" :aiNameList="aiNameList" :chatData="chatList" v-show="pageStatus == 0 && !showIndexPage" />
 			<!-- <div class="t-t-m-Item" v-show="cardStatus==1"> -->
 			<iframe
 				ref="viframe"
-				v-if="barNum == 2"
+				v-if="pageStatus == 2 && !showIndexPage"
 				style="width: 100%; height: 100%; border: none"
 				:src="
 					'https://view.officeapps.live.com/op/view.aspx?src=' +
@@ -47,11 +52,11 @@
 			<div class="ca-b-operation">
 				<div class="ca-b-o-header">
 					<div class="ca-b-o-h-left">
-						<div class="ca-b-o-h-l-select" @click.stop="changeAnalysis()">
+						<!-- <div class="ca-b-o-h-l-select" @click.stop="changeAnalysis()">
 							<span class="ca-b-o-h-l-s-icon el-icon-collection"></span>
 							<div class="ca-b-o-h-s-l-text">课堂观察</div>
 							<span class="ca-b-o-h-s-l-icon2 el-icon-caret-top"></span>
-						</div>
+						</div> -->
 
 						<div class="ca-b-o-h-l-select" style="color: #3681fc">
 							<div
@@ -71,7 +76,6 @@
 									v-for="(i, index) in languageList"
 									:key="index + 'lag'"
 									:class="i.label == languageRadio ? 'radioBg' : ''"
-									@click.stop="changeLanguage"
 									v-model.number="languageRadio"
 									:label.Num="i.label"
 									>{{ i.lang }}</el-radio
@@ -88,13 +92,26 @@
 					<div class="ca-b-o-h-right">
 						<div class="ca-b-o-h-r-radio">
 							<div
-								:class="TapeNum == index ? 'TapeCss' : ''"
+								:class="
+									(index == 0 && showIndexPage) ||
+									(index == 1 && !showIndexPage)
+										? 'TapeCss'
+										: ''
+								"
 								class="tapeSty"
 								@click="cutTape(index)"
 								v-for="(i, index) in tapeList"
 								:key="index + 'b'"
 							>
-								<img :src="TapeNum == index ? i.ico : i.ico1" alt="" />
+								<img
+									:src="
+										(index == 0 && showIndexPage) ||
+										(index == 1 && !showIndexPage)
+											? i.ico
+											: i.ico1
+									"
+									alt=""
+								/>
 							</div>
 
 							<!-- <span @click.stop="changeContinuousDialogue(!continuousDialogue)"
@@ -109,16 +126,16 @@
 						</div>
 					</div>
 				</div>
-				<div v-show="!judge" class="ca-b-o-main">
+				<div class="ca-b-o-main">
 					<div
 						class="ca-b-o-m-tape"
-						v-show="TapeNum == 0 && startTape == 0"
-						@click.stop="judge = 1"
+						v-show="controlsStatus == 0"
+						@click.stop="recordedStart()"
 					>
 						<span class="el-icon-microphone"></span>
 						<div class="ca-b-o-m-t-text">点击开始录音</div>
 					</div>
-					<div class="ca-b-o-m-tapeTwo" v-show="TapeNum == 0 && startTape == 1">
+					<div class="ca-b-o-m-tapeTwo" v-show="controlsStatus == 2">
 						<mini-audio
 							:audio-source="audioUrl"
 							class="audio_class"
@@ -133,7 +150,7 @@
 								justify-content: center;
 								align-items: center;
 							"
-							@click="judge = 1"
+							@click="recordedStart()"
 						>
 							<img
 								style="width: 10px; height: 16px"
@@ -142,54 +159,76 @@
 							/>
 						</div>
 					</div>
-					<div
-						class="ca-b-o-m-inputAre"
-						v-show="TapeNum == 1 && startTape == 0"
-					>
+					<div class="ca-b-o-m-inputAre" v-show="controlsStatus == 3">
 						<div class="ca-b-o-m-left">
 							<textarea
 								id="myTextarea"
+								ref="textareaRef"
 								min-rows="1"
 								max-rows="5"
-								:value="textareaValue"
-								placeholder="在此输入您想了解的内容,输入“/”可获取提示语,shift+enter换行"
+								v-model="textareaValue"
+								placeholder="在此输入您想了解的内容"
 								autosize="none"
+								@input="textareaChange"
+								@change="textareaChange"
 							></textarea>
 						</div>
 						<div class="ca-b-o-m-right">
 							<span @click.stop="tapeSubmit()"></span>
-							<div :class="sendBtnDsiable ? 'ca-b-o-m-r-dsiableBtn' : ''">
+							<!-- <div :class="sendBtnDsiable ? 'ca-b-o-m-r-dsiableBtn' : ''">
 								发送
-							</div>
+							</div> -->
+							<el-button :disabled="textareaValue.trim().length==0" type="primary" size="mini" @click="send()">发送</el-button>
 						</div>
 					</div>
-				</div>
-				<div class="ca-b-o-m-inputAreImg" v-show="judge">
-					<img
-						style="height: 120%"
-						src="@/assets/icon/classroomObservation/tapetime.png"
-						alt=""
-					/>
-					<div
-						style="width: 100px; display: flex; justify-content: space-between"
-					>
-						<div class="lyStart" @click="(judge = 0), (startTape = 1)">
+					<div class="ca-b-o-m-TapeArea" v-show="controlsStatus == 1">
+						<div class="ca-b-o-m-i-left">
 							<img
-								style="width: 12px; height: 12px"
-								src="@/assets/icon/classroomObservation/lyStart.png"
+								style="height: 120%"
+								src="@/assets/icon/classroomObservation/isTape.png"
 								alt=""
 							/>
+							<div>
+								<div v-if="recordedForm.status == 1" style="color:#EE3E3E">录音中...</div>
+								<div v-if="recordedForm.status == 2" style="color:#6b798e">已暂停...</div>
+								<span>{{ recordedForm.time }}</span>
+							</div>
 						</div>
-
-						<div class="lyStart" @click="(judge = 0), (startTape = 1)">
-							<img
-								style="width: 12px; height: 12px"
-								src="@/assets/icon/classroomObservation/lyStop.png"
-								alt=""
-							/>
+						<!-- <img
+							style="height: 120%"
+							src="@/assets/icon/classroomObservation/tapetime.png"
+							alt=""
+						/> -->
+						<div
+							style="
+								width: 100px;
+								display: flex;
+								justify-content: space-between;
+							"
+						>
+							<div class="lyStart" @click="stopRecorded()">
+								<img
+									style="width: 12px; height: 12px"
+									src="@/assets/icon/classroomObservation/lyStart.png"
+									alt=""
+									v-if="recordedForm.status == 1"
+								/>
+								<img
+									style="width: 12px; height: 12px"
+									src="@/assets/icon/classroomObservation/start.png"
+									alt=""
+									v-if="recordedForm.status == 2"
+								/>
+							</div>
+							<div class="lyStart" @click="finishRecorded()">
+								<img
+									style="width: 12px; height: 12px"
+									src="@/assets/icon/classroomObservation/lyStop.png"
+									alt=""
+								/>
+							</div>
 						</div>
-					</div>
-					<!-- <div class="ca-b-o-m-left">
+						<!-- <div class="ca-b-o-m-left">
 							<textarea :value="textareaValue" autosize="none"></textarea>
 						</div>
 						<div class="ca-b-o-m-right">
@@ -198,6 +237,7 @@
 								发送
 							</div>
 						</div> -->
+					</div>
 				</div>
 			</div>
 		</div>
@@ -209,6 +249,26 @@ import startPage from "./startPage.vue";
 import transcription from "./transcription.vue";
 import tape from "./tape.vue";
 
+import Recorder from "js-audio-recorder";
+const lamejs = require("lamejs");
+
+const recorder = new Recorder({
+	sampleBits: 16, // 采样位数,支持 8 或 16,默认是16
+	sampleRate: 48000, // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
+	numChannels: 1, // 声道,支持 1 或 2, 默认是1
+	// compiling: false,(0.x版本中生效,1.x增加中) // 是否边录边转换,默认是false
+});
+
+// 绑定事件-打印的是当前录音数据
+// recorder.onprogress = function (params) {
+// 	console.log('--------------START---------------')
+// 	console.log('录音时长(秒)', params.duration);
+// 	console.log('录音大小(字节)', params.fileSize);
+// 	console.log('录音音量百分比(%)', params.vol);
+// 	console.log('当前录音的总数据([DataView, DataView...])', params.data);
+// 	console.log('--------------END---------------')
+// };
+
 // 自定义指令,用于处理点击外部区域的事件
 const clickOutside = {
 	bind(el, binding) {
@@ -229,16 +289,16 @@ const clickOutside = {
 	},
 };
 export default {
-	emits:["updateFileId"],
+	emits: ["updateFileId"],
 	props: {
 		tid: {
 			type: String,
-			require:true,
+			require: true,
 		},
 		fileIdid: {
 			type: String,
-			default: ''
-		}
+			default: "",
+		},
 	},
 	components: {
 		startPage,
@@ -250,24 +310,27 @@ export default {
 	},
 	data() {
 		return {
-			continuousDialogue: true,
-			mainBtnStatus: 0, //0--录音 1--输入
-			pageStatus: 0, //0--初始页面  1--实时转录  2--上传录音页
+			// continuousDialogue: true,
+			controlsStatus: 0, //0--点击开始录音  1--录音中   2--录音完毕预览  3--文字输入
+			pageStatus: 0, //0--ai对话  1--原文文稿  2--转录文稿
+			showIndexPage: true, //是否显示初始页面
 			languageRadio: 1, //设置选择语言
-			languageShow: 0, //控制显示
-			// 判断0录音与1打字切换
-			TapeNum: 0,
-			startTape: 0,
-			loading:false,
-			judge: 0,
+			languageShow: false, //控制显示
+			loading: false,
 			textareaValue: "",
-			barNum: 0,
+			recordedForm: {
+				time: "00:00:00", //时间
+				status: 0, //0--未录音  1--正在录音  2--暂停  3--录音结束
+			},
+			aiNameList:[
+				{index:0,name:"ai助手"},
+				{index:1,name:"ABC模型"},
+				{index:2,name:'5EX模型'}
+			],
 			audioUrl:
 				"https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/%E8%A7%A3%E5%86%B3%E5%9E%83%E5%9C%BE%E9%97%AE%E9%A2%981713172672090.m4a",
-
 			fileUrl:
 				"https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/%E8%BD%AC%E5%BD%95%E6%96%87%E7%A8%BF1713172600896.xlsx",
-
 			// 设置list
 			languageList: [
 				{ label: 1, lang: "普通话" },
@@ -350,12 +413,6 @@ export default {
 直接填埋这种方法会占用大量土地,而且还会污染土地,焚烧发电这种方法会会污_
 `,
 			},
-			/* [
-				{
-					time:'00:01'k,
-					content:''
-				}
-			]*/
 			chatList: [
 				{
 					role: "ai",
@@ -407,20 +464,20 @@ Markdown表格Markdown表格Markdown表格Markdown表格Markdown表格Markdown
 			return true;
 		},
 	},
+	watch: {},
 	methods: {
 		handleBlur(event) {
 			// console.log("点击其它区域啦", event);
 			this.languageShow = !this.languageShow;
 		},
-		handShow() {},
 		// 上传录音
 		uploadRecording() {
 			let input = document.createElement("input");
 			input.type = "file";
-			input.accept = "*";
+			input.accept = "audio/*, .txt, .pdf, .xlsx";
 			input.click();
 			input.onchange = () => {
-				this.loading=  true;
+				this.loading = true;
 				let file = input.files[0];
 				var credentials = {
 					accessKeyId: "AKIATLPEDU37QV5CHLMH",
@@ -460,30 +517,47 @@ Markdown表格Markdown表格Markdown表格Markdown表格Markdown表格Markdown
 								_this.$message.error("上传失败");
 								_this.loading = false;
 							} else {
-								_this.ajax.put("https://gpt4.cocorobo.cn/upload_file_knowledge",{url: data.Location}).then(res=>{
-									let _data = res.data.FunctionResponse;
-									if(_data.result && _data.result.id){
-										_this.$emit("updateFileId", _data.result.id)
-										let pram2 = {
-											id: _this.fileIdid,
-											json_data: JSON.stringify({file_ids:_data.result.id}),
-											// json_data: JSON.stringify({file_ids:'file-r5phg4I2oFqly4WpW7oOOTnA'}),									
-										};
-										_this.ajax
-										.post(
-											"https://gpt4.cocorobo.cn/update_classroom_observation",
-											pram2
-										)
-									}else{
-										_this.$message.error("上传失败")
-									}
+								// 判断是不是音频文件
+								const audioRegex = /\.(mp3|wav|ogg|flac|m4a)$/i;
+								if (audioRegex.test(data.Location)) {
+									_this.controlsStatus = 2;
+									_this.showIndexPage = false;
+									_this.pageStatus = 1;
+									_this.audioUrl = data.Location;
 									_this.loading = false;
-									// this.$emit("updateFileId", data.Location)
-								}).catch(e=>{
-									_this.loading = false;
-									_this.$message.error("上传失败")
-								})
-								
+								} else {
+									_this.ajax
+										.put("https://gpt4.cocorobo.cn/upload_file_knowledge", {
+											url: data.Location,
+										})
+										.then((res) => {
+											let _data = res.data.FunctionResponse;
+											if (_data.result && _data.result.id) {
+												_this.$emit("updateFileId", _data.result.id);
+												let pram2 = {
+													id: _this.fileIdid,
+													json_data: JSON.stringify({
+														file_ids: _data.result.id,
+													}),
+													// json_data: JSON.stringify({file_ids:'file-r5phg4I2oFqly4WpW7oOOTnA'}),
+												};
+												_this.ajax.post(
+													"https://gpt4.cocorobo.cn/update_classroom_observation",
+													pram2
+												);
+											} else {
+												_this.$message.error("上传失败");
+											}
+											_this.loading = false;
+											// this.$emit("updateFileId", data.Location)
+										})
+										.catch((e) => {
+											_this.loading = false;
+											_this.$message.error("上传失败");
+										});
+								}
+
+								// console.log(data.Location)
 							}
 						});
 				}
@@ -492,32 +566,297 @@ Markdown表格Markdown表格Markdown表格Markdown表格Markdown表格Markdown
 			// this.barNum = 4;
 		},
 		cutBar(val) {
-			this.barNum = val;
+			this.pageStatus = val;
+			if (this.pageStatus == 0) {
+				//ai对话
+				this.controlsStatus = 3;
+			} else if (this.pageStatus == 1 || this.pageStatus == 2) {
+				// 原文速览&&转录文稿
+				this.controlsStatus = 2;
+			}
+			this.showIndexPage = false;
 		},
 		cutTape(val) {
-			this.TapeNum = val * 1;
-			this.judge = 0;
-			this.startTape = 0;
-			if (val == 1) {
-				this.barNum = 0;
+			if (val == 0) {
+				this.showIndexPage = true;
+				this.controlsStatus = 0;
+			} else if (val == 1) {
+				if (this.pageStatus == 0) {
+					//ai对话
+					this.controlsStatus = 3;
+				} else if (this.pageStatus == 1 || this.pageStatus == 2) {
+					// 原文速览&&转录文稿
+					this.controlsStatus = 2;
+				}
+				this.showIndexPage = false;
 			}
 		},
-		// 切换语言
-		changeLanguage() {
-			this.$message.info("切换语言");
+		recordedStart() {
+			// 开始录音
+			if (this.controlsStatus != 1 && this.recordedForm.status == 0) {
+				recorder.initRecorder(); //初始化录音
+				recorder.destroy(); // 销毁录音
+				// 开始录音
+				recorder.start().then(
+					() => {
+						this.controlsStatus = 1;
+						this.recordedForm.status = 1;
+						recorder.onprogress = this.updateRecordedTime;
+						this.$message.success("录音已开始");
+					},
+					(error) => {
+						this.controlsStatus = 0;
+						this.recordedForm.status = 0;
+						// _this.$message.error(`${error.name} : ${error.message}`);
+						this.$message.error(
+							`没有找到可使用的麦克风,或者您没有允许此网页使用麦克风`
+						);
+						// 出错了
+						console.log(`${error.name} : ${error.message}`);
+						// if (_this.calcTimer) {
+						//   clearInterval(_this.calcTimer)
+						//   _this.calcTimer = null;
+						// }
+					}
+				);
+			} else if ([1, 2].includes(this.recordedForm.status)) {
+				this.controlsStatus = 1;
+				this.$message.info("还在录音中");
+			} else if ([3].includes(this.recordedForm.status)) {
+				this.$confirm("再次录音会顶替掉之前的录音,您确定吗", "提醒", {
+					confirmButtonText: "确定",
+					cancelButtonText: "取消",
+					type: "warning",
+				})
+					.then(() => {
+						this.recordedForm.status = 0;
+						recorder.initRecorder(); //初始化录音
+						recorder.destroy(); // 销毁录音
+						this.recordedStart();
+					})
+					.catch((_) => {
+						console.log("不顶替");
+					});
+			}
+			// this.controlsStatus = 1;
 		},
-		//切换观察
-		changeAnalysis() {
-			this.$message.info("切换观察");
+		updateRecordedTime({duration}) {
+			// 更新currentTime,将秒数转换为时分秒格式
+			let hours = Math.floor(duration / 3600);
+			let minutes = Math.floor((duration % 3600) / 60);
+			let seconds = Math.floor(duration % 60);
+			this.recordedForm.time = `${hours.toString().padStart(2, "0")}:${minutes
+				.toString()
+				.padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`;
 		},
+		//切换观察
+		// changeAnalysis() {
+		// 	this.$message.info("切换观察");
+		// },
 		// 切换连续对话
 		changeContinuousDialogue(newValue) {
 			this.continuousDialogue = newValue;
 		},
-		//点击开始录音
+		// 点击发送旁的录音
 		tapeSubmit() {
-			this.mainBtnStatus = 0;
-			this.pageStatus = 1;
+			// this.$message.info("发送旁的录音");
+			// this.mainBtnStatus = 0;
+			// this.pageStatus = 1;
+			// this.TapeNum = 0;
+		},
+		async finishRecorded() {
+			this.loading = true;
+			recorder.stop();
+			this.$message.success("已结束录音");
+
+			let file = this.convertToMp3(recorder.getWAV());
+			file.lastModifiedDate = new Date();
+			file.name = "recordedFile.mp3";
+			var credentials = {
+				accessKeyId: "AKIATLPEDU37QV5CHLMH",
+				secretAccessKey: "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",
+			}; //秘钥形式的登录上传
+			window.AWS.config.update(credentials);
+			window.AWS.config.region = "cn-northwest-1"; //设置区域
+
+			var bucket = new window.AWS.S3({ params: { Bucket: "ccrb" } }); //选择桶
+			var _this = this;
+
+			if (file) {
+				var params = {
+					Key:
+						file.name.split(".")[0] +
+						new Date().getTime() +
+						"." +
+						file.name.split(".")[file.name.split(".").length - 1],
+					ContentType: file.type,
+					Body: file,
+					"Access-Control-Allow-Credentials": "*",
+					ACL: "public-read",
+				}; //key可以设置为桶的相抵路径,Body为文件, ACL最好要设置
+				var options = {
+					partSize: 2048 * 1024 * 1024,
+					queueSize: 2,
+					leavePartsOnError: true,
+				};
+				bucket
+					.upload(params, options)
+					.on("httpUploadProgress", function (evt) {
+						//这里可以写进度条
+						// console.log("Uploaded : " + parseInt((evt.loaded * 80) / evt.total) + '%');
+					})
+					.send(function (err, data) {
+						if (err) {
+							_this.$message.error("上传失败");
+							_this.loading = false;
+						} else {
+							// 判断是不是音频文件
+							// 更改录音文件
+							_this.audioUrl = data.Location;
+							_this.controlsStatus = 2;
+							_this.pageStatus = 1;
+							_this.recordedForm.status = 3;
+							_this.showIndexPage = false;
+							_this.loading = false;
+							// const audioRegex = /\.(mp3|wav|ogg|flac|m4a)$/i;
+							// if (audioRegex.test(data.Location)) {
+							// 	_this.controlsStatus = 2;
+							// 	_this.showIndexPage = false;
+							// 	_this.pageStatus = 1;
+							// 	_this.audioUrl = data.Location;
+							// 	_this.loading = false;
+							// } else {
+							// 	_this.ajax
+							// 		.put("https://gpt4.cocorobo.cn/upload_file_knowledge", {
+							// 			url: data.Location,
+							// 		})
+							// 		.then((res) => {
+							// 			let _data = res.data.FunctionResponse;
+							// 			if (_data.result && _data.result.id) {
+							// 				_this.$emit("updateFileId", _data.result.id);
+							// 				let pram2 = {
+							// 					id: _this.fileIdid,
+							// 					json_data: JSON.stringify({
+							// 						file_ids: _data.result.id,
+							// 					}),
+							// 					// json_data: JSON.stringify({file_ids:'file-r5phg4I2oFqly4WpW7oOOTnA'}),
+							// 				};
+							// 				_this.ajax.post(
+							// 					"https://gpt4.cocorobo.cn/update_classroom_observation",
+							// 					pram2
+							// 				);
+							// 			} else {
+							// 				_this.$message.error("上传失败");
+							// 			}
+							// 			_this.loading = false;
+							// 			// this.$emit("updateFileId", data.Location)
+							// 		})
+							// 		.catch((e) => {
+							// 			_this.loading = false;
+							// 			_this.$message.error("上传失败");
+							// 		});
+							// }
+
+							// console.log(data.Location)
+						}
+					});
+			}
+			// recorder.download(mp3Blob, "recorder", "mp3");
+			// let wavBlob = await recorder.getWAVBlob()
+			// const reader = new FileReader();
+			//将blob转未ArrayBuffer
+			// reader.onload = () => {
+			// 	const audioData = reader.result; // 获取 WAV blob 数据
+			// 	const samples = new Int16Array(audioData); // 转换为 Int16Array
+			// 	// 创建一个mp3编码器
+			// 	const mp3Encoder = new lamejs.Mp3Encoder(1, 44100, 128);
+			// 	// 将录音数据编码为MP3
+			// 	const mp3Data = mp3Encoder.encodeBuffer(samples);
+			// 	// 创建一个Blob包含MP3数据
+			// 	const mp3Blob = new Blob([mp3Data], { type: "audio/mp3" });
+			// 	console.log(`MP3文件:${mp3Blob}`);
+			// 	this.loading = false;
+			// 	recorder.initRecorder(); // 初始化录音
+			// 	recorder.destroy(); // 销毁录音
+			// };
+			// reader.readAsArrayBuffer(blob);
+		},
+		stopRecorded() {
+			if (!recorder.ispause) {
+				recorder.pause();
+				this.recordedForm.status = 2;
+				this.$message.warning("已暂停录音");
+			} else {
+				recorder.resume();
+				this.recordedForm.status = 1;
+				this.$message.success("已继续录音");
+			}
+		},
+
+		// 发送消息
+		send(){
+			if(this.textareaValue.trim().length<=0)return this.$message.info(`请输入内容`);
+
+			this.chatList.push({
+					role: "user",
+					name: "我",
+					create_at: new Date().toLocaleString().replace(/\//ig,'-'),
+					content: `${this.textareaValue}`,
+				},)
+
+			this.textareaValue = "";
+			this.chatList.push({
+					role: "ai",
+					name: "AI助手",
+					create_at: new Date().toLocaleString().replace(/\//ig,'-'),
+					content:`您好呀,我有什么可以帮助您的吗`,
+				},)
+				
+				this.$nextTick(() => {
+					this.$refs.textareaRef.style.height = '50px'
+					this.$refs.tapeRef.$el.querySelector('.t-chartArea').scrollTop = this.$refs.tapeRef.$el.querySelector('.t-chartArea').scrollHeight;
+				});;
+		},
+		textareaChange(){
+			this.$refs.textareaRef.style.height = '50px'
+			this.$refs.textareaRef.style.height = this.$refs.textareaRef.scrollHeight+"px"
+		},
+
+		convertToMp3(wavDataView) {
+			// 获取wav头信息
+			const wav = lamejs.WavHeader.readHeader(wavDataView); // 此处其实可以不用去读wav头信息,毕竟有对应的config配置
+			const { channels, sampleRate } = wav;
+			const mp3enc = new lamejs.Mp3Encoder(channels, sampleRate, 128);
+			// 获取左右通道数据
+			const result = recorder.getChannelData();
+			const buffer = [];
+			const leftData =
+				result.left &&
+				new Int16Array(result.left.buffer, 0, result.left.byteLength / 2);
+			const rightData =
+				result.right &&
+				new Int16Array(result.right.buffer, 0, result.right.byteLength / 2);
+			const remaining = leftData.length + (rightData ? rightData.length : 0);
+			const maxSamples = 1152;
+			for (let i = 0; i < remaining; i += maxSamples) {
+				const left = leftData.subarray(i, i + maxSamples);
+				let right = null;
+				let mp3buf = null;
+				if (channels === 2) {
+					right = rightData.subarray(i, i + maxSamples);
+					mp3buf = mp3enc.encodeBuffer(left, right);
+				} else {
+					mp3buf = mp3enc.encodeBuffer(left);
+				}
+				if (mp3buf.length > 0) {
+					buffer.push(mp3buf);
+				}
+			}
+			const enc = mp3enc.flush();
+			if (enc.length > 0) {
+				buffer.push(enc);
+			}
+			return new Blob(buffer, { type: "audio/mp3" });
 		},
 	},
 };
@@ -648,6 +987,7 @@ Markdown表格Markdown表格Markdown表格Markdown表格Markdown表格Markdown
 	display: flex;
 	flex-direction: column;
 	justify-content: flex-end;
+	position: relative;
 }
 .ca-b-o-header {
 	width: 100%;
@@ -765,9 +1105,8 @@ Markdown表格Markdown表格Markdown表格Markdown表格Markdown表格Markdown
 
 	margin-top: 5px;
 	border-radius: 16px;
-	background-color: white;
-	box-shadow: 0 5px 10px 10px #e6eaeb;
 	transition: 0.3s;
+	position: relative;
 }
 
 .ca-b-o-main:hover {
@@ -783,6 +1122,9 @@ Markdown表格Markdown表格Markdown表格Markdown表格Markdown表格Markdown
 	align-items: center;
 	font-size: 20px;
 	color: #3681fc;
+	border-radius: 16px;
+	background-color: white;
+	box-shadow: 0 5px 10px 10px #e6eaeb;
 	transition: 0.3s;
 }
 .ca-b-o-m-tapeTwo {
@@ -796,6 +1138,9 @@ Markdown表格Markdown表格Markdown表格Markdown表格Markdown表格Markdown
 	color: #3681fc;
 	box-sizing: border-box;
 	padding: 0 20px;
+	border-radius: 16px;
+	background-color: white;
+	box-shadow: 0 5px 10px 10px #e6eaeb;
 	transition: 0.3s;
 }
 .ca-b-o-m-tapeTwo >>> .vueAudioBetter {
@@ -812,49 +1157,85 @@ Markdown表格Markdown表格Markdown表格Markdown表格Markdown表格Markdown
 
 .ca-b-o-m-inputAre {
 	width: 100%;
-	height: 100%;
+	min-height: 100%;
+	height: auto;
 	display: flex;
-	align-items: center;
+	align-items: flex-end;
+	border-radius: 16px;
+	background-color: white;
+	box-shadow: 0 5px 10px 10px #e6eaeb;
+	transition: 0.3s;
+	position: absolute;
+	bottom: 0;
 }
 
-.ca-b-o-m-inputAreImg {
+.ca-b-o-m-TapeArea{
 	width: 100%;
-	height: 64px;
+	height: 100%;
 	display: flex;
-	margin-top: 5px;
 	justify-content: space-between;
+	border-radius: 16px;
 	background-color: #f0f2f5;
+	box-shadow: 0 5px 10px 10px #e6eaeb;
+	transition: 0.3s;
+	align-items: center;
+	padding-right: 20px;
+	box-sizing: border-box;
+}
+
+.ca-b-o-m-i-left {
+	display: flex;
 	align-items: center;
 }
-.ca-b-o-m-inputAreImg > img {
-	height: 100%;
+
+.ca-b-o-m-i-left > div > div {
+	color: #ee3e3e;
+	font-weight: bold;
+}
+
+.ca-b-o-m-i-left > div > span {
+	font-size: 14px;
+	margin-top: 5px;
+}
+
+.ca-b-o-m-i-left > img {
+	margin-left: 10px;
+	border-radius: 50%;
+	margin-right: 20px;
 }
 
 .ca-b-o-m-left {
 	flex: 1;
-	height: 100%;
+	height: auto;
+	min-height: 64px;
 	display: flex;
 	/* justify-content: center; */
 	align-items: center;
 	box-sizing: border-box;
-	padding: 0 20px;
+	padding-left:  20px;
 }
 
 .ca-b-o-m-left > textarea {
 	resize: none;
-	height: 80%;
-	width: 98%;
+	min-height: 50px;
+	margin: 7px 0;
+	max-height: 500px;
+	width: 100%;
 	font-size: 18px;
 	border: none;
 	outline: none;
+	resize: none;
+	overflow: auto;
 }
 .ca-b-o-m-right {
-	width: 150px;
-	height: 100%;
+	width: 100px;
+	min-width: 80px;
+	height: 64px;
+	max-height: 64px;
 	display: flex;
 	justify-content: center;
 	align-items: center;
-	/* background-color: red; */
+	margin-right: 10px;
 }
 
 #myTextarea::-webkit-input-placeholder {

+ 37 - 20
src/components/pages/classroomObservation/components/messageArea.vue

@@ -494,25 +494,25 @@ export default {
 					});
 			});
 		},
-		getFileId() {
-			let pram = {
-				tid: this.tid,
-				type: "10",
-			};
-			this.ajax
-				.post("https://gpt4.cocorobo.cn/get_classroom_observation_new", pram)
-				.then((res) => {
-					let _data = res.data.FunctionResponse.result.length
-						? JSON.parse(res.data.FunctionResponse.result)
-						: [];
-					this.$emit('updateFileIdid', _data[0].id)
-					if(_data[0].jsonData !='' ){
-						this.$emit("updateFileId", JSON.parse(_data[0].jsonData).file_ids)				
-					}else {
-						this.$emit("updateFileId", '')				
-					}
-				});
-		},
+		// getFileId() {
+		// 	let pram = {
+		// 		tid: this.tid,
+		// 		type: "10",
+		// 	};
+		// 	this.ajax
+		// 		.post("https://gpt4.cocorobo.cn/get_classroom_observation_new", pram)
+		// 		.then((res) => {
+		// 			let _data = res.data.FunctionResponse.result.length
+		// 				? JSON.parse(res.data.FunctionResponse.result)
+		// 				: [];
+		// 			this.$emit('updateFileIdid', _data[0].id)
+		// 			if(_data[0].jsonData !='' ){
+		// 				this.$emit("updateFileId", JSON.parse(_data[0].jsonData).file_ids)				
+		// 			}else {
+		// 				this.$emit("updateFileId", '')				
+		// 			}
+		// 		});
+		// },
 		getCurrencyAndBaseMessageData() {
 			let pram = {
 				tid: this.tid,
@@ -521,6 +521,23 @@ export default {
 			};
 			this.currencyLoading = true;
 			this.baseMessageLoading = true;
+			this.bmData = {
+				id:"",
+				tId:this.tid,
+				tIndex:0,
+				jsonData:{
+					activity_methods:"",
+					activity_structure:"",
+					classroom_resources:"",
+					courseName:"",
+					name:"",
+					studentNum:0,
+					subject:"",
+					textbook:"",
+				}
+			}
+			this.imageList = [];
+				this.dataList = [];
 			this.ajax
 				.post("https://gpt4.cocorobo.cn/get_classroom_observation_new", pram)
 				.then((res) => {
@@ -636,7 +653,7 @@ export default {
 			this.getScienceData();
 			this.getExtendData();
 			this.getValueAddedData();
-			this.getFileId();
+			// this.getFileId();
 		},
 		saveData(fn) {
 			// return;

+ 43 - 411
src/components/pages/classroomObservation/components/tape.vue

@@ -7,7 +7,7 @@
 		<!-- <div class="t-tapeAudio">
 			<mini-audio :audio-source="audioUrl" class="audio_class"></mini-audio>
 		</div> -->
-		<div class="t-tapeFile">
+		<!-- <div class="t-tapeFile"> -->
 			<!-- <div class="t-t-header">
 				<div class="t-t-h-left">
 					<div class="t-t-h-l-Item" :style="cardStatus==0&&foldStatus?'background:white':''" @click.stop="changeCardStatus(0)">
@@ -24,7 +24,7 @@
 					<div class="t-t-h-r-text">{{ foldStatus==0 ? '展开' : '收起'}}</div>
 				</div>
 			</div> -->
-			<div class="t-t-main" v-show="foldStatus">
+			<!-- <div class="t-t-main" v-show="foldStatus">
 				<div class="t-t-m-Item" v-show="cardStatus == 0">
 					<p v-for="(item, index) in pList" :key="index" v-text="item"></p>
 				</div>
@@ -39,9 +39,9 @@
 						"
 					></iframe>
 				</div>
-			</div>
-		</div>
-		<div class="t-chartArea" v-show="!foldStatus">
+			</div> -->
+		<!-- </div> -->
+		<div class="t-chartArea" ref="chartAreaRef">
 			<div class="t_ca_box" v-for="(item, index) in chatData" :key="index">
 				<div class="t_ca_b_roleAi" v-if="item.role == 'ai'">
 					<div class="t_ca_b_ai_avatar">
@@ -92,7 +92,7 @@
 									@click="copyContent(item.content)"
 								/>
 							</div>
-							<div class="t_ca_b_u_c_m_right">{{ item.content }}</div>
+							<div class="t_ca_b_u_c_m_right" v-html="contentValue(item.content)"></div>
 						</div>
 						<div class="t_ca_b_u_c_time">{{ item.create_at }}</div>
 					</div>
@@ -135,423 +135,45 @@ export default {
 				return [];
 			},
 		},
+		aiNameList:{
+			type:Array,
+			default:()=>{
+				return [];
+			}
+		}
 	},
 	data() {
 		return {
-			foldStatus: false, //0--收起状态   1--展开状态
-			cardStatus: 0, //0--录音原文   1--转录文稿
-
-			pList: [
-				"说话人1 00:00",
-				"对爱整洁,有精神、不拖拉,多思考。老师你好,同学们好。",
-				"说话人2 00:10",
-				"请坐。前几天白老师关注到一则新闻,我们大鹏新区政府提出要将2024年作为旅游高质量发展年,为了吸引更多的游客来到咱们大鹏,你认为最重要的是什么来?第一小组。",
-				"说话人1 00:42",
-				"我认为最重要的是要先把环境、绿水青山环境弄好,这样才能吸引更多的人来,大鹏是的。",
-				"说话人2 00:51",
-				"大家同意他的想法吗?保护大棚环境人人有责,上周咱们班的两位环境调查员就去到葵冲进行了实地调查,我们来看看他们发现了什么。",
-				"说话人1 01:12",
-				"大家好,我们是人大附中深圳学校五1班的张龙溪,何瑞一为了响应区政府的号召,今天我们作为环境调查员,准备实地调查一下葵冲的环境情况,走跟随我们的镜头一起去看一看我们调查到的情况有什么样,这样的。",
-				"说话人3 01:36",
-				"应该是这样的,就是这样的,像这样的。",
-				"说话人2 01:41",
-				"像这种情况。",
-				"",
-				"像这种情况。",
-				"说话人3 01:52",
-				"像这样的。",
-				"说话人1 01:54",
-				"我们调查到的情况不是很好,同学们你们。",
-				"说话人3 02:02",
-				"谁知谁知。",
-				"说话人2 02:33",
-				"刚刚视频有一些小小的不同步,但不影响我们去观察里面的内容。",
-				"",
-				"好,来,同学们,通过刚才的视频,你看到了哪些环境问题?第五小组。",
-				"说话人1 02:51",
-				"我看到了菜市场上到处是垃圾,到处是那些烂掉的瓜果皮,是的。",
-				"说话人2 02:57",
-				"其他小组呢?来第八小组我。",
-				"说话人1 02:59",
-				"看我看到了路上还有很多漂移的垃圾就路上了。",
-				"说话人2 03:06",
-				"你观察得很认真,是的,在咱们生活的这片区域确实存在很多的垃圾问题,这些垃圾主要是家庭里面产生的生活垃圾。",
-				"",
-				"根据调查,一个家庭一天产生的垃圾大约是三千克,咱们班一共有45位同学,所有同学的家庭一天产生的生活垃圾总质量是多少?老师还调查到一些数据。我校小学部一共有1556人,整个大鹏新区共有55,224户家庭,整个深圳市有6,424,556户家庭,他们一天分别产生多少垃圾呢?现在请小组长从材料框当中拿出实验记录单,我们用计算器来速算一下,将结果记录下来。",
-				"",
-				"好,可以开始计算。二十五六场这样做的之前工作。",
-				"说话人1 04:49",
-				"还差一些,这样更准确一点。",
-				"说话人2 05:29",
-				"用计算器这样更准确算完了没有?",
-				"说话人1 05:38",
-				"你们。",
-				"说话人2 05:38",
-				"算完了吗老师?",
-				"说话人1 05:44",
-				"拍一下照片。",
-				"说话人2 06:05",
-				"大家算完了吗?",
-				"",
-				"好,算完的小组面向老师坐,好好表扬第八小组。好,第五、第四、第三。",
-				"",
-				"好,这是第四小组的数据,我们来看跟大家的一样吗?一样,在刚刚大家记录数据的时候,你发现了什么?在你刚刚写下这些数据,有什么发现?第三小组。",
-				"说话人1 06:42",
-				"我发现每天生产的垃圾会非常多。",
-				"说话人2 06:46",
-				"垃圾很多多,到什么程度?我们来看。多到全班同学一天产生的垃圾,相当于一头成年公羊这么重,多到全校小学部家庭的垃圾,一天有一头非洲大象这么重。大鹏新区所有家庭一天产生的垃圾量相当于32头,非洲大象这么重,整个深圳市一天产生的垃圾高达3800头,非洲大象这么重。",
-				"",
-				"老师看到很多同学发出来很惊讶的表情,整个深圳市就产生这么多的垃圾,整个广东省全国23个省加起来,放眼全球,全世界一年产生的垃圾是多少?我们来看这个统计图,把各个地区的垃圾量加起来,全球一年产生垃圾量高达20.17亿吨。这么多的垃圾如果填埋高度是一米的话,它可以埋掉三个深圳或者一个广州的面积。",
-				"",
-				"面对这组数据,你有什么样的感受跟大家分享一下。来,第一小组,垃圾好多。",
-				"说话人4 08:27",
-				"垃圾很多。",
-				"说话人2 08:29",
-				"其他小组有什么样的感受?第八小组。",
-				"说话人1 08:36",
-				"如果我们一直都以填埋的方式去处理垃圾的话,可能全球的土地都用于填埋垃圾了。",
-				"说话人2 08:45",
-				"你还告诉了大家处理垃圾的一种方式是的,这么多的垃圾如果没有得到及时的处理,他们会侵占大量的土地包围我们的城市家园,我们就会陷入到一种垃圾围城的现状,面对这么庞大的垃圾量,我们该怎么办?",
-				"",
-				"第七小组。",
-				"说话人1 09:15",
-				"我觉得我们可以按照垃圾的种类来进行分类,比如说回收垃圾,它可以是回收,然后再利用的或者就是有害垃圾,比如说电池会污染,将会人们将会对它处以专业的处理。",
-				"说话人2 09:37",
-				"你想到了垃圾分类,其他小组。",
-				"",
-				"第五小组。",
-				"说话人1 09:44",
-				"并且像很多我们要应该少用一次性的垃圾,比如说你买菜的时候要少用一次性的塑料袋,尽量用布袋,这样子的话可以节省既节省资源,又节省了垃圾的。",
-				"说话人2 09:58",
-				"生产量,你说的是一个非常实用的方法,大家刚刚都说出来了,实际的行动是的。今天就让我们一起行动起来,一起共同想办法来解决垃圾问题。",
-				"说话人1 10:14",
-				"面对垃圾问题。",
-				"说话人2 10:22",
-				"正如第八小组刚刚说的,咱们国家早期的处理方式是直接填埋和焚烧发电,这两种方法在一定程度上减少了垃圾,但也存在着很严重的弊端。现在我们就一起来说一说这两种方法的好处和弊端。第一小组。",
-				"说话人4 10:50",
-				"直接填埋这种方法会占用大量土地,而且还会污染土地,焚烧发电这种方法会会污染大气。",
-				"说话人2 11:00",
-				"你对两种方法思考得很深入,其他小组有补充吗?好,第五小组。",
-				"说话人1 11:09",
-				"如果是填埋电池的话,可能对土壤有害,以后要是在这片土上种。",
-				"说话人4 11:15",
-				"植物的话,可能植物很快就会死掉,无法进行光合作用。",
-				"说话人1 11:20",
-				"和传输氧气。",
-				"说话人2 11:23",
-				"你思考了一种垃圾,电池可能对我们土壤产生的危害想法很深入,你。",
-				"说话人1 11:34",
-				"我觉得直接填埋有个好处就是比较方便比较迅速,而直接填埋就会污染土地和水源。",
-				"",
-				"而焚烧发电可以把垃圾发电站也利用了一下垃圾,但是却会污染大气,造成我们一些呼吸上的问题。",
-				"说话人2 11:53",
-				"他说的有没有道理?大家点头赞同,是的,这两种方法看来存在着很严重的环境污染问题,并且这两种做法也是政府的行为,我们个人是没有办法进行的。那面对垃圾问题,我们自己能做些什么?减少它的量,现在就请我们小组展开头脑风暴,讨论解决垃圾问题,我们自己能做的行为。",
-				"",
-				"好,以关键词或句子的方式写到记录单当中,好,现在可以开始。",
-				"说话人3 12:34",
-				"谁知因为我还是你平常拉着我的东西,谁知到什么道路了,他可能对结果就不到了。把拿起来,谁知发生 Ew。好了,有的话写作业的时候就到里面,但是我今天的话我再给您说,谁知位置主要的地方可以通过文章的方式来进行数据上传,谁知10月份20 6 18 14号28号20分钟应该把这个问题没有谢谢。",
-				"",
-				"就不知道2.62.6性格你说的对。这句话谁知你知道你怎么说话。谁知谁知还有什么?还有谁知。后面的测试出来的一样,当时的好的也吗?",
-				"",
-				"我写好了吗?谁知这样的地方。这个也是可以的,少都买少买菜的时候去,因为那个时候出来还有什么?为什么我想说然后找一些画面,如果你生了一个兔是吧?吐了人家不知道,不代表他有回复利用的物质,谁知道?老师看你们写网上看看,我们写了好多,我能拍一下你的可以吗?我看一下好不好?你看到了尽量,谁知小宠物去网上买的一般,确实对教育较高的分了。我喜欢光盘,不是光盘,就是关系方向,他用的倍数。",
-				"",
-				"好,时间到。",
-				"说话人2 15:26",
-				"好说,停。",
-				"",
-				"第一小组第四、第五。好,我们来看这是第四小组他们的做法。先看第一个少,用一次性工具,这种方法你们是怎么想的?来。",
-				"",
-				"第四小组。第四小这是他们的做法,你想补充可以。",
-				"说话人4 15:51",
-				"如果你用一次一次性工具的话,它用了一次你就只能扔掉,但如果你不用它的话,你用的这些东西可以循环很多次的话,那就不用它了,那就可以减少垃圾的产生。",
-				"说话人2 16:13",
-				"这种方法是相当的厉害,我们从一开始就减少了这个工具的使用,相当于垃圾的量就减少了,科学上我们把这种处理方式叫做减量化。",
-				"",
-				"刚刚那个同学说我们减少使用这个一次性的工具再次重复利用起来。好,大家想把垃圾变成了重复利用的一种资源,它被重新利用起来了,相当于是一种新的资源,科学上把这种方法叫做资源化处理。我们来看第二条,垃圾分类,关于垃圾分类,老师有疑问,请你们小组起立。",
-				"说话人1 17:13",
-				"垃圾分类的话,因为我们现在有一些可回收垃圾、厨余垃圾和有害垃圾,其他垃圾可回收垃圾,我们在经过特殊处理以后可以重复利用起来,相当于是变变废为宝,而有害垃圾要经过特殊的处理,才可以让我们的环境不受到污染,所以我们认为把垃圾分类以后可以做到环保护环境,而且也可以解决一些浪费的问题。",
-				"说话人2 17:43",
-				"垃圾被分类后,垃圾的数量减少了吗?",
-				"",
-				"没有。",
-				"",
-				"垃圾问题依然存在,我们需要经过进一步的处理,就像他刚刚说的。",
-				"",
-				"好,关于你的回答,老师有一点小疑问,你说到了有害垃圾,有害垃圾是对什么有害?",
-				"说话人1 18:06",
-				"我们认为有害垃圾如果它像进行填埋或者说把它进行发电的话,可能会对环境有一些污染,比如说填埋的话,有一些电池和过期药品埋到地地下以后会影响土地里面的一些一些的营养,然后让一些植物就不太好生长,对环境有害。",
-				"说话人2 18:35",
-				"很可能对什么有害。",
-				"说话人1 18:40",
-				"可能对人体有害,因为有些过期的那种化妆品,它里面有一些那种化学成分,而这些化学成分可能对人体有害,所以说有害垃圾它是对人体有害的。",
-				"说话人2 18:53",
-				"大家赞同这种垃圾太可怕了,我们得远离它,当然咱们也不可以随地的乱丢这种垃圾,这种垃圾就需要我们经过专业的无害化的处理,让它对人和环境的危害最小,科学上把这种方法叫做无害化处理。我们继续往下看第四条循环利用,废物利用。好,这种方法你们小组是怎么思考的?是哪个小组写的?来。",
-				"说话人4 19:38",
-				"一些可能没他原来没有用的东西,你可能可以用它来做些手工,或者对别人还有用,你也可以捐给别人,这样他就又有用了。",
-				"说话人2 19:54",
-				"是个非常有爱心的孩子,我们把垃圾相当于又再次利用起来了,大家想垃圾的量怎么样?这是哪种方式?",
-				"",
-				"是的,好,换另外一个角度,我们继续想把垃圾做成了手工艺品,把它变成了一种这是资源化的处理方式。",
-				"",
-				"对的。",
-				"",
-				"好,除了这个小组提出的这些想法,其他小组有要补充的吗?第六小组。",
-				"说话人1 20:34",
-				"我们小组认为吃完饭之后,剩饭剩菜可以喂给小动物吃,比如那些小猫小狗的什么的。",
-				"说话人2 20:46",
-				"也就是说你们把一些剩饭剩菜这样的垃圾又再次用起来了,这种方式是哪种方法?资源化。换另外一个角度。",
-				"说话人4 21:02",
-				"想。",
-				"说话人2 21:04",
-				"为什么是减量化?来我们来听听他怎么说。",
-				"说话人1 21:12",
-				"因为本来如果是倒掉的话,它就会增加垃圾,但是如果喂给那些小猫的话,垃圾量就减少了。",
-				"说话人2 21:21",
-				"他思考的好不好?把掌声送给他。",
-				"",
-				"其他小组还有要补充的吗?第八小组。",
-				"说话人1 21:31",
-				"我认为厨余垃圾可以拿去堆肥。",
-				"说话人2 21:35",
-				"也就是说把垃圾做成肥料,默默的奉献自己变成了一种什么?养分,它相当养分。",
-				"说话人3 21:47",
-				"相当于是资源一种资源。",
-				"说话人2 21:51",
-				"这种方式叫做资源化的处理。",
-				"",
-				"好,其他小组还有要补充的吗?",
-				"",
-				"好,没有了。",
-				"",
-				"经过我们刚刚的讨论,我们发现解决垃圾问题最常用的是三种方法,分别是无害化。是的,面对垃圾问题,这三种方法其实是有先后顺序的,我们首先应该做到的是减量化的处理,在生活当中咱们还是不可避免实在没有办法产生的一些垃圾,该怎么办呢?",
-				"",
-				"好,具体一点怎么资源化第七小组。",
-				"说话人1 22:48",
-				"比如说我们喝那些饮料,剩下来的易拉罐我们可以不用丢,可以把它与另外一些垃圾组成一一种手工用品,这样子还增加了趣味性。",
-				"说话人2 23:01",
-				"大家同意吗?老师想问了,所有的垃圾都可以做成这样的手工艺品吗?",
-				"",
-				"第三小组。",
-				"说话人1 23:14",
-				"一些有害垃圾是不能做成手工艺品的,因为如果做的话,它可能会释放那些有毒的东西,然后污染。",
-				"说话人2 23:24",
-				"那个环境是的,什么样的垃圾可以去做手工艺品呢?意思叫做我。",
-				"说话人1 23:32",
-				"认为我认为比如说一些可回收垃圾,就像是一些易拉罐,还有那些纸制品都可以用来作为咱们的。",
-				"说话人2 23:49",
-				"做成手工,大家同意吗?你有没有这样的变废为宝的经历,有吗?有没有?",
-				"",
-				"有同学点头了,是的,我们就把这类塑料,刚才说的玻璃等等,它其实是一种有价值的垃圾,我们是不是应该把它给分出来?这类垃圾可以叫做。",
-				"说话人3 24:15",
-				"回收回收垃圾。",
-				"说话人2 24:17",
-				"垃圾回收再次利用,它对应的解决方法应该是。",
-				"说话人3 24:25",
-				"减轻了什么?",
-				"说话人2 24:26",
-				"计划有不一样的想法了,谁来分享一下?",
-				"",
-				"第八小组。",
-				"说话人1 24:39",
-				"我觉得是资源化,因为它已经是可回收的垃圾了,就没有必要再去减量了,而且可回收垃圾可以做成像我们刚才说的手工制品,变成资源。",
-				"说话人2 24:51",
-				"成为资源化其他小组。",
-				"",
-				"第六小组第四小组。",
-				"说话人1 24:59",
-				"我觉得它既是减量化也是资源化,因为可回收垃圾它不仅减少了我们我们产出的垃圾,它不仅从这垃圾的部分中减少了一部分,而且它还将这些垃圾又回收利用,再形成了一种新的物体。",
-				"说话人2 25:18",
-				"所以是减量化和资源化一起来解决可回收的垃圾。",
-				"",
-				"好,继续思考,剩下的还有很多不可以回收的垃圾,这些垃圾该怎么办?比如说我们的剩饭剩菜,第三小组。",
-				"说话人1 25:44",
-				"那些剩饭剩菜也可以资源化,可以像刚才黄家俊说的,喂给小猫小狗那些小动物吃。",
-				"说话人2 25:54",
-				"好,你打算把这些垃圾剩饭剩菜喂给小猫小狗,其他同学有不同观点吗?好,第五小组。",
-				"说话人1 26:04",
-				"还可以像刚刚第八小组说的,把它变成堆肥,这样子的话可以灌溉农田,这样子的话也可以让植物养得更好,这个也是资源化。",
-				"说话人2 26:17",
-				"不管是喂给小猫小狗或者是做成肥料,总的来说垃圾又被我们变成了资源,这样的垃圾有价值,我们需要把它单独给分出来,叫做厨余垃圾,厨余垃圾。",
-				"",
-				"好,垃圾变成了资源,它的处理方式应该是资源化。咱们刚刚第五小组补充举手的女生。",
-				"说话人1 26:51",
-				"如果是电池的话要扔掉的话也可以我见过一种给电池充电的设备,用电池充好电之后还能重复利用。",
-				"说话人2 27:06",
-				"充电的电池可以重复利用,好它重复利用充电的次数是有限的。",
-				"",
-				"当这些电池报废之后,这些电池老师产生了疑问,它还有一些金属的元件,还有我们废弃的灯泡,也有一些玻璃的成分在这,两种垃圾可不可以直接回收?大家都在摇头,为什么不可以?",
-				"",
-				"老师很疑惑,来第七小组。",
-				"说话人1 27:39",
-				"因为如果我们把电池这些里面含有特殊元素的,比如说给它转为资源化的话,那么资源化就像做手工艺品一样,它并不能做手工艺品,而且它里面的化学里面一些不明物质和化学物质会对周围的环境以及人体产生相对的伤害。",
-				"说话人2 28:03",
-				"是的。",
-				"",
-				"像这类的垃圾它含有有毒有害的成分,我们不能直接回收,而且现在咱们国家的垃圾处理技术,还不能够将这些有毒有害的垃圾变成无毒可回收的垃圾,所以他们怎么办?需要单独的给它处理起来,把它叫做无害化,这类垃圾叫做。",
-				"说话人1 28:37",
-				"有害垃圾。好。",
-				"说话人2 28:42",
-				"我们继续思考,有些垃圾它既不可以回收,也不是厨房里产生的,也无毒无害,这类垃圾通通的叫做其他垃圾。我们采用焚烧和填埋的方式来解决,因为他们的量已经很小了。",
-				"",
-				"好,在刚刚我们讨论过程当中,我们逐渐的将垃圾分成了4大类,其实咱们国家把垃圾就分成的是这4类,看来垃圾分类很重要,垃圾分类只是解决垃圾问题的前提条件,后续回收回来还是要进一步的去处理的。",
-				"",
-				"好,老师这里有8种生活垃圾,请大家按照刚刚的4种分类方法将它们进行分类,把序号写在相应的垃圾桶身上。好,现在请小组长翻开记录单的背面,完成分类开始。",
-				"说话人3 29:59",
-				"塑料瓶上面都要给哥哥烧,谁知餐具其他垃圾,其他的垃圾沙发正在处置垃圾残缺,落叶处置垃圾。他们4号回来吃饭,他应该是12头肌土地有害了,一起讨论了,大多数人的意志就是必须要的但是它里面有一个化学都不能对烟头应该是烟头是其他的,为什么?因为它已经被燃烧过了,燃烧过了之后就只剩下后面那点了。快递纸箱应该是一个点,你们看好了吗?你分的这么快。对,快递只能把它打破物流质量不错的服务。",
-				"",
-				"谁知谁知我们再讨论一下,我只是表演一下,没有。写完了,要不然你们分的好看再讨论一下,看看有没有你不确定的,谁知看来还是太大了。",
-				"说话人1 31:35",
-				"难道我就想问一下。",
-				"说话人3 31:37",
-				"难道难道你的处理垃圾就一件事还能给小猫小狗搞个香蕉?他就是我小狗。再说过期,过期了以后。",
-				"说话人2 31:54",
-				"大家都分完了吗?分完的小组面向老师坐好好。",
-				"",
-				"第七第八456123好看这里我们来看这个小组它的分类,先从可回收垃圾看起,他们将1号塑料瓶,7号快递纸箱归为可回收垃圾,有和大家不一样的吗?有不一样的吗?好,没有,我们来看厨余垃圾,他们将三号剩饭剩菜归为厨余垃圾,有不一样的吗?有好多。",
-				"",
-				"来,第六小组。",
-				"说话人1 32:43",
-				"我觉得4号残枝落叶也是厨余垃圾。",
-				"说话人2 32:47",
-				"你的理由是?我暂时还没想好小组内有要帮帮他的吗?你们小组是怎么想的?和他们一样认为4号属于厨余垃圾的。说一下理由。第三小组。",
-				"说话人1 33:10",
-				"我觉得残枝落叶也是厨余垃圾,因为剩菜剩饭还没有变成剩饭,全是蔬菜,蔬菜跟那些落叶是差不多的,而且它们腐烂之后腐烂之后也会变成泥土,就像那些残枝落叶也是会变成那些肥料的。",
-				"说话人2 33:32",
-				"老师听明白了,你认为残枝落叶也可以腐烂,归为了厨余垃圾是吗?好,来第六小组。",
-				"说话人1 33:41",
-				"我不认同石新宇的观点,因为厨余垃圾我们从字面分析。",
-				"",
-				"食用后的垃圾,而残肢过夜是不能是不属于可以用来使用的。所以我认为残这个也不是厨余垃圾。",
-				"说话人2 34:05",
-				"也就是说你的标准4号残枝落叶它不是我们吃剩下的,对吗?归为其他垃圾。",
-				"",
-				"关于4号看来两个小组产生了分歧,来,第八小组。",
-				"说话人1 34:22",
-				"但是我们知道残枝落叶它也就是埋在土里,它以后很快就可以销毁,然后然后厨余垃圾一般就是指那些食物,而且比较容易在土里土里销毁的一些物品,然后黄家俊刚才说说残枝落叶得是吃过的才算,但是残枝落叶是算树叶,也算是一种食品。",
-				"说话人2 34:55",
-				"所以你赞同的是第三小组的观点,是吧?",
-				"",
-				"好,来。",
-				"说话人1 35:02",
-				"我不认同黄家俊的看法,因为其他垃圾它是既不能归为可回收垃圾,也不能归为厨余垃圾,也不能归为有害垃圾的。厨余垃圾它可以做成肥料罐,让植物长得更好,残枝落叶就可以用来当做肥料,所以我觉得黄家俊说的是错误的。",
-				"说话人2 35:23",
-				"大家看来对4号产生了很大的争议,我们先放一放,来看厨余垃圾还有不一样的吗?没了,来,咱们看有害垃圾有不同的吗?第五小组。",
-				"说话人1 35:41",
-				"我们小组认为6号的烟头它并不是有害垃圾,因为烟头它是燃烧过后的才叫做烟头,而没有燃烧过后的那叫做烟,而烟头燃烧过后,它那些烟草已经燃烧完毕了,而后面那些那些纸团棉花之类的,它就是其他垃圾,因为已经被嘴巴给含过了,所以说应该就是有害垃圾,应该就是其他垃圾。",
-				"说话人2 36:10",
-				"也就是说你认为抽完的烟头没有危害了,把它归到了其他垃圾。",
-				"",
-				"好,6号两个小组产生了分歧,我们采访一下,来,这是第六小组的,你们把6号作为有害垃圾的依据是什么?",
-				"说话人1 36:32",
-				"我认为烟头虽然现在灭了,但如果一一不小心死灰复燃了,就有可能燃起一场大火,所以我把烟头归到了有害垃圾里面。",
-				"说话人2 36:46",
-				"烟头很可能引发火灾。来,其他有补充的吗?来,你说。",
-				"说话人1 36:52",
-				"因为我们都知道抽烟有害身体健康,那么烟里面肯定是有一些有害身体的,如果你不能保证烟里边有害身体的都被抽完了的话,我觉得没熄灭的烟头就是有害垃圾。",
-				"说话人2 37:11",
-				"说的也有道理。",
-				"",
-				"来第七小组。",
-				"说话人1 37:15",
-				"我是不赞成曾静纯的观点的,因为烟中含有含有尼古丁,尼古丁能对人的身体产生危害,而且烟头它不一定里面有害物质都是全抽完,可能还有一点残留在里面,况且没有熄灭的烟头,我之前了解过没熄灭的烟头,如果产生火灾的话将称为燃阴,燃的话可能阴燃扑灭火的可能性很低,也就是说它火会很大,可能也会影响到人的生命安全。",
-				"说话人2 37:53",
-				"好,他关于烟头展开了一番很深入的全面的一番思考,非常不错,来。",
-				"",
-				"第六小组第四小组。",
-				"说话人1 38:03",
-				"我们认为烟头它是其他垃圾,因为有害垃圾像杀虫剂过期药品,它们是自身不需要处理,就会散发出有毒的气体或者有毒的物质,而烟头它需要再次的燃烧才能产生尼古,才能让尼古丁散发出去,从而对人体有伤害,所以我认为烟头它属于其他垃圾。",
-				"说话人2 38:27",
-				"好,请坐。",
-				"",
-				"你和你们小组和第七小组观点最大不同的是你认为烟头里的尼古丁没有燃烧,没有害,归为其他垃圾,他们认为烟头里的尼古丁即使没有燃烧也有害,所以归为了有害垃圾,是吗?",
-				"",
-				"好,关于6号我们又产生了很大的分歧,好,我们也先再放一放,来看有害垃圾还有不同的吗?来看其他垃圾有不一样的吗?好,现在我们来看大家存在很大争议的垃圾是三个,一个是一共是两个,一个是4号残枝落叶,还有6号烟头。好,我们国家把这两类垃圾归为哪一类?我们来看一下国家的分类标准。",
-				"",
-				"好,来看,我们国家把可以回收利用的垃圾投在可回收垃圾箱,容易腐烂的垃圾投在厨余垃圾箱,对人和环境有害的垃圾投在有害垃圾箱。除了这三类难以回收的全部放在其他垃圾箱,残枝落叶,我们来看它可以回收利用吗?没有重复利用的价值它容易腐烂吗?所以国家把它归为厨余垃圾。好,接下来再看烟头是大家争议很大的一个垃圾,好,我们依次来看,它可以回收利用吗?",
-				"说话人3 40:28",
-				"没有价值。",
-				"说话人2 40:31",
-				"容易腐烂吗?对。人和环境有害吗?",
-				"",
-				"有是这样的,抽剩下的熄灭的烟头,它对人和环境危害性很小,我们的尼古丁只有在燃烧的时候才会产生有毒有害的气体或物质,但这个烟头已经是一般情况下已经熄灭了,它的危害性比较小,所以把它归为灾害其他垃圾。好,对比我们小组的分类标准和国家的标准,我们发现有的小组和国家一样,有的不一样,国家的这种分类标准你有什么样的建议?",
-				"",
-				"第一小组。",
-				"说话人1 41:31",
-				"我觉得烟头虽然它的危害很小,不过世界上有很多人都是吸烟的,但所有烟头都在一起的话,它的危害就会慢慢变大。",
-				"说话人2 41:44",
-				"你认为怎么我。",
-				"说话人1 41:45",
-				"认为它可以变成有害垃圾。",
-				"说话人2 41:48",
-				"变成有害垃圾,这是你的想法,跟我们国家的标准是不一样的,可不可以在这个基础上改进,提出自己的新的想法?好。",
-				"",
-				"来第五小组。",
-				"说话人1 42:07",
-				"我建议再提出一个垃圾桶专门回收烟类的,这样子的话就好区分一点,也好,分类一点也好,后面也好。",
-				"说话人2 42:21",
-				"处理一点有想法的孩子,大家同意吗?",
-				"说话人1 42:25",
-				"关于烟头每个人的标准不一样。",
-				"说话人2 42:28",
-				"太难区分它了,是不是?我们就不如在再放一个垃圾箱,就专门来放烟头,好不好?放烟头之类的物品,看来有一定的道理。好,其他小组还有不同的建议吗?",
-				"",
-				"第四小组我。",
-				"说话人1 42:45",
-				"要反驳一下第一小组的账号君说的话,如果把烟头放进有害垃圾的话,要是烟头当时没有完全熄灭,然后有害垃圾箱里面又有电池,那些都东西,然后烟没熄灭导致火灾,然后电池爆炸,那就会炸,可能会炸伤许多人。",
-				"",
-				"所以我不建议把那烟头放进有害垃圾箱里。",
-				"说话人2 43:17",
-				"是的,很多人很粗心,有时候烟并没有完全熄灭就扔掉了,他这种情况有可能发生吗?怎么改进呢?有什么好的建议?来,你们小组。",
-				"说话人1 43:33",
-				"我是认为烟头它如果是没有完全燃烧结束,它还有火的话,它不管放到哪个垃圾桶里面,它都会引发或燃烧和爆炸。而且一般烟头它如果没有熄灭的话,很多人他习惯没熄灭,往地上一扔一踩就走了。很多烟头都是环卫工人捡起来以后,收集好以后再去再去扔到垃圾桶里面的。",
-				"",
-				"再一个我就觉得可以说不一定非要在垃圾桶的分类上进行一些改变,可以我们对在平时我们生活的时候提出一些新的要求或者建议,比如说多设一多设立一些吸烟的站,让我们吸烟的地方也吸完烟以后就可以找到一个比较近的地方将烟掐灭,这样就可以阻止尼古丁的释放和爆炸着火的风险。",
-				"说话人2 44:34",
-				"非常有个人想法的一个建议。",
-				"",
-				"好,其他小组第五小组。",
-				"说话人1 44:43",
-				"我是这样认为的,其实我觉得国家可以少生产一点烟,这样子就不会有那么多烟头了。",
-				"说话人2 44:51",
-				"少抽烟大家同意吗?少抽烟烟对人有害健康。",
-				"",
-				"来,4小组补充。",
-				"说话人1 45:02",
-				"我想补充一下第五小组郑明达决定重新设一设立一个垃圾桶的想法,我觉得再可以再设立一个垃圾桶,只有我在外界条件允许下才会变成有害垃圾的一个垃圾桶,因为垃圾桶做一个就是保护措施,就防止像刚刚我们小组说的,里面还有其他的物质引引发爆炸之类的有道理。",
-				"说话人2 45:28",
-				"好,来第八小组用话筒。",
-				"说话人1 45:34",
-				"我认为没有改进的必要,因为现在很多垃圾桶上面都有一个面噎的地方。",
-				"说话人2 45:40",
-				"你很赞成现在的4分法,同学们刚刚提的建议都有一定的道理,有合理的地方,随着我们国家垃圾处理技术的不断提高,我们国家的分类标准在以后也可能会发生变化,在未来作为国家公民,我们每个孩子都有机会为更好的垃圾分类方案提出自己的建议。",
-				"",
-				"好,但是目前4分法国家的4分法还是能够有效的解决很多的垃圾问题的。生活当中咱们还按照4分法来分类。",
-				"",
-				"好了,孩子们,今天。",
-				"说话人1 46:23",
-				"我们。",
-				"说话人2 46:24",
-				"学了很多关于垃圾分类不同的国家,其实分类标准也不一样,我们来了解一下,德国将垃圾分成6类,日本是世界上垃圾分类做得最好的国家,瑞士将垃圾分成了10多种,今天我们讨论了很多的问题,也达成了一些共识。好,那么作为大棚的一份子保护环境,我们每个人责无旁贷。五一班的小朋友们,五一班的环保小卫士们,让我们就从现在行动起来,垃圾分类从我做起,好不好?好好,今天大家表现都非常棒,好,大家辛苦了,下课。",
-				"说话人1 47:16",
-				"丽丽老师再见。",
-				"",
-			],
+			// foldStatus: false, //0--收起状态   1--展开状态
+
 			fileUrl:
 				"https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/%E8%BD%AC%E5%BD%95%E6%96%87%E7%A8%BF1713172600896.xlsx",
 			audioUrl:
 				"https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/%E8%A7%A3%E5%86%B3%E5%9E%83%E5%9C%BE%E9%97%AE%E9%A2%981713172672090.m4a",
 		};
 	},
+	computed:{
+		contentValue(){
+			return (text)=>{
+				let newText = text;
+				this.aiNameList.forEach(i=>{
+					const regex = new RegExp(`@(${i.name})`,"g");
+					newText = newText.replace(regex,`<span class='atName'>@$1</span>`);
+				})
+				return newText;
+			}
+		},
+	},
 	methods: {
 		// 切换折叠状态
-		changeFoldStatus(newValue) {
-			this.foldStatus = newValue;
-		},
+		// changeFoldStatus(newValue) {
+		// 	this.foldStatus = newValue;
+		// },
 		//切换卡片
-		changeCardStatus(newValue) {
-			this.foldStatus = 1;
-			this.cardStatus = newValue;
-		},
+		// changeCardStatus(newValue) {
+		// 	this.foldStatus = 1;
+		// 	this.cardStatus = newValue;
+		// },
 		addWork() {
 			this.$message.info("添加到工作区");
 		},
@@ -584,6 +206,7 @@ export default {
 .tape {
 	width: 100%;
 	height: 100%;
+	overflow: auto;
 }
 .t-header {
 	width: 100%;
@@ -873,6 +496,7 @@ export default {
 .t_ca_b_u_c_main {
 	display: flex;
 	width: auto;
+	justify-content: flex-end;
 }
 .t_ca_b_u_c_m_right {
 	max-width: calc(100% - 60px);
@@ -889,9 +513,17 @@ export default {
 }
 
 .t_ca_b_u_c_time {
+	white-space: nowrap;
 	font-size: 14px;
 	color: #a8a9ab;
 	margin-top: 10px;
 	text-align: right;
 }
+.t_ca_b_u_c_m_right>>>.atName{
+	background-color: #063a708c;
+	border-radius: 5px;
+	box-sizing: border-box;
+	padding: 2px 5px;
+	color: white;
+}
 </style>

+ 1 - 1
src/components/pages/classroomObservation/components/transcription.vue

@@ -6,7 +6,7 @@
 		</div> -->
 		<div class="t-content">
 			<!-- {{ data.content }} -->
-			<div class="contentCon" v-for="(i, index) in chatList" :key="i + 'a'">
+			<div class="contentCon" v-for="(i, index) in chatList" :key="index">
 				<div class="conTim">{{ i.timer }}</div>
 				<div class="conTxt">
 					{{ i.con }}

+ 22 - 2
src/components/pages/classroomObservation/index.vue

@@ -12,7 +12,7 @@
 		</div> -->
 		<div class="co-header2">
 			<div class="co-h2-left">
-				<span class="co-h2-l-icon"></span>
+				<span class="co-h2-l-icon" @click="$refs.addNewCourseDialogRef.open()"></span>
 				<span class="co-h2-l-hr"></span>
 				<span class="co-h2-l-text">
 					<el-select class="co_h2_l_t_select" v-model="tid" placeholder="请选择" @change="changeTid">
@@ -60,6 +60,7 @@
 				<messageArea :tid="tid" :fileId="fileId" ref="messageAreaRef" @updateFileId="updateFileId"  @updateFileIdid="updateFileIdid"/>
 			</div>
 		</div>
+		<addNewCourseDialog ref="addNewCourseDialogRef" @success="addNewCourse"/>
 	</div>
 </template>
 
@@ -68,10 +69,13 @@
 import chatArea from "./components/chatArea.vue";
 // 信息区域
 import messageArea from "./components/messageArea.vue";
+// 添加课程弹窗
+import addNewCourseDialog from "./components/addNewCourseDialog.vue";
 export default {
 	components: {
 		chatArea,
 		messageArea,
+		addNewCourseDialog
 	},
 	data() {
 		return {
@@ -95,6 +99,19 @@ export default {
 				this.$refs.messageAreaRef.getData();
 			})
 		},
+		addNewCourse(form){
+			console.log("👇")
+			console.log(form)
+			this.optionData.push({
+				label:form.name,
+				value:form.no,
+			})
+			this.tid = form.no;
+			this.$nextTick(()=>{
+				this.$refs.messageAreaRef.getData();
+			})
+
+		},
 		updateFileId(newValue){
 			this.fileId = newValue;
 		},
@@ -164,6 +181,7 @@ export default {
 
 <style scoped>
 .classroomObservation {
+	min-width: 1500px;
 	width: 100%;
 	height: 100%;
 	display: flex;
@@ -252,9 +270,11 @@ export default {
 	width: 20px;
 	height: 20px;
 	position: relative;
-	background: url("../../../assets/icon/classroomObservation/Zkicon.png")
+	background: url("../../../assets/icon/classroomObservation/close.png")
 		no-repeat;
+		transform: rotate(45deg);
 	background-size: 100% 100%;
+	cursor: pointer;
 }
 .co-h2-l-hr {
 	width: 2px;