Jelajahi Sumber

Merge branch 'beta' into alpha

lsc 10 bulan lalu
induk
melakukan
ca1ca54427
28 mengubah file dengan 6828 tambahan dan 2225 penghapusan
  1. 1 1
      dist/index.html
  2. 0 0
      dist/static/css/app.1df1c0d0469f25f586767b0d9856e3d7.css.map
  3. 0 0
      dist/static/css/app.59374363b7971a767a552a85fee7234d.css
  4. 0 0
      dist/static/css/app.59374363b7971a767a552a85fee7234d.css.map
  5. 0 0
      dist/static/js/app.dbff2dddb3599457580f.js
  6. 0 0
      dist/static/js/app.dbff2dddb3599457580f.js.map
  7. 0 0
      dist/static/js/manifest.3ad1d5771e9b13dbdad2.js.map
  8. 9 0
      src/assets/icon/newIcons/Brootper.svg
  9. TEMPAT SAMPAH
      src/assets/icon/newIcons/blueRoot.png
  10. TEMPAT SAMPAH
      src/assets/icon/newIcons/commG.png
  11. TEMPAT SAMPAH
      src/assets/icon/newIcons/fullScreen.png
  12. TEMPAT SAMPAH
      src/assets/icon/newIcons/likeG.png
  13. 756 78
      src/components/classRoomHelper/component/AnnotationCanvas.vue
  14. 1435 1238
      src/components/classRoomHelper/component/countdown.vue
  15. 656 598
      src/components/classRoomHelper/component/languageAssistant.vue
  16. 35 3
      src/components/classRoomHelper/component/levitatedSphere.vue
  17. 723 0
      src/components/classRoomHelper/component/reviewArea.vue
  18. 380 80
      src/components/classRoomHelper/component/searchArea.vue
  19. 272 129
      src/components/classRoomHelper/component/taskArea.vue
  20. 255 12
      src/components/classRoomHelper/index.vue
  21. 1 1
      src/components/components/answerData2.vue
  22. 1 1
      src/components/components/askStatic.vue
  23. 2 2
      src/components/components/askStatic2.vue
  24. 1352 0
      src/components/easy2/commpont/markDialog.vue
  25. 191 64
      src/components/easy2/commpont/markScore.vue
  26. 757 16
      src/components/easy2/studyStudent.vue
  27. 1 1
      src/components/easy3/studyStudent.vue
  28. 1 1
      src/components/studyStudent.vue

+ 1 - 1
dist/index.html

@@ -27,7 +27,7 @@
     html,
     body{
       font-family: '黑体';
-    }</style><link href=./static/css/app.1df1c0d0469f25f586767b0d9856e3d7.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.3ad1d5771e9b13dbdad2.js></script><script type=text/javascript src=./static/js/vendor.b5a78a47ec38c79eb330.js></script><script type=text/javascript src=./static/js/app.1617e88e66fbb63beb2f.js></script></body></html><script>function stopSafari() {
+    }</style><link href=./static/css/app.59374363b7971a767a552a85fee7234d.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.3ad1d5771e9b13dbdad2.js></script><script type=text/javascript src=./static/js/vendor.b5a78a47ec38c79eb330.js></script><script type=text/javascript src=./static/js/app.dbff2dddb3599457580f.js></script></body></html><script>function stopSafari() {
     //阻止safari浏览器双击放大功能
     let lastTouchEnd = 0  //更新手指弹起的时间
     document.documentElement.addEventListener("touchstart", function (event) {

File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/css/app.1df1c0d0469f25f586767b0d9856e3d7.css.map


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/css/app.59374363b7971a767a552a85fee7234d.css


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/css/app.59374363b7971a767a552a85fee7234d.css.map


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/app.dbff2dddb3599457580f.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/app.dbff2dddb3599457580f.js.map


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/manifest.3ad1d5771e9b13dbdad2.js.map


+ 9 - 0
src/assets/icon/newIcons/Brootper.svg

@@ -0,0 +1,9 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M7.25 6.25C7.25 6.66422 6.91422 7 6.5 7C6.08578 7 5.75 6.66422 5.75 6.25C5.75 5.83578 6.08578 5.5 6.5 5.5C6.91422 5.5 7.25 5.83578 7.25 6.25Z" fill="#3681FC"/>
+<path d="M9.5 7C9.91422 7 10.25 6.66422 10.25 6.25C10.25 5.83578 9.91422 5.5 9.5 5.5C9.08578 5.5 8.75 5.83578 8.75 6.25C8.75 6.66422 9.08578 7 9.5 7Z" fill="#3681FC"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M8.5 2.5C8.5 2.22386 8.27614 2 8 2C7.72386 2 7.5 2.22386 7.5 2.5V3H4.5C4.22386 3 4 3.22386 4 3.5V9.5C4 9.77614 4.22386 10 4.5 10H6.5V10.5H3C2.72386 10.5 2.5 10.7239 2.5 11V13.5C2.5 13.7761 2.72386 14 3 14H12.5C12.7761 14 13 13.7761 13 13.5V11C13 10.7239 12.7761 10.5 12.5 10.5H9.5V10H11.5C11.7761 10 12 9.77614 12 9.5V3.5C12 3.22386 11.7761 3 11.5 3H8.5V2.5ZM7 11.5C7.27614 11.5 7.5 11.2761 7.5 11V10H8.5V11C8.5 11.2761 8.72386 11.5 9 11.5H12V13H3.5V11.5H7ZM5 9V4H11V9H5Z" fill="#3681FC"/>
+<path d="M3 4.5C3.27614 4.5 3.5 4.72386 3.5 5V8C3.5 8.27614 3.27614 8.5 3 8.5C2.72386 8.5 2.5 8.27614 2.5 8V5C2.5 4.72386 2.72386 4.5 3 4.5Z" fill="#3681FC"/>
+<path d="M1.5 5.5C1.77614 5.5 2 5.72386 2 6V7C2 7.27614 1.77614 7.5 1.5 7.5C1.22386 7.5 1 7.27614 1 7V6C1 5.72386 1.22386 5.5 1.5 5.5Z" fill="#3681FC"/>
+<path d="M14.5 5.5C14.7761 5.5 15 5.72386 15 6V7C15 7.27614 14.7761 7.5 14.5 7.5C14.2239 7.5 14 7.27614 14 7V6C14 5.72386 14.2239 5.5 14.5 5.5Z" fill="#3681FC"/>
+<path d="M13.5 5C13.5 4.72386 13.2761 4.5 13 4.5C12.7239 4.5 12.5 4.72386 12.5 5V8C12.5 8.27614 12.7239 8.5 13 8.5C13.2761 8.5 13.5 8.27614 13.5 8V5Z" fill="#3681FC"/>
+</svg>

TEMPAT SAMPAH
src/assets/icon/newIcons/blueRoot.png


TEMPAT SAMPAH
src/assets/icon/newIcons/commG.png


TEMPAT SAMPAH
src/assets/icon/newIcons/fullScreen.png


TEMPAT SAMPAH
src/assets/icon/newIcons/likeG.png


+ 756 - 78
src/components/classRoomHelper/component/AnnotationCanvas.vue

@@ -8,11 +8,40 @@
 					@mousedown="handleMouseDown"
 					@mousemove="handleMouseMove"
 					@mouseup="handleMouseUp"
-					@mouseleave="handleMouseUp"
 					@touchstart="handleTouchStart"
 					@touchmove="handleTouchMove"
 					@touchend="handleTouchEnd"
 				></canvas>
+
+				<canvas
+					ref="canvas2"
+					class="drawing-canvas"
+					v-show="showCanvas2"
+					@mousedown="handleMouseDown"
+					@mousemove="handleMouseMove"
+					@mouseup="handleMouseUp"
+					@touchstart="handleTouchStart"
+					@touchmove="handleTouchMove"
+					@touchend="handleTouchEnd"
+				></canvas>
+
+				<!-- <canvas
+					ref="canvas3"
+					class="drawing-canvas screenshotCanvas"
+					v-show="mode==='screenshot'"
+					@mousedown="screenshotMouseDown"
+					@mousemove="screenshotMouseMove"
+					@mouseup="screenshotMouseUp"
+					@touchstart="screenshotTouchStart"
+					@touchmove="screenshotTouchMove"
+					@touchend="screenshotTouchEnd"
+				></canvas>
+
+				<div class="screenshotBox" v-show="showCanvas4">
+					<canvas ref="canvas4" :style="`position:absolute;left:${startX}px;top:${startY}px`">
+
+					</canvas>
+				</div> -->
 			</el-col>
 		</el-row>
 		<el-row
@@ -28,12 +57,21 @@
 						:class="{ active: mode === 'draw' }"
 						>画笔</el-button
 					> -->
-					<el-tooltip class="item" effect="light" content="画笔" placement="top">
+					<el-tooltip
+						class="item"
+						effect="light"
+						content="画笔"
+						placement="top"
+					>
 						<svg
 							width="24"
 							height="24"
 							viewBox="0 0 24 24"
-							:style="mode === 'draw' ? `background-color:${brushColor}` : ''"
+							:style="
+								mode === 'draw' && canDraw
+									? `background-color:${brushColor}`
+									: ''
+							"
 							fill="none"
 							xmlns="http://www.w3.org/2000/svg"
 							@click.stop="setMode('draw')"
@@ -42,13 +80,25 @@
 								fill-rule="evenodd"
 								clip-rule="evenodd"
 								d="M12 6.75C12.2508 6.75 12.4849 6.87533 12.624 7.08397L15.624 11.584C15.7062 11.7072 15.75 11.8519 15.75 12V21C15.75 21.4142 15.4142 21.75 15 21.75C14.5858 21.75 14.25 21.4142 14.25 21V12.75H9.75V21C9.75 21.4142 9.41421 21.75 9 21.75C8.58579 21.75 8.25 21.4142 8.25 21V12C8.25 11.8519 8.29383 11.7072 8.37596 11.584L11.376 7.08397C11.5151 6.87533 11.7492 6.75 12 6.75ZM10.4014 11.25H13.5986L12 8.85208L10.4014 11.25Z"
-								:fill="mode === 'draw' ? brushColor==='#FFFFFF'?'black':'#fff' : '#3681FC'"
+								:fill="
+									mode === 'draw' && canDraw
+										? brushColor === '#FFFFFF'
+											? 'black'
+											: '#fff'
+										: '#3681FC'
+								"
 							/>
 							<path
 								fill-rule="evenodd"
 								clip-rule="evenodd"
 								d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21ZM12 22.5C17.799 22.5 22.5 17.799 22.5 12C22.5 6.20101 17.799 1.5 12 1.5C6.20101 1.5 1.5 6.20101 1.5 12C1.5 17.799 6.20101 22.5 12 22.5Z"
-								:fill="mode === 'draw' ? brushColor==='#FFFFFF'?'black':'#fff' : 'black'"
+								:fill="
+									mode === 'draw' && canDraw
+										? brushColor === '#FFFFFF'
+											? 'black'
+											: '#fff'
+										: 'black'
+								"
 								fill-opacity="0.9"
 							/>
 						</svg>
@@ -57,7 +107,7 @@
 					<el-tooltip
 						class="item"
 						effect="light"
-						content="切换颜色"
+						content="切换颜色与大小"
 						placement="top"
 					>
 						<el-button
@@ -68,8 +118,15 @@
 							"
 						></el-button>
 					</el-tooltip>
-					<div class="brushBtn_colorBox" v-if="openBrushColorBox">
-						<span
+					<div class="brushBtn_colorBox" v-if="openBrushColorBox"  v-click-outside="handleBlur">
+						<div class="bb_cb_drawSize">
+							<div>大小</div>
+							<el-slider v-model="drawSize" :min="1" :max="20"></el-slider>
+							<div>颜色</div>
+						</div>
+						<div class="bb_cb_drawColor">
+							
+							<span
 							v-for="(item, index) in colorList"
 							:key="index"
 							:style="`background-color: ${item};${
@@ -77,24 +134,217 @@
 							}`"
 							@click="setColor(item)"
 						></span>
+						</div>
+						
 					</div>
 				</div>
-
-				<div>
-					<el-slider
-						v-model="brushSize"
-						:min="1"
-						:max="20"
-						style="width: 100px"
-					></el-slider>
-				</div>
-
 				<!-- <div>
 					<el-color-picker
 						v-model="brushColor"
 						@active-change="setColor"
 					></el-color-picker>
 				</div> -->
+<!-- 
+				<div>
+					<el-slider v-model="drawSize" :min="1" :max="20" style="width: 100px;"></el-slider>
+				</div> -->
+
+				<div class="shape">
+					<div
+						:class="[
+							['line', 'circle', 'arrow', 'rect'].includes(shape) && canShape
+								? 'shapeActive'
+								: '',
+						]"
+						@click.stop="setShape('open')"
+					>
+						<svg
+							v-if="shape === 'line'"
+							t="1723428738446"
+							class="icon"
+							viewBox="0 0 1024 1024"
+							version="1.1"
+							xmlns="http://www.w3.org/2000/svg"
+							p-id="5383"
+							width="200"
+							height="200"
+							fill="black"
+						>
+							<path
+								d="M195.584 866.816l-38.4-38.4c-12.288-12.288-12.288-31.744 0-43.52L784.384 157.184c12.288-12.288 31.744-12.288 43.52 0l38.4 38.4c12.288 12.288 12.288 31.744 0 43.52L239.104 866.816c-11.776 12.288-31.232 12.288-43.52 0z"
+								p-id="5384"
+							></path>
+						</svg>
+						<svg
+							v-else-if="shape === 'circle'"
+							t="1723428969048"
+							class="icon"
+							viewBox="0 0 1024 1024"
+							version="1.1"
+							xmlns="http://www.w3.org/2000/svg"
+							p-id="6395"
+							width="200"
+							height="200"
+							fill="black"
+						>
+							<path
+								d="M512 928C282.624 928 96 741.376 96 512S282.624 96 512 96s416 186.624 416 416-186.624 416-416 416z m0-768C317.92 160 160 317.92 160 512s157.92 352 352 352 352-157.92 352-352S706.08 160 512 160z"
+								p-id="6396"
+							></path>
+						</svg>
+						<svg
+							v-else-if="shape === 'arrow'"
+							t="1723429061277"
+							class="icon"
+							viewBox="0 0 1024 1024"
+							version="1.1"
+							xmlns="http://www.w3.org/2000/svg"
+							p-id="7359"
+							width="200"
+							height="200"
+						>
+							<path
+								d="M708.864 343.872l4.48 3.84 146.112 146.176a25.6 25.6 0 0 1 0 36.224l-146.112 146.112a40 40 0 0 1-60.416-52.032l3.84-4.48 67.584-67.712H168a40 40 0 1 1 0-80h556.48l-67.712-67.648a40 40 0 0 1-3.84-52.096l3.84-4.48a40 40 0 0 1 52.096-3.84z"
+								p-id="7360"
+							></path>
+						</svg>
+						<svg
+							v-else
+							t="1723428698910"
+							class="icon"
+							viewBox="0 0 1024 1024"
+							version="1.1"
+							xmlns="http://www.w3.org/2000/svg"
+							p-id="4240"
+							width="200"
+							height="200"
+							fill="black"
+						>
+							<path
+								d="M864 896H160a32 32 0 0 1-32-32V160a32 32 0 0 1 32-32h704a32 32 0 0 1 32 32v704a32 32 0 0 1-32 32zM192 832h640V192H192v640z"
+								p-id="4241"
+							></path>
+						</svg>
+					</div>
+					<el-tooltip
+						class="item"
+						effect="light"
+						content="切换形状"
+						placement="top"
+					>
+						<el-button
+							class="selectBox"
+							@click.stop="changeOpenShape(!openShapeBox)"
+							:icon="openShapeBox ? 'el-icon-arrow-down' : 'el-icon-arrow-up'"
+						></el-button>
+					</el-tooltip>
+					<div class="shapeBox" v-if="openShapeBox" v-click-outside="handleBlur">
+						<div
+							class="shapeItem"
+							:class="{ shapeItemActive: shape === 'line' }"
+							@click.stop="setShape('line')"
+						>
+							<svg
+								t="1723428738446"
+								class="icon"
+								viewBox="0 0 1024 1024"
+								version="1.1"
+								xmlns="http://www.w3.org/2000/svg"
+								p-id="5383"
+								width="200"
+								height="200"
+								fill="black"
+							>
+								<path
+									d="M195.584 866.816l-38.4-38.4c-12.288-12.288-12.288-31.744 0-43.52L784.384 157.184c12.288-12.288 31.744-12.288 43.52 0l38.4 38.4c12.288 12.288 12.288 31.744 0 43.52L239.104 866.816c-11.776 12.288-31.232 12.288-43.52 0z"
+									p-id="5384"
+								></path>
+							</svg>
+							<span>直线</span>
+						</div>
+						<div
+							class="shapeItem"
+							:class="{ shapeItemActive: shape === 'circle' }"
+							@click.stop="setShape('circle')"
+						>
+							<svg
+								t="1723428969048"
+								class="icon"
+								viewBox="0 0 1024 1024"
+								version="1.1"
+								xmlns="http://www.w3.org/2000/svg"
+								p-id="6395"
+								width="200"
+								height="200"
+								fill="black"
+							>
+								<path
+									d="M512 928C282.624 928 96 741.376 96 512S282.624 96 512 96s416 186.624 416 416-186.624 416-416 416z m0-768C317.92 160 160 317.92 160 512s157.92 352 352 352 352-157.92 352-352S706.08 160 512 160z"
+									p-id="6396"
+								></path>
+							</svg>
+							<span>圆形</span>
+						</div>
+						<div
+							class="shapeItem"
+							:class="{ shapeItemActive: shape === 'arrow' }"
+							@click.stop="setShape('arrow')"
+						>
+							<svg
+								t="1723429061277"
+								class="icon"
+								viewBox="0 0 1024 1024"
+								version="1.1"
+								xmlns="http://www.w3.org/2000/svg"
+								p-id="7359"
+								width="200"
+								height="200"
+							>
+								<path
+									d="M708.864 343.872l4.48 3.84 146.112 146.176a25.6 25.6 0 0 1 0 36.224l-146.112 146.112a40 40 0 0 1-60.416-52.032l3.84-4.48 67.584-67.712H168a40 40 0 1 1 0-80h556.48l-67.712-67.648a40 40 0 0 1-3.84-52.096l3.84-4.48a40 40 0 0 1 52.096-3.84z"
+									p-id="7360"
+								></path>
+							</svg>
+							<span>箭头</span>
+						</div>
+						<div
+							class="shapeItem"
+							:class="{ shapeItemActive: shape === 'rect' }"
+							@click.stop="setShape('rect')"
+						>
+							<svg
+								t="1723428698910"
+								class="icon"
+								viewBox="0 0 1024 1024"
+								version="1.1"
+								xmlns="http://www.w3.org/2000/svg"
+								p-id="4240"
+								width="200"
+								height="200"
+								fill="black"
+							>
+								<path
+									d="M864 896H160a32 32 0 0 1-32-32V160a32 32 0 0 1 32-32h704a32 32 0 0 1 32 32v704a32 32 0 0 1-32 32zM192 832h640V192H192v640z"
+									p-id="4241"
+								></path>
+							</svg>
+							<span>矩形</span>
+						</div>
+					</div>
+					<!-- <div class="brushBtn_colorBox" v-if="openShapeBox">
+						<span
+							v-for="(item, index) in colorList"
+							:key="index"
+							:style="`background-color: ${item};${
+								item === '#FFFFFF' ? 'border:solid 2px #E2E1E5' : ''
+							}`"
+							@click="setShapeColor(item)"
+						></span>
+						<div class="bb_cb_drawSize">
+							<el-slider v-model="shapeSize" :min="1" :max="20"></el-slider>
+						</div>
+					</div> -->
+				</div>
 
 				<div class="eraserBtn">
 					<el-tooltip
@@ -108,7 +358,7 @@
 							height="24"
 							viewBox="0 0 24 24"
 							fill="none"
-							:class="{ eraserBtnActive: mode === 'erase' }"
+							:class="{ eraserBtnActive: mode === 'erase' && canDraw }"
 							xmlns="http://www.w3.org/2000/svg"
 							@click.stop="setMode('erase')"
 						>
@@ -116,26 +366,63 @@
 								fill-rule="evenodd"
 								clip-rule="evenodd"
 								d="M13.6464 6.14645C13.8417 5.95118 14.1583 5.95118 14.3536 6.14645L17.8536 9.64645C18.0488 9.84171 18.0488 10.1583 17.8536 10.3536L11.2071 17H17.5V18H10C9.86739 18 9.74021 17.9473 9.64645 17.8536L6.14645 14.3536C5.95118 14.1583 5.95118 13.8417 6.14645 13.6464L13.6464 6.14645ZM10 16.7929L7.20711 14L9 12.2071L11.7929 15L10 16.7929ZM12.5 14.2929L16.7929 10L14 7.20711L9.70711 11.5L12.5 14.2929Z"
-								fill="black"
+								:fill="mode === 'erase' && canDraw ? '#fff' : 'black'"
 								fill-opacity="0.9"
 							/>
 						</svg>
+						
 					</el-tooltip>
-					<!-- <el-button
-						@click="setMode('erase')"
+					<el-tooltip
+						class="item"
+						effect="light"
+						content="选择大小"
+						placement="top"
+					>
+						<el-button
+							class="selectBox"
+							@click.stop="changeOpenEraser(!openEraserBox)"
+							:icon="openEraserBox ? 'el-icon-arrow-down' : 'el-icon-arrow-up'"
+						></el-button>
+					</el-tooltip>
+					<div class="eb_changeSize" v-if="openEraserBox"  v-click-outside="handleBlur">
+						<el-slider v-model="eraserSize" :min="5" :max="30" style="width: 150px;"></el-slider>
+					</div>
+				</div>
+
+				<!-- <el-button
+						@click="screenshot()"
 						icon="el-icon-connection"
-						:class="{ active: mode === 'erase' }"
-						>橡皮擦</el-button
+						:class="{ active: mode === 'screenshot' }"
+						>截图</el-button
 					> -->
-				</div>
-				<!-- <el-button @click="setMode('line')" :class="{ active: mode === 'line' }">直线</el-button>
-        <el-button @click="setMode('rect')" :class="{ active: mode === 'rect' }">矩形</el-button>
-        <el-button @click="setMode('circle')" :class="{ active: mode === 'circle' }">圆圈</el-button> -->
+
+				<!-- <el-button @click="setMode('line')" :class="{ active: mode === 'line' }"
+          >直线</el-button
+        >
+        <el-button @click="setMode('rect')" :class="{ active: mode === 'rect' }"
+          >矩形</el-button
+        >
+        <el-button
+          @click="setMode('circle')"
+          :class="{ active: mode === 'circle' }"
+          >圆圈</el-button
+        >
+
+        <el-button
+          @click="setMode('arrow')"
+          :class="{ active: mode === 'arrow' }"
+          >箭头</el-button
+        > -->
 				<div class="clearScreenBtn">
 					<!-- <el-button @click="clearCanvas" icon="el-icon-refresh-left"
 						>清空画布</el-button
 					> -->
-					<el-tooltip class="item" effect="light" content="清空" placement="top">
+					<el-tooltip
+						class="item"
+						effect="light"
+						content="清空"
+						placement="top"
+					>
 						<svg
 							width="24"
 							height="24"
@@ -258,20 +545,56 @@
 </template>
 
 <script>
-// import html2canvas from "html2canvas";
+import html2canvas from "html2canvas";
 import "element-ui/lib/theme-chalk/index.css";
-
+// 自定义指令,用于处理点击外部区域的事件
+const clickOutside = {
+  bind(el, binding) {
+    // 在元素上绑定一个点击事件监听器
+    el.clickOutsideEvent = function (event) {
+      // 检查点击事件是否发生在元素的内部
+      if (!(el === event.target || el.contains(event.target))) {
+        // 如果点击事件发生在元素的外部,则触发指令绑定的方法,将点击的event数据传过去
+        binding.value(event);
+      }
+    };
+    // 在文档上添加点击事件监听器
+    document.addEventListener("mousedown", el.clickOutsideEvent);
+  },
+  unbind(el) {
+    // 在元素上解除点击事件监听器
+    document.removeEventListener("mousedown", el.clickOutsideEvent);
+  },
+};
 export default {
 	emits: ["close"],
+	directives: {
+    "click-outside": clickOutside, // 注册自定义指令
+  },
 	data() {
 		return {
 			show: false,
 			showTool: false,
 			canvas: null,
+			showCanvas2: false,
+			showCanvas3: false,
+			showCanvas4: false,
+			canvas2: null,
+			ctx2: null,
+			// canvas3: null,
+			// ctx3: null,
+			// canvas4:null,
+			// ctx4:null,
 			ctx: null,
 			brushColor: "#000000",
-			brushSize: 5,
+			shapeColor:"#000000",
+			drawSize: 5,
+			shapeSize:5,
+			eraserSize:5,
 			mode: "draw",
+			canDraw: true,
+			canShape: false,
+			shape: "rect",
 			history: [],
 			historyStep: -1,
 			startX: 0,
@@ -280,6 +603,8 @@ export default {
 			tempShape: null,
 			tempCtx: null,
 			openBrushColorBox: false,
+			openShapeBox: false,
+			openEraserBox:false,
 			colorList: [
 				"#000000",
 				"#E2E1E5",
@@ -333,13 +658,70 @@ export default {
 		},
 		initCanvas() {
 			this.canvas = this.$refs.canvas;
+			this.canvas2 = this.$refs.canvas2;
+			// this.canvas3 = this.$refs.canvas3;
+			// this.canvas4 = this.$refs.canvas4;
+
 			this.ctx = this.canvas.getContext("2d");
+			this.ctx2 = this.canvas2.getContext("2d");
+			// this.ctx3 = this.canvas3.getContext("2d");
+			// this.ctx4 = this.canvas4.getContext("2d");
+
 			this.canvas.width = window.innerWidth;
 			this.canvas.height = window.innerHeight;
+
+			this.canvas2.width = window.innerWidth;
+			this.canvas2.height = window.innerHeight;
+
+			// this.canvas3.width = window.innerWidth;
+			// this.canvas3.height = window.innerHeight;
+
+			// this.canvas4.width = window.innerWidth;
+			// this.canvas4.height = window.innerHeight;
 			this.saveState();
 		},
-		setMode(mode) {
+		setMode(mode,type=true) {
+			this.openBrushColorBox = false;
+			this.openShapeBox = false;
+			this.openEraserBox = false;
+			if (this.mode == mode && this.canDraw && type) return (this.canDraw = false);
+			this.canDraw = true;
 			this.mode = mode;
+			this.canShape = false;
+			
+			// this.mode = mode;
+			// this.openShapeBox = false;
+			// if(this.mode==="screenshot"){
+			// 	this.ctx3.fillStyle = '#00000044';
+			// 	this.ctx3.fillRect(0, 0, this.canvas3.width, this.canvas3.height);
+			// }
+		},
+		setShape(shape) {
+			this.openBrushColorBox = false;
+			this.openShapeBox = false;
+			this.openEraserBox = false;
+			if (this.shape == shape && this.canShape) return (this.canShape = false);
+			if (shape === "open") {
+				if (this.canShape) this.canShape = false;
+				else this.canShape = true;
+				return (this.canDraw = false);
+			}
+
+			
+			this.canShape = true;
+			this.shape = shape;
+			this.canDraw = false;
+			
+		},
+		setShapeColor(newColor){
+			this.shapeColor = newColor;
+			this.openShapeColorBox = false;
+		},
+		changeOpenShape(newValue) {
+			this.openShapeBox = newValue;
+		},
+		changeOpenEraser(newValue){
+			this.openEraserBox = newValue
 		},
 		clearCanvas() {
 			this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
@@ -403,11 +785,16 @@ export default {
 				this.ctx.drawImage(img, 0, 0);
 			};
 		},
+		handleBlur(){
+			this.openEraserBox = false;
+			this.openShapeBox = false;
+			this.openBrushColorBox = false;
+		},
 		handleMouseDown(event) {
-			if (this.mode === "erase" || this.mode === "draw") {
+			if (["erase", "draw"].includes(this.mode) && this.canDraw) {
 				this.ctx.strokeStyle =
 					this.mode === "erase" ? "white" : this.brushColor;
-				this.ctx.lineWidth = this.brushSize;
+				this.ctx.lineWidth = this.mode=='draw'?this.drawSize:this.eraserSize;
 				this.ctx.lineCap = "round";
 				this.ctx.lineJoin = "round";
 				this.isDrawing = true;
@@ -416,68 +803,90 @@ export default {
 				this.startX = event.clientX - rect.left;
 				this.startY = event.clientY - rect.top;
 				this.ctx.moveTo(this.startX, this.startY);
-			} else if (["line", "rect", "circle"].includes(this.mode)) {
-				this.tempShape = document.createElement("canvas");
-				this.tempShape.width = this.canvas.width;
-				this.tempShape.height = this.canvas.height;
-				this.tempCtx = this.tempShape.getContext("2d");
-				this.tempCtx.strokeStyle = this.brushColor;
-				this.tempCtx.lineWidth = this.brushSize;
-				this.tempCtx.fillStyle = this.brushColor;
+			} else if (
+				["line", "rect", "circle", "arrow"].includes(this.shape) &&
+				this.canShape
+			) {
+				this.showCanvas2 = true;
+				// this.ctx2.strokeStyle = this.brushColor;
+				this.ctx2.strokeStyle = "#000000";
+
+				// this.ctx2.lineWidth = this.drawSize;
+				this.ctx2.lineWidth = 5;
+
+				// this.ctx2.fillStyle = this.brushColor;
+				this.ctx2.fillStyle = "#000000";
 				this.isDrawing = true;
-				const rect = this.canvas.getBoundingClientRect();
+				const rect = this.canvas2.getBoundingClientRect();
 				this.startX = event.clientX - rect.left;
 				this.startY = event.clientY - rect.top;
 			}
 		},
 		handleMouseMove(event) {
 			if (!this.isDrawing) return;
+
 			const rect = this.canvas.getBoundingClientRect();
 			const x = event.clientX - rect.left;
 			const y = event.clientY - rect.top;
-			// this.drawPreviewSize(x,y)
 
-			if (this.mode === "draw") {
+			if (this.mode === "draw" && this.canDraw) {
 				this.ctx.lineTo(x, y);
 				this.ctx.stroke();
-			} else if (this.mode === "erase") {
+			} else if (this.mode === "erase" && this.canDraw) {
 				this.ctx.beginPath();
 				this.ctx.clearRect(
-					x - this.brushSize / 2,
-					y - this.brushSize / 2,
-					this.brushSize * 3,
-					this.brushSize * 3
+					x - this.eraserSize / 2,
+					y - this.eraserSize / 2,
+					this.eraserSize * 3,
+					this.eraserSize * 3
 				);
-			} else if (this.tempShape) {
-				this.tempCtx.clearRect(
-					0,
-					0,
-					this.tempShape.width,
-					this.tempShape.height
-				);
-				if (this.mode === "line") {
-					this.tempCtx.beginPath();
-					this.tempCtx.moveTo(this.startX, this.startY);
-					this.tempCtx.lineTo(x, y);
-					this.tempCtx.stroke();
-				} else if (this.mode === "rect") {
-					this.tempCtx.strokeRect(
+			} else if (this.showCanvas2) {
+				// 清除临时画布上的内容
+				this.ctx2.clearRect(0, 0, this.canvas2.width, this.canvas2.height);
+
+				if (this.shape === "line" && this.canShape) {
+					this.ctx2.beginPath();
+					this.ctx2.moveTo(this.startX, this.startY);
+					this.ctx2.lineTo(x, y);
+					this.ctx2.stroke();
+				} else if (this.shape === "rect" && this.canShape) {
+					this.ctx2.strokeRect(
 						this.startX,
 						this.startY,
 						x - this.startX,
 						y - this.startY
 					);
-				} else if (this.mode === "circle") {
+				} else if (this.shape === "circle" && this.canShape) {
 					const radius = Math.sqrt(
 						Math.pow(x - this.startX, 2) + Math.pow(y - this.startY, 2)
 					);
-					this.tempCtx.beginPath();
-					this.tempCtx.arc(this.startX, this.startY, radius, 0, Math.PI * 2);
-					this.tempCtx.stroke();
+					this.ctx2.beginPath();
+					this.ctx2.arc(this.startX, this.startY, radius, 0, Math.PI * 2);
+					this.ctx2.stroke();
+				} else if (this.shape === "arrow" && this.canShape) {
+					// 计算箭头的角度
+					const headlen = 5 * 5; // 箭头的长度
+					const angle = Math.atan2(y - this.startY, x - this.startX);
+
+					// 画箭头的主线
+					this.ctx2.beginPath();
+					this.ctx2.moveTo(this.startX, this.startY);
+					this.ctx2.lineTo(x, y);
+					this.ctx2.stroke();
+
+					// 画箭头的两条边
+					this.ctx2.moveTo(x - 1, y);
+					this.ctx2.lineTo(
+						x - headlen * Math.cos(angle - Math.PI / 6),
+						y - headlen * Math.sin(angle - Math.PI / 6)
+					);
+					this.ctx2.moveTo(x + 1, y);
+					this.ctx2.lineTo(
+						x - headlen * Math.cos(angle + Math.PI / 6),
+						y - headlen * Math.sin(angle + Math.PI / 6)
+					);
+					this.ctx2.stroke();
 				}
-				this.ctx.drawImage(this.tempShape, 0, 0);
-				// this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
-				this.restoreState();
 			}
 		},
 		drawPreviewSize(x, y) {
@@ -502,12 +911,15 @@ export default {
 		},
 		handleMouseUp() {
 			if (!this.isDrawing) return;
+
 			this.isDrawing = false;
 			this.ctx.closePath();
-			if (this.tempShape) {
-				this.ctx.drawImage(this.tempShape, 0, 0);
-				this.tempShape = null;
-				this.tempCtx = null;
+			if (this.showCanvas2) {
+				this.showCanvas2 = false;
+				this.ctx.drawImage(this.canvas2, 0, 0);
+				this.ctx2.clearRect(0, 0, this.canvas2.width, this.canvas2.height);
+				//   // this.tempShape = null;
+				//   // this.tempCtx = null;
 			}
 			this.saveState();
 		},
@@ -534,11 +946,129 @@ export default {
 		setColor(newColor) {
 			this.brushColor = newColor;
 			this.openBrushColorBox = false;
-			this.setMode("draw");
+			this.setMode("draw",false);
 		},
 		changeOpenBrushColorBox(newValue) {
 			this.openBrushColorBox = newValue;
 		},
+		screenshotMouseDown(e) {
+			this.isDrawing = true;
+			this.ctx3.fillStyle = "#00000044";
+			this.startX = e.clientX;
+			this.startY = e.clientY;
+		},
+		screenshotMouseMove(e) {
+			if (!this.isDrawing) return;
+			this.ctx3.clearRect(0, 0, this.canvas3.width, this.canvas3.height);
+			this.ctx3.fillStyle = "#00000044";
+			this.ctx3.fillRect(0, 0, this.canvas3.width, this.canvas3.height);
+
+			const width = e.clientX - this.startX;
+			const height = e.clientY - this.startY;
+
+			this.ctx3.globalCompositeOperation = "destination-out";
+			this.ctx3.clearRect(this.startX, this.startY, width, height);
+			this.ctx3.globalCompositeOperation = "source-over";
+		},
+		screenshotMouseUp(e) {
+			if (!this.isDrawing) return;
+			console.log("👇");
+			console.log(this.startX, this.startY);
+			console.log(e.clientX, e.clientY);
+			console.log("👆");
+			this.isDrawing = false;
+			// 截取指定区域
+			const rect = {
+				x: Math.min(this.startX, e.clientX),
+				y: Math.min(this.startY, e.clientY),
+				width: Math.abs(e.clientX - this.startX),
+				height: Math.abs(e.clientY - this.startY),
+			};
+			console.log(rect);
+			html2canvas(document.body, {
+				x: rect.x,
+				y: rect.y,
+				width: rect.width,
+				height: rect.height,
+				windowWidth: document.body.scrollWidth,
+				windowHeight: document.body.scrollHeight,
+				scale: window.devicePixelRatio,
+			}).then((result) => {
+				this.mode = "";
+				this.showCanvas4 = true;
+				this.canvas4.width = rect.width;
+				this.canvas4.height = rect.height;
+				this.ctx4.drawImage(result, 0, 0, rect.width, rect.height);
+				// 移除覆盖的 canvas
+			});
+		},
+		screenshotTouchStart(e) {
+			e.preventDefault();
+			const touch = e.touches[0];
+			this.screenshotMouseDown({
+				clientX: touch.clientX,
+				clientY: touch.clientY,
+			});
+		},
+		screenshotTouchMove(e) {
+			e.preventDefault();
+			const touch = e.touches[0];
+			this.screenshotMouseMove({
+				clientX: touch.clientX,
+				clientY: touch.clientY,
+			});
+		},
+		screenshotTouchEnd(e) {
+			e.preventDefault();
+			this.screenshotMouseUp();
+		},
+		screenshot(){
+				// return console.log(document.clientWidth,document.clientHeight)
+				html2canvas(document.body, {
+					x: 0,
+					y: 0,
+					width: document.documentElement.clientWidth,
+					height: document.documentElement.clientHeight,
+					useCORS:true,
+					windowWidth: 0,
+					windowHeight: 0,
+					scale: window.devicePixelRatio,
+				}).then((result) => {
+					console.log(result);
+					// this.mode = "";
+					// this.showCanvas4 = true;
+					// this.canvas4.width = result.width/2;
+					// this.canvas4.height = result.height/2;
+					// this.ctx4.drawImage(
+					// 	result,
+					// 	0,
+					// 	0,
+					// 	document.clientWidth,
+					// 	document.clientHeight
+					// );
+					// return
+					var imgURL = result.toDataURL({
+						format: "image/png",
+						quality: 1,
+						width: result.width,
+						height: result.height,
+					});
+					var dlLink = document.createElement("a");
+					dlLink.download = "fileName";
+					dlLink.href = imgURL;
+					dlLink.dataset.downloadurl = [
+						"png",
+						dlLink.download,
+						dlLink.href,
+					].join(":");
+					document.body.appendChild(dlLink);
+					dlLink.click();
+					document.body.removeChild(dlLink);
+					// 移除覆盖的 canvas
+				});
+				// this.ctx3.fillStyle = '#00000044';
+				// this.ctx3.fillRect(0, 0, this.canvas3.width, this.canvas3.height);
+		}
 	},
 	watch: {
 		brushColor(newColor) {
@@ -561,6 +1091,20 @@ export default {
 	background-color: rgba(255, 255, 255, 0);
 }
 
+.screenshotBox {
+	position: fixed;
+	top: 0;
+	left: 0;
+	width: 100vw;
+	height: 100vh;
+	background-color: #00000044;
+	z-index: 12;
+}
+
+.screenshotCanvas {
+	z-index: 11;
+}
+
 .toolbar {
 	position: fixed;
 	bottom: 0;
@@ -576,6 +1120,7 @@ export default {
 	box-shadow: 0px 6px 30px 5px #0000000d;
 	transform: translateX(-50%);
 	max-width: 100vw;
+	z-index: 10;
 }
 
 .toolbar-container {
@@ -616,6 +1161,10 @@ export default {
 	cursor: pointer;
 }
 
+.eraserBtn{
+	position: relative;
+}
+
 .eraserBtn > svg {
 	width: 40px;
 	height: 40px;
@@ -648,8 +1197,18 @@ export default {
 	justify-content: center;
 	flex-wrap: wrap;
 }
+.bb_cb_drawColor{
+	width: 250px;
+	height: auto;
+	background-color: #ffffff;
+	padding: 4px, 8px, 4px, 8px;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	flex-wrap: wrap;
+}
 
-.brushBtn_colorBox > span {
+.bb_cb_drawColor > span {
 	width: 25px;
 	height: 25px;
 	border-radius: 100%;
@@ -667,4 +1226,123 @@ export default {
 	padding: 5px !important;
 	margin-left: 5px;
 }
+
+.shape {
+	position: relative;
+}
+
+.shape > div {
+	width: 40px;
+	height: 40px;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	cursor: pointer;
+	border-radius: 8px;
+}
+
+.shape > div > svg {
+	width: 80%;
+	height: 80%;
+}
+.shapeActive {
+	background-color: #3681fc;
+}
+
+.shapeActive > svg {
+	fill: #fff;
+}
+
+.shapeBox {
+	position: absolute;
+	left: 0;
+	bottom: calc(100% + 10px);
+	width: auto !important;
+	height: auto !important;
+	background-color: #fff;
+	box-shadow: 0px 4px 10px 0px #1d398314;
+	box-shadow: 1px 1px 20px 4px #1d39830d;
+	border-radius: 6px;
+	padding: 8px;
+	cursor: default;
+	display: flex;
+	flex-direction: column;
+	justify-content: center;
+	align-items: center;
+}
+
+.shapeItem {
+	width: auto;
+	height: auto;
+	padding: 5px;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	cursor: pointer;
+	border-radius: 8px;
+	color: black;
+	margin-bottom: 5px;
+}
+
+.shapeItem > span {
+	width: 2em;
+}
+
+.shapeItem > svg {
+	width: 25px;
+	height: 25px;
+	margin-right: 10px;
+}
+
+.shapeItem:hover {
+	background-color: #e6e6e6;
+	color: black;
+}
+
+.shapeItemActive {
+	background-color: #3681fc !important;
+	color: #fff !important;
+	fill: #fff !important;
+}
+
+.shapeItemActive > svg {
+	fill: #fff !important;
+}
+
+.eraserBtnActive {
+	background-color: #3681fc !important;
+	color: #fff !important;
+	fill: #fff !important;
+	border-radius: 8px;
+}
+
+.bb_cb_drawSize {
+	width: 100%;
+	box-sizing: border-box;
+	padding: 5px 20px;
+	color: black;
+}
+
+.eb_changeSize{
+	position: absolute;
+	left: 0;
+	bottom: calc(100% + 10px);
+	width: auto !important;
+	height: auto !important;
+	background-color: #fff;
+	box-shadow: 0px 4px 10px 0px #1d398314;
+	box-shadow: 1px 1px 20px 4px #1d39830d;
+	border-radius: 6px;
+	padding: 8px 15px 8px 15px;
+	cursor: default;
+	display: flex;
+	flex-direction: column;
+	justify-content: center;
+	align-items: center;
+}
+
+.selectBox{
+	border: none;
+	background-color: none;
+}
 </style>

File diff ditekan karena terlalu besar
+ 1435 - 1238
src/components/classRoomHelper/component/countdown.vue


File diff ditekan karena terlalu besar
+ 656 - 598
src/components/classRoomHelper/component/languageAssistant.vue


+ 35 - 3
src/components/classRoomHelper/component/levitatedSphere.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="levitatedSphere" v-show="show">
-    <div :class="['ls_hello']" v-show="showIndex == 0">
+    <div :class="['ls_hello']" v-show="showIndex == 0" @click="stopOne()" @dblclick="stopTwo()">
       <el-image
         style="width: 110%; height: 110%"
         v-show="aiStatus == 1"
@@ -62,8 +62,8 @@ export default {
   data() {
     return {
       show: false,
-      showIndex: 0, //0 :在说话 1 : 接收 2:待命
-      aiStatus: 0,
+      showIndex: 0,
+      aiStatus: 0, //0 :在说话 1 : 接收 2:待命
       aiText: "您好,我是小可,有什么可以帮助您的?",
       userText: "",
       showTextIndex: 0, //0:ai,1:用户, 2:组织语言  3: 无
@@ -85,6 +85,28 @@ export default {
     }
   },
   methods: {
+		stopTwo(){
+			this.show = false;
+      this.showTextIndex = 3;
+      this.aiStatus = 2;
+      this.aiText = "";
+      this.userText = "";
+      this.stopRecord();
+		},
+		stopOne(){
+			if(this.source){
+				this.source.close();
+				this.source = null;
+			}
+			if (this.talkLoading) {
+        this.stopTalk();
+      }
+			this.showIndex = 0;
+			this.showTextIndex = 0;
+			this.aiText = "您好,我是小可,有什么可以帮助您的?";
+			this.aiStatus = 0;
+			this.chatLoading = false;
+		},
     recordStart(_text) {
       var OpenCC = require("opencc-js");
       let converter = OpenCC.Converter({
@@ -101,12 +123,18 @@ export default {
         "languageOptions"
       ).selectedIndex = 2; //普通话
       iiframe.contentWindow.testdoContinuousPronunciationAssessment();
+			this.talkTextList.push("我在");
+			this.talkText();
+			// return;
       // this.$message.success("已开启语音助手,请说“可可同学”来唤醒");
       this.$parent.changeRecordType(1);
       this.isOpen = true;
       this.aiText = "您好,我是小可,有什么可以帮助您的?";
       this.aiStatus = 0;
       this.showIndex = 0;
+			this.showTextIndex = 0;
+			this.chatLoading = false;
+			this.talkLoading == false;
       this.show = true;
       console.log("已唤醒");
       iiframe.contentWindow.onRecognizedResult = e => {
@@ -215,6 +243,7 @@ export default {
                       converter("发送成功")
                     ) {
                       this.userText = "";
+											this.showIndex = 0;
                     } else {
                       // this.$message.warning(res.data.FunctionResponse.result);
                       console.log(res.data.FunctionResponse.result);
@@ -371,6 +400,8 @@ export default {
       // let _talkIndex = 0;
       // const md = new MarkdownIt();
       this.source.onmessage = _e => {
+				this.showIndex = 0;
+				this.aiStatus = 0
         let _eData = JSON.parse(_e.data);
         if (_eData.content.replace("'", "").replace("'", "") == "[DONE]") {
           let _result = [];
@@ -480,6 +511,7 @@ export default {
   position: absolute;
   top: 0;
   right: 0;
+	cursor: pointer;
   animation: smallToBig 1s both;
 }
 

+ 723 - 0
src/components/classRoomHelper/component/reviewArea.vue

@@ -0,0 +1,723 @@
+<template>
+  <div class="reviewArea" v-loading="loading">
+		<div class="pzTop2">
+ 
+        <div class="checkbox">
+
+					<div class="cb-tabList">
+						<div :class="[commentTagShow==0?'cb-tabItem':'']" @click="commentTagShow=0">评论</div>
+
+						<div :class="[commentTagShow==2?'cb-tabItem':'']" @click="commentTagShow=2">总评</div>
+					</div>
+          <el-select v-model="pzStype" @change="selectPz" class="selectBox" v-show="commentTagShow == 0">
+            <el-option label="时间降序" :value="1"></el-option>
+            <el-option label="时间升序" :value="2"></el-option>
+            <el-option label="我的评课" :value="3"></el-option>
+          </el-select>
+        </div>
+      </div>
+			<div :class="pzList && pzList.length ? 'pzBox' : 'noPzBox'" v-if="commentTagShow==0">
+        <div class="pzListBox" v-if="pzList && pzList.length">
+          <div class="pzList" v-for="(pz, pzIndex) in pzList" :key="pzIndex">
+            <div class="pzNavTop">
+              <div>评</div>
+              <div>
+                {{
+                  pz.username && pz.username.length > 5
+                    ? pz.username.substring(0, 5) + "..."
+                    : pz.username
+                }}的评论
+              </div>
+              <div
+                class="pzDelete"
+                v-if="pz.userid == userid"
+                @click="deletePz(pz.id)"
+              >
+                删除
+              </div>
+            </div>
+            <div
+              @click="checkImg(getImgList(pz.content))"
+              class="pzContent cont"
+              v-html="pz.content"
+              v-if="pz.type == '1'"
+            ></div>
+            <div class="pzContent" v-if="pz.type == '2'">
+              <audio :src="pz.content" controls="controls" ref="audio">
+                Your browser does not support the audio element.
+              </audio>
+            </div>
+            <div class="pzContent" v-if="pz.type == '3'">
+              <img
+                :src="pz.content"
+                style="width: 90%; margin: 0 auto; display: block"
+                @click="previewImg(pz.content)"
+              />
+            </div>
+            <div class="timeAndReply">
+              <div class="time">
+                {{ pz.time }}
+              </div>
+              <div @click="setReplyIndex(pz.id, pzIndex)">回复</div>
+            </div>
+
+            <div v-if="pz.hfList && pz.hfList.length > 0" class="hfBox">
+              <div
+                v-for="(h, hIndex) in pz.hfList"
+                :key="hIndex"
+                class="hfItem"
+              >
+                <div class="whoReplyWho">
+                  <div class="hfName">{{ h.username }}</div>
+                  <div class="hfImg">
+                    <img src="../../../assets/icon/newIcons/right.png" alt="" />
+                  </div>
+                  <div class="hfName">{{ pz.username }}</div>
+                </div>
+                <div class="hfContent" v-html="h.content"></div>
+                <div class="hfBottom">
+                  <div class="hfTime">{{ h.time }}</div>
+                  <div
+                    class="deleteHfItem"
+                    @click="deleteReply(h.id)"
+                    v-if="userid == h.userid"
+                  >
+                    <img src="../../../assets/icon/newIcons/delete.png" alt="" />
+                  </div>
+                </div>
+              </div>
+            </div>
+
+            <!-- <div class="replyBox" v-if="replyIndex[pzIndex] && replyIndex[pzIndex] == true">
+              <div class="replyInput">
+                <el-input v-model="reply[pzIndex]"></el-input>
+              </div>
+              <el-button @click="addHf(pz.id, pzIndex)">回复</el-button>
+            </div> -->
+          </div>
+        </div>
+        <div class="noPz" v-else>
+          <img src="../../../assets/icon/noPz.png" alt="" />
+        </div>
+        <div class="addPzButton">
+          <div class="addPz" @click="(addPzDialog = true), (pzType = 1)">
+            添加评论
+          </div>
+          <!-- <div class="img1">
+            <div @click="(addPzDialog = true), (pzType = 2)">
+              <img src="../assets/audio.png" /><span>音频</span>
+            </div>
+          </div> -->
+        </div>
+      </div>
+			<div class="scoreList" v-if="commentTagShow==1">
+				<scoreItem v-for="item in scoreList.datalist" @refresh="getScoreList" :data="item" :isScore="scoreList.isScoreList.filter(i=>(i.userid==item.userid && i.courseid == item.courseId))" :key="item.courseId"/>
+			</div>
+			<div class="scoreList" v-if="commentTagShow==2" style="position: relative">
+        <scoreZong :courseid="id" :userid="userid" @insertMemorandum="insertMemorandum"></scoreZong>
+			</div>
+			<div v-if="addPzDialog == true" class="addDialogCss" v-el-drag-dialog>
+      <div class="pzTop">
+        <div class="teacherPz">
+          <div class="teacherPzImg">
+            <img src="../../../assets/icon/teacherPz.png" alt="" />
+          </div>
+          <div style="margin-left: 10px; height: 25px">教师评论</div>
+        </div>
+        <div @click="addPzDialog = false">
+          <img src="../../../assets/close1.png" class="pzClose" alt="" />
+        </div>
+      </div>
+      <div class="addPzBox">
+        <div class="addPzCheck">
+          <span :class="{ isChooseActive: pzType == 1 }" @click="pzType = 1"
+            >文本</span
+          >
+          <!-- <span :class="{isChooseActive:pzType==3}" @click="pzType = 3">图片</span> -->
+          <span :class="{ isChooseActive: pzType == 2 }" @click="pzType = 2"
+            >音频</span
+          >
+        </div>
+        <div style="height: calc(100% - 95px)">
+          <!-- <textarea class="binfo_input pzConText" cols placeholder="请填写项目课程关键问题...." v-model="pzConText"
+            v-if="pzType == 1"></textarea> -->
+          <editor-bar
+            class="binfo_input pzConText"
+            style="width: 100% !important"
+            placeholder="请输入任务描述"
+            v-model="pzConText"
+            @change="change"
+            v-if="pzType == 1"
+          ></editor-bar>
+          <Audio @addPz="addPz" class="pzAudioClass" v-if="pzType == 2"></Audio>
+          <!-- <div class="pzAudioClass" v-if="pzType == 3">
+            <div @click="addImg($event)">
+              <el-button type="primary">上传图片</el-button>
+              <input type="file" accept="image/png, image/gif, image/jpeg" style="display: none"
+                @change="beforeUpload1($event, 4)" />
+            </div>
+          </div> -->
+        </div>
+        <div class="addTextCss" @click="addPz('1')" v-if="pzType == 1">
+          确定
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import scoreItem from '../../scoreList/scoreItem.vue'
+import scoreZong from '../../scoreZong/index.vue'
+import EditorBar from "../../tools/wangEnduit.vue";
+import Audio from "../../components/audio.vue";
+export default {
+	components:{
+		scoreItem,
+		scoreZong,
+		EditorBar,
+		Audio
+	},	
+	props:{
+		taskCount:{
+			type:Number,
+			default:0
+		},
+		courseType:{
+			type:Number,
+			default:0
+		},
+		
+	},
+	watch:{
+		taskCount(){
+			this.selectPz();
+		},
+		courseType(){
+			this.selectPz();
+		}
+	},
+  data() {
+    return {
+      commentTagShow: 0,
+      pzStype: 1,
+      pzList: [],
+			loading:false,
+			pzDialog:false,
+      id: this.$route.query.courseId,
+      userid: this.$route.query.userid,
+			addPzDialog:false,
+			pzType:0,
+			pzConText:"",
+			scoreList:{
+				datalist:[],
+				isScoreList:[]
+			},
+    };
+  },
+  methods: {
+		insertMemorandum(_html) {
+      //保存行为操作
+      //variable
+      //btn
+      let params = [
+        {
+          uid: this.userid,
+          courseId: this.courseId+(this.tcid2?this.tcid2:""),
+          content: _html
+        }
+      ];
+
+      this.ajax
+        .post(
+          this.$store.state.api + "insert_systemOperation_countdownBehavior",
+          params
+        )
+        .then(res => {
+          if (res.data == 1) {
+            console.log("保存操作成功");
+          } else {
+            console.log("保存操作失败");
+          }
+        })
+        .catch(e => {
+          console.log("保存操作失败");
+          console.log(e);
+        });
+    },
+    selectPz() {
+      let params = {
+        cid: this.id,
+        s: this.courseType,
+        t: this.taskCount,
+        type: this.pzStype,
+        uid: this.userid
+      };
+      this.ajax
+        .get(this.$store.state.api + "selectPzListType", params)
+        .then(res => {
+          this.pzList = res.data[0];
+          var a = res.data[1];
+          for (var i = 0; i < a.length; i++) {
+            for (var j = 0; j < this.pzList.length; j++) {
+              if (!this.pzList[j].hfList) {
+                this.pzList[j].hfList = [];
+              }
+              if (a[i].pid == this.pzList[j].id) {
+                this.pzList[j].hfList.push(a[i]);
+              }
+            }
+          }
+        })
+        .catch(err => {
+          console.error(err);
+        });
+    },
+		getScoreList(){
+			let params = {
+        cid: this.id,
+      };
+      this.ajax
+        .get(this.$store.state.api + "selectTestCourseByCid", params)
+        .then((res) => {
+					let result = res.data;
+					this.scoreList.datalist = result[0];
+					this.scoreList.isScoreList = result[1];
+        })
+        .catch((err) => {
+          console.error(err);
+        });
+		},
+		addPz(type, content) {
+      if (type == "1" && this.pzConText == "") {
+        this.$message.error("评论不能为空!");
+        return;
+      }
+      let params = [
+        {
+          cid: this.id,
+          uid: this.userid,
+          s: this.courseType,
+          t: this.taskCount,
+          c: type == "1" ? this.pzConText : content,
+          type: type,
+        },
+      ];
+      this.ajax
+        .post(this.$store.state.api + "addPz2", params)
+        .then((res) => {
+          this.$message({
+            message: "添加成功",
+            type: "success",
+          });
+          this.pzConText = "";
+          this.addPzDialog = false;
+          this.selectPz();
+					this.insertMemorandum(`使用<span class="btn">评论</span>功能,添加评论`)
+        })
+        .catch((err) => {
+          this.$message.error("添加失败");
+          console.error(err);
+        });
+				
+    },
+		change(val){
+			console.log(val);
+		}
+  },
+	mounted() {
+		this.selectPz();
+		this.getScoreList();
+	},
+};
+</script>
+
+<style scoped>
+.reviewArea {
+  width: 100%;
+  height: 100%;
+	
+}
+
+.pzTop2 .check {
+  text-align: center;
+  cursor: pointer;
+  box-sizing: border-box;
+  display: flex;
+}
+
+.pzTop2 img {
+  width: 25px;
+  cursor: pointer;
+}
+
+.pzTop2 .checkbox {
+  display: flex;
+  align-items: center;
+  padding: 5px 10px;
+  flex: 0 0 auto;
+  font-weight: bold;
+  border-bottom: 1px solid #eee;
+  justify-content: space-between;
+}
+
+.checkbox>.cb-tabList{
+	height:40px;
+	display:flex;
+	align-items:center;
+}
+
+.cb-tabList>div{
+	margin-right:20px;
+	font-weight:400;
+	cursor:pointer;
+}
+
+.cb-tabList>.cb-tabItem{
+	color:#1684FC;
+	position:relative;
+}
+
+.cb-tabItem::after{
+	content:"";
+	width:100%;
+	height:2px;
+	background:#1684FC;
+	position:absolute;
+	bottom:-5px;
+	left:0
+}
+
+.pzBox,
+.noPzBox {
+  height: calc(100% - 60px);
+  /* background: #ededed; */
+  background: #fff;
+  /* border-radius: 0 0 15px 15px; */
+}
+
+.noPzBox {
+  display: flex;
+  flex-direction: column;
+  flex-wrap: nowrap;
+  justify-content: center;
+  align-items: center;
+}
+
+.pzList {
+  background: #f7f7f7;
+  width: 90%;
+  margin: 0 auto 15px;
+  border-radius: 5px;
+}
+
+.pzNavTop {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  padding: 10px 10px 0 10px;
+  align-items: center;
+}
+
+.pzDelete {
+  cursor: pointer;
+  margin-left: auto;
+  font-size: 14px;
+  color: #afafaf;
+}
+
+.pzNavTop > div:nth-child(1) {
+  background: #3760af;
+  width: 35px;
+  height: 35px;
+  color: #fff;
+  text-align: center;
+  line-height: 35px;
+  border-radius: 50%;
+  font-size: 14px;
+}
+
+.pzNavTop > div:nth-child(2) {
+  font-size: 18px;
+  color: #959595;
+  margin-left: 5px;
+}
+
+.pzContent {
+  padding: 10px;
+  word-break: break-word;
+}
+
+.pzContent audio {
+  width: 100%;
+}
+
+.pzContent audio::-webkit-media-controls-panel {
+  background: #fff;
+}
+
+.pzContent >>> img {
+  max-width: 100%;
+}
+
+.pzListBox {
+  padding-top: 15px;
+  height: calc(100% - 110px);
+  overflow: auto;
+}
+
+.addPzButton {
+  position: relative;
+  margin-top: 3px;
+  width: 100%;
+}
+
+.addPzButton .img1 {
+  position: absolute;
+  top: 50%;
+  right: 25px;
+  transform: translateY(-50%);
+  height: 100%;
+  display: flex;
+  align-items: center;
+}
+
+.addPzButton .img1 div {
+  display: flex;
+}
+
+.addPzButton .img1 div img {
+  width: 28px;
+  margin-left: 10px;
+  cursor: pointer;
+}
+
+.addPzButton .img1 div span {
+  font-size: 14px;
+  margin: 4px 0 0 3px;
+  color: #afafaf;
+}
+
+.addPz {
+  background: #4b79ce;
+  width: 100px;
+  color: #fff;
+  font-size: 12px;
+  height: 30px;
+  margin: 0 auto;
+  text-align: center;
+  line-height: 30px;
+  border-radius: 10px;
+  cursor: pointer;
+}
+
+.addDialogCss {
+  position: fixed;
+  width: 600px;
+  height: 70%;
+  min-height: 450px;
+  box-shadow: 0px 0 8px 0px #555555;
+  border-radius: 15px;
+  z-index: 999;
+  left: 50%;
+  top: 50%;
+  margin: -18% 0 0 -300px;
+}
+
+.teacherPz {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  flex-wrap: nowrap;
+}
+
+.teacherPzImg {
+  width: 30px;
+  height: 30px;
+}
+
+.teacherPzImg > img {
+  width: 100%;
+  height: 100%;
+}
+
+.addPzBox {
+  height: calc(100% - 40px);
+  background: #ededed;
+  border-bottom-left-radius: 15px;
+  border-bottom-right-radius: 15px;
+}
+
+.pzAudioClass {
+  margin: 15px 14px;
+  background: #fff;
+  height: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.pzConText {
+  width: 95%;
+  height: 100%;
+  margin: 10px auto 0;
+  border: none;
+  background: #fff;
+  border-radius: 0px;
+}
+
+.pzConText >>> .text {
+  height: calc(100% - 82px);
+}
+
+.whoReplyWho > .hfImg {
+  width: 12px;
+  height: 12px;
+  margin: 0 5px;
+}
+.whoReplyWho > .hfImg > img {
+  width: 100%;
+  height: 100%;
+}
+.hfContent {
+  padding-top: 10px;
+  box-sizing: border-box;
+  display: -webkit-box;
+  overflow: hidden;
+  white-space: normal !important;
+  text-overflow: ellipsis;
+  word-wrap: break-word;
+  -webkit-box-orient: vertical;
+}
+
+.hfTime {
+  text-align: left;
+  box-sizing: border-box;
+  padding: 10px 0 10px 0px;
+  color: #bfbfbf;
+  font-size: 14px;
+}
+
+.timeAndReply {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  justify-content: space-between;
+  align-items: center;
+  font-size: 14px;
+  box-sizing: border-box;
+  padding: 0 10px 10px 0px;
+}
+.timeAndReply .time {
+  color: #bfbfbf;
+  padding: 0 0 0 10px;
+  box-sizing: border-box;
+}
+.timeAndReply > div:last-child {
+  cursor: pointer;
+  color: #777;
+}
+
+.hfBox {
+  padding: 10px;
+  box-sizing: border-box;
+}
+
+.whoReplyWho {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  align-items: baseline;
+  justify-content: flex-start;
+}
+.hfBottom {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  align-items: center;
+  justify-content: space-between;
+  font-size: 14px;
+}
+.deleteHfItem {
+  cursor: pointer;
+  width: 20px;
+  height: 20px;
+}
+
+.deleteHfItem > img {
+  width: 100%;
+  height: 100%;
+}
+
+.addPzCheck {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  padding: 10px 15px 0;
+}
+
+.addPzCheck span {
+  cursor: pointer;
+  padding-bottom: 5px;
+  font-weight: bold;
+}
+
+.addPzCheck span + span {
+  margin-left: 10px;
+}
+
+.addPzCheck .isChooseActive {
+  color: #3e88f4;
+  border-bottom: 2px solid #2f80f3;
+}
+.pzTop {
+  color: #fff;
+  background: #000;
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  align-items: center;
+  justify-content: space-between;
+  height: 40px;
+  border-radius: 15px 15px 0 0;
+  user-select: none;
+}
+
+.pzTop > div:nth-child(1) {
+  padding-left: 10px;
+}
+
+.pzTop > div:nth-child(2) {
+  width: 15px;
+  height: 15px;
+  padding-right: 10px;
+  cursor: pointer;
+}
+
+.pzTop > div:nth-child(2) > img {
+  width: 100%;
+  height: 100%;
+}
+
+
+.addTextCss {
+  background: #4b79ce;
+  width: 80px;
+  height: 30px;
+  text-align: center;
+  color: #fff;
+  line-height: 30px;
+  border-radius: 10px;
+  margin: 10px auto 0;
+  cursor: pointer;
+}
+
+.scoreList{
+	width:100%;
+	height:100%;
+	box-sizing:border-box;
+	padding:10px 15px;
+	overflow:auto;
+	padding-bottom:80px;
+}
+</style>

+ 380 - 80
src/components/classRoomHelper/component/searchArea.vue

@@ -476,7 +476,7 @@
                 fill="none"
                 @click.stop="changeMegaphone()"
                 xmlns="http://www.w3.org/2000/svg"
-								v-if="!openMegaphone"
+                v-if="!openMegaphone"
               >
                 <path
                   fill-rule="evenodd"
@@ -494,19 +494,39 @@
                 />
               </svg>
 
-							<svg v-else  @click.stop="changeMegaphone()" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path fill-rule="evenodd" clip-rule="evenodd" d="M13.65 2.02537C13.9812 1.7766 14.4513 1.84342 14.7001 2.17461C16.3635 4.38918 17.3495 7.14305 17.3495 10.125C17.3495 13.107 16.3635 15.8609 14.7001 18.0755C14.4513 18.4067 13.9812 18.4735 13.65 18.2247C13.3188 17.9759 13.252 17.5058 13.5007 17.1746C14.9758 15.2109 15.8495 12.7711 15.8495 10.125C15.8495 7.47901 14.9758 5.03921 13.5007 3.07548C13.252 2.74429 13.3188 2.27414 13.65 2.02537Z" fill="#3681FC"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M8.64952 5.77537C8.98072 5.5266 9.45087 5.59342 9.69963 5.92461C10.5784 7.09461 11.0995 8.55006 11.0995 10.125C11.0995 11.7 10.5784 13.1555 9.69963 14.3255C9.45087 14.6567 8.98072 14.7235 8.64952 14.4747C8.31833 14.226 8.25152 13.7558 8.50028 13.4246C9.19069 12.5055 9.5995 11.3641 9.5995 10.125C9.5995 8.88601 9.19069 7.74463 8.50028 6.82548C8.25152 6.49429 8.31833 6.02414 8.64952 5.77537Z" fill="#3681FC"/>
-<path fill-rule="evenodd" clip-rule="evenodd" d="M4.00873 9.07423C4.31294 8.79311 4.78744 8.81182 5.06857 9.11603C5.3975 9.47198 5.59951 9.94984 5.59951 10.4732C5.59951 11.0115 5.38582 11.5015 5.04023 11.8604C4.75291 12.1588 4.27812 12.1677 3.97976 11.8804C3.6814 11.5931 3.67245 11.1183 3.95977 10.8199C4.04703 10.7293 4.09951 10.6082 4.09951 10.4732C4.09951 10.3419 4.04986 10.2238 3.96693 10.1341C3.68581 9.82986 3.70452 9.35535 4.00873 9.07423Z" fill="#3681FC"/>
-</svg>
-
-							
-							</el-tooltip
+              <svg
+                v-else
+                @click.stop="changeMegaphone()"
+                width="20"
+                height="20"
+                viewBox="0 0 20 20"
+                fill="none"
+                xmlns="http://www.w3.org/2000/svg"
+              >
+                <path
+                  fill-rule="evenodd"
+                  clip-rule="evenodd"
+                  d="M13.65 2.02537C13.9812 1.7766 14.4513 1.84342 14.7001 2.17461C16.3635 4.38918 17.3495 7.14305 17.3495 10.125C17.3495 13.107 16.3635 15.8609 14.7001 18.0755C14.4513 18.4067 13.9812 18.4735 13.65 18.2247C13.3188 17.9759 13.252 17.5058 13.5007 17.1746C14.9758 15.2109 15.8495 12.7711 15.8495 10.125C15.8495 7.47901 14.9758 5.03921 13.5007 3.07548C13.252 2.74429 13.3188 2.27414 13.65 2.02537Z"
+                  fill="#3681FC"
+                />
+                <path
+                  fill-rule="evenodd"
+                  clip-rule="evenodd"
+                  d="M8.64952 5.77537C8.98072 5.5266 9.45087 5.59342 9.69963 5.92461C10.5784 7.09461 11.0995 8.55006 11.0995 10.125C11.0995 11.7 10.5784 13.1555 9.69963 14.3255C9.45087 14.6567 8.98072 14.7235 8.64952 14.4747C8.31833 14.226 8.25152 13.7558 8.50028 13.4246C9.19069 12.5055 9.5995 11.3641 9.5995 10.125C9.5995 8.88601 9.19069 7.74463 8.50028 6.82548C8.25152 6.49429 8.31833 6.02414 8.64952 5.77537Z"
+                  fill="#3681FC"
+                />
+                <path
+                  fill-rule="evenodd"
+                  clip-rule="evenodd"
+                  d="M4.00873 9.07423C4.31294 8.79311 4.78744 8.81182 5.06857 9.11603C5.3975 9.47198 5.59951 9.94984 5.59951 10.4732C5.59951 11.0115 5.38582 11.5015 5.04023 11.8604C4.75291 12.1588 4.27812 12.1677 3.97976 11.8804C3.6814 11.5931 3.67245 11.1183 3.95977 10.8199C4.04703 10.7293 4.09951 10.6082 4.09951 10.4732C4.09951 10.3419 4.04986 10.2238 3.96693 10.1341C3.68581 9.82986 3.70452 9.35535 4.00873 9.07423Z"
+                  fill="#3681FC"
+                />
+              </svg> </el-tooltip
           ></span>
         </div>
         <div class="s_b_bat_right">
           <!-- <img :src="require('../../../assets/icon/course/bulb.svg')"> -->
-          <span>
+          <span v-if="!canShowTips">
             <svg
               width="20"
               height="20"
@@ -572,6 +592,166 @@
               />
             </svg>
           </span>
+
+          <span v-else @click.stop="showTipsFn()">
+            <svg
+              width="20"
+              height="21"
+              viewBox="0 0 20 21"
+              fill="none"
+              xmlns="http://www.w3.org/2000/svg"
+            >
+              <circle cx="10" cy="10.0732" r="5" fill="#FFE607" />
+              <path
+                fill-rule="evenodd"
+                clip-rule="evenodd"
+                d="M10 6.32324C7.92893 6.32324 6.25 8.00217 6.25 10.0732C6.25 12.1443 7.92893 13.8232 10 13.8232C12.0711 13.8232 13.75 12.1443 13.75 10.0732C13.75 8.00217 12.0711 6.32324 10 6.32324ZM5 10.0732C5 7.31182 7.23858 5.07324 10 5.07324C12.7614 5.07324 15 7.31182 15 10.0732C15 12.8347 12.7614 15.0732 10 15.0732C7.23858 15.0732 5 12.8347 5 10.0732Z"
+                fill="black"
+                fill-opacity="0.9"
+              />
+              <path
+                fill-rule="evenodd"
+                clip-rule="evenodd"
+                d="M10 1.32324C10.3452 1.32324 10.625 1.60306 10.625 1.94824V3.19824C10.625 3.54342 10.3452 3.82324 10 3.82324C9.65482 3.82324 9.375 3.54342 9.375 3.19824V1.94824C9.375 1.60306 9.65482 1.32324 10 1.32324Z"
+                fill="black"
+                fill-opacity="0.9"
+              />
+              <path
+                fill-rule="evenodd"
+                clip-rule="evenodd"
+                d="M18.75 10.0732C18.75 10.4184 18.4702 10.6982 18.125 10.6982L16.875 10.6982C16.5298 10.6982 16.25 10.4184 16.25 10.0732C16.25 9.72806 16.5298 9.44824 16.875 9.44824L18.125 9.44824C18.4702 9.44824 18.75 9.72806 18.75 10.0732Z"
+                fill="black"
+                fill-opacity="0.9"
+              />
+              <path
+                fill-rule="evenodd"
+                clip-rule="evenodd"
+                d="M3.75 10.0732C3.75 10.4184 3.47018 10.6982 3.125 10.6982L1.875 10.6982C1.52982 10.6982 1.25 10.4184 1.25 10.0732C1.25 9.72806 1.52982 9.44824 1.875 9.44824L3.125 9.44824C3.47018 9.44824 3.75 9.72806 3.75 10.0732Z"
+                fill="black"
+                fill-opacity="0.9"
+              />
+              <path
+                fill-rule="evenodd"
+                clip-rule="evenodd"
+                d="M5.58052 5.65386C5.33644 5.89793 4.94071 5.89793 4.69664 5.65386L3.81275 4.76997C3.56867 4.52589 3.56867 4.13017 3.81275 3.88609C4.05683 3.64201 4.45256 3.64201 4.69664 3.88609L5.58052 4.76997C5.8246 5.01405 5.8246 5.40978 5.58052 5.65386Z"
+                fill="black"
+                fill-opacity="0.9"
+              />
+              <path
+                fill-rule="evenodd"
+                clip-rule="evenodd"
+                d="M14.4194 5.65376C14.1753 5.40968 14.1753 5.01396 14.4194 4.76988L15.3033 3.88599C15.5473 3.64192 15.9431 3.64192 16.1872 3.88599C16.4312 4.13007 16.4312 4.5258 16.1872 4.76988L15.3033 5.65376C15.0592 5.89784 14.6635 5.89784 14.4194 5.65376Z"
+                fill="black"
+                fill-opacity="0.9"
+              />
+              <path
+                fill-rule="evenodd"
+                clip-rule="evenodd"
+                d="M8.75 18.1982C8.75 17.8531 9.02982 17.5732 9.375 17.5732H10.625C10.9702 17.5732 11.25 17.8531 11.25 18.1982C11.25 18.5434 10.9702 18.8232 10.625 18.8232H9.375C9.02982 18.8232 8.75 18.5434 8.75 18.1982Z"
+                fill="black"
+                fill-opacity="0.9"
+              />
+              <path
+                fill-rule="evenodd"
+                clip-rule="evenodd"
+                d="M7.5 16.3232C7.5 15.9781 7.77982 15.6982 8.125 15.6982H11.875C12.2202 15.6982 12.5 15.9781 12.5 16.3232C12.5 16.6684 12.2202 16.9482 11.875 16.9482H8.125C7.77982 16.9482 7.5 16.6684 7.5 16.3232Z"
+                fill="black"
+                fill-opacity="0.9"
+              />
+            </svg>
+          </span>
+
+          <div class="tips" v-if="showTips">
+            <div class="tipsList">
+							<div v-for="(item,index) in showTipsList" :key="index">{{ index+1 }}.{{ item }}</div>
+						</div>
+            <div class="tipsBottom">
+              <div @click.stop="showTips = false">
+                <svg
+                  width="20"
+                  height="20"
+                  viewBox="0 0 20 20"
+                  fill="none"
+                  xmlns="http://www.w3.org/2000/svg"
+                >
+                  <circle cx="10" cy="10" r="5" fill="#FFE607" />
+                  <path
+                    fill-rule="evenodd"
+                    clip-rule="evenodd"
+                    d="M10 6.25C7.92893 6.25 6.25 7.92893 6.25 10C6.25 12.0711 7.92893 13.75 10 13.75C12.0711 13.75 13.75 12.0711 13.75 10C13.75 7.92893 12.0711 6.25 10 6.25ZM5 10C5 7.23858 7.23858 5 10 5C12.7614 5 15 7.23858 15 10C15 12.7614 12.7614 15 10 15C7.23858 15 5 12.7614 5 10Z"
+                    fill="black"
+                    fill-opacity="0.9"
+                  />
+                  <path
+                    fill-rule="evenodd"
+                    clip-rule="evenodd"
+                    d="M10 1.25C10.3452 1.25 10.625 1.52982 10.625 1.875V3.125C10.625 3.47018 10.3452 3.75 10 3.75C9.65482 3.75 9.375 3.47018 9.375 3.125V1.875C9.375 1.52982 9.65482 1.25 10 1.25Z"
+                    fill="black"
+                    fill-opacity="0.9"
+                  />
+                  <path
+                    fill-rule="evenodd"
+                    clip-rule="evenodd"
+                    d="M18.75 10C18.75 10.3452 18.4702 10.625 18.125 10.625L16.875 10.625C16.5298 10.625 16.25 10.3452 16.25 10C16.25 9.65482 16.5298 9.375 16.875 9.375L18.125 9.375C18.4702 9.375 18.75 9.65482 18.75 10Z"
+                    fill="black"
+                    fill-opacity="0.9"
+                  />
+                  <path
+                    fill-rule="evenodd"
+                    clip-rule="evenodd"
+                    d="M3.75 10C3.75 10.3452 3.47018 10.625 3.125 10.625L1.875 10.625C1.52982 10.625 1.25 10.3452 1.25 10C1.25 9.65482 1.52982 9.375 1.875 9.375L3.125 9.375C3.47018 9.375 3.75 9.65482 3.75 10Z"
+                    fill="black"
+                    fill-opacity="0.9"
+                  />
+                  <path
+                    fill-rule="evenodd"
+                    clip-rule="evenodd"
+                    d="M5.58052 5.58061C5.33644 5.82469 4.94071 5.82469 4.69664 5.58061L3.81275 4.69673C3.56867 4.45265 3.56867 4.05692 3.81275 3.81285C4.05683 3.56877 4.45256 3.56877 4.69664 3.81285L5.58052 4.69673C5.8246 4.94081 5.8246 5.33654 5.58052 5.58061Z"
+                    fill="black"
+                    fill-opacity="0.9"
+                  />
+                  <path
+                    fill-rule="evenodd"
+                    clip-rule="evenodd"
+                    d="M14.4194 5.58052C14.1753 5.33644 14.1753 4.94071 14.4194 4.69664L15.3033 3.81275C15.5473 3.56867 15.9431 3.56867 16.1872 3.81275C16.4312 4.05683 16.4312 4.45256 16.1872 4.69664L15.3033 5.58052C15.0592 5.8246 14.6635 5.8246 14.4194 5.58052Z"
+                    fill="black"
+                    fill-opacity="0.9"
+                  />
+                  <path
+                    fill-rule="evenodd"
+                    clip-rule="evenodd"
+                    d="M8.75 18.125C8.75 17.7798 9.02982 17.5 9.375 17.5H10.625C10.9702 17.5 11.25 17.7798 11.25 18.125C11.25 18.4702 10.9702 18.75 10.625 18.75H9.375C9.02982 18.75 8.75 18.4702 8.75 18.125Z"
+                    fill="black"
+                    fill-opacity="0.9"
+                  />
+                  <path
+                    fill-rule="evenodd"
+                    clip-rule="evenodd"
+                    d="M7.5 16.25C7.5 15.9048 7.77982 15.625 8.125 15.625H11.875C12.2202 15.625 12.5 15.9048 12.5 16.25C12.5 16.5952 12.2202 16.875 11.875 16.875H8.125C7.77982 16.875 7.5 16.5952 7.5 16.25Z"
+                    fill="black"
+                    fill-opacity="0.9"
+                  />
+                </svg>
+                <span>课堂小贴士</span>
+                <svg
+                  width="16"
+                  height="16"
+                  viewBox="0 0 16 16"
+                  fill="none"
+                  xmlns="http://www.w3.org/2000/svg"
+                >
+                  <path
+                    fill-rule="evenodd"
+                    clip-rule="evenodd"
+                    d="M12.8737 5.66782C13.0572 5.87421 13.0386 6.19025 12.8322 6.37371L8.33218 10.3737C8.14273 10.5421 7.85726 10.5421 7.66781 10.3737L3.16781 6.37371C2.96142 6.19025 2.94283 5.87421 3.12629 5.66782C3.30975 5.46143 3.62578 5.44284 3.83218 5.6263L7.99999 9.33103L12.1678 5.6263C12.3742 5.44284 12.6902 5.46143 12.8737 5.66782Z"
+                    fill="black"
+                    fill-opacity="0.6"
+                  />
+                </svg>
+              </div>
+            </div>
+          </div>
+          <!-- <div></div> -->
         </div>
       </div>
       <div class="s_b_btnArea">
@@ -903,7 +1083,7 @@
           ></el-input>
 
           <el-input
-            v-loading="loading || chatLoading"
+            v-loading="loading"
             v-if="sendFnType == 1 && isTalk"
             :readonly="isReadonly"
             @focus="setCursorToEnd"
@@ -916,7 +1096,7 @@
           <div
             class="s_b_recorded"
             @click.stop="talk()"
-            v-loading="loading || chatLoading"
+            v-loading="loading"
             v-if="sendFnType && !isTalk"
           >
             <span>点击说话</span>
@@ -954,7 +1134,7 @@
           </el-tooltip>
 
           <el-tooltip
-            v-if="sendFnType == 1 && text == '' && !isTalk && !chatLoading"
+            v-if="sendFnType == 1 && text == '' && !isTalk"
             class="item"
             effect="light"
             content="文字输入"
@@ -986,39 +1166,10 @@
             </span>
           </el-tooltip>
 
-          <el-tooltip
-            v-if="text == '' && !isTalk && !chatLoading"
-            class="item"
-            effect="light"
-            content="语音助手"
-            placement="top"
-          >
-            <span @click.stop="openPhone">
-              <svg
-                width="22"
-                height="22"
-                viewBox="0 0 22 22"
-                fill="none"
-                xmlns="http://www.w3.org/2000/svg"
-              >
-                <path
-                  fill-rule="evenodd"
-                  clip-rule="evenodd"
-                  d="M6.84155 5.76478C6.55991 5.4855 6.10327 5.4855 5.82162 5.76478L4.37921 7.1951C4.23486 7.33825 4.18177 7.5001 4.19436 7.6318C4.3842 9.61702 5.57859 12.5019 7.56276 14.4694C9.61252 16.502 11.9775 17.6669 14.4337 17.8187C14.5856 17.8281 14.7568 17.7668 14.8985 17.6263L16.2213 16.3145C16.5253 16.0132 16.4975 15.5167 16.1619 15.2504L14.8224 14.1878C14.5354 13.9602 14.1218 13.9829 13.8619 14.2405L13.3463 14.7518C12.6962 15.3965 11.6475 15.5966 10.809 15.0406C10.2045 14.6397 9.43899 14.0617 8.70643 13.3353C7.92049 12.556 7.30647 11.7387 6.90026 11.1205C6.41585 10.3834 6.52495 9.47493 7.0107 8.83269L7.88884 7.67165C8.10418 7.38693 8.07563 6.98852 7.82185 6.73686L6.84155 5.76478ZM4.80168 4.7534C5.64663 3.91553 7.01655 3.91554 7.86149 4.7534L8.84178 5.72547C9.60314 6.48045 9.6888 7.67569 9.04277 8.52984L8.16462 9.69089C7.99476 9.91548 7.99659 10.169 8.10873 10.3396C8.47364 10.8949 9.02654 11.63 9.72637 12.3239C10.3781 12.9702 11.0661 13.4905 11.6108 13.8516C11.8045 13.9801 12.0985 13.9664 12.3264 13.7404L12.842 13.2292C13.6215 12.4561 14.8626 12.388 15.7235 13.0709L17.063 14.1335C18.0699 14.9323 18.1531 16.4217 17.2413 17.3259L15.9185 18.6377C15.5191 19.0336 14.9558 19.284 14.344 19.2462C11.4699 19.0687 8.78913 17.7083 6.54282 15.4808C4.31506 13.2717 2.97905 10.0743 2.7584 7.76683C2.69877 7.14323 2.96262 6.57704 3.35928 6.18372L4.80168 4.7534Z"
-                  fill="#3681FC"
-                />
-                <path
-                  fill-rule="evenodd"
-                  clip-rule="evenodd"
-                  d="M11.9697 2.96967C12.2626 2.67678 12.7374 2.67678 13.0303 2.96967L19.0303 8.96967C19.3232 9.26256 19.3232 9.73744 19.0303 10.0303C18.7374 10.3232 18.2626 10.3232 17.9697 10.0303L11.9697 4.03033C11.6768 3.73744 11.6768 3.26256 11.9697 2.96967ZM11.2197 7.78033C10.9268 7.48744 10.9268 7.01256 11.2197 6.71967C11.5126 6.42678 11.9874 6.42678 12.2803 6.71967L15.2803 9.71967C15.5732 10.0126 15.5732 10.4874 15.2803 10.7803C14.9874 11.0732 14.5126 11.0732 14.2197 10.7803L11.2197 7.78033Z"
-                  fill="#3681FC"
-                />
-              </svg>
-            </span>
-          </el-tooltip>
+          
 
           <el-tooltip
-            v-if="isTalk && !chatLoading"
+            v-if="isTalk"
             class="item"
             effect="light"
             content="结束录音"
@@ -1068,7 +1219,7 @@
           </el-tooltip>
 
           <el-tooltip
-            v-if="chatLoading"
+            v-if="chatLoading && sendFnType==0"
             class="item"
             effect="light"
             content="停止发送"
@@ -1089,6 +1240,37 @@
                 />
               </svg>
             </span>
+          </el-tooltip>
+
+					<el-tooltip
+            v-if="text == '' && !isTalk"
+            class="item"
+            effect="light"
+            content="语音助手"
+            placement="top"
+          >
+            <span @click.stop="openPhone">
+              <svg
+                width="22"
+                height="22"
+                viewBox="0 0 22 22"
+                fill="none"
+                xmlns="http://www.w3.org/2000/svg"
+              >
+                <path
+                  fill-rule="evenodd"
+                  clip-rule="evenodd"
+                  d="M6.84155 5.76478C6.55991 5.4855 6.10327 5.4855 5.82162 5.76478L4.37921 7.1951C4.23486 7.33825 4.18177 7.5001 4.19436 7.6318C4.3842 9.61702 5.57859 12.5019 7.56276 14.4694C9.61252 16.502 11.9775 17.6669 14.4337 17.8187C14.5856 17.8281 14.7568 17.7668 14.8985 17.6263L16.2213 16.3145C16.5253 16.0132 16.4975 15.5167 16.1619 15.2504L14.8224 14.1878C14.5354 13.9602 14.1218 13.9829 13.8619 14.2405L13.3463 14.7518C12.6962 15.3965 11.6475 15.5966 10.809 15.0406C10.2045 14.6397 9.43899 14.0617 8.70643 13.3353C7.92049 12.556 7.30647 11.7387 6.90026 11.1205C6.41585 10.3834 6.52495 9.47493 7.0107 8.83269L7.88884 7.67165C8.10418 7.38693 8.07563 6.98852 7.82185 6.73686L6.84155 5.76478ZM4.80168 4.7534C5.64663 3.91553 7.01655 3.91554 7.86149 4.7534L8.84178 5.72547C9.60314 6.48045 9.6888 7.67569 9.04277 8.52984L8.16462 9.69089C7.99476 9.91548 7.99659 10.169 8.10873 10.3396C8.47364 10.8949 9.02654 11.63 9.72637 12.3239C10.3781 12.9702 11.0661 13.4905 11.6108 13.8516C11.8045 13.9801 12.0985 13.9664 12.3264 13.7404L12.842 13.2292C13.6215 12.4561 14.8626 12.388 15.7235 13.0709L17.063 14.1335C18.0699 14.9323 18.1531 16.4217 17.2413 17.3259L15.9185 18.6377C15.5191 19.0336 14.9558 19.284 14.344 19.2462C11.4699 19.0687 8.78913 17.7083 6.54282 15.4808C4.31506 13.2717 2.97905 10.0743 2.7584 7.76683C2.69877 7.14323 2.96262 6.57704 3.35928 6.18372L4.80168 4.7534Z"
+                  fill="#3681FC"
+                />
+                <path
+                  fill-rule="evenodd"
+                  clip-rule="evenodd"
+                  d="M11.9697 2.96967C12.2626 2.67678 12.7374 2.67678 13.0303 2.96967L19.0303 8.96967C19.3232 9.26256 19.3232 9.73744 19.0303 10.0303C18.7374 10.3232 18.2626 10.3232 17.9697 10.0303L11.9697 4.03033C11.6768 3.73744 11.6768 3.26256 11.9697 2.96967ZM11.2197 7.78033C10.9268 7.48744 10.9268 7.01256 11.2197 6.71967C11.5126 6.42678 11.9874 6.42678 12.2803 6.71967L15.2803 9.71967C15.5732 10.0126 15.5732 10.4874 15.2803 10.7803C14.9874 11.0732 14.5126 11.0732 14.2197 10.7803L11.2197 7.78033Z"
+                  fill="#3681FC"
+                />
+              </svg>
+            </span>
           </el-tooltip>
         </div>
         <!-- <div class="voice_or_keyboard">
@@ -1163,10 +1345,21 @@
             placement="top"
           >
             <span style="background-color: #3681FC;">
-              <svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path fill-rule="evenodd" clip-rule="evenodd" d="M10.568 6.01235C8.05196 6.01235 6.01235 8.05196 6.01235 10.568C6.01235 13.0839 8.05196 15.1235 10.568 15.1235C11.8261 15.1235 12.9643 14.6142 13.7892 13.7892C14.6142 12.9643 15.1235 11.8261 15.1235 10.568C15.1235 8.05196 13.0839 6.01235 10.568 6.01235ZM5 10.568C5 7.49286 7.49286 5 10.568 5C13.643 5 16.1359 7.49286 16.1359 10.568C16.1359 11.923 15.6513 13.1657 14.8468 14.1309L16.6421 15.9262C16.8398 16.1239 16.8398 16.4444 16.6421 16.6421C16.4444 16.8398 16.1239 16.8398 15.9262 16.6421L14.1309 14.8468C13.1657 15.6513 11.923 16.1359 10.568 16.1359C7.49286 16.1359 5 13.643 5 10.568Z" fill="white" fill-opacity="0.9"/>
-</svg>
-
+              <svg
+                width="22"
+                height="22"
+                viewBox="0 0 22 22"
+                fill="none"
+                xmlns="http://www.w3.org/2000/svg"
+              >
+                <path
+                  fill-rule="evenodd"
+                  clip-rule="evenodd"
+                  d="M10.568 6.01235C8.05196 6.01235 6.01235 8.05196 6.01235 10.568C6.01235 13.0839 8.05196 15.1235 10.568 15.1235C11.8261 15.1235 12.9643 14.6142 13.7892 13.7892C14.6142 12.9643 15.1235 11.8261 15.1235 10.568C15.1235 8.05196 13.0839 6.01235 10.568 6.01235ZM5 10.568C5 7.49286 7.49286 5 10.568 5C13.643 5 16.1359 7.49286 16.1359 10.568C16.1359 11.923 15.6513 13.1657 14.8468 14.1309L16.6421 15.9262C16.8398 16.1239 16.8398 16.4444 16.6421 16.6421C16.4444 16.8398 16.1239 16.8398 15.9262 16.6421L14.1309 14.8468C13.1657 15.6513 11.923 16.1359 10.568 16.1359C7.49286 16.1359 5 13.643 5 10.568Z"
+                  fill="white"
+                  fill-opacity="0.9"
+                />
+              </svg>
             </span>
           </el-tooltip>
         </div>
@@ -1223,7 +1416,19 @@ export default {
     openMegaphone: {
       type: Boolean,
       default: false
-    }
+    },
+    canShowTips: {
+      type: Boolean,
+      default: false
+    },
+    showTipsLoading: {
+      type: Boolean,
+      default: false
+    },
+    tipsList: {
+      type: Array,
+      default: () => []
+    },
   },
   data() {
     return {
@@ -1298,7 +1503,9 @@ export default {
       roleList2: [],
       sortOption: 0, //切换角色 0我的 1 社区
       roleText: "",
-      isReadonly: true
+      isReadonly: true,
+      showTips: false,
+			showTipsList:[],
     };
   },
   computed: {
@@ -1423,6 +1630,11 @@ export default {
     }
   },
   methods: {
+    showTipsFn() {
+			this.showTipsList = this.tipsList[this.tipsList.length-1]
+      this.showTips = true;
+			this.$parent.getTipsListTime(5000)
+    },
     insertMemorandum(_html) {
       //保存行为操作
       //variable
@@ -1848,7 +2060,7 @@ export default {
         session_name: `${this.courseId}-studyStudent-md`,
         uid: _uuid,
         file_ids: this.fileId,
-				model: "gpt-4o-2024-08-06",
+        model: "gpt-4o-2024-08-06"
       };
       // let params = {
       //   model: "gpt-3.5-turbo",
@@ -2018,7 +2230,7 @@ ${_atList
         session_name: `${this.courseId}-studyStudent-md`,
         uid: _uuid,
         file_ids: this.fileId,
-				model: "gpt-4o-2024-08-06",
+        model: "gpt-4o-2024-08-06"
       };
       // let params = {
       //   model: "gpt-3.5-turbo",
@@ -2357,7 +2569,25 @@ ${_atList
       if (this.loading) return this.$message.info("请稍等");
       this.send(text);
     },
-    getWantSearch() {
+    getWantSearch(_uuid2) {
+
+			// if(!this.$parent.getWangLoading){
+			// 	return this.getWantSearch(_uuid2)
+			// }
+			if(_uuid2 && this.$parent.getWangLoading){
+				return setTimeout(()=>{
+					console.log("等待获取")
+					this.getWantSearch(_uuid2)
+				},1000)
+			}else if(this.$parent.wangData && this.$parent.canUseWangData && _uuid2){
+				this.chatList.find(i => i.uid == _uuid2).aiContent = JSON.parse(
+         this.$parent.getWanData()
+        );
+        this.chatList.find(i => i.uid == _uuid2).isalltext = true;
+        this.chatList.find(i => i.uid == _uuid2).isShowSynchronization = true;
+        this.chatList.find(i => i.uid == _uuid2).loading = false;
+				return;
+			}
       let _uuid = uuidv4();
 
       let _msg = `
@@ -2387,6 +2617,7 @@ Instruction: Based on the context, follow "Format example", write content
 ## Format example
 [{"index": 1,"title": "垃圾分类标准","label": "不同国家的垃圾分类标准和方法?"},{"index": 2,"title":"可回收垃圾处理","label": "可回收垃圾的处理流程和再利用方法?"},{  "index": 3,  "title": "有害垃圾的影响",  "label": "有害垃圾对环境和人体健康的潜在影响?"},{  "index": 4,  "title": "垃圾分类标准",  "label": "不同国家的垃圾分类标准和方法?"},{  "index": 5,  "title": "可回收垃圾处理",  "label": "可回收垃圾的处理流程和再利用方法?"},{  "index": 6,  "title": "有害垃圾的影响",  "label": "有害垃圾对环境和人体健康的潜在影响?"}]
 `;
+
       this.chatList.push({
         role: "user",
         content: `wanSearch`,
@@ -2403,6 +2634,19 @@ Instruction: Based on the context, follow "Format example", write content
 
       this.scrollBottom();
 
+			if(this.$parent.getWangLoading){
+				return setTimeout(()=>{
+					this.getWantSearch(_uuid)
+				},1000)
+			}else if(this.$parent.wangData && this.$parent.canUseWangData){
+				this.chatList.find(i => i.uid == _uuid).aiContent = JSON.parse(
+         this.$parent.getWanData()
+        );
+        this.chatList.find(i => i.uid == _uuid).isalltext = true;
+        this.chatList.find(i => i.uid == _uuid).isShowSynchronization = true;
+        this.chatList.find(i => i.uid == _uuid).loading = false;
+				return;
+			}
       // let params = {
       //   model: "gpt-3.5-turbo",
       //   temperature: 0,
@@ -2421,7 +2665,7 @@ Instruction: Based on the context, follow "Format example", write content
         session_name: _uuid,
         // uid: _uuid,
         file_ids: this.fileId,
-				model: "gpt-4o-2024-08-06",
+        model: "gpt-4o-2024-08-06"
       };
       // let params = {
       //   message: {
@@ -2534,7 +2778,7 @@ Instruction: Based on the context, follow "Format example", write content
         session_name: _uuid,
         // uid: _uuid,
         file_ids: this.fileId,
-				model: "gpt-4o-2024-08-06",
+        model: "gpt-4o-2024-08-06"
       };
       // let params = {
       //   message: {
@@ -2790,7 +3034,7 @@ ${_wordData}
             session_name: `${this.courseId}-studyStudent-md`,
             uid: _uuid,
             file_ids: this.fileId,
-						model: "gpt-4o-2024-08-06",
+            model: "gpt-4o-2024-08-06"
           };
           // let params = {
           //   model: "gpt-3.5-turbo",
@@ -2988,7 +3232,7 @@ ${_wordData}
         session_name: `${this.courseId}-studyStudent-md`,
         uid: _uuid,
         file_ids: this.fileId,
-				model: "gpt-4o-2024-08-06",
+        model: "gpt-4o-2024-08-06"
       };
       // let params = {
       //     model: "gpt-3.5-turbo",
@@ -3116,10 +3360,10 @@ ${_wordData}
       // 	this.aiIsTalk = true;
       // }
     },
-		changeMegaphone(){
-			this.$parent.changeMegaphone()
-			if(this.aiIsTalk){
-				try {
+    changeMegaphone() {
+      this.$parent.changeMegaphone();
+      if (this.aiIsTalk) {
+        try {
           this.aiTalkList = [];
           let _talkTextIiframe2 = this.$refs.iiframe2;
           _talkTextIiframe2.contentWindow.pausesynthesizer();
@@ -3129,8 +3373,8 @@ ${_wordData}
           this.aiTalkList = [];
           this.aiIsTalk = false;
         }
-			}
-		},
+      }
+    },
     aiTalkAll(item) {
       if (this.aiTalkUid == item.uid && this.aiIsTalk) {
         try {
@@ -3274,10 +3518,10 @@ ${_wordData}
   width: 100%;
   height: 100%;
   box-sizing: border-box;
-	position: relative;
-	display: flex;
-	flex-direction: column;
-	justify-content: flex-end;
+  position: relative;
+  display: flex;
+  flex-direction: column;
+  justify-content: flex-end;
 }
 .checkboxCss {
   color: #fff;
@@ -3309,9 +3553,9 @@ ${_wordData}
   overflow-x: hidden;
   box-sizing: border-box;
   padding: 20px 0;
-	position: absolute;
+  position: absolute;
   padding-bottom: 70px;
-	top: 0;
+  top: 0;
 }
 
 .s_t_chat {
@@ -3550,7 +3794,7 @@ ${_wordData}
   align-items: center;
   box-sizing: border-box;
   padding: 0 10px;
-  overflow: auto;
+  /* overflow: auto; */
   display: flex;
   justify-content: space-between;
 }
@@ -3588,6 +3832,10 @@ ${_wordData}
   height: 20px;
 }
 
+.s_b_bat_right {
+  position: relative;
+}
+
 .s_b_bat_right > span {
   padding: 3px 10px;
   background: #fff;
@@ -3600,6 +3848,7 @@ ${_wordData}
   justify-content: center;
   align-items: center;
   cursor: pointer;
+  position: relative;
 }
 
 .s_b_bat_right > span > svg {
@@ -3621,6 +3870,57 @@ ${_wordData}
   margin-right: 5px;
 }
 
+.tips {
+  width: 380px;
+  position: absolute;
+  bottom: 0;
+  right: 0;
+  box-sizing: border-box;
+  padding:20px 15px 12px 15px;
+  border-radius: 8px;
+  background: #ffffff;
+  border: 1px solid #f0f2f5;
+	display: flex;
+	flex-direction: column;
+	justify-content: space-between;
+
+  box-shadow: 0px 8px 10px -5px #00000014;
+
+  box-shadow: 0px 16px 24px 2px #0000000a;
+
+  box-shadow: 0px 6px 30px 5px #0000000d;
+	z-index: 2001;
+}
+
+.tipsList{
+	width: 100%;
+	height: auto;
+}
+
+.tipsList>div{
+	margin-bottom:20px;
+	width: 100%;
+	height: auto; 
+}
+
+.tipsBottom {
+  width: 100%;
+  height: auto;
+  display: flex;
+  justify-content: flex-end;
+}
+
+.tipsBottom>div{
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	cursor: pointer;
+}
+
+.tipsBottom>div>span{
+	margin: 0 5px
+}
+
 .s_b_btnArea {
   width: 100%;
   height: 30px;
@@ -4281,13 +4581,13 @@ ${_wordData}
 }
 
 .cs_b_i_avatar {
-	width: 50px;
-	height: 50px;
-	display: flex;
-	justify-content: center;
-	align-items: center;
+  width: 50px;
+  height: 50px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
   background-color: #ffffffe5;
-	border-radius: 8px;
+  border-radius: 8px;
 }
 
 .cs_b_item:hover {
@@ -4297,13 +4597,13 @@ ${_wordData}
 .cs_b_i_name {
   font-weight: bold;
   color: #768196;
-	font-size: 14px;
+  font-size: 14px;
 }
 
 .cs_b_i_des {
   color: #768196;
-	margin-top: 5px;
-	font-size: 12px;
+  margin-top: 5px;
+  font-size: 12px;
 }
 
 .cs_box > .cs_b_item:nth-of-type(3n + 2) {

+ 272 - 129
src/components/classRoomHelper/component/taskArea.vue

@@ -32,7 +32,7 @@
       <div class="tt_item">
         <div class="tt_i_title">
           <span>任务状态</span>
-          <span v-if="isWorkStudent!==0">学生活动中...</span>
+          <span v-if="isWorkStudent !== 0">学生活动中...</span>
         </div>
         <div class="tt_i_box">
           <div class="tt_i_b_item">
@@ -80,25 +80,30 @@
         <div class="aba_t_left">
           <img :src="require('../../../assets/icon/course/practice.svg')" />
           <span>巩固练习</span>
-					<el-tooltip class="item" effect="light" content="刷新" placement="top"   v-if="showCard == 1">
-						<svg
-          
-						@click.stop="selectDefaultTaskList"
-            width="16"
-            height="16"
-            viewBox="0 0 16 16"
-            fill="none"
-            xmlns="http://www.w3.org/2000/svg"
+          <el-tooltip
+            class="item"
+            effect="light"
+            content="刷新"
+            placement="top"
+            v-if="showCard == 1"
           >
-            <path
-              fill-rule="evenodd"
-              clip-rule="evenodd"
-              d="M2.07324 11.2394L3.48974 8.91992L3.87418 9.79981C4.56904 11.3902 6.15545 12.5 7.99996 12.5C10.4852 12.5 12.5 10.4853 12.5 8L13.5 8C13.5 11.0376 11.0375 13.5 7.99996 13.5C6.06914 13.5 4.3715 12.5051 3.39039 11.0013L2.92668 11.7606L2.07324 11.2394ZM7.99996 3.5C5.51468 3.5 3.49996 5.51472 3.49996 8L2.49996 8C2.49996 4.96243 4.9624 2.5 7.99996 2.5C9.93079 2.5 11.6284 3.49489 12.6095 4.99871L13.0732 4.2394L13.9267 4.7606L12.5102 7.08008L12.1257 6.20019C11.4309 4.60983 9.84447 3.5 7.99996 3.5Z"
-              fill="black"
-              fill-opacity="0.6"
-            />
-          </svg>
-    </el-tooltip>
+            <svg
+              @click.stop="selectDefaultTaskList"
+              width="16"
+              height="16"
+              viewBox="0 0 16 16"
+              fill="none"
+              xmlns="http://www.w3.org/2000/svg"
+            >
+              <path
+                fill-rule="evenodd"
+                clip-rule="evenodd"
+                d="M2.07324 11.2394L3.48974 8.91992L3.87418 9.79981C4.56904 11.3902 6.15545 12.5 7.99996 12.5C10.4852 12.5 12.5 10.4853 12.5 8L13.5 8C13.5 11.0376 11.0375 13.5 7.99996 13.5C6.06914 13.5 4.3715 12.5051 3.39039 11.0013L2.92668 11.7606L2.07324 11.2394ZM7.99996 3.5C5.51468 3.5 3.49996 5.51472 3.49996 8L2.49996 8C2.49996 4.96243 4.9624 2.5 7.99996 2.5C9.93079 2.5 11.6284 3.49489 12.6095 4.99871L13.0732 4.2394L13.9267 4.7606L12.5102 7.08008L12.1257 6.20019C11.4309 4.60983 9.84447 3.5 7.99996 3.5Z"
+                fill="black"
+                fill-opacity="0.6"
+              />
+            </svg>
+          </el-tooltip>
         </div>
         <div class="aba_t_right" v-if="showCard == 1">
           <div>
@@ -112,12 +117,20 @@
         <div class="aa_ab_noTask" v-if="showCard == 0">
           <img :src="require('../../../assets/icon/course/aiLogo.png')" />
           <span>当前课堂未添加练习题</span>
-          <div class="aa_ab_nt_btn" @click.stop="getTopic()" v-show="ttype==1">一键出题</div>
-          <div v-show="
+          <div
+            class="aa_ab_nt_btn"
+            @click.stop="getTopic()"
+            v-show="ttype == 1"
+          >
+            一键出题
+          </div>
+          <div
+            v-show="
               this.courseDetail.userid == userid ||
                 this.courseDetail.juri.indexOf(userid) != -1
-            ">
-            或前往“<span @click.stop="goSetTopic()"  >课堂管理</span
+            "
+          >
+            或前往“<span @click.stop="goSetTopic()">课堂管理</span
             >”编辑工具,自主添加题目
           </div>
         </div>
@@ -169,14 +182,11 @@
                 >{{ chooseList[index] }}、<span>{{ item }}</span></span
               >
             </div> -->
-						<div
+            <div
               :class="[
                 'aa_ab_t_cl_item',
-                showBottomCard==2
-                  ? checkAnswer(
-                      topicList[showTopicIndex].answer,
-                      topicList[showTopicIndex].answer2
-                    ).yes.includes(index)
+                showBottomCard == 2
+                  ? (typeof topicList[showTopicIndex].answer== 'number'?topicList[showTopicIndex].answer == index:topicList[showTopicIndex].answer.includes(index))
                     ? 'aa_ab_t_cl_itemYes'
                     : checkAnswer(
                         topicList[showTopicIndex].answer,
@@ -185,12 +195,14 @@
                     ? ''
                     : ''
                   : 'aa_ab_t_cl_itemActive',
-									
+
                 typeof topicList[showTopicIndex].answer != 'number'
-                  ? topicList[showTopicIndex].answer2.includes(index) && showBottomCard!=2
+                  ? topicList[showTopicIndex].answer2.includes(index) &&
+                    showBottomCard != 2
                     ? 'aa_ab_t_cl_itemChoice'
                     : ''
-                  : topicList[showTopicIndex].answer2 === index && showBottomCard!=2
+                  : topicList[showTopicIndex].answer2 === index &&
+                    showBottomCard != 2
                   ? 'aa_ab_t_cl_itemChoice'
                   : ''
               ]"
@@ -205,32 +217,51 @@
               <span v-else
                 >{{ chooseList[index] }}、<span>{{ item }}</span></span
               >
+              <div
+                class="aa_ab_t_cl_itemAnswer"
+                v-if="(typeof topicList[showTopicIndex].answer== 'number'?topicList[showTopicIndex].answer == index:topicList[showTopicIndex].answer.includes(index)) && showBottomCard==2"
+              >
+                <svg
+                  t="1724308424838"
+                  class="icon"
+                  viewBox="0 0 1024 1024"
+                  version="1.1"
+                  xmlns="http://www.w3.org/2000/svg"
+                  p-id="4297"
+                  width="200"
+                  height="200"
+                >
+                  <path
+                    d="M817.728 198.72l111.744 114.56-545.216 532.128-285.92-273.024 110.528-115.712 174.176 166.336z"
+                    fill="#3581FC"
+                    p-id="4298"
+                  ></path>
+                </svg>
+              </div>
             </div>
           </div>
           <div class="aa_ab_t_btnArea">
-            <div
-              class="aa_ab_t_message"
-            >
+            <div class="aa_ab_t_message">
               <div class="aa_ab_t_m_answer">
-                正确答案:<span v-if="showBottomCard==2">{{
+                正确答案:<span v-if="showBottomCard == 2">{{
                   topicList[showTopicIndex].answer.length
                     ? topicList[showTopicIndex].answer
                         .map(i => chooseList[i])
                         .join("、")
                     : chooseList[topicList[showTopicIndex].answer]
                 }}</span>
-								<span v-else>-</span>
+                <span v-else>-</span>
               </div>
               <div class="aa_ab_t_m_btn">
                 <span
                   :class="[showBottomCard == 1 ? 'aa_ab_t_m_btnActive' : '']"
                   @click.stop="statistics()"
-									v-if="ttype!=2"
+                  v-if="ttype != 2"
                   >题目统计</span
                 >
                 <span
                   :class="[showBottomCard == 2 ? 'aa_ab_t_m_btnActive' : '']"
-									v-if="ttype!=2"
+                  v-if="ttype != 2"
                   @click.stop="analyze()"
                   >答案解析</span
                 >
@@ -251,17 +282,21 @@
                 </div>
 
                 <div class="sc_t_refresh" @click.sto="getStatistics()">
-								<el-tooltip class="item" effect="dark" content="刷新" placement="top">
-									<img :src="require('../../../assets/icon/course/refresh.svg')">
-    						</el-tooltip>
-								
-							</div>
+                  <el-tooltip
+                    class="item"
+                    effect="dark"
+                    content="刷新"
+                    placement="top"
+                  >
+                    <img
+                      :src="require('../../../assets/icon/course/refresh.svg')"
+                    />
+                  </el-tooltip>
+                </div>
               </div>
 
               <div class="sc_bottom">
-                <span v-if="statisticsData.total == 0"
-                  >当前暂无学生提交.</span
-                >
+                <span v-if="statisticsData.total == 0">当前暂无学生提交.</span>
                 <div
                   class="sc_b_item"
                   v-else
@@ -283,7 +318,6 @@
               v-if="showBottomCard == 2"
             >
               <span>{{ analyzeText }}</span>
-              
             </div>
             <!-- <div
               class="aa_ab_t_ba_submit"
@@ -293,27 +327,54 @@
               确认选择
             </div> -->
             <div class="aa_ab_t_ba_nextOrUp">
-
-							<div :class="['aa_ab_t_ba_nu_questions']" @click.stop="getAiTopic()" v-show="this.courseDetail.userid == userid && ttype!=2">
-								<span>智能出题</span>
-								<svg width="17" :style="showMenu?'transform: rotate(180deg);':''" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path fill-rule="evenodd" clip-rule="evenodd" d="M13.5404 10.3322C13.7239 10.1258 13.7053 9.80975 13.4989 9.62629L8.99892 5.62629C8.80948 5.4579 8.524 5.4579 8.33456 5.62629L3.83456 9.62629C3.62817 9.80975 3.60958 10.1258 3.79304 10.3322C3.9765 10.5386 4.29253 10.5572 4.49892 10.3737L8.66674 6.66897L12.8346 10.3737C13.041 10.5572 13.357 10.5386 13.5404 10.3322Z" fill="#3681FC"/>
-</svg>
-							<div class="aa_ab_t_ba_nu_q_menu" v-if="showMenu" v-click-outside="handleBlur">
+              <div
+                :class="['aa_ab_t_ba_nu_questions']"
+                @click.stop="getAiTopic()"
+                v-show="ttype == 1"
+              >
+                <span>智能出题</span>
+                <svg
+                  width="17"
+                  :style="showMenu ? 'transform: rotate(180deg);' : ''"
+                  height="16"
+                  viewBox="0 0 17 16"
+                  fill="none"
+                  xmlns="http://www.w3.org/2000/svg"
+                >
+                  <path
+                    fill-rule="evenodd"
+                    clip-rule="evenodd"
+                    d="M13.5404 10.3322C13.7239 10.1258 13.7053 9.80975 13.4989 9.62629L8.99892 5.62629C8.80948 5.4579 8.524 5.4579 8.33456 5.62629L3.83456 9.62629C3.62817 9.80975 3.60958 10.1258 3.79304 10.3322C3.9765 10.5386 4.29253 10.5572 4.49892 10.3737L8.66674 6.66897L12.8346 10.3737C13.041 10.5572 13.357 10.5386 13.5404 10.3322Z"
+                    fill="#3681FC"
+                  />
+                </svg>
+                <div
+                  class="aa_ab_t_ba_nu_q_menu"
+                  v-if="showMenu"
+                  v-click-outside="handleBlur"
+                >
                   <span @click.stop="getAiTopicByyType(0)">相似题</span>
                   <span @click.stop="getAiTopicByyType(1)">更难题</span>
                   <span @click.stop="getAiTopicByyType(2)">更易题</span>
                 </div>
-							</div>
+              </div>
 
               <div
-                :class="['aa_ab_t_ba_nu_up',showTopicIndex > 0?'':'aa_ab_t_ba_nu_disabled'] "
+                :class="[
+                  'aa_ab_t_ba_nu_up',
+                  showTopicIndex > 0 ? '' : 'aa_ab_t_ba_nu_disabled'
+                ]"
                 @click.stop="up()"
               >
                 上一题
               </div>
               <div
-                 :class="['aa_ab_t_ba_nu_next',showTopicIndex != topicList.length - 1 && topicList.length > 0?'':'aa_ab_t_ba_nu_disabled'] "
+                :class="[
+                  'aa_ab_t_ba_nu_next',
+                  showTopicIndex != topicList.length - 1 && topicList.length > 0
+                    ? ''
+                    : 'aa_ab_t_ba_nu_disabled'
+                ]"
                 @click.stop="next()"
               >
                 下一题
@@ -517,12 +578,11 @@ let converter = OpenCC.Converter({
   to: "cn"
 });
 
-
 // 自定义指令,用于处理点击外部区域的事件
 const clickOutside = {
   bind(el, binding) {
     // 在元素上绑定一个点击事件监听器
-    el.clickOutsideEvent = function (event) {
+    el.clickOutsideEvent = function(event) {
       // 检查点击事件是否发生在元素的内部
       if (!(el === event.target || el.contains(event.target))) {
         // 如果点击事件发生在元素的外部,则触发指令绑定的方法,将点击的event数据传过去
@@ -535,7 +595,7 @@ const clickOutside = {
   unbind(el) {
     // 在元素上解除点击事件监听器
     document.removeEventListener("click", el.clickOutsideEvent);
-  },
+  }
 };
 
 export default {
@@ -574,7 +634,7 @@ export default {
       userid: this.$route.query.userid,
       courseId: this.$route.query.courseId,
       ttype: this.$route.query.tType,
-			tcid2: this.$route.query.tcid,
+      tcid2: this.$route.query.tcid,
       loading: false,
       aiBoxLoading: false,
       chatLoading: false,
@@ -597,8 +657,34 @@ export default {
       showBottomCard: 0, // 0不显示  1:显示统计   2:显示解析
       analyzeText: "",
       statisticsLoading: false,
-			chooseList:["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"],
-     
+      chooseList: [
+        "A",
+        "B",
+        "C",
+        "D",
+        "E",
+        "F",
+        "G",
+        "H",
+        "I",
+        "J",
+        "K",
+        "L",
+        "M",
+        "N",
+        "O",
+        "P",
+        "Q",
+        "R",
+        "S",
+        "T",
+        "U",
+        "V",
+        "W",
+        "X",
+        "Y",
+        "Z"
+      ]
     };
   },
   computed: {
@@ -718,17 +804,21 @@ export default {
       let _data = JSON.parse(JSON.stringify(this.submitStudent));
       _data.forEach((i, index1) => {
         let _task = i.content[this.showTopicIndex];
-        
+
         if (index1 == 0) {
           _task.checkList.forEach((i2, index2) => {
-            _result.checkList.push({ index: this.chooseList[index2], accuracy: 0, num: 0 });
+            _result.checkList.push({
+              index: this.chooseList[index2],
+              accuracy: 0,
+              num: 0
+            });
           });
         }
 
-				// if (!_task || !_task.isSubmit) return; //未做此题
-				if (!_task) return; //未做此题
+        // if (!_task || !_task.isSubmit) return; //未做此题
+        if (!_task) return; //未做此题
 
-        if (typeof _task.answer!='number') {
+        if (typeof _task.answer != "number") {
           //多选题
           if (!_task.answer2.length) return; //未做此题
           _result.total += 1;
@@ -786,6 +876,7 @@ export default {
             _result.no = [answer2];
           }
         } else {
+					console.log("多选题")
           if (
             answer.length == answer2.length &&
             answer.every(i => answer2.includes(i))
@@ -801,13 +892,13 @@ export default {
       };
     }
   },
-	directives: {
-    "click-outside": clickOutside, // 注册自定义指令
+  directives: {
+    "click-outside": clickOutside // 注册自定义指令
   },
   methods: {
-		handleBlur(){
-			this.showMenu = !this.showMenu;
-		},
+    handleBlur() {
+      this.showMenu = !this.showMenu;
+    },
     insertMemorandum(_html) {
       //保存行为操作
       //variable
@@ -816,7 +907,7 @@ export default {
       let params = [
         {
           uid: this.userid,
-          courseId: this.courseId+(this.tcid2?this.tcid2:''),
+          courseId: this.courseId + (this.tcid2 ? this.tcid2 : ""),
           content: _html
         }
       ];
@@ -1130,7 +1221,7 @@ ${_textData}
         session_name: uuidv4(),
         // uid: _uuid,
         file_ids: this.fileId,
-				model: "gpt-4o-2024-08-06",
+        model: "gpt-4o-2024-08-06"
       };
 
       this.ajax
@@ -1140,7 +1231,6 @@ ${_textData}
         .then(res => {
           let _data = res.data.FunctionResponse.message;
           _data = _data.replaceAll("```json", "").replaceAll("```", "");
-          console.log(_data);
           const match = _data.match(/\[\s*\{[\s\S]*?\}\s*\]/);
           let _result = JSON.parse(match[0]) || [];
           _result.forEach(i => {
@@ -1263,7 +1353,7 @@ ${_textData}
           _data.forEach(i => {
             i.content = JSON.parse(i.content);
             if (i.tType == 2) {
-            	_result.push(i);
+              _result.push(i);
             }
           });
           this.submitStudent = _result;
@@ -1278,7 +1368,9 @@ ${_textData}
       let _nowTask = this.topicList[this.showTopicIndex];
       let taskText = `${_nowTask.teststitle}\n选项:\n`;
       _nowTask.checkList.forEach((i, index) => {
-        taskText += `${this.chooseList[index]}:${i.src ? JSON.stringify(i) : i}\n`;
+        taskText += `${this.chooseList[index]}:${
+          i.src ? JSON.stringify(i) : i
+        }\n`;
       });
       taskText += `答案:${
         _nowTask.answer.length
@@ -1402,7 +1494,7 @@ ${taskText}
         session_name: uuidv4(),
         // uid: _uuid,
         file_ids: this.fileId,
-				model: "gpt-4o-2024-08-06",
+        model: "gpt-4o-2024-08-06"
       };
 
       this.ajax
@@ -1412,7 +1504,6 @@ ${taskText}
         .then(res => {
           let _data = res.data.FunctionResponse.message;
           _data = _data.replaceAll("```json", "").replaceAll("```", "");
-          console.log(_data);
           const match = _data.match(
             /{[^{}]*"teststitle"[\s\S]*?"end":\s*""[^{}]*}/
           );
@@ -1421,8 +1512,12 @@ ${taskText}
             (_result.uuid = uuidv4());
           delete _result.end;
           this.topicList.splice(this.showTopicIndex + 1, 0, _result);
-          this.saveTaskList(1);
-          this.next();
+          // this.saveTaskList(1);
+          this.saveTaskList(2).then(_ => {
+            this.saveTaskList().then(_ => {
+              this.next();
+            });
+          });
           this.aiBoxLoading = false;
         })
         .catch(e => {
@@ -1448,7 +1543,7 @@ ${taskText}
       }
     },
     chooseAnswer(answer) {
-			if(this.showBottomCard==2)return;
+      if (this.showBottomCard == 2) return;
       if (this.topicList[this.showTopicIndex].isSubmit)
         return this.$message.error("该题已经提交过了");
       if (this.topicList[this.showTopicIndex].answer.length) {
@@ -1469,7 +1564,9 @@ ${taskText}
     confirmSubmission() {
       //确认选择
       if (
-        (typeof this.topicList[this.showTopicIndex].answer2 =='number' && this.topicList[this.showTopicIndex].answer2==="") || this.topicList[this.showTopicIndex].answer2.length==0
+        (typeof this.topicList[this.showTopicIndex].answer2 == "number" &&
+          this.topicList[this.showTopicIndex].answer2 === "") ||
+        this.topicList[this.showTopicIndex].answer2.length == 0
       ) {
         return this.$message.error("请先答题");
       } else {
@@ -1586,6 +1683,48 @@ ${taskText}
         });
     },
     saveTaskList(type = 0) {
+      if (type == 2) {
+        this.aiBoxLoading = true;
+        return new Promise(resolve => {
+          let params = {
+            uid: this.courseDetail.userid,
+            cid: this.courseId
+          };
+          this.ajax
+            .get(
+              this.$store.state.api + "select_courseWorks_classRoomHelper",
+              params
+            )
+            .then(res => {
+              let _data = res.data[0];
+              if (_data.length) {
+                let _task = JSON.parse(_data[0].content);
+                _task.splice(
+                  this.showTopicIndex + 1,
+                  0,
+                  this.topicList[this.showTopicIndex + 1]
+                );
+                let params2 = [
+                  {
+                    uid: this.courseDetail.userid,
+                    cid: this.courseId,
+                    jsonData: JSON.stringify(_task)
+                  }
+                ];
+                this.ajax
+                  .post(
+                    this.$store.state.api + "updateCourseWorks_classRoomHelper",
+                    params2
+                  )
+                  .then(res => {
+                    resolve();
+                  });
+              } else {
+                resolve();
+              }
+            });
+        });
+      }
       return new Promise(resolve => {
         let params = [
           {
@@ -1687,7 +1826,7 @@ ${_choiceText}
           session_name: uuidv4(),
           // uid: _uuid,
           file_ids: this.fileId,
-					model: "gpt-4o-2024-08-06",
+          model: "gpt-4o-2024-08-06"
         };
 
         this.ajax
@@ -1695,11 +1834,9 @@ ${_choiceText}
           // .post("https://claude3.cocorobo.cn/chat", params)
           .post("https://gpt4.cocorobo.cn/ai_agent_park_chat", params)
           .then(res => {
-            console.log(res);
             let _data = res.data.FunctionResponse.message;
             _data = _data.replaceAll("```json", "").replaceAll("```", "");
             const match = _data.match(/{[^}]*"analyze"[^}]*}/);
-            console.log(match);
             let _result = JSON.parse(match[0]);
             resolve({ ..._result, uuid: data.uuid });
           })
@@ -2034,16 +2171,23 @@ ${_choiceText}
   border-radius: 3px;
   border: solid 1px #fff;
   margin-top: 15px;
-	display:flex;
-	flex-wrap:wrap;
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-between;
 }
 
-.aa_ab_t_cl_item>span{
-	word-break: break-all;
+.aa_ab_t_cl_item > span {
+  word-break: break-all;
+  float: left;
 }
 
-.aa_ab_t_cl_item img{
-	width:90%;
+.aa_ab_t_cl_item img {
+  width: 90%;
+}
+
+.aa_ab_t_cl_itemAnswer > svg {
+  width: 20px;
+  height: 20px;
 }
 
 .aa_ab_t_cl_itemNo {
@@ -2362,38 +2506,37 @@ ${_choiceText}
   border-radius: 50px;
 }
 
-.aa_ab_t_ba_nextOrUp>.aa_ab_t_ba_nu_disabled{
-	background-color: #75aaff;
-	cursor: not-allowed;
+.aa_ab_t_ba_nextOrUp > .aa_ab_t_ba_nu_disabled {
+  background-color: #75aaff;
+  cursor: not-allowed;
 }
 
-.aa_ab_t_ba_nu_up{
-	margin-right:10px;
+.aa_ab_t_ba_nu_up {
+  margin-right: 10px;
 }
 
-.aa_ab_t_ba_nu_questions{
-	margin-right: 20px;
-	background-color: #fff !important;
-	color: black !important;
-	position: relative;
-	cursor: pointer;
-	box-sizing: border-box;
-	border: solid 1px #3681FC;
-	display: flex;
-	justify-content: center;
-	align-items: center;
-	
+.aa_ab_t_ba_nu_questions {
+  margin-right: 20px;
+  background-color: #fff !important;
+  color: black !important;
+  position: relative;
+  cursor: pointer;
+  box-sizing: border-box;
+  border: solid 1px #3681fc;
+  display: flex;
+  justify-content: center;
+  align-items: center;
 }
 
-.aa_ab_t_ba_nu_questions>svg{
-	width: 20px;
-	height: 20px;
-	transition: .3s;
-	/* margin-left: 5px; */
+.aa_ab_t_ba_nu_questions > svg {
+  width: 20px;
+  height: 20px;
+  transition: 0.3s;
+  /* margin-left: 5px; */
 }
 
-.aa_ab_t_ba_nu_q_menu{
-	width: auto;
+.aa_ab_t_ba_nu_q_menu {
+  width: auto;
   height: auto;
   display: flex;
   align-items: center;
@@ -2402,30 +2545,30 @@ ${_choiceText}
   bottom: calc(100% + 5px);
   right: 0;
   flex-direction: column;
-	background-color: #fff;
-	padding: 5px 10px;
-	border-radius: 5px;
-	box-shadow: 0 0 5px #ccc
+  background-color: #fff;
+  padding: 5px 10px;
+  border-radius: 5px;
+  box-shadow: 0 0 5px #ccc;
 }
 .aa_ab_t_ba_nu_q_menu > span {
   width: auto;
-	height: auto;
-	padding: 8px;
+  height: auto;
+  padding: 8px;
   background-color: #fff;
   border-radius: 6px;
   cursor: pointer;
   display: flex;
   align-items: center;
   justify-content: center;
-	margin-bottom: 5px;
+  margin-bottom: 5px;
 }
 
 .aa_ab_t_ba_nu_q_menu > span:hover {
-  background-color: #F3F7FD;
+  background-color: #f3f7fd;
 }
 
-.aa_ab_t_ba_nu_next{
-	margin-left:10px;
+.aa_ab_t_ba_nu_next {
+  margin-left: 10px;
 }
 
 .aa_ab_t_message {
@@ -2453,7 +2596,7 @@ ${_choiceText}
 .aa_ab_t_m_btnActive {
   font-weight: bold;
   color: #0061ff !important;
-	transform: scale(1.1,1.1);
+  transform: scale(1.1, 1.1);
 }
 
 .aa_ab_t_m_answer {

+ 255 - 12
src/components/classRoomHelper/index.vue

@@ -10,6 +10,9 @@
         :fileId="fileId"
         :recordType="recordType"
         v-if="itemType == 1"
+				:canShowTips="canShowTips"
+				:showTipsLoading="showTipsLoading"
+				:tipsList="tipsList"
       />
       <taskArea
         :courseDetail="courseDetail"
@@ -30,6 +33,8 @@
       />
 
       <languageAssistant ref="languageAssistantRef" v-if="itemType == 4" />
+
+			<reviewArea ref="reviewAreaRef" v-if="itemType==5" :courseType="courseType" :taskCount="taskCount"/>
       <!-- <dialogArea
         :courseDetail="courseDetail"
 				:openMegaphone="openMegaphone"
@@ -55,7 +60,7 @@
           </el-tooltip>
         </div>
 
-        <div @click="$emit('review')" v-if="tType == 1">
+        <div @click="changeItemType(5)" v-if="tType == 1">
           <el-tooltip class="item" effect="dark" content="评论" placement="top">
             <img
               :src="require('../../assets/icon/course/comment2.svg')"
@@ -150,7 +155,7 @@
         </div>
       </div>
       <div class="ch_nav_box_bottom">
-        <div @click.stop="commentAndAnnotate()">
+        <div @click.stop="commentAndAnnotate()" style="z-index: 9999;">
           <el-tooltip class="item" effect="dark" content="批注" placement="top">
             <img
               :src="require('../../assets/icon/course/edit2.svg')"
@@ -259,6 +264,8 @@ import timepiece from "./component/timepiece.vue";
 import countdown from "./component/countdown.vue";
 import AnnotationCanvas from "./component/AnnotationCanvas.vue";
 import languageAssistant from "./component/languageAssistant.vue";
+import reviewArea from "./component/reviewArea.vue";
+import { v4 as uuidv4 } from "uuid";
 // 自定义指令,用于处理点击外部区域的事件
 const clickOutside = {
   bind(el, binding) {
@@ -299,7 +306,8 @@ export default {
     timepiece,
     countdown,
     AnnotationCanvas,
-    languageAssistant
+    languageAssistant,
+		reviewArea
   },
   props: {
     courseDetail: {
@@ -352,14 +360,129 @@ export default {
       fold: false,
       openMegaphone: false, //是否打开喇叭
       getFileIdLoading: false,
-      AnnotationCanvasShow: false
+      AnnotationCanvasShow: false,
+			canShowTips:false,
+			showTipsLoading:false,
+			tipsList:[],
+			firstEnterTime:null,
+			canGetTips:true,
+			getTipsTimer:null,
+			getWangLoading:false,
+			canUseWangData:false,
+			wangData:"",
     };
   },
   mounted() {
     this.setWidth();
     this.getFileId();
+		this.firstEnterTime = new Date().getTime();
+		this.getWantSearch();
+		setTimeout(()=>{
+			this.canGetTips = true;
+			this.getTipsList()
+		},3000)
   },
   methods: {
+		getTipsListTime(time = 5000){
+			if(this.getTipsTimer)clearTimeout(this.getTipsListTime)
+			this.getTipsTimer = setTimeout(()=>{
+				this.canGetTips = true;
+				this.getTipsList();
+				this.getTipsTimer = null;
+			},time)
+		},
+		getTipsList(){
+			return new Promise((resolve)=>{
+				if(!this.canGetTips)return;
+			this.showTipsLoading = true;
+			let nowTaskObj = this.navList[this.courseType].task[this.taskCount]
+			let nowTask = `【任务${this.taskCount+1}:${nowTaskObj.taskName}】`
+			let _textData = `课程名称:${this.courseDetail.title}\n分类:${this.courseDetail.name}\n\n`;
+      let _chapters = JSON.parse(this.courseDetail.chapters);
+      _chapters.forEach((i1, index1) => {
+        if (i1.dyName) {
+          _textData += `阶段${index1 + 1}:${i1.dyName}\n`;
+        }
+        i1.chapterInfo[0].taskJson.forEach((i2, index2) => {
+          if (i2.task) {
+            _textData += `任务${index2 + 1}:${i2.task}\n`;
+            _textData += `${i2.taskDetail}\n`;
+          }
+        });
+        _textData += "\n";
+      });
+			let _msg = `Language: Please use the same language as the user requirement, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
+ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example".
+Instruction: Based on the context, follow "Format example", write content
+
+#Context
+## 任务
+你是专业的教学评估员,擅长分析课堂动态和学生的认知状态,能够根据教师的当前思路提供有效的教学建议。
+你需要根据我提供的信息,推测分析,之后给出3个具体的操作步骤的建议。
+
+##工作流程
+1. 仔细阅读并分析我提供的课堂信息或课堂实录内容。
+2. 观察课堂上学生的行为和反应,推测他们的认知状态。
+3. 通过教师的言行和教学安排,推测教师当前的思路和教学目标。
+4. 根据教师的思路和学生的认知状态,提出一个教学建议,并给出3个具体的操作步骤。只需要描述对应的动作,不需要指出该动作的目标和作用。
+
+##输出
+###输出要求
+1. 最终输出仅包含具体操作步骤。
+2. 具体操作步骤以数组形式输出,包含3个步骤。
+3. 每个步骤用一句话描述,详细一些
+
+##课堂内容
+当前进行到:${nowTask}
+
+##Format example
+["步骤的描述","步骤的描述","步骤的描述"]
+${_textData}
+`
+let params = {
+        // assistant_id: "6063369f-289a-11ef-8bf4-12e77c4cb76b",
+        // userId: this.userid,
+        // message: [{ type: "text", text: _msg }],
+        // session_name: uuidv4(),
+        // // uid: _uuid,
+        // file_ids: this.fileId,
+				// model: "gpt-4o-2024-08-06",
+					model: "gpt-4o-2024-08-06",
+					temperature: 0,
+					max_tokens: 4096,
+					top_p: 1,
+					frequency_penalty: 0,
+					presence_penalty: 0,
+					messages: [{ role: "user", content: _msg }],
+					uid: uuidv4(),
+					mind_map_question: "",
+					stream: false,
+      };
+      this.ajax
+        // .post("https://gpt4.cocorobo.cn/chat", params)
+        // .post("https://claude3.cocorobo.cn/chat", params)
+        .post("https://gpt4.cocorobo.cn/chat", params)
+        .then(res => {
+          let _data = res.data.FunctionResponse.choices[0].message.content;
+          _data = _data.replaceAll("```json", "").replaceAll("```", "");
+					console.log(_data)
+          const match = _data.match(/\[\s*[^]*\s*\]/);
+          let _result = JSON.parse(match[0]) || [];
+					
+					this.tipsList.push(_result)
+					
+          this.showTipsLoading = false;
+					this.canShowTips = true;
+					this.canGetTips = false;
+					resolve()
+        })
+        .catch(e => {
+          this.showTipsLoading = false;
+          this.$message.error("获取课堂小贴士失败");
+          console.log(e);
+        });
+			})
+		},
 		handleBlur(){
 			// console.log(this.fold)
 			this.fold = !this.fold;
@@ -416,7 +539,15 @@ export default {
     },
     changeItemType(type) {
       this.type = 0;
-      this.openSetting();
+			
+      
+			if(this.itemType==type){
+				this.itemType = 0;
+				this.type = 1;
+				this.openSetting();
+				return;
+			}
+			this.openSetting();
       // this.$message.info("切换到"+type)
       this.$nextTick(() => {
         // if (this.itemType == 1 && type != 1) {
@@ -448,7 +579,7 @@ export default {
       this.fileId = [];
       let _this = this;
       let _successFileUrl = [];
-      if (this.fileList.length <= 0) retrun;
+      if (this.fileList.length <= 0) return;
       let addType = ["DOCX", "DOC", "PPT", "PPTX", "MD", "TXT", "PDF"];
       this.fileList.forEach(i => {
         if (
@@ -494,8 +625,8 @@ export default {
         this.$refs.levitatedSphereRef.recordStart();
       } else if (this.recordType == 1) {
         // this.$message.info("关闭")
-        // this.changeRecordType(0)
-        this.$refs.levitatedSphereRef.stopRecord();
+        this.$refs.levitatedSphereRef.stopTwo();
+				// this.changeRecordType(0)
       }
     },
     changeMegaphone() {
@@ -529,7 +660,7 @@ export default {
       this.$refs.levitatedSphereRef.startRecord();
     },
     stopRecord() {
-      this.$refs.levitatedSphereRef.stopRecord();
+      this.$refs.levitatedSphereRef.stopTwo();
     },
     // 语音合成
     startSpeak() {
@@ -539,12 +670,124 @@ export default {
       this.recordType = type;
     },
     commentAndAnnotate() {
-      this.$refs.AnnotationCanvasRef.open();
-      this.insertMemorandum(`开始使用<span class="btn">批注</span>功能`);
+			if(this.AnnotationCanvasShow){
+				this.$refs.AnnotationCanvasRef.close()
+			}else{
+				this.$refs.AnnotationCanvasRef.open();
+      	this.insertMemorandum(`开始使用<span class="btn">批注</span>功能`);
+			}
+      
     },
     endCommentAndAnnotate() {
       this.insertMemorandum(`结束使用<span class="btn">批注</span>功能`);
-    }
+    },
+		getWantSearch() {
+			console.log("获取猜你想搜")
+      let _uuid = uuidv4();
+			this.getWangLoading = true
+			this.canUseWangData = false
+			this.wangData=""
+      let _msg = `
+Language: Please use the same language as the user requirement, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
+ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example".
+Instruction: Based on the context, follow "Format example", write content
+
+## 任务
+你的任务是根据“课程信息”,提供用户需要的搜索建议,将搜索建议的结果以有序列表的形式返回给用户。
+## 课程信息
+#### 课程标题:${this.courseDetail.title ? this.courseDetail.title : ""}
+#### 分类:${this.courseDetail.name ? this.courseDetail.name : "无"}
+#### 学生年级:${
+        this.courseDetail.classname ? this.courseDetail.classname : "无"
+      }
+
+## 规则
+输出结果基于“课程信息”,避免提供无关的信息。
+搜索建议的结果符合伦理规范。
+## 输出
+输出应包括6个相关的搜索建议,每个搜索建议需要以问号的方式结束。
+请一步步思考如何根据现有信息推送搜索建议,但是不需要输出搜索建议以外的内
+
+## 输出格式
+搜索建议应以有序列表形式呈现,每个建议包括关键词和简短描述。输出JSON格式的
+
+## Format example
+[{"index": 1,"title": "垃圾分类标准","label": "不同国家的垃圾分类标准和方法?"},{"index": 2,"title":"可回收垃圾处理","label": "可回收垃圾的处理流程和再利用方法?"},{  "index": 3,  "title": "有害垃圾的影响",  "label": "有害垃圾对环境和人体健康的潜在影响?"},{  "index": 4,  "title": "垃圾分类标准",  "label": "不同国家的垃圾分类标准和方法?"},{  "index": 5,  "title": "可回收垃圾处理",  "label": "可回收垃圾的处理流程和再利用方法?"},{  "index": 6,  "title": "有害垃圾的影响",  "label": "有害垃圾对环境和人体健康的潜在影响?"}]
+`;
+
+      // let params = {
+      //   model: "gpt-3.5-turbo",
+      //   temperature: 0,
+      //   max_tokens: 4096,
+      //   top_p: 1,
+      //   frequency_penalty: 0,
+      //   presence_penalty: 0,
+      //   messages: [{ role: "user", content: _msg }],
+      //   uid: _uuid,
+      //   mind_map_question: ""
+      // };
+      let params = {
+        assistant_id: "6063369f-289a-11ef-8bf4-12e77c4cb76b",
+        userId: this.userid,
+        message: [{ type: "text", text: _msg }],
+        session_name: _uuid,
+        // uid: _uuid,
+        file_ids: this.fileId,
+        model: "gpt-4o-2024-08-06"
+      };
+      // let params = {
+      //   message: {
+      //     anthropic_version: "bedrock-2023-05-31",
+      //     max_tokens: 4096,
+      //     temperature: 0,
+      //     top_p: 1,
+      //     messages: [{ role: "user", content: _msg }]
+      //   },
+      //   uid: _uuid,
+      //   model: "Claude 3 Sonnet" // Claude 3 Sonnet或者Claude 3 Haiku
+      // };
+      this.text = "";
+
+      this.ajax
+        // .post("https://gpt4.cocorobo.cn/chat", params)
+        // .post("https://claude3.cocorobo.cn/chat", params)
+        .post("https://gpt4.cocorobo.cn/ai_agent_park_chat", params)
+        .then(res => {
+          // console.log(res);
+          let _data = res.data.FunctionResponse.message;
+          _data = _data.replaceAll("```json", "").replaceAll("```", "");
+          const match = _data.match(/\[\s*{[^]*}\s*\]/);
+					this.wangData = match[0];
+					this.canUseWangData = true;
+					this.getWangLoading = false;
+          // console.log(_data);
+          // console.log(match);
+          // this.chatList.find(i => i.uid == _uuid).aiContent = JSON.parse(
+          //   match[0]
+          // );
+          // this.chatList.find(i => i.uid == _uuid).isalltext = true;
+          // this.chatList.find(i => i.uid == _uuid).isShowSynchronization = true;
+          // this.chatList.find(i => i.uid == _uuid).loading = false;
+          // this.scrollBottom();
+          // this.chatLoading = false;
+        })
+        .catch(e => {
+          this.chatLoading = false;
+					this.canUseWangData = false;
+					this.getWangLoading = false;
+					console.log(e);
+        });
+      // this.getWAntSearchContent(_uuid);
+    },
+		getWanData(){
+			if(this.wangData && this.canUseWangData){
+				const _result = this.wangData;
+				this.wangData = "";
+				this.canUseWangData = false;
+				this.getWantSearch();
+				return _result;
+			}
+		}
   }
 };
 </script>

+ 1 - 1
src/components/components/answerData2.vue

@@ -200,7 +200,7 @@ export default {
             count++;
           }
         }
-        console.log(this.person);
+        // console.log(this.person);
         this.count = count;
         if (!this.chartObj) {
           this.setChart(this.ooption);

+ 1 - 1
src/components/components/askStatic.vue

@@ -183,7 +183,7 @@ export default {
         for (var i = 0; i < this.checkJson.length; i++) {
           // debuggerA
           let el = this.checkJson[i];
-          console.log(el);
+          // console.log(el);
         }
         this.checkJson2 = this.checkJson;
       },

+ 2 - 2
src/components/components/askStatic2.vue

@@ -223,7 +223,7 @@ export default {
         for (var i = 0; i < this.checkJson.length; i++) {
           // debuggerA
           let el = this.checkJson[i];
-          console.log(el);
+          // console.log(el);
         }
         this.checkJson2 = this.checkJson;
       },
@@ -234,7 +234,7 @@ export default {
     this.askJSONC = this.askJSON ? this.askJSON : {};
     for (var i = 0; i < this.checkJson.length; i++) {
       let el = this.checkJson[i];
-      console.log(el);
+      // console.log(el);
     }
     this.checkJson2 = this.checkJson;
   },

+ 1352 - 0
src/components/easy2/commpont/markDialog.vue

@@ -0,0 +1,1352 @@
+<template>
+  <div class="markDialog" v-loading="vLoading">
+    <div
+      style="overflow: auto;overflow-x: hidden;width: 315px;box-sizing: content-box;border-right: 1px rgba(231, 231, 231, 1) solid;"
+    >
+      <div class="left">
+        <div
+          v-if="markScoreworksStudent.length - 1 == toolIndex"
+          v-loading="ScLoading"
+        >
+          <div class="scoreTit">
+            <div>任务得分</div>
+            <div>
+              <span style="color: rgba(54, 129, 252, 1);margin-right: 3px;">{{
+                totalScore ? totalScore : 0
+              }}</span
+              >分
+            </div>
+          </div>
+          <div class="allD">
+            <div class="scoreStar">
+              <div
+                v-show="reveal"
+                v-for="(e, index) in scoTitList"
+                :key="index + 'a'"
+              >
+                <div class="scoreStarBack" >
+                  <el-tooltip
+                    class="item"
+                    effect="dark"
+                    :content="e.value"
+                    placement="top"
+                  >
+                    <div class="briefTit">
+                      <img class="titRoot" src="../../../assets/icon/newIcons/blueRoot.png" alt="">
+                      {{ e.value }}
+                    </div>
+                  </el-tooltip>
+                  <el-rate v-model="e.cog"></el-rate>
+                </div>
+              </div>
+              <div
+                v-show="!reveal"
+                v-for="(e, index) in scoTitList.slice(0, 3)"
+                :key="index + 'b'"
+              >
+                <div class="scoreStarBack">
+                  <el-tooltip
+                    class="item"
+                    effect="dark"
+                    :content="e.value"
+                    placement="top"
+                  >
+                    <div class="briefTit">
+                      <img class="titRoot" src="../../../assets/icon/newIcons/blueRoot.png" alt="">
+                      {{ e.value }}
+                    </div>
+                  </el-tooltip>
+                  <el-rate v-model="e.cog"></el-rate>
+                </div>
+              </div>
+            </div>
+
+            <div
+              v-if="reveal && scoTitList.length > 3"
+              class="scoreStar2"
+              @click="revealBtn"
+            >
+              折叠 <i class="el-icon-arrow-up"></i>
+            </div>
+            <div
+              v-if="!reveal && scoTitList.length > 3"
+              class="scoreStar2"
+              @click="revealBtn"
+            >
+              全部 <i class="el-icon-arrow-down"></i>
+            </div>
+          </div>
+          <div class="AreaCss">
+            <el-input
+              type="textarea"
+              placeholder="您可在此输入评语"
+              v-model="textarea"
+              style="padding-bottom: 10px;"
+            >
+            </el-input>
+            <div
+              class="AreaBtn"
+              v-if="
+                currentUid.type == 10 || currentUid.type == 13 || isMarkCom == 1
+              "
+              @click="generateMsg(currentUid)"
+            >
+              <span>重新生成</span>
+            </div>
+          </div>
+
+          <div
+            style="width:100%;display:flex;height: 25px;;justify-content: space-between;"
+          >
+            <div
+              class="ScrBtn"
+              @click="AIsubmit(currentUid)"
+              v-if="
+                currentUid.type == 10 || currentUid.type == 13 || isMarkCom == 1
+              "
+            >
+              <img
+                src="../../../assets/icon/newIcons/Brootper.svg"
+                alt=""
+              />AI评分
+            </div>
+            <div v-else></div>
+
+            <div style="display: flex;">
+              <div
+                class="ScrBtn"
+                @click="reset"
+                style="color: rgba(0, 0, 0, 0.6);background-color: rgba(243, 247, 253, 1);border: none;"
+              >
+                重置
+              </div>
+              <div
+                class="ScrBtn"
+                @click="submit"
+                style="margin-left: 10px;color:#fff;border: none;background-color: rgba(54, 129, 252, 1);"
+              >
+                确认
+              </div>
+            </div>
+          </div>
+        </div>
+
+        <!-- 提交列表 -->
+        <div style="flex: 1;display: flex;flex-direction: column;overflow: auto;">
+          <div class="workListTit" @click="workListTitBtn">
+            <i class="el-icon-arrow-down"></i>提交列表({{ workList.length }})
+          </div>
+          <div style="overflow: auto;flex: 1;">
+            <div
+              v-if="workListShow"
+              v-for="(i, index) in workList"
+              :key="index"
+              :class="['schPer', i.userid == DgUid ? 'selBlock' : '']"
+              style="cursor: pointer;"
+              @click="cutPer(i.userid)"
+            >
+              <img v-if="i.headportrait" :src="i.headportrait" alt="" />
+              <img
+                v-else
+                src="https://beta.pbl.cocorobo.cn/pbl-teacher-table/dist/static/img/portal.b3cf7fa.png"
+                alt=""
+              />
+
+              <div class="con">
+                <div class="tit">
+                  <span
+                    style="font-size: 14px;color: rgba(0, 0, 0, 0.9);font-weight: 400;"
+                    >{{ i.name }}</span
+                  >
+
+                  <span
+                    style="font-size: 14px;color:rgba(0, 0, 0, 0.4);"
+                    v-if="i.markSco == null"
+                    >未评分</span
+                  >
+                  <span
+                    v-else
+                    style="font-size: 16px;color: rgba(0, 0, 0, 0.9);font-weight: 600;"
+                    >{{ i.markSco }}</span
+                  >
+                </div>
+                <div class="Timer">{{ i.time }}</div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 作业展示区 -->
+    <div class="Rig">
+      <div class="RigTop">
+        <div
+          style="display: flex;align-items: center;justify-content: space-between;width: 100%;"
+        >
+          <div
+            class="schPer"
+            style="border: none;width: 300px;padding: 0;margin: 0;"
+          >
+            <img
+              v-if="currentUid.headportrait"
+              :src="currentUid.headportrait"
+              alt=""
+            />
+            <img
+              v-else
+              src="https://beta.pbl.cocorobo.cn/pbl-teacher-table/dist/static/img/portal.b3cf7fa.png"
+              alt=""
+            />
+            <div class="con">
+              <div class="tit">
+                <span
+                  style="font-size: 14px;color: rgba(0, 0, 0, 0.9);font-weight: 400;"
+                  >{{ currentUid.name }}</span
+                >
+              </div>
+              <div class="Timer">{{ currentUid.time }}</div>
+            </div>
+          </div>
+          <div class="cutStuBtn">
+            <div>
+              <span @click="prevStu" style="cursor: pointer;">上一个</span>
+            </div>
+            <div>
+              <span @click="nextStu" style="cursor: pointer;">下一个</span>
+            </div>
+            <!-- <div><span @click="prevStu" v-if="this.current > 0">上一个</span></div>
+            <div><span @click="nextStu" v-if="this.current < this.workList.length-1">下一个</span></div> -->
+          </div>
+        </div>
+      </div>
+      <div class="RigConTit">
+        <div :class="[cutNum ? '' : 'RigConTitOn']" @click="cutPage(0)">
+          学生作业
+        </div>
+        <div :class="[cutNum ? 'RigConTitOn' : '']" @click="cutPage(1)">
+          点赞与评论
+        </div>
+      </div>
+      <div class="RigCon">
+        <!-- 作业内容  -->
+        <div v-if="cutNum == 0" style="height: 100%;">
+          <div
+            v-if="
+              currentUid.type == 13 || currentUid.type == 10
+              // currentUid.type == 15
+            "
+          >
+            <div class="cont" v-html="currentUid.content.text"></div>
+          </div>
+          <div v-if="currentUid.type == 1">
+            <img
+              @click="previewImg(currentUid.content)"
+              style="max-width: 100%;object-fit: cover;"
+              :src="currentUid.content"
+              alt=""
+            />
+          </div>
+          <div v-if="currentUid.type == 3">
+            <div style="width: 100%;text-align: center;">
+              <div
+                style="margin-bottom: 20px;font-weight: 600;font-size: 16px;"
+              >
+                {{ currentUid.content[0].answerTitle }}
+              </div>
+              <div>{{ currentUid.content[0].answer }}</div>
+            </div>
+          </div>
+          <div v-if="currentUid.type == 4" style="height: 100%;">
+            <iframe
+              v-if="ifPdf == 1"
+              style="width: 100%; height: 99%; border: none"
+              :src="
+                'https://cloud.cocorobo.cn/pdf.js/web/viewer.html?file=' +
+                  encodeURIComponent(currentUid.content)
+              "
+            ></iframe>
+
+            <iframe
+              v-else
+              style="width: 100%; height: 100%; border: none"
+              :src="
+                'https://view.officeapps.live.com/op/view.aspx?src=' +
+                  encodeURIComponent(currentUid.content)
+              "
+              frameborder="0"
+            ></iframe>
+          </div>
+          <div v-if="currentUid.type == 12" style="height: 100%;">
+            <div>
+              <div
+                style="cursor: pointer;"
+                @click="downloadFile(currentUid.content)"
+              >
+                下载txt
+              </div>
+              <!-- <div>{{ currentUid.content }}</div> -->
+            </div>
+          </div>
+          <div v-if="currentUid.type == 15" style="height: 100%;">
+            <div
+              class="worksAnswer"
+              v-if="currentUid.content"
+              @click="
+                openCocoPi(57, toolIndex, currentUid.userid, currentUid.name)
+              "
+            >
+              <img src="../../../assets/icon/codeFile.png" />
+              <div>点击打开CocoPi</div>
+            </div>
+          </div>
+          <div v-if="currentUid.type == 5" style="height: 100%;">
+            <video-player
+              class="video-player vjs-custom-skin"
+              :playsinline="true"
+              :options="playerOptions"
+              @play="onPlayerPlay($event)"
+              style="width: 90%; height: 95%; margin: 0 0 0 30px"
+            ></video-player>
+          </div>
+        </div>
+        <!-- 点赞与评论  -->
+        <div v-if="cutNum == 1">
+          <div style="display: flex;align-items: center;">
+            <img
+              style="margin-right: 3px;"
+              src="../../../assets/icon/newIcons/likeG.png"
+              alt=""
+            />点赞({{ likeList.length }})
+          </div>
+          <div class="likeList">
+            <div v-for="i in likeList" :key="i.id">{{ i.username }}</div>
+          </div>
+          <div style="display: flex;align-items: center;">
+            <img
+              style="margin-right: 3px;"
+              src="../../../assets/icon/newIcons/commG.png"
+              alt=""
+            />评论({{ commentList.length }})
+          </div>
+          <div class="commentListCss" v-if="commentList.length">
+            <div
+              style="padding-bottom: 25px;display: flex;justify-content: space-between;"
+              v-for="i in commentList"
+              :key="i.id"
+            >
+              <div class="schPer2" style="border: none;width: 90%;padding: 0;">
+                <img v-if="i.headportrait" :src="i.headportrait" alt="" />
+                <img
+                  v-else
+                  src="https://beta.pbl.cocorobo.cn/pbl-teacher-table/dist/static/img/portal.b3cf7fa.png"
+                  alt=""
+                />
+                <div class="con">
+                  <div class="tit2">
+                    <div class="TitName">{{ i.username }}</div>
+                    <span
+                      style="font-size: 14px;color: rgba(0, 0, 0, 0.9);font-weight: 400;width: 200px;"
+                      >{{ i.time }}</span
+                    >
+                  </div>
+                  <div class="Timer">{{ i.comment }}</div>
+                </div>
+              </div>
+              <div>
+                <span
+                  style="color: #3B7BD7;cursor: pointer;"
+                  @click="deleteComment(i.id)"
+                  >删除</span
+                >
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { v4 as uuidv4 } from "uuid";
+
+export default {
+  props: [
+    "uid",
+    "stage",
+    "toolIndex",
+    "task",
+    "scoTit",
+    "markScoreVisible",
+    "markScoreworksStudent"
+  ],
+  data() {
+    return {
+      textarea: "",
+      reveal: false, //得分详情框全部与折叠
+      workListShow: true, //作业显示
+      cutNum: 0, //作业与评论切换
+      scoTitList: [], //得分详情框数据
+      workList: [], //作业列表
+      cid: this.$route.query.courseId,
+      cUserid: this.$route.query.userid, //账号登录人id
+      cuScoCon: "",
+      currentUid: {}, //当前评分框学生信息
+      current: "", //上一位下一位中的第几位
+      DgUid: this.uid, //当前评分框学生id
+      likeList: [], //喜欢list
+      commentList: [], //评分list
+      workId: "", //作业id。用于分类评论与点赞list
+      vLoading: false,
+      allSco: 0,
+      ifPdf: 1,
+      ScLoading: false,
+      playerOptions: {
+        playbackRates: [0.7, 1.0, 1.5, 2.0], //播放速度
+        autoplay: false, //如果true,浏览器准备好时开始回放。
+        muted: false, // 默认情况下将会消除任何音频。
+        loop: false, // 导致视频一结束就重新开始。
+        preload: "auto", // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
+        language: "zh-CN",
+        aspectRatio: "16:9", // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
+        fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
+        sources: [
+          {
+            type: "video/mp4", //这里的种类支持很多种:基本视频格式、直播、流媒体等,具体可以参看git网址项目   || "video/ogg"|| "video/webm"
+            src: "" //url地址require("../../../assets/media/aaa.mp4")
+          }
+        ],
+        // poster: require("../../../assets/tu31.png"), //你的封面地址
+        // poster: dataRes.imgUrl, //你的封面地址
+        notSupportedMessage: "此视频暂无法播放,请稍后再试", //允许覆盖Video.js无法播放媒体源时显示的默认信息。
+        controlBar: {
+          timeDivider: true, //当前时间和持续时间的分隔符
+          durationDisplay: true, //显示持续时间
+          remainingTimeDisplay: false, //是否显示剩余时间功能
+          fullscreenToggle: true //全屏按钮
+        }
+      },
+      xianObj: ["DOCX", "MD", "TXT", "PDF"]
+    };
+  },
+  watch: {
+    markScoreVisible(newVal) {
+      this.workListShow = true;
+      this.reveal = false;
+      this.cutNum = 0;
+      this.textarea = "";
+      this.scoTitList = JSON.parse(JSON.stringify(this.scoTit));
+      this.selectSWorksData();
+    }
+  },
+  computed: {
+    totalScore() {
+      let a = 0;
+
+      this.scoTitList.forEach(e => {
+        if (e.cog) {
+          a += e.cog * 1;
+        }
+      });
+      
+      return (a / this.scoTit.length).toFixed(1);
+    },
+    isMarkCom() {
+      // console.log('a',this.currentUid);
+      if (this.currentUid.type == 4 || this.currentUid.type == 12) {
+        let a = this.currentUid.content.slice(
+          this.currentUid.content.lastIndexOf(".") + 1
+        );
+
+        if (this.xianObj.indexOf(a.toUpperCase()) != -1) {
+          return 1;
+        } else {
+          return 0;
+        }
+      } else {
+        return 0;
+      }
+    }
+  },
+  mounted() {
+    this.scoTitList = JSON.parse(JSON.stringify(this.scoTit));
+
+    this.selectSWorksData();
+  },
+  methods: {
+    // 预览图片
+    previewImg(url) {
+      //预览图片
+      this.$hevueImgPreview(url);
+    },
+    onPlayerPlay() {},
+
+    // 获取文档id
+    createFileid(url) {
+      let _this = this;
+      return new Promise((resolve, reject) => {
+        try {
+          _this.ajax
+            .put("https://gpt4.cocorobo.cn/upload_file_knowledge", {
+              url: url
+            })
+            .then(res => {
+              let _data = res.data.FunctionResponse;
+              if (_data.result && _data.result.id) {
+                resolve(_data.result.id);
+              } else {
+                resolve(1);
+              }
+            })
+            .catch(function(error) {
+              resolve(1);
+            });
+        } catch (e) {
+          resolve(1);
+        }
+      });
+    },
+
+    // 老师提交评分
+    submit() {
+      let data = this.scoTitList.map(e => {
+        return e.value + ":" + e.cog;
+      });
+      // console.log("data", data);
+      const processedData = {};
+
+      data.forEach(item => {
+        const [key, value] = item.split(":");
+        processedData[key] = Number(value) ? Number(value) : 0;
+      });
+
+      processedData.content = this.textarea;
+      // console.log(processedData);
+      let params = {
+        cid: this.cid,
+        s: this.stage,
+        t: this.task,
+        rate: JSON.stringify(processedData),
+        uid: this.DgUid
+      };
+      // return console.log(params);
+      this.ajax
+        .get(this.$store.state.api + "updateWorksEva", params)
+        .then(res => {
+          this.$message({
+            message: "评价成功",
+            type: "success"
+          });
+          this.ScLoading = false;
+
+          this.selectSWorksData();
+          // this.$emit("refreshOther", this.toolIndex);
+        })
+        .catch(err => {
+          this.$message.error("评价失败");
+          console.error(err);
+        });
+    },
+
+    // 重置
+    reset() {
+      this.scoTitList.forEach(e => {
+        e.cog = 0;
+      });
+      this.textarea = "";
+      // this.scoTitList = JSON.parse(JSON.stringify(this.scoTit));
+    },
+
+    async generateMsg(work) {
+      this.ScLoading = true;
+      let tit = this.scoTit;
+      tit.forEach((e, index) => {
+        if (!e.isai) {
+          e.isai = 1;
+        }
+      });
+      let _fileid = "";
+      if (work.type == 4 || work.type == 12) {
+        _fileid = await this.createFileid(work.content);
+      }
+      let con = this.cuScoCon;
+
+      let laws = "";
+      for (let i = 0; i < tit.length; i++) {
+        if (tit[i].isai == 1) {
+          laws += `评价维度:${tit[i].value} 评价细则:${tit[i].rule} \n`;
+        }
+      }
+      let msg = `NOTICE
+          Role:你是一个专业的项目式学习导师,你要对学生的评价高度负责。你要根据“六级评价细则”评价学生作业。
+          Language: Please use the same language as the user requirement, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
+          ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example".
+          Instruction: Based on the context, follow "Format example", write content.
+
+          #Context
+          ##要求
+          根据<评价细则>和<作业内容>的相关性评价作业,只用输出作业的综合性“评语”,不要带标题,字数控制在150字左右,不要输出其他无关内容。
+
+
+          ##评分资料
+          评价细则:${laws}
+          作业内容:${_fileid ? "上传的文件内容" : con}
+
+
+          # Format example
+          学生能够全面且正确地描述光合作用中氧气和葡萄糖的生成过程,涵盖光反应和暗反应的每个阶段和主要反应物及产物。同时,学生也能够全面、准确地解释氧气和葡萄糖在植物生命活动中的重要作用,并展示了对光合作用的深入理解。论文结构良好,内容详实,逻辑清晰,论据充分。
+          `;
+      // return console.log(msg);
+
+      this.generateRemark(msg, _fileid);
+    },
+    // 重新获取评语
+    generateRemark(messages, _fileid) {
+      let _this = this;
+
+      let params = {
+        assistant_id: "f8e1ebb2-2e0d-11ef-8bf4-12e77c4cb76b",
+        message: [
+          {
+            type: "text",
+            text: messages.replaceAll("\n", " ").replaceAll("*", "")
+          }
+        ],
+        session_name: uuidv4(),
+        userId: this.cUserid,
+        file_ids: _fileid ? [_fileid] : [],
+        model: "gpt-4o-2024-08-06"
+      };
+      this.ajax
+        .post("https://gpt4.cocorobo.cn/ai_agent_park_chat", params)
+        .then(response => {
+          let data = response.data.FunctionResponse;
+          // console.log("data", data);
+          this.textarea = data.message;
+          // this.selectSWorksData()
+          this.ScLoading = false;
+        })
+        .catch(error => {
+          this.ScLoading = false;
+
+          _this.$message.error("评价失败");
+          console.log(error);
+        });
+    },
+    // ai评分
+    async AIsubmit(work) {
+      // return console.log("con", this.scoTit, this.cuScoCon);
+      this.ScLoading = true;
+      let _fileid = "";
+      if (work.type == 4 || work.type == 12) {
+        _fileid = await this.createFileid(work.content);
+      }
+      let tit = JSON.parse(JSON.stringify(this.scoTit));
+      tit.forEach((e, index) => {
+        if (!e.isai) {
+          e.isai = 1;
+        }
+      });
+      let con = this.cuScoCon;
+
+      let laws = "";
+      for (let i = 0; i < tit.length; i++) {
+        if (tit[i].isai == 1) {
+          let a = tit[i].value
+          let result = a.match(/[\u4e00-\u9fa5a-zA-Z]+/g).join("");
+        
+          laws += `评价维度:“${result}”, 评价细则:${tit[i].rule} \n`;
+        }
+      }
+
+      let msg = `NOTICE
+      Role: 你是一个专业的项目式学习导师,你要对学生的评价高度负责。你要根据“六级评价细则”给学生作品评分,并生成需要的JSON数据。
+      Language: Please use the same language as the user requirement, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
+      ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example".
+      Instruction: Based on the context, follow "Format example", write content.
+
+      #Context
+      ##要求
+      根据<评价细则>和<作业内容>的相关性评价作业,判断该作业属于六级中的哪个等级,结合“评价细则”和等级写评语。如果作业内容与评价细则无关,则直接评为0星。
+
+      ##评分资料
+      评价细则:${laws}
+      作业内容:${_fileid ? "上传的文件内容" : con}
+
+      #输出要求#
+      输出每个维度的“等级”和作业的综合性“评语”
+      “评语”控制在150字左右
+      评价维度要按原样输出,只输出 ##评分资料 “评分细则”引号内的
+
+
+      # Format example
+      [{'评价维度':'评价等级0-5(数字)'},{'评价维度':'评价等级0-5(数字)'},{'评价维度':'评价等级0-5(数字)'},{'评价维度':'评价等级0-5(数字)'},{'评语':'评语(150个字左右)'}]
+      `;
+      // console.log(msg);
+      this.aiGet2(msg, _fileid);
+    },
+
+    // ai打分
+    aiGet2(messages, _fileid) {
+      let _this = this;
+
+      let params = {
+        assistant_id: "6063369f-289a-11ef-8bf4-12e77c4cb76b",
+        message: [
+          {
+            type: "text",
+            text: messages.replaceAll("\n", " ").replaceAll("*", "")
+          }
+        ],
+        session_name: uuidv4(),
+        userId: this.cUserid,
+        file_ids: _fileid ? [_fileid] : [],
+        model: "gpt-4o-2024-08-06"
+      };
+      this.ajax
+        .post("https://gpt4.cocorobo.cn/ai_agent_park_chat", params)
+        .then(response => {
+          let data = response.data.FunctionResponse;
+          console.log("data", data);
+          if (data.message) {
+            let dArray = {};
+            try {
+              dArray = JSON.parse(
+                data.message.replaceAll("```json", "").replaceAll("```", "")
+              );
+            } catch (error) {
+              console.log("error_________________" + error);
+              try {
+                let regex = new RegExp("(?<=```json)([\\s\\S]*?)(?=```)");
+
+                let match = data.message.match(regex);
+                dArray = JSON.parse(
+                  match[0]
+                    .replace(/\n/g, "")
+                    .replace(/\s{2,}/g, "")
+                    .replace(/\'/g, '"')
+                );
+              } catch (error) {
+                try {
+                  dArray = JSON.parse(
+                    data.message
+                      .replaceAll("```json", "")
+                      .replaceAll("# Solution", "")
+                      .replaceAll("```", "")
+                      .replace(/\n/g, "")
+                      .replace(/\s{2,}/g, "")
+                      .replace(/\'/g, '"')
+                  );
+                } catch (error) {
+                  console.log("error_________________" + error);
+                }
+                console.log("error_________________" + error);
+              }
+            }
+
+            let processedData = {};
+            // console.log(JSON.parse(JSON.stringify(dArray)));
+
+            dArray.forEach(function(item) {
+              let key = Object.keys(item)[0];
+              let value = item[key];
+              processedData[key] = value;
+            });
+
+            // console.log(JSON.parse(JSON.stringify(processedData)));
+
+            for (const key in processedData) {
+              if (key == "评语") {
+                processedData.content = processedData[key];
+              }
+            }
+            delete processedData["评语"];
+            console.log("processedData", processedData);
+
+            let params = {
+              cid: _this.cid,
+              s: _this.stage,
+              t: _this.task,
+              rate: JSON.stringify(processedData),
+              uid: _this.DgUid
+            };
+            // console.log("params", params);
+            _this.ajax
+              .get(_this.$store.state.api + "updateWorksEva", params)
+              .then(res => {
+                _this.$message({
+                  message: "评价成功",
+                  type: "success"
+                });
+
+                _this.ScLoading = false;
+                _this.selectSWorksData();
+              })
+              .catch(err => {
+                _this.ScLoading = false;
+                _this.$message.error("评价失败");
+
+                console.error(err);
+              });
+          }
+          this.$forceUpdate();
+        })
+        .catch(error => {
+          _this.$message.error("评价失败");
+          _this.ScLoading = false;
+
+          console.log(error);
+        });
+    },
+    // 上一个
+    prevStu() {
+      if (this.ScLoading) return this.$message.info("请稍后,正在ai评价中");
+      if (this.current > 0) {
+        this.current--;
+        this.DgUid = this.workList[this.current].userid;
+        this.selectSWorksData();
+      } else {
+        this.$message.info("已经是第一位了");
+      }
+    },
+    // 下一个
+    nextStu() {
+      if (this.ScLoading) return this.$message.info("请稍后,正在ai评价中");
+
+      if (this.current < this.workList.length - 1) {
+        this.current++;
+        this.DgUid = this.workList[this.current].userid;
+        this.selectSWorksData();
+      } else {
+        this.$message.info("已经是最后一位了");
+      }
+    },
+    // 提交列表点击切换
+    cutPer(val) {
+      if (this.ScLoading) return this.$message.info("请稍后,正在ai评价中");
+
+      this.DgUid = val;
+      this.selectSWorksData();
+    },
+    // 任务得分折叠
+    revealBtn() {
+      this.reveal = !this.reveal;
+    },
+    // 提交列表折叠
+    workListTitBtn() {
+      this.workListShow = !this.workListShow;
+    },
+    // 点赞与评论切换
+    cutPage(val) {
+      this.cutNum = val;
+    },
+    // 删除评论
+    deleteComment(wid) {
+      this.$confirm("确定删除此评论吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      })
+        .then(() => {
+          let params = {
+            id: wid
+          };
+          this.ajax
+            .get(this.$store.state.api + "deleteComment2", params)
+            .then(res => {
+              this.$message({
+                message: "删除评论成功",
+                type: "success"
+              });
+              this.selectSWorksData();
+            })
+            .catch(err => {
+              console.error(err);
+            });
+        })
+        .catch(() => {});
+    },
+    openCocoPi(tool, i, uid, uname) {
+      // return console.log('?????',tool, i, uid, uname);
+
+      let student = {
+        userid: uid,
+        student: uname
+      };
+      if (tool == 57) {
+        window.parent.postMessage(
+          {
+            tools: tool + "teacher",
+            cid: this.cid,
+            stage: this.stage,
+            task: this.task,
+            tool: this.toolIndex,
+            student: student
+          },
+          "*"
+        );
+      }
+    },
+    //全部作业
+    selectSWorksData() {
+      this.vLoading = true;
+      this.textarea = "";
+
+      let params = {
+        uid: this.DgUid,
+        cid: this.cid,
+        s: this.stage,
+        t: this.task,
+        g: this.toolIndex
+      };
+      // return console.log(params);
+      this.ajax
+        .get(this.$store.state.api + "selectMarkDialogWorks", params)
+        .then(res => {
+          let data = res.data[0];
+
+          data.forEach(e => {
+            if (e.rate) {
+              let data2 = JSON.parse(e.rate);
+
+              e.markSco = 0;
+              let k = 0
+
+              for (const key in data2) {
+                if (data2[key] && key != "content" || data2[key] == "0" ) {
+                  e.markSco += data2[key] * 1;
+                }else{
+                  k += 1
+                }
+              }
+              
+              if (k > 1) {
+                e.markSco = null;
+              }else{
+                e.markSco = (e.markSco / this.scoTitList.length).toFixed(1);
+              }
+            } else {
+              e.markSco = null;
+            }
+          });
+          this.workList = data;
+
+          data.forEach((e, index) => {
+            if (e.userid == this.DgUid) {
+              this.currentUid = e;
+
+              if (
+                this.currentUid.type == 3 ||
+                this.currentUid.type == 10 ||
+                this.currentUid.type == 13
+                // this.currentUid.type == 15
+              ) {
+                this.currentUid.content = JSON.parse(e.content);
+                this.cuScoCon = this.currentUid.content.text;
+              }
+              if (this.currentUid.type == 4) {
+                let a = this.currentUid.content;
+                let data = a.slice(a.lastIndexOf(".") + 1);
+                this.cuScoCon = this.currentUid.content;
+
+                if (data == "pdf") {
+                  this.ifPdf = 1;
+                } else {
+                  this.ifPdf = 0;
+                }
+              }
+              if (this.currentUid.type == 5) {
+                this.playerOptions.sources[0].src = this.currentUid.content;
+              }
+              this.current = index;
+              this.workId = e.id;
+              this.appraise(e);
+            }
+          });
+
+          let likeData = res.data[1];
+          this.likeList = [];
+          likeData.forEach(e => {
+            if (e.workId == this.workId) {
+              this.likeList.push(e);
+            }
+          });
+
+          let commentData = res.data[2];
+          this.commentList = [];
+          commentData.forEach(e => {
+            if (e.workId == this.workId) {
+              this.commentList.push(e);
+            }
+          });
+          this.vLoading = false;
+        });
+    },
+    downloadFile(url) {
+      var credentials = {
+        accessKeyId: "AKIATLPEDU37QV5CHLMH",
+        secretAccessKey: "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"
+      }; //秘钥形式的登录上传
+      window.AWS.config.update(credentials);
+      window.AWS.config.region = "cn-northwest-1"; //设置区域
+      let url2 = url;
+      let _url2 = "";
+      if (
+        url2.indexOf("https://view.officeapps.live.com/op/view.aspx?src=") != -1
+      ) {
+        _url2 = url2.split(
+          "https://view.officeapps.live.com/op/view.aspx?src="
+        )[1];
+      } else {
+        _url2 = url2;
+      }
+      const loading2 = this.$loading.service({
+        background: "rgba(255, 255, 255, 0.7)",
+        target: document.body,
+        text: "文件加载中..."
+      });
+      var s3 = new window.AWS.S3({ params: { Bucket: "ccrb" } });
+      let name = decodeURIComponent(
+        _url2.split("https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/")[1]
+      );
+      var params = {
+        Bucket: "ccrb",
+        Key: name
+      };
+      s3.getObject(params, function(err, data) {
+        loading2.close();
+        if (err) console.log(err, err.stack);
+        // an error occurred
+        else {
+          let url = window.URL.createObjectURL(new Blob([data.Body]));
+          let a = document.createElement("a");
+          a.name = name;
+          a.href = url;
+          a.download = name;
+          a.click();
+          console.log(data);
+        } // sxuccessful response
+      });
+    },
+    // 处理任务的分展示
+    appraise(val) {
+      if (val.rate) {
+        // this.scoTitList = JSON.parse(JSON.stringify(this.scoTit));
+        // console.log("val.rate", val.rate);
+
+        let data = JSON.parse(val.rate);
+        this.scoTitList.forEach((e, index) => {
+          e.cog = null;
+          for (const key in data) {
+            // if (e.value.endsWith("。")) {
+            //   e.value = e.value.slice(0, -1); // 如果字符串以句号结尾,则去除最后一个字符
+            // }
+
+            let result = e.value.match(/[\u4e00-\u9fa5a-zA-Z]+/g).join("");
+            let key2 = key.match(/[\u4e00-\u9fa5a-zA-Z]+/g).join("");
+
+
+
+            if (result.indexOf(key2) != -1) {
+              e.cog = data[key];
+            }
+            if ("content" == key) {
+              this.textarea = data[key];
+            }
+          }
+        });
+      } else {
+        this.scoTitList.forEach(e => {
+          e.cog = 0;
+        });
+      }
+    }
+  }
+};
+</script>
+
+<style scoped>
+.markDialog {
+  display: flex;
+  /* height: 100%; */
+  min-height: 600px;
+  height: 100%;
+}
+.left {
+  /* overflow: auto; */
+  width: 310px;
+  /* border-right: 1px rgba(231, 231, 231, 1) solid; */
+  padding: 20px 20px 0;
+  box-sizing: border-box;
+  padding-right: 10px;
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+}
+
+.Rig {
+  flex: 1;
+  padding: 15px;
+  display: flex;
+  flex-direction: column;
+}
+.RigTop {
+  border-bottom: 1px rgba(231, 231, 231, 1) solid;
+  padding: 0px 0 15px;
+}
+.AreaCss {
+  position: relative;
+  margin-bottom: 5px;
+}
+.AreaCss >>> .el-textarea__inner {
+  min-height: 150px !important;
+  /* max-height: 150px; */
+  padding-bottom: 20px;
+}
+.AreaBtn {
+  position: absolute;
+  width: calc(100% - 30px);
+  text-align: right;
+  background-color: #fff;
+  bottom: 11px;
+  right: 20px;
+  color: rgba(54, 129, 252, 1);
+  cursor: pointer;
+}
+.likeList {
+  width: 100%;
+  display: flex;
+  padding: 10px 0;
+  flex-wrap: wrap;
+}
+.likeList > div {
+  padding: 4px 0px;
+  background-color: rgba(243, 247, 253, 1);
+  margin-right: 10px;
+  width: calc((100% - 60px) / 7);
+  text-align: center;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  margin-bottom: 10px;
+}
+.likeList > div:nth-child(7n) {
+  margin-right: 0px;
+}
+.commentListCss {
+  background-color: #fafafa;
+  padding: 25px 15px 0;
+  box-sizing: border-box;
+  margin-top: 10px;
+  border-radius: 5px;
+}
+.RigConTit {
+  width: 100%;
+  display: flex;
+  margin: 10px 0;
+}
+.RigConTit > div {
+  font-size: 14px;
+  color: rgba(0, 0, 0, 0.6);
+  padding: 8px;
+  cursor: pointer;
+}
+.RigConTitOn {
+  border-bottom: 3px solid rgba(54, 129, 252, 1);
+}
+.RigCon {
+  width: 100%;
+  overflow: auto;
+  flex: 1;
+  padding: 10px 0;
+  box-sizing: border-box;
+  /* background-color: aqua; */
+}
+.selBlock {
+  background-color: #f3f7fd !important;
+  border: 1px #68a0fc solid !important;
+}
+.cutStuBtn {
+  display: flex;
+  color: rgba(54, 129, 252, 1);
+}
+.cutStuBtn > div {
+  margin-left: 10px;
+}
+.scoreTit {
+  font-size: 16px;
+  font-weight: 600;
+  display: flex;
+  justify-content: space-between;
+  box-sizing: border-box;
+  color: rgba(0, 0, 0, 0.9);
+}
+.allD {
+  margin: 10px 0;
+  min-height: 60px;
+  background-color: #f3f7fd;
+  margin-left: 17px;
+
+}
+.scoreStar2 {
+  padding: 0 10px 10px;
+  height: 100%;
+  flex: 1;
+  color: rgba(54, 129, 252, 1);
+  cursor: pointer;
+}
+.scoreStar {
+  padding: 0px 10px 10px;
+  height: 100%;
+  flex: 1;
+}
+
+.scoreStarBack {
+  flex: 1;
+  display: flex;
+  justify-content: space-between;
+  padding-top: 10px;
+  position: relative;
+}
+/* .scoreStar > div:first-child > .scoreStarBack {
+  margin-top: 0;
+} */
+.ScrBtn {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  cursor: pointer;
+  padding: 2px 8px;
+  border-radius: 5px;
+  color: rgba(54, 129, 252, 1);
+  border: 1px rgba(54, 129, 252, 1) solid;
+}
+.worksAnswer {
+  color: #4078dd;
+  margin: 10px 0;
+  font-size: 16px;
+  display: flex;
+  align-items: center;
+  cursor: pointer;
+}
+
+.worksAnswer > img {
+  width: 100%;
+  height: 300px;
+  object-fit: contain;
+  margin: 0 auto;
+  display: block;
+}
+
+.briefTit {
+  width: 120px;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  white-space: nowrap;
+  
+}
+.briefTit > .titRoot{
+  position: absolute;
+  top: 0;
+  left: -27px;
+  transform: translate(0,10px);
+}
+.workListTit {
+  color: rgba(0, 0, 0, 0.6);
+  font-size: 12px;
+  font-weight: 400;
+  margin: 10px 0;
+  cursor: pointer;
+}
+.schPer2 {
+  padding: 10px;
+  box-sizing: border-box;
+  display: flex;
+  border-radius: 5px;
+  border: 1px solid rgba(240, 242, 245, 1);
+  /* margin-bottom: 10px; */
+}
+.schPer2 > img {
+  width: 45px;
+  height: 45px;
+  border-radius: 50%;
+  object-fit: cover;
+}
+.schPer {
+  padding: 10px;
+  box-sizing: border-box;
+  display: flex;
+  border-radius: 5px;
+  border: 1px solid rgba(240, 242, 245, 1);
+  margin-bottom: 10px;
+}
+.schPer > img {
+  width: 40px;
+  height: 40px;
+  border-radius: 50%;
+  object-fit: cover;
+}
+.con {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  padding: 0 10px;
+  box-sizing: border-box;
+}
+.con > .tit {
+  width: 100%;
+  display: flex;
+  justify-content: space-between;
+}
+.con > .tit2 {
+  width: 100%;
+  display: flex;
+  margin-bottom: 15px;
+}
+
+.TitName {
+  width: 70px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  margin-right: 10px;
+}
+.worksAnswer {
+  color: #4078dd;
+  margin: 10px 0;
+  font-size: 16px;
+  position: relative;
+}
+
+.worksAnswer > img {
+  width: 500px;
+  height: 300px;
+  object-fit: contain;
+  margin: 0 auto;
+  display: block;
+}
+.cont {
+  overflow-wrap: break-word;
+  word-break: break-word;
+  white-space: pre-line;
+}
+.cont >>> table {
+  border-top: 1px solid #ccc;
+  border-left: 1px solid #ccc;
+}
+.cont >>> table td,
+.cont >>> table th {
+  border-bottom: 1px solid #ccc;
+  border-right: 1px solid #ccc;
+  padding: 5px 10px;
+  max-width: 0px;
+  height: 30px;
+  vertical-align: baseline;
+  box-sizing: border-box;
+}
+.video-player >>> .video-js {
+  height: 100%;
+}
+</style>

+ 191 - 64
src/components/easy2/commpont/markScore.vue

@@ -1,33 +1,65 @@
 <template>
   <div>
-    <div v-loading="loading">
+    <div v-loading="loading" style="cursor: pointer;" @click.stop="markScoreDigBtn">
       <div class="scoreTit">
         <div>任务得分</div>
         <div>{{ totalScore ? totalScore : 0 }}分</div>
       </div>
-      <div class="scoreStar">
-        <div v-for="(e, index) in scoTitList" :key="index">
-          <div class="scoreStarBack">
-            <el-tooltip
-              class="item"
-              effect="dark"
-              :content="e.value"
-              placement="top"
-            >
-              <div class="briefTit">{{ e.value }}</div>
-            </el-tooltip>
-
-            <el-rate v-model="e.cog"></el-rate>
+      <div class="allD">
+        <div class="scoreStarBack2">
+          <div
+            v-for="(e, index) in scoTitList"
+            :key="index"
+            style="height: 30px;"
+          >
+            <img
+              class="rootImg"
+              v-if="e.isai == 1 || !e.isai"
+              src="../../../assets/icon/newIcons/blueRoot.png"
+              alt=""
+            />
           </div>
         </div>
+        <div class="scoreStar">
+          <div v-for="(e, index) in scoTitList" :key="index">
+            <div class="scoreStarBack">
+              <el-tooltip
+                class="item"
+                effect="dark"
+                :content="e.value"
+                placement="top"
+              >
+                <div class="briefTit">
+                  {{ e.value }}
+                </div>
+              </el-tooltip>
+              <el-rate
+                disabled
+                disabled-void-color="#ccc"
+                v-model="e.cog"
+              ></el-rate>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="AreaCss">
+        {{ textarea }}
+        <!-- <el-input
+          type="textarea"
+          disabled
+          placeholder="您可在此输入评语"
+          v-model="textarea"
+          style="padding-bottom: 10px;"
+        >
+        </el-input> -->
       </div>
-      <div style="width:100%;display:flex;justify-content: flex-end;">
+      <!-- <div style="width:100%;display:flex;justify-content: flex-end;">
         <el-button size="mini" @click="reset">重置</el-button>
         <el-button type="primary" size="mini" @click="submit">确认</el-button>
         <el-button type="primary" size="mini" @click="AIsubmit"
           >AI评分</el-button
         >
-      </div>
+      </div> -->
     </div>
   </div>
 </template>
@@ -42,12 +74,9 @@ export default {
     "scoCon",
     "task",
     "stage",
-    "allData",
     "loading",
     "wIndex",
     "toolIndex",
-    "toolDetail",
-    "refreshKey"
   ],
 
   data() {
@@ -67,10 +96,10 @@ export default {
       let a = 0;
       let isPing = 0;
       this.scoTitList.forEach(e => {
-        if (!e.cog && e.cog != 0) {
-          isPing += 1;
-        } else {
+        if (e.cog || e.cog == "0") {
           a += e.cog * 1;
+        } else {
+          isPing += 1;
         }
       });
 
@@ -100,8 +129,38 @@ export default {
   },
 
   methods: {
+   
+    // // 获取文档id
+    createFileid(url) {
+      let _this = this;
+      return new Promise((resolve, reject) => {
+        try {
+          _this.ajax
+            .put("https://gpt4.cocorobo.cn/upload_file_knowledge", {
+              url: url
+            })
+            .then(res => {
+              let _data = res.data.FunctionResponse;
+              if (_data.result && _data.result.id) {
+                resolve(_data.result.id);
+              } else {
+                resolve(1);
+              }
+            })
+            .catch(function(error) {
+              resolve(1);
+            });
+        } catch (e) {
+          resolve(1);
+        }
+      });
+    },
+
     // 获取单个数据
     getData() {
+      // this.fileId =[]
+      // console.log(' this.scoCon', this.scoCon);
+      
       let params = {
         uid: this.scoCon.userid,
         cid: this.id
@@ -119,6 +178,8 @@ export default {
                 this.homeworkVal = res.data[0][index];
               }
             });
+            // console.log('data2',data2);
+            
             if (data2.length == 0) {
               this.scoTitList = JSON.parse(JSON.stringify(this.scoTit));
             } else {
@@ -126,8 +187,17 @@ export default {
               this.scoTitList.forEach((e, index) => {
                 e.cog = null;
                 for (const key in data) {
-                  if (e.value == key) {
-                    e.cog = data[key] * 1;
+                  // if (e.value.endsWith('。')) {
+                  //   e.value = e.value.slice(0, -1); // 如果字符串以句号结尾,则去除最后一个字符
+                  // }
+                  let result = e.value.match(/[\u4e00-\u9fa5a-zA-Z]+/g).join("");
+                  let key2 = key.match(/[\u4e00-\u9fa5a-zA-Z]+/g).join("");
+
+                  if (result.indexOf(key2) != -1) {
+                    e.cog = data[key];
+                  }
+                  if ("content" == key) {
+                    this.textarea = data[key];
                   }
                 }
               });
@@ -143,6 +213,16 @@ export default {
           console.error(err);
         });
     },
+    markScoreDigBtn() {
+      // console.log('11112222');
+
+      this.$emit("markScoreDig", {
+        val: this.stUid,
+        val2: this.toolIndex,
+        tit: this.scoTit,
+        uname:this.scoCon.sName
+      });
+    },
     // 重置
     reset() {
       this.scoTitList.forEach(e => {
@@ -164,7 +244,7 @@ export default {
         processedData[key] = Number(value) ? Number(value) : 0;
       });
 
-      processedData.content = "";
+      processedData.content = this.textarea;
       // console.log(processedData);
       let params = {
         cid: this.id,
@@ -192,11 +272,11 @@ export default {
     // ai评分
     AIsubmit() {
       let tit = this.scoTit;
-      tit.forEach((e,index)=>{
-          if(!e.isai){
-            e.isai=1
-          }
-        })
+      tit.forEach((e, index) => {
+        if (!e.isai) {
+          e.isai = 1;
+        }
+      });
       let con = JSON.parse(this.scoCon.works);
       this.$emit("updateLoading", {
         val: this.toolIndex,
@@ -209,14 +289,14 @@ export default {
           _text += `评价名称:${tit[i].value} 评价描述:${tit[i].detail} \n`;
         }
       }
-      let laws = ""
+      let laws = "";
       for (let i = 0; i < tit.length; i++) {
-        if(tit[i].isai == 1){
-          laws += `评价维度:${tit[i].value} 评价细则:${tit[i].rule} \n`
+        if (tit[i].isai == 1) {
+          laws += `评价维度:${tit[i].value} 评价细则:${tit[i].rule} \n`;
         }
       }
-      
-    //  console.log(_text);
+
+      //  console.log(_text);
       let msg = `NOTICE
       Role: 你是一个专业的项目式学习导师,你要对学生的评价高度负责。你要根据“六级评价细则”给学生作品评分,并生成需要的JSON数据。
       Language: Please use the same language as the user requirement, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
@@ -239,18 +319,24 @@ export default {
       // console.log(msg);
       this.aiGet2(msg);
     },
+
     // ai打分
     aiGet2(messages, callback) {
       // console.log(this.toolIndex, this.wIndex);
       let _this = this;
 
       let params = {
-        assistant_id: 'f8e1ebb2-2e0d-11ef-8bf4-12e77c4cb76b',
-        message: [{"type":"text", "text":messages.replaceAll('\n', " ").replaceAll('*', "")}],
+        assistant_id: "6063369f-289a-11ef-8bf4-12e77c4cb76b",
+        message: [
+          {
+            type: "text",
+            text: messages.replaceAll("\n", " ").replaceAll("*", "")
+          }
+        ],
         session_name: uuidv4(),
         userId: this.userid,
         file_ids: [],
-        model:'gpt-4o-2024-08-06'
+        model: "gpt-4o-2024-08-06"
       };
       this.ajax
         .post("https://gpt4.cocorobo.cn/ai_agent_park_chat", params)
@@ -261,9 +347,7 @@ export default {
             let dArray = {};
             try {
               dArray = JSON.parse(
-                data.message
-                  .replaceAll("```json", "")
-                  .replaceAll("```", "")
+                data.message.replaceAll("```json", "").replaceAll("```", "")
               );
             } catch (error) {
               console.log("error_________________" + error);
@@ -315,7 +399,7 @@ export default {
               }
             }
 
-            processedData.content = "";
+            processedData.content = this.textarea;
 
             let params = {
               cid: _this.id,
@@ -371,18 +455,23 @@ export default {
           console.log(error);
         });
     },
+
+
     // ai循环评分
-    aiupdetaSco(messages, uid, stage, task, callback) {
+    async aiupdetaSco(messages, uid, stage, task,_fileid, callback) {
       let _this = this;
-
       let params = {
-      
-        assistant_id: 'f8e1ebb2-2e0d-11ef-8bf4-12e77c4cb76b',
-        message: [{"type":"text", "text":messages.replaceAll('\n', " ").replaceAll('*', "")}],
+        assistant_id: "6063369f-289a-11ef-8bf4-12e77c4cb76b",
+        message: [
+          {
+            type: "text",
+            text: messages.replaceAll("\n", " ").replaceAll("*", "")
+          }
+        ],
         session_name: uuidv4(),
         userId: this.userid,
-        file_ids: [],
-        model:'gpt-4o-2024-08-06'
+        file_ids: _fileid ? [_fileid] : [],
+        model: "gpt-4o-2024-08-06"
       };
       return new Promise(resolve => {
         this.ajax
@@ -391,15 +480,11 @@ export default {
             let data = response.data.FunctionResponse;
             // console.log(data);
 
-            if (
-              data.message
-            ) {
+            if (data.message) {
               let dArray = {};
               try {
                 dArray = JSON.parse(
-                  data.message
-                    .replaceAll("```json", "")
-                    .replaceAll("```", "")
+                  data.message.replaceAll("```json", "").replaceAll("```", "")
                 );
               } catch (error) {
                 console.log("error_________________" + error);
@@ -441,12 +526,16 @@ export default {
               });
 
               for (const key in processedData) {
-                if (!Number.isFinite(processedData[key] * 1)) {
-                  processedData[key] = 0;
+                // if (!Number.isFinite(processedData[key] * 1)) {
+                //   processedData[key] = 0;
+                // }
+                if (key == "评语") {
+                  processedData.content = processedData[key];
                 }
               }
+              delete processedData["评语"];
 
-              processedData.content = "";
+              // processedData.content = this.textarea;
 
               let params = {
                 cid: _this.id,
@@ -480,7 +569,8 @@ export default {
             console.log(error);
           });
       });
-    }
+    },
+    
   }
 };
 </script>
@@ -490,21 +580,58 @@ export default {
   font-weight: 600;
   display: flex;
   justify-content: space-between;
+  box-sizing: border-box;
+}
+.allD {
+  margin: 5px 0;
+  display: flex;
+  width: 100%;
+  overflow: auto;
+  max-height: 100px;
+  min-height: 60px;
 }
 .scoreStar {
   background-color: #f3f7fd;
   padding: 10px;
-  margin: 10px 0;
-  max-height: 100px;
-  min-height: 60px;
-  overflow: auto;
+  height: 100%;
+  flex: 1;
+}
+.scoreStar > div:last-child > .scoreStarBack {
+  margin-bottom: 0;
 }
 .scoreStarBack {
-  width: 100%;
+  flex: 1;
   display: flex;
   justify-content: space-between;
   margin-bottom: 10px;
 }
+
+.rootImg {
+  padding-top: 1px;
+  box-sizing: border-box;
+  display: block;
+}
+
+.scoreStarBack2 {
+  padding: 10px 0;
+  margin-right: 2px;
+}
+
+.AreaCss {
+  margin-bottom: 5px;
+  -webkit-line-clamp: 2;
+  display: -webkit-box;
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  /* margin-left: 20px; */
+}
+.AreaCss >>> .el-textarea__inner {
+  min-height: 60px;
+  max-height: 150px;
+  padding-bottom: 20px;
+}
+
 .briefTit {
   width: 150px;
   text-overflow: ellipsis;

File diff ditekan karena terlalu besar
+ 757 - 16
src/components/easy2/studyStudent.vue


+ 1 - 1
src/components/easy3/studyStudent.vue

@@ -1360,10 +1360,10 @@
                     </div>
                     <div class="tooldetail" v-if="tool.toolDetail != ''" :class="{isUpdateToolDetailClass:toolDetailIndex == toolIndex}">
                       <!-- <div class="toolTitle">工具描述</div> -->
+                      <!-- @click.stop="updateToolDetail(toolIndex, 2)" 点击开启修改-->
                       <div style="height:100%;"
                         v-html="contentConvent(tool.toolDetail)"
                         v-if="toolDetailIndex != toolIndex"
-                        @click.stop="updateToolDetail(toolIndex, 2)"
                       ></div>
                       <div v-else @click.stop="" style="height:100%;">
                         <textarea @change="() => { $forceUpdate() }" class="checkTextArea" rows="3" v-autoHeight="70" type="text" placeholder="请输入任务描述" v-model="updateToolDetailInner"></textarea>

+ 1 - 1
src/components/studyStudent.vue

@@ -1329,10 +1329,10 @@
                     </div>
                     <div class="tooldetail" v-if="tool.toolDetail != ''" :class="{isUpdateToolDetailClass:toolDetailIndex == toolIndex}">
                       <!-- <div class="toolTitle">工具描述</div> -->
+                        <!-- @click.stop="updateToolDetail(toolIndex, 2)" -->
                       <div style="height:100%;"
                         v-html="contentConvent(tool.toolDetail)"
                         v-if="toolDetailIndex != toolIndex"
-                        @click.stop="updateToolDetail(toolIndex, 2)"
                       ></div>
                       <div v-else @click.stop="" style="height:100%;">
                         <textarea @change="() => { $forceUpdate() }" class="checkTextArea" rows="3" v-autoHeight="70" type="text" placeholder="请输入任务描述" v-model="updateToolDetailInner"></textarea>

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini