choiceQuestionDetailDialog.vue 117 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383
  1. <template>
  2. <div class="choiceQuestionDetailDialog">
  3. <div class="content" @click="clickContent(true)" :style="{
  4. width: slideWidth + 'px',
  5. height: slideHeight + 'px',
  6. }">
  7. <span v-show="false" class="closeIcon" @click.stop="closeSlideIndex()">
  8. <img src="../../../assets/img/close.png" />
  9. </span>
  10. <!-- 选择题 -->
  11. <div class="c_t45" v-if="workDetail && workDetail.type === '45' && props.showData">
  12. <div class="c_t45_title">
  13. <div class="c_title" v-if="props.showData.choiceQuestionListData[props.showData.workIndex]">
  14. <span>{{
  15. props.showData.choiceQuestionListData[props.showData.workIndex]
  16. .teststitle
  17. }}</span>
  18. <div class="switch_btn" v-if="props.isCreator && props.roleType == 1">
  19. <div class="switch">
  20. <Switch :value="canValue" @update:value="handleCanChange" />
  21. <span>{{ lang.ssShowResult }}</span>
  22. </div>
  23. </div>
  24. </div>
  25. <div class="c_t45_msg" v-if="props.roleType == 1">
  26. <div>{{ lang.ssAnswerCount }} {{ props.showData.workArray.length }}<span
  27. v-if="props.showData.unsubmittedStudents.length > 0">/{{ props.showData.workArray.length +
  28. props.showData.unsubmittedStudents.length
  29. }}</span></div>
  30. <span v-if="props.showData.unsubmittedStudents.length > 0" @click.stop="viewUnsubmittedStudents()">{{
  31. lang.ssViewSubmitStatus2 }}</span>
  32. </div>
  33. <!--<span class="c_t45_t_btn" :class="{'c_t45_t_btn_noActive': props.showData.workIndex <= 0}" @click="changeWorkIndex(0)">{{ lang.ssPrevQ }}</span>-->
  34. <!--<span class="c_t45_t_btn" :class="{'c_t45_t_btn_noActive': props.showData.workIndex >= props.showData.choiceQuestionListData.length - 1}" @click="changeWorkIndex(1)">{{ lang.ssNextQ }}</span>-->
  35. </div>
  36. <img class="c_t45_img" :src="props.showData.choiceQuestionListData[props.showData.workIndex]
  37. .timuList[0].src
  38. " v-if="props.showData.choiceQuestionListData[props.showData.workIndex] &&
  39. props.showData.choiceQuestionListData[props.showData.workIndex]
  40. .timuList.length > 0
  41. " @click.stop="previewImageToolRef.previewImage(props.showData.choiceQuestionListData[props.showData.workIndex]
  42. .timuList[0].src)" />
  43. <!-- <span class="c_t45_type" v-if="
  44. props.showData.choiceQuestionListData[props.showData.workIndex]
  45. .type === '1'
  46. ">{{ lang.ssSingleSel }}</span>
  47. <span class="c_t45_type" v-if="
  48. props.showData.choiceQuestionListData[props.showData.workIndex]
  49. .type === '2'
  50. ">{{ lang.ssMultiOpt }}</span> -->
  51. <!-- <span class="c_t45_type">{{ lang.ssChoiceQuestion }}</span> -->
  52. <div class="c_t45_echarts" :style="{
  53. width: slideWidth - 40 + 'px',
  54. }">
  55. <div id="echartsArea1" ref="echartsArea1"></div>
  56. </div>
  57. <div class="aiAnalysis" v-if="props.workArray.length > 0 && props.roleType == 1">
  58. <div class="ai_header">
  59. <div class="ai_title">
  60. <svg viewBox="0 0 1024 1024" width="200" height="200">
  61. <path
  62. d="M512 170.666667C323.477333 170.666667 170.666667 323.477333 170.666667 512s152.810667 341.333333 341.333333 341.333333 341.333333-152.810667 341.333333-341.333333S700.522667 170.666667 512 170.666667zM85.333333 512C85.333333 276.352 276.352 85.333333 512 85.333333s426.666667 191.018667 426.666667 426.666667-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512z">
  63. </path>
  64. <path
  65. d="M693.013333 330.986667a42.666667 42.666667 0 0 1 10.304 43.648l-75.413333 226.282666a42.666667 42.666667 0 0 1-26.986667 26.986667l-226.282666 75.413333a42.666667 42.666667 0 0 1-53.973334-53.973333l75.434667-226.261333a42.666667 42.666667 0 0 1 26.986667-26.986667l226.282666-75.413333a42.666667 42.666667 0 0 1 43.648 10.304z m-222.72 139.306666l-41.685333 125.098667 125.077333-41.706667 41.706667-125.077333-125.077333 41.706667z">
  66. </path>
  67. </svg>{{ lang.ssAnalysis }}
  68. </div>
  69. <div class="ai_refresh" :class="{ 'disabled': currentAnalysis && currentAnalysis.loading }"
  70. @click.stop="aiAnalysisRefresh45()">
  71. {{ lang.ssAIGenerate }}
  72. <svg viewBox="0 0 1024 1024" width="200" height="200">
  73. <path
  74. d="M875 483c-33.4 0-60.5 27.1-60.5 60.5v0.1C814.4 710.3 678.8 846 512 846S209.5 710.3 209.5 543.5 345.2 241 512 241c36.8 0 71.7 7.6 104.4 19.7-32 3-57.4 29.1-57.4 61.9 0 34.8 28.2 63 63 63h201.9c34.8 0 63-28.2 63-63V120c0-34.8-28.2-63-63-63s-63 28.2-63 63v81.4C691 150.5 605.2 120 512 120 278.1 120 88.5 309.6 88.5 543.5S278.1 967 512 967s423.5-189.6 423.5-423.5c0-33.4-27.1-60.5-60.5-60.5z">
  75. </path>
  76. </svg>
  77. </div>
  78. </div>
  79. <div class="ai_content" v-if="currentAnalysis && currentAnalysis.json">
  80. {{ currentAnalysis.json.text }}
  81. </div>
  82. <div class="ai_echartsData" v-if="currentAnalysis && currentAnalysis.json.keyword">
  83. {{ currentAnalysis.json.keyword }}
  84. </div>
  85. <div class="generatingContent" v-if="currentAnalysis && currentAnalysis.loading">
  86. {{ lang.ssGeneratingContent }}...</div>
  87. <div class="ai_updateTime" v-if="currentAnalysis">{{ lang.ssUpdateTime }}:{{ currentAnalysis.update_at }}
  88. </div>
  89. </div>
  90. <div class="cq_changeBtn" v-if="props.showData.choiceQuestionListData.length > 1">
  91. <div :class="{ cq_cb_disabled: props.showData.workIndex <= 0 }" @click.stop="changeWorkIndex(0)">
  92. <svg style="transform: rotate(-90deg);" viewBox="0 0 1024 1024" version="1.1" width="200" height="200">
  93. <path
  94. d="M512 330.666667c14.933333 0 29.866667 4.266667 40.533333 14.933333l277.33333399 234.666667c27.733333 23.466667 29.866667 64 8.53333301 89.6-23.466667 27.733333-64 29.866667-89.6 8.53333299L512 477.866667l-236.8 200.53333299c-27.733333 23.466667-68.266667 19.19999999-89.6-8.53333299-23.466667-27.733333-19.19999999-68.266667 8.53333301-89.6l277.33333399-234.666667c10.666667-10.666667 25.6-14.933333 40.533333-14.933333z"
  95. fill=""></path>
  96. </svg>
  97. </div>
  98. <span>{{ props.showData.workIndex + 1 }}/{{ props.showData.choiceQuestionListData.length }}</span>
  99. <div :class="{ cq_cb_disabled: props.showData.workIndex >= props.showData.choiceQuestionListData.length - 1 }"
  100. @click.stop="changeWorkIndex(1)">
  101. <svg style="transform: rotate(90deg);" viewBox="0 0 1024 1024" version="1.1" width="200" height="200">
  102. <path
  103. d="M512 330.666667c14.933333 0 29.866667 4.266667 40.533333 14.933333l277.33333399 234.666667c27.733333 23.466667 29.866667 64 8.53333301 89.6-23.466667 27.733333-64 29.866667-89.6 8.53333299L512 477.866667l-236.8 200.53333299c-27.733333 23.466667-68.266667 19.19999999-89.6-8.53333299-23.466667-27.733333-19.19999999-68.266667 8.53333301-89.6l277.33333399-234.666667c10.666667-10.666667 25.6-14.933333 40.533333-14.933333z"
  104. fill=""></path>
  105. </svg>
  106. </div>
  107. </div>
  108. </div>
  109. <!-- 投票 -->
  110. <div class="c_t45" v-if="workDetail && workDetail.type === '78' && props.showData">
  111. <div class="c_t45_title">
  112. <div class="c_title" v-if="props.showData.choiceQuestionListData[props.showData.workIndex]">
  113. <span>{{
  114. props.showData.choiceQuestionListData[props.showData.workIndex]
  115. .teststitle
  116. }}</span>
  117. <div class="switch_btn" v-if="props.isCreator && props.roleType == 1">
  118. <div class="switch">
  119. <Switch :value="canValue" @update:value="handleCanChange" />
  120. <span>{{ lang.ssShowResult }}</span>
  121. </div>
  122. <div class="switch">
  123. <Switch :value="anonymousValue" @update:value="handleAnonymousChange" />
  124. <span>{{anonymousValue ? lang.ssAnonymous : lang.ssRealName}}</span>
  125. </div>
  126. </div>
  127. </div>
  128. <div class="c_t45_msg" v-if="props.roleType == 1">
  129. <div>{{ lang.ssAnswerCount }} {{ props.showData.workArray.length }}<span
  130. v-if="props.showData.unsubmittedStudents.length > 0">/{{ props.showData.workArray.length +
  131. props.showData.unsubmittedStudents.length
  132. }}</span></div>
  133. <span v-if="props.showData.unsubmittedStudents.length > 0" @click.stop="viewUnsubmittedStudents()">{{
  134. lang.ssViewSubmitStatus2 }}</span>
  135. </div>
  136. <!--<span class="c_t45_t_btn" :class="{'c_t45_t_btn_noActive': props.showData.workIndex <= 0}" @click="changeWorkIndex(0)">{{ lang.ssPrevQ }}</span>-->
  137. <!--<span class="c_t45_t_btn" :class="{'c_t45_t_btn_noActive': props.showData.workIndex >= props.showData.choiceQuestionListData.length - 1}" @click="changeWorkIndex(1)">{{ lang.ssNextQ }}</span>-->
  138. </div>
  139. <img class="c_t45_img" :src="props.showData.choiceQuestionListData[props.showData.workIndex]
  140. .timuList[0].src
  141. " v-if="props.showData.choiceQuestionListData[props.showData.workIndex] &&
  142. props.showData.choiceQuestionListData[props.showData.workIndex]
  143. .timuList.length > 0
  144. " @click.stop="previewImageToolRef.previewImage(props.showData.choiceQuestionListData[props.showData.workIndex]
  145. .timuList[0].src)" />
  146. <!-- <span class="c_t45_type" v-if="
  147. props.showData.choiceQuestionListData[props.showData.workIndex]
  148. .type === '1'
  149. ">{{ lang.ssSingleSel }}</span>
  150. <span class="c_t45_type" v-if="
  151. props.showData.choiceQuestionListData[props.showData.workIndex]
  152. .type === '2'
  153. ">{{ lang.ssMultiOpt }}</span> -->
  154. <!-- <span class="c_t45_type">{{ lang.ssChoiceQuestion }}</span> -->
  155. <div class="c_t45_echarts" :style="{
  156. width: slideWidth - 40 + 'px',
  157. }">
  158. <div id="echartsArea1" ref="echartsArea1"></div>
  159. </div>
  160. <!-- v-if="props.workArray.length > 0" -->
  161. <div class="aiAnalysis" v-if="false">
  162. <div class="ai_header">
  163. <div class="ai_title">
  164. <svg viewBox="0 0 1024 1024" width="200" height="200">
  165. <path
  166. d="M512 170.666667C323.477333 170.666667 170.666667 323.477333 170.666667 512s152.810667 341.333333 341.333333 341.333333 341.333333-152.810667 341.333333-341.333333S700.522667 170.666667 512 170.666667zM85.333333 512C85.333333 276.352 276.352 85.333333 512 85.333333s426.666667 191.018667 426.666667 426.666667-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512z">
  167. </path>
  168. <path
  169. d="M693.013333 330.986667a42.666667 42.666667 0 0 1 10.304 43.648l-75.413333 226.282666a42.666667 42.666667 0 0 1-26.986667 26.986667l-226.282666 75.413333a42.666667 42.666667 0 0 1-53.973334-53.973333l75.434667-226.261333a42.666667 42.666667 0 0 1 26.986667-26.986667l226.282666-75.413333a42.666667 42.666667 0 0 1 43.648 10.304z m-222.72 139.306666l-41.685333 125.098667 125.077333-41.706667 41.706667-125.077333-125.077333 41.706667z">
  170. </path>
  171. </svg>{{ lang.ssAnalysis }}
  172. </div>
  173. <div class="ai_refresh" :class="{ 'disabled': currentAnalysis && currentAnalysis.loading }"
  174. @click.stop="aiAnalysisRefresh78()">
  175. {{ lang.ssAIGenerate }}
  176. <svg viewBox="0 0 1024 1024" width="200" height="200">
  177. <path
  178. d="M875 483c-33.4 0-60.5 27.1-60.5 60.5v0.1C814.4 710.3 678.8 846 512 846S209.5 710.3 209.5 543.5 345.2 241 512 241c36.8 0 71.7 7.6 104.4 19.7-32 3-57.4 29.1-57.4 61.9 0 34.8 28.2 63 63 63h201.9c34.8 0 63-28.2 63-63V120c0-34.8-28.2-63-63-63s-63 28.2-63 63v81.4C691 150.5 605.2 120 512 120 278.1 120 88.5 309.6 88.5 543.5S278.1 967 512 967s423.5-189.6 423.5-423.5c0-33.4-27.1-60.5-60.5-60.5z">
  179. </path>
  180. </svg>
  181. </div>
  182. </div>
  183. <div class="ai_content" v-if="currentAnalysis && currentAnalysis.json">
  184. {{ currentAnalysis.json.text }}
  185. </div>
  186. <div class="ai_echartsData" v-if="currentAnalysis && currentAnalysis.json.keyword">
  187. {{ currentAnalysis.json.keyword }}
  188. </div>
  189. <div class="generatingContent" v-if="currentAnalysis && currentAnalysis.loading">
  190. {{ lang.ssGeneratingContent }}...</div>
  191. <div class="ai_updateTime" v-if="currentAnalysis">{{ lang.ssUpdateTime }}:{{ currentAnalysis.update_at }}
  192. </div>
  193. </div>
  194. <div class="cq_changeBtn" v-if="props.showData.choiceQuestionListData.length > 1">
  195. <div :class="{ cq_cb_disabled: props.showData.workIndex <= 0 }" @click.stop="changeWorkIndex(0)">
  196. <svg style="transform: rotate(-90deg);" viewBox="0 0 1024 1024" version="1.1" width="200" height="200">
  197. <path
  198. d="M512 330.666667c14.933333 0 29.866667 4.266667 40.533333 14.933333l277.33333399 234.666667c27.733333 23.466667 29.866667 64 8.53333301 89.6-23.466667 27.733333-64 29.866667-89.6 8.53333299L512 477.866667l-236.8 200.53333299c-27.733333 23.466667-68.266667 19.19999999-89.6-8.53333299-23.466667-27.733333-19.19999999-68.266667 8.53333301-89.6l277.33333399-234.666667c10.666667-10.666667 25.6-14.933333 40.533333-14.933333z"
  199. fill=""></path>
  200. </svg>
  201. </div>
  202. <span>{{ props.showData.workIndex + 1 }}/{{ props.showData.choiceQuestionListData.length }}</span>
  203. <div :class="{ cq_cb_disabled: props.showData.workIndex >= props.showData.choiceQuestionListData.length - 1 }"
  204. @click.stop="changeWorkIndex(1)">
  205. <svg style="transform: rotate(90deg);" viewBox="0 0 1024 1024" version="1.1" width="200" height="200">
  206. <path
  207. d="M512 330.666667c14.933333 0 29.866667 4.266667 40.533333 14.933333l277.33333399 234.666667c27.733333 23.466667 29.866667 64 8.53333301 89.6-23.466667 27.733333-64 29.866667-89.6 8.53333299L512 477.866667l-236.8 200.53333299c-27.733333 23.466667-68.266667 19.19999999-89.6-8.53333299-23.466667-27.733333-19.19999999-68.266667 8.53333301-89.6l277.33333399-234.666667c10.666667-10.666667 25.6-14.933333 40.533333-14.933333z"
  208. fill=""></path>
  209. </svg>
  210. </div>
  211. </div>
  212. </div>
  213. <!-- 问答题 -->
  214. <div class="c_t15" v-if="workDetail && workDetail.type === '15' && props.showData">
  215. <div class="c_t15_title">
  216. <div class="c_title">
  217. <span>{{ workDetail.json.answerQ }}</span>
  218. <div class="switch_btn" v-if="props.isCreator && props.roleType == 1">
  219. <div class="switch">
  220. <Switch :value="canValue" @update:value="handleCanChange" />
  221. <span>{{ lang.ssShowResult }}</span>
  222. </div>
  223. <div class="switch">
  224. <Switch :value="likeValue" @update:value="handleLikeChange" />
  225. <span>{{ lang.ssLike }}</span>
  226. </div>
  227. </div>
  228. </div>
  229. </div>
  230. <span class="c_t15_type">{{ lang.ssQATest }}</span>
  231. <div class="c_t15_msg" v-if="props.roleType == 1">
  232. <div>{{ lang.ssAnswerCount }} {{ props.showData.workArray.length }}<span
  233. v-if="props.showData.unsubmittedStudents.length > 0">/{{ props.showData.workArray.length +
  234. props.showData.unsubmittedStudents.length
  235. }}</span></div>
  236. <span v-if="props.showData.unsubmittedStudents.length > 0" @click.stop="viewUnsubmittedStudents()">{{
  237. lang.ssViewSubmitStatus2 }}</span>
  238. </div>
  239. <div class="c_t15_content" v-show="!lookWorkData">
  240. <div class="c_t15_c_item" v-for="item in processedWorkArray" :key="item.id" @click.stop="lookWork(item.id)">
  241. <div class="c_t15_c_i_top">
  242. <span>{{ item.name.charAt(0) }}</span>
  243. <div>{{ item.name }}</div>
  244. <div class="cast_sreen_btn" @click.stop="castScreen(item)" v-if="props.isCreator && props.roleType == 1 && isFollowModeActive && canValue">
  245. <IconCastScreen />
  246. {{ lang.ssCastScreen }}
  247. </div>
  248. </div>
  249. <div class="c_t15_c_i_bottom">
  250. <span v-html="item.content.answer"></span>
  251. </div>
  252. <div class="bottom_btn" v-if="likeValue">
  253. <div class="bottom_like" :class="{'active': item.isLikes}" @click.stop="handleLikeClick(item)">
  254. <IconThumbsUp />
  255. <span>{{ item.likesCount }}</span>
  256. </div>
  257. </div>
  258. </div>
  259. </div>
  260. <div class="aiAnalysis" style="margin-top:1rem ;"
  261. v-if="processedWorkArray.length > 0 && lookWorkData === null && workDetail.type === '15' && props.roleType == 1"
  262. @click.stop="clickContent(false)">
  263. <div class="ai_header">
  264. <div class="ai_title">
  265. <svg viewBox="0 0 1024 1024" width="200" height="200">
  266. <path
  267. d="M512 170.666667C323.477333 170.666667 170.666667 323.477333 170.666667 512s152.810667 341.333333 341.333333 341.333333 341.333333-152.810667 341.333333-341.333333S700.522667 170.666667 512 170.666667zM85.333333 512C85.333333 276.352 276.352 85.333333 512 85.333333s426.666667 191.018667 426.666667 426.666667-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512z">
  268. </path>
  269. <path
  270. d="M693.013333 330.986667a42.666667 42.666667 0 0 1 10.304 43.648l-75.413333 226.282666a42.666667 42.666667 0 0 1-26.986667 26.986667l-226.282666 75.413333a42.666667 42.666667 0 0 1-53.973334-53.973333l75.434667-226.261333a42.666667 42.666667 0 0 1 26.986667-26.986667l226.282666-75.413333a42.666667 42.666667 0 0 1 43.648 10.304z m-222.72 139.306666l-41.685333 125.098667 125.077333-41.706667 41.706667-125.077333-125.077333 41.706667z">
  271. </path>
  272. </svg>{{ lang.ssAnalysis }}
  273. </div>
  274. <div class="ai_refresh" :class="{ 'disabled': currentAnalysis && currentAnalysis.loading }"
  275. @click.stop="aiAnalysisRefresh15()">
  276. {{ lang.ssAIGenerate }}
  277. <svg viewBox="0 0 1024 1024" width="200" height="200">
  278. <path
  279. d="M875 483c-33.4 0-60.5 27.1-60.5 60.5v0.1C814.4 710.3 678.8 846 512 846S209.5 710.3 209.5 543.5 345.2 241 512 241c36.8 0 71.7 7.6 104.4 19.7-32 3-57.4 29.1-57.4 61.9 0 34.8 28.2 63 63 63h201.9c34.8 0 63-28.2 63-63V120c0-34.8-28.2-63-63-63s-63 28.2-63 63v81.4C691 150.5 605.2 120 512 120 278.1 120 88.5 309.6 88.5 543.5S278.1 967 512 967s423.5-189.6 423.5-423.5c0-33.4-27.1-60.5-60.5-60.5z">
  280. </path>
  281. </svg>
  282. </div>
  283. </div>
  284. <div class="ai_content" v-if="currentAnalysis && currentAnalysis.json">
  285. {{ currentAnalysis.json.text }}
  286. </div>
  287. <div class="ai_echartsData" v-if="currentAnalysis && currentAnalysis.json.keyword">
  288. <div class="title">{{ lang.ssKeyword }}:</div>
  289. <span v-for="(item, index) in currentAnalysis.json.keyword" :key="index">{{ item }}</span>
  290. <div class="btn" @click.stop="openEchatsDialog()">{{ lang.ssViewKeywordCloud }}</div>
  291. </div>
  292. <div class="generatingContent" v-if="currentAnalysis && currentAnalysis.generatingContent">{{
  293. lang.ssGeneratingContent }}...</div>
  294. <div class="ai_updateTime" v-if="currentAnalysis">{{ lang.ssUpdateTime }}:{{ currentAnalysis.update_at }}
  295. </div>
  296. </div>
  297. <div class="c_t15_workDetail" v-if="lookWorkData" @click.stop="clickContent(false)">
  298. <div class="c_t15_wd_top">
  299. <img src="../../../assets/img/arrow_left.png" @click.stop="lookWork('')" v-if="!isCastScreen"/>
  300. <span>{{ lookWorkData.name.charAt(0) }}</span>
  301. <div>{{ lookWorkData.name }}</div>
  302. <div class="cast_sreen_btn" @click.stop="exitCastScreen" v-if="(props.isCreator && props.roleType == 1 && isCastScreen) || (!isFollowModeActive && isCastScreen)">
  303. <IconCastScreen />
  304. {{ lang.ssExitCastScreen }}
  305. </div>
  306. </div>
  307. <div class="c_t15_wd_content">
  308. <span v-html="lookWorkData.content.answer"></span>
  309. <div class="c_t15_wd_c_imageList" v-if="lookWorkData.content.fileList.length > 0">
  310. <img v-for="item in lookWorkData.content.fileList" :src="item.url" :key="item.uploadTime"
  311. @click.stop="lookImage(item.url)" />
  312. </div>
  313. </div>
  314. </div>
  315. </div>
  316. <!-- 拍照 -->
  317. <div class="c_t15" v-if="workDetail && workDetail.type === '79' && props.showData">
  318. <div class="c_t15_title">
  319. <div class="c_title">
  320. <span>{{ workDetail.json.answerQ }}</span>
  321. <div class="switch_btn" v-if="props.isCreator && props.roleType == 1">
  322. <div class="switch">
  323. <Switch :value="canValue" @update:value="handleCanChange" />
  324. <span>{{ lang.ssShowResult }}</span>
  325. </div>
  326. <div class="switch">
  327. <Switch :value="likeValue" @update:value="handleLikeChange" />
  328. <span>{{ lang.ssLike }}</span>
  329. </div>
  330. </div>
  331. </div>
  332. </div>
  333. <span class="c_t15_type">{{ lang.ssPhoto }}</span>
  334. <div class="c_t15_msg" v-if="props.roleType == 1">
  335. <div>{{ lang.ssAnswerCount }} {{ props.showData.workArray.length }}<span
  336. v-if="props.showData.unsubmittedStudents.length > 0">/{{ props.showData.workArray.length +
  337. props.showData.unsubmittedStudents.length
  338. }}</span></div>
  339. <span v-if="props.showData.unsubmittedStudents.length > 0" @click.stop="viewUnsubmittedStudents()">{{
  340. lang.ssViewSubmitStatus2 }}</span>
  341. </div>
  342. <div class="c_t15_content" v-show="!lookWorkData">
  343. <div class="c_t15_c_item" v-for="item in processedWorkArray" :key="item.id"
  344. @click.stop="item.content && item.content.fileList.length > 0 ? lookWork(item.id) : ''">
  345. <div class="c_t15_c_i_top">
  346. <span>{{ item.name.charAt(0) }}</span>
  347. <div>{{ item.name }}</div>
  348. <div class="cast_sreen_btn" @click.stop="castScreen(item)" v-if="props.isCreator && props.roleType == 1 && isFollowModeActive && canValue">
  349. <IconCastScreen />
  350. {{ lang.ssCastScreen }}
  351. </div>
  352. </div>
  353. <div class="c_t73_c_i_bottom" v-if="item.content && item.content.fileList.length > 0">
  354. <img :src="item.content.fileList[0].url" />
  355. </div>
  356. <div class="c_t73_c_i_bottom" v-else>
  357. <span>{{ lang.ssNoPhoto }}</span>
  358. </div>
  359. <div class="bottom_btn" v-if="likeValue">
  360. <div class="bottom_like" :class="{'active': item.isLikes}" @click.stop="handleLikeClick(item)">
  361. <IconThumbsUp />
  362. <span>{{ item.likesCount }}</span>
  363. </div>
  364. </div>
  365. </div>
  366. </div>
  367. <div class="c_t79_workDetail" v-if="lookWorkData" @click.stop="clickContent(false)">
  368. <div class="c_t79_wd_top">
  369. <img src="../../../assets/img/arrow_left.png" @click.stop="lookWork('')" v-if="!isCastScreen"/>
  370. <span>{{ lookWorkData.name.charAt(0) }}</span>
  371. <div>{{ lookWorkData.name }}</div>
  372. <div class="cast_sreen_btn" @click.stop="exitCastScreen" v-if="(props.isCreator && props.roleType == 1 && isCastScreen) || (!isFollowModeActive && isCastScreen)">
  373. <IconCastScreen />
  374. {{ lang.ssExitCastScreen }}
  375. </div>
  376. </div>
  377. <div class="c_t79_wd_content">
  378. <img :src="lookWorkData.content.fileList[lookWorkIndex].url"
  379. @click.stop="lookImage(lookWorkData.content.fileList[lookWorkIndex].url)" />
  380. </div>
  381. <!-- <div class="nextAndUpBtn" v-if="lookWorkData.content.fileList.length>1">
  382. <span :class="{no_active:lookWorkIndex==0}" @click="changelookWorkIndex(0)">{{ lang.ssPrevP }}</span>
  383. <span :class="{no_active:lookWorkData.content.fileList.length-1<=lookWorkIndex}" @click="changelookWorkIndex(1)">{{ lang.ssNextP }}</span>
  384. </div> -->
  385. <div class="cq_changeBtn" v-if="lookWorkData.content.fileList.length > 1">
  386. <div :class="{ cq_cb_disabled: lookWorkIndex <= 0 }" @click.stop="changelookWorkIndex(0)">
  387. <svg style="transform: rotate(-90deg);" viewBox="0 0 1024 1024" version="1.1" width="200" height="200">
  388. <path
  389. d="M512 330.666667c14.933333 0 29.866667 4.266667 40.533333 14.933333l277.33333399 234.666667c27.733333 23.466667 29.866667 64 8.53333301 89.6-23.466667 27.733333-64 29.866667-89.6 8.53333299L512 477.866667l-236.8 200.53333299c-27.733333 23.466667-68.266667 19.19999999-89.6-8.53333299-23.466667-27.733333-19.19999999-68.266667 8.53333301-89.6l277.33333399-234.666667c10.666667-10.666667 25.6-14.933333 40.533333-14.933333z"
  390. fill=""></path>
  391. </svg>
  392. </div>
  393. <span>{{ lookWorkIndex + 1 }}/{{ lookWorkData.content.fileList.length }}</span>
  394. <div :class="{ cq_cb_disabled: lookWorkIndex >= lookWorkData.content.fileList.length - 1 }"
  395. @click.stop="changelookWorkIndex(1)">
  396. <svg style="transform: rotate(90deg);" viewBox="0 0 1024 1024" version="1.1" width="200" height="200">
  397. <path
  398. d="M512 330.666667c14.933333 0 29.866667 4.266667 40.533333 14.933333l277.33333399 234.666667c27.733333 23.466667 29.866667 64 8.53333301 89.6-23.466667 27.733333-64 29.866667-89.6 8.53333299L512 477.866667l-236.8 200.53333299c-27.733333 23.466667-68.266667 19.19999999-89.6-8.53333299-23.466667-27.733333-19.19999999-68.266667 8.53333301-89.6l277.33333399-234.666667c10.666667-10.666667 25.6-14.933333 40.533333-14.933333z"
  399. fill=""></path>
  400. </svg>
  401. </div>
  402. </div>
  403. </div>
  404. </div>
  405. <!-- AI应用 -->
  406. <div class="c_t72" v-if="props.showData && props.showData.toolType === 72">
  407. <div class="c_t72_title">
  408. <div class="c_title">
  409. <span>{{ lang.ssAiApp }}</span>
  410. <div class="switch_btn" v-if="props.isCreator && props.roleType == 1">
  411. <div class="switch">
  412. <Switch :value="canValue" @update:value="handleCanChange" />
  413. <span>{{ lang.ssShowResult }}</span>
  414. </div>
  415. <div class="switch">
  416. <Switch :value="likeValue" @update:value="handleLikeChange" />
  417. <span>{{ lang.ssLike }}</span>
  418. </div>
  419. </div>
  420. </div>
  421. </div>
  422. <span class="c_t72_type">{{ lang.ssAiApp }}</span>
  423. <div class="c_t72_msg" v-if="props.roleType == 1">
  424. <div>{{ lang.ssAnswerCount }} {{ props.showData.workArray.length }}<span
  425. v-if="props.showData.unsubmittedStudents.length > 0">/{{ props.showData.workArray.length +
  426. props.showData.unsubmittedStudents.length
  427. }}</span></div>
  428. <span v-if="props.showData.unsubmittedStudents.length > 0" @click.stop="viewUnsubmittedStudents()">{{
  429. lang.ssViewSubmitStatus2 }}</span>
  430. </div>
  431. <div class="c_t72_content" v-show="!lookWorkData">
  432. <div class="c_t72_c_item" v-for="item in processedWorkArray" :key="item.id" @click.stop="lookWork(item.id)">
  433. <div class="c_t72_c_i_top">
  434. <span>{{ item.name.charAt(0) }}</span>
  435. <div>{{ item.name }}</div>
  436. <div class="cast_sreen_btn" @click.stop="castScreen(item)" v-if="props.isCreator && props.roleType == 1 && isFollowModeActive && canValue">
  437. <IconCastScreen />
  438. {{ lang.ssCastScreen }}
  439. </div>
  440. </div>
  441. <div class="bottom_btn" v-if="likeValue">
  442. <div class="bottom_like" :class="{'active': item.isLikes}" @click.stop="handleLikeClick(item)">
  443. <IconThumbsUp />
  444. <span>{{ item.likesCount }}</span>
  445. </div>
  446. </div>
  447. </div>
  448. </div>
  449. <div class="aiAnalysis" style="margin-top:1rem ;"
  450. v-if="processedWorkArray.length > 0 && lookWorkData === null && props.showData.toolType === 72 && props.roleType == 1"
  451. @click.stop="clickContent(false)">
  452. <div class="ai_header">
  453. <div class="ai_title">
  454. <svg viewBox="0 0 1024 1024" width="200" height="200">
  455. <path
  456. d="M512 170.666667C323.477333 170.666667 170.666667 323.477333 170.666667 512s152.810667 341.333333 341.333333 341.333333 341.333333-152.810667 341.333333-341.333333S700.522667 170.666667 512 170.666667zM85.333333 512C85.333333 276.352 276.352 85.333333 512 85.333333s426.666667 191.018667 426.666667 426.666667-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512z">
  457. </path>
  458. <path
  459. d="M693.013333 330.986667a42.666667 42.666667 0 0 1 10.304 43.648l-75.413333 226.282666a42.666667 42.666667 0 0 1-26.986667 26.986667l-226.282666 75.413333a42.666667 42.666667 0 0 1-53.973334-53.973333l75.434667-226.261333a42.666667 42.666667 0 0 1 26.986667-26.986667l226.282666-75.413333a42.666667 42.666667 0 0 1 43.648 10.304z m-222.72 139.306666l-41.685333 125.098667 125.077333-41.706667 41.706667-125.077333-125.077333 41.706667z">
  460. </path>
  461. </svg>{{ lang.ssAnalysis }}
  462. </div>
  463. <div class="ai_refresh" :class="{ 'disabled': currentAnalysis && currentAnalysis.loading }"
  464. @click.stop="aiAnalysisRefresh72()">
  465. {{ lang.ssAIGenerate }}
  466. <svg viewBox="0 0 1024 1024" width="200" height="200">
  467. <path
  468. d="M875 483c-33.4 0-60.5 27.1-60.5 60.5v0.1C814.4 710.3 678.8 846 512 846S209.5 710.3 209.5 543.5 345.2 241 512 241c36.8 0 71.7 7.6 104.4 19.7-32 3-57.4 29.1-57.4 61.9 0 34.8 28.2 63 63 63h201.9c34.8 0 63-28.2 63-63V120c0-34.8-28.2-63-63-63s-63 28.2-63 63v81.4C691 150.5 605.2 120 512 120 278.1 120 88.5 309.6 88.5 543.5S278.1 967 512 967s423.5-189.6 423.5-423.5c0-33.4-27.1-60.5-60.5-60.5z">
  469. </path>
  470. </svg>
  471. </div>
  472. </div>
  473. <div class="ai_content" v-if="currentAnalysis && currentAnalysis.json" v-html="currentAnalysis.json.text">
  474. </div>
  475. <div class="ai_updateTime" v-if="currentAnalysis">{{ lang.ssUpdateTime }}:{{ currentAnalysis.update_at }}
  476. </div>
  477. </div>
  478. <div class="c_t72_workDetail" v-if="lookWorkData" @click.stop="clickContent(false)">
  479. <div class="c_t72_wd_top">
  480. <img src="../../../assets/img/arrow_left.png" @click.stop="lookWork('')" v-if="!isCastScreen"/>
  481. <span>{{ lookWorkData.name.charAt(0) }}</span>
  482. <div>{{ lookWorkData.name }}</div>
  483. <div class="cast_sreen_btn" @click.stop="exitCastScreen" v-if="(props.isCreator && props.roleType == 1 && isCastScreen) || (!isFollowModeActive && isCastScreen)">
  484. <IconCastScreen />
  485. {{ lang.ssExitCastScreen }}
  486. </div>
  487. </div>
  488. <div class="c_t72_wd_content">
  489. <template v-for="(item, index) in lookWorkData.content" :key="item.id">
  490. <div class="messageNodeArea" v-if="item.messages || item.imageUrls">
  491. <div class="messageNode">
  492. <div class="mn_title">{{ lang.ssNodeTitle.replace(/\*/g, String(index + 1)) }}</div>
  493. <div class="mn_content">
  494. <template v-for="(item2, index2) in item.messages" :key="`${index}-${index2}`">
  495. <div>
  496. <div class="na_m_item" v-if="item2.role == 'user' && item2.content">
  497. <div class="na_m_i_name">
  498. {{ item2.sender }}
  499. </div>
  500. <div class="na_m_i_content" v-html="item2.content"></div>
  501. </div>
  502. <div class="na_m_item" v-if="item2.role == 'assistant' && item2.content">
  503. <div class="na_m_i_name aiName">
  504. {{ item2.sender }}
  505. </div>
  506. <div class="na_m_i_content" v-html="item2.content"></div>
  507. </div>
  508. </div>
  509. </template>
  510. <template v-if="item.imageUrls" v-for="(item3, index3) in item.imageUrls"
  511. :key="`${index}-${index3}`">
  512. <div class="na_m_item">
  513. <div class="na_m_i_name">
  514. {{ item.type }}
  515. </div>
  516. <div class="na_m_i_content">
  517. <img @click.stop="lookImage(item3)" style="height: 100px;width: auto;cursor: pointer;"
  518. :src="item3" />
  519. </div>
  520. </div>
  521. </template>
  522. </div>
  523. </div>
  524. </div>
  525. </template>
  526. </div>
  527. </div>
  528. </div>
  529. <!-- H5页面 -->
  530. <div class="c_t73" v-if="props.showData && props.showData.toolType === 73">
  531. <div class="c_t73_title">
  532. <div class="c_title">
  533. <span>{{ lang.ssPageImage }}</span>
  534. <div class="switch_btn" v-if="props.isCreator && props.roleType == 1">
  535. <div class="switch">
  536. <Switch :value="canValue" @update:value="handleCanChange" />
  537. <span>{{ lang.ssShowResult }}</span>
  538. </div>
  539. <div class="switch">
  540. <Switch :value="likeValue" @update:value="handleLikeChange" />
  541. <span>{{ lang.ssLike }}</span>
  542. </div>
  543. </div>
  544. </div>
  545. </div>
  546. <span class="c_t73_type">{{ lang.ssHPage }}</span>
  547. <div class="c_t73_msg" v-if="props.roleType == 1">
  548. <div>{{ lang.ssAnswerCount }} {{ props.showData.workArray.length }}<span
  549. v-if="props.showData.unsubmittedStudents.length > 0">/{{ props.showData.workArray.length +
  550. props.showData.unsubmittedStudents.length
  551. }}</span></div>
  552. <span v-if="props.showData.unsubmittedStudents.length > 0" @click.stop="viewUnsubmittedStudents()">{{
  553. lang.ssViewSubmitStatus2 }}</span>
  554. </div>
  555. <div class="c_t73_content" v-show="!lookWorkData">
  556. <div class="c_t73_c_item" v-for="item in processedWorkArray" :key="item.id" @click.stop="lookWork(item.id)">
  557. <div class="c_t73_c_i_top">
  558. <span>{{ item.name.charAt(0) }}</span>
  559. <div>{{ item.name }}</div>
  560. <div class="cast_sreen_btn" @click.stop="castScreen(item)" v-if="props.isCreator && props.roleType == 1 && isFollowModeActive && canValue">
  561. <IconCastScreen />
  562. {{ lang.ssCastScreen }}
  563. </div>
  564. </div>
  565. <div class="c_t73_c_i_bottom">
  566. <img :src="item.content" />
  567. </div>
  568. <div class="bottom_btn" v-if="likeValue">
  569. <div class="bottom_like" :class="{'active': item.isLikes}" @click.stop="handleLikeClick(item)">
  570. <IconThumbsUp />
  571. <span>{{ item.likesCount }}</span>
  572. </div>
  573. </div>
  574. </div>
  575. </div>
  576. <div class="c_t73_workDetail" v-if="lookWorkData" @click.stop="clickContent(false)">
  577. <div class="c_t73_wd_top">
  578. <img src="../../../assets/img/arrow_left.png" @click.stop="lookWork('')" v-if="!isCastScreen"/>
  579. <span>{{ lookWorkData.name.charAt(0) }}</span>
  580. <div>{{ lookWorkData.name }}</div>
  581. <div class="cast_sreen_btn" @click.stop="exitCastScreen" v-if="(props.isCreator && props.roleType == 1 && isCastScreen) || (!isFollowModeActive && isCastScreen)">
  582. <IconCastScreen />
  583. {{ lang.ssExitCastScreen }}
  584. </div>
  585. </div>
  586. <div class="c_t73_wd_content">
  587. <img :src="lookWorkData.content" />
  588. </div>
  589. </div>
  590. </div>
  591. </div>
  592. <previewImageTool ref="previewImageToolRef" />
  593. <selectUserDialog ref="selectUserDialogRef" />
  594. <echartsDialog ref="echartsDialogRef" />
  595. </div>
  596. </template>
  597. <script setup lang="ts">
  598. import { computed, ref, watch, onUnmounted, nextTick, onMounted } from 'vue'
  599. import * as echarts from 'echarts'
  600. import previewImageTool from '../../components/tool/previewImageTool.vue'
  601. import MarkdownIt from 'markdown-it'
  602. import useImport from '@/hooks/useImport'
  603. import { lang } from '@/main'
  604. import selectUserDialog from './selectUserDialog.vue'
  605. import echartsDialog from './echartsDialog.vue'
  606. import { chat_stream, chat_no_stream } from '@/tools/aiChat'
  607. import axios from '@/services/config'
  608. import Switch from '@/components/Switch.vue'
  609. import { likeWork } from '@/services/course'
  610. const props = defineProps<{
  611. visible: number[];
  612. workIndex: number;
  613. slideWidth: number;
  614. slideHeight: number;
  615. slideIndex: number;
  616. showData: any;
  617. workArray: any[];
  618. courseDetail: any;
  619. userId: string;
  620. workId: string;
  621. cid: string;
  622. workUrl: string;
  623. roleType: number;
  624. resultArray: { [key: string]: any };
  625. isCreator: boolean;
  626. isFollowModeActive: boolean;
  627. courseid: string;
  628. }>()
  629. const emit = defineEmits<{
  630. (e: 'update:visible', v: number[]): void;
  631. (e: 'changeWorkIndex', v: number): void;
  632. (e: 'setIsResultArray', v: boolean, key: string): void;
  633. (e: 'successLike'): void;
  634. (e: 'sendMessage', v: any): void;
  635. }>()
  636. const visible = computed({
  637. get: () => props.visible,
  638. set: (v: number[]) => emit('update:visible', v),
  639. })
  640. const workDetail = computed(() => {
  641. if (props.showData) {
  642. return props.showData.workDetail
  643. }
  644. return null
  645. })
  646. const canValue = ref(props.resultArray?.can ?? false)
  647. watch(() => props.resultArray?.can, (newVal) => {
  648. canValue.value = newVal
  649. })
  650. const likeValue = ref(props.resultArray?.like ?? false)
  651. watch(() => props.resultArray?.like, (newVal) => {
  652. likeValue.value = newVal
  653. })
  654. const anonymousValue = ref(props.resultArray?.anonymous ?? false)
  655. watch(() => props.resultArray?.anonymous, (newVal) => {
  656. anonymousValue.value = newVal
  657. })
  658. const handleCanChange = (value: boolean) => {
  659. console.log(value)
  660. console.log(props.resultArray)
  661. emit('setIsResultArray', value, 'can')
  662. }
  663. const handleLikeChange = (value: boolean) => {
  664. if (value && !canValue.value) {
  665. emit('setIsResultArray', true, 'can')
  666. }
  667. console.log(value)
  668. console.log(props.resultArray)
  669. emit('setIsResultArray', value, 'like')
  670. }
  671. const handleAnonymousChange = (value: boolean) => {
  672. console.log(value)
  673. console.log(props.resultArray)
  674. emit('setIsResultArray', value, 'anonymous')
  675. }
  676. import _ from 'lodash'
  677. import type { workerData } from 'worker_threads'
  678. const handleLikeClick = _.debounce((item: any) => {
  679. likeWork({
  680. wid: item.id,
  681. lid: props.userId,
  682. t: 1,
  683. c: ''
  684. })
  685. emit('successLike')
  686. }, 300)
  687. // 预览图片组件
  688. const previewImageToolRef = ref<any>(null)
  689. // 选择用户组件
  690. const selectUserDialogRef = ref<any>(null)
  691. // 词云图组件
  692. const echartsDialogRef = ref<any>(null)
  693. // ai分析数据
  694. const aiAnalysisData = ref<Array<any>>([])
  695. const md = new MarkdownIt({
  696. html: true,
  697. })
  698. const { getFile } = useImport()
  699. // 判断是否是 URL 链接
  700. const isUrl = (str: string): boolean => {
  701. try {
  702. const url = new URL(str)
  703. return (url.protocol === 'http:' || url.protocol === 'https:') && str.includes('json')
  704. }
  705. catch {
  706. return false
  707. }
  708. }
  709. // 从链接获取文件内容
  710. const loadContentFromUrl = async (url: string): Promise<string> => {
  711. try {
  712. const fileData = await getFile(url)
  713. if (fileData && fileData.data) {
  714. // 将 ArrayBuffer 转为字符串
  715. const uint8Array = new Uint8Array(fileData.data)
  716. const jsonStr = new TextDecoder('utf-8').decode(uint8Array)
  717. return jsonStr
  718. }
  719. return ''
  720. }
  721. catch (error) {
  722. console.error('获取文件内容失败:', error)
  723. return ''
  724. }
  725. }
  726. // 处理单个作业内容
  727. const processWorkContent = async (content: string, toolType: number): Promise<any> => {
  728. let contentToParse = content
  729. // 如果是链接,先获取文件内容
  730. if (isUrl(content)) {
  731. contentToParse = await loadContentFromUrl(content)
  732. }
  733. if (!contentToParse) {
  734. return null
  735. }
  736. try {
  737. if ([45, 15, 78, 79].includes(toolType)) {
  738. return JSON.parse(decodeURIComponent(contentToParse))
  739. }
  740. else if (toolType === 72) {
  741. const parsed = JSON.parse(contentToParse)
  742. if (Array.isArray(parsed)) {
  743. parsed.forEach((item: any) => {
  744. if (item.messages && item.messages.length) {
  745. item.messages.forEach((item2: any) => {
  746. // 如果已经包含html标签则不再渲染
  747. if (
  748. !/^(\s*<[^>]+>.*<\/[^>]+>\s*|<[^>]+\/>\s*)$/s.test(
  749. item2.content.trim()
  750. )
  751. ) {
  752. item2.content = item2.content.replace(/&lt;/g, '<').replace(/&quot;/g, '"').replace(/&gt;/g, '>')
  753. item2.content = md.render(item2.content)
  754. }
  755. })
  756. }
  757. })
  758. }
  759. return parsed
  760. }
  761. return contentToParse
  762. }
  763. catch (error) {
  764. console.error('解析内容失败:', error)
  765. return null
  766. }
  767. }
  768. const processedWorkArray = ref<any[]>([])
  769. // 监听 workArray 和 showData 变化
  770. watch(
  771. () => [props.workArray, props.showData?.toolType],
  772. async () => {
  773. if (props.workArray && props.showData) {
  774. const _workArray = JSON.parse(JSON.stringify(props.workArray))
  775. // 处理每个作业内容
  776. for (const i of _workArray) {
  777. if (i.content) {
  778. const processedContent = await processWorkContent(i.content, props.showData.toolType)
  779. if (processedContent !== null) {
  780. i.content = processedContent
  781. }
  782. }
  783. }
  784. processedWorkArray.value = _workArray
  785. }
  786. else {
  787. processedWorkArray.value = []
  788. }
  789. },
  790. { immediate: true, deep: true }
  791. )
  792. // 关闭对应的作业详细页面
  793. const closeSlideIndex = () => {
  794. visible.value = visible.value.filter((v) => v !== props.slideIndex)
  795. }
  796. // 切换题目
  797. const changeWorkIndex = (type: number) => {
  798. emit('changeWorkIndex', type)
  799. // console.log(props.workIndex, props.showData.choiceQuestionListData.length)
  800. // if (type === 0 && props.workIndex > 0) {
  801. // emit('changeWorkIndex', 0)
  802. // }
  803. // else if (type === 1 && props.workIndex < props.showData.choiceQuestionListData.length) {
  804. // emit('changeWorkIndex', props.workIndex + 1)
  805. // }
  806. }
  807. // 选择题图表div
  808. const echartsArea1 = ref<any>(null)
  809. // 查看的作业详细id
  810. const lookWorkDetail = ref<string>('')
  811. // 查看作业详细的数据
  812. const lookWorkData = computed(() => {
  813. let _result = null
  814. if (lookWorkDetail.value && processedWorkArray.value.length > 0) {
  815. const _workFind = processedWorkArray.value.find(
  816. (i: any) => i.id === lookWorkDetail.value
  817. )
  818. if (_workFind) {
  819. _result = _workFind
  820. }
  821. }
  822. return _result
  823. })
  824. // 查看图片
  825. const lookImage = (url: string) => {
  826. if (previewImageToolRef.value) {
  827. previewImageToolRef.value.previewImage(url)
  828. }
  829. }
  830. const lookWorkIndex = ref<number>(0)
  831. // 查看作业
  832. const lookWork = (id: string) => {
  833. lookWorkIndex.value = 0
  834. lookWorkDetail.value = id
  835. if (isCastScreen.value && !id) {
  836. emit('sendMessage', {
  837. type: 'exit_cast_screen',
  838. courseid: props.courseid,
  839. })
  840. isCastScreen.value = false
  841. }
  842. }
  843. const isCastScreen = ref<boolean>(false)
  844. // 投屏
  845. const castScreen = (item: any) => {
  846. lookWorkIndex.value = 0
  847. lookWorkDetail.value = item.id
  848. isCastScreen.value = true
  849. emit('sendMessage', {
  850. type: 'cast_screen',
  851. courseid: props.courseid,
  852. workerData: item
  853. })
  854. console.log(item)
  855. }
  856. // 退出投屏
  857. const exitCastScreen = () => {
  858. if (props.roleType != 1) {
  859. isCastScreen.value = false
  860. }
  861. lookWork('')
  862. }
  863. // 暴露给父级(Student/index.vue)用 ref 调用
  864. defineExpose({ castScreen, exitCastScreen })
  865. // 切换查看作业图片
  866. const changelookWorkIndex = (type: number) => {
  867. if (type === 0 && lookWorkIndex.value > 0) {
  868. lookWorkIndex.value = lookWorkIndex.value - 1
  869. }
  870. else if (type === 1 && lookWorkIndex.value < lookWorkData.value.content.fileList.length - 1) {
  871. lookWorkIndex.value = lookWorkIndex.value + 1
  872. }
  873. }
  874. // 选择题图表实例
  875. const myChart = ref<any>(null)
  876. // resize防抖定时器
  877. let resizeTimer: ReturnType<typeof setTimeout> | null = null
  878. // 处理ECharts resize
  879. const handleChartResize = () => {
  880. // 清除之前的定时器
  881. if (resizeTimer) {
  882. clearTimeout(resizeTimer)
  883. }
  884. resizeTimer = setTimeout(() => {
  885. nextTick(() => {
  886. if (
  887. myChart.value &&
  888. typeof myChart.value.resize === 'function' &&
  889. !myChart.value.isDisposed()
  890. ) {
  891. try {
  892. myChart.value.resize()
  893. }
  894. catch (e) {
  895. // console.error('myChart resize error:', e)
  896. // 如果resize失败,重新初始化图表
  897. if (
  898. props.showData &&
  899. props.showData.workDetail &&
  900. (props.showData.workDetail.type === '45' || props.showData.workDetail.type === '78')
  901. ) {
  902. setEchartsArea1()
  903. }
  904. }
  905. }
  906. })
  907. }, 200) // 防抖延迟200ms
  908. }
  909. // 设置选择题图表
  910. const setEchartsArea1 = () => {
  911. // 如果已有实例且未销毁,先销毁
  912. if (myChart.value && !myChart.value.isDisposed()) {
  913. myChart.value.dispose()
  914. }
  915. if (echartsArea1.value) {
  916. myChart.value = echarts.init(echartsArea1.value)
  917. }
  918. else {
  919. myChart.value = null
  920. }
  921. if (myChart.value) {
  922. const _work =
  923. props.showData.choiceQuestionListData[props.showData.workIndex]
  924. console.log('_work', _work)
  925. // 修正版,处理xAxis.data内为图片对象的case,formatter始终只拿到src或自定义label,保证无[object Object]问题
  926. const option = {
  927. tooltip: {
  928. show: false, // 禁用鼠标移动到柱体时的内容显示
  929. },
  930. yAxis: {
  931. show: false, // 不显示最左边的y轴
  932. },
  933. xAxis: {
  934. data: [],
  935. axisLabel: {
  936. color: 'rgba(0, 0, 0, 0.9)',
  937. fontWeight: 600,
  938. fontSize: 17,
  939. lineHeight: 20,
  940. interval: 0,
  941. formatter: function(value: any, idx: number) {
  942. // 如果是字符串且格式为JSON(图片),则解析处理
  943. if (typeof value === 'string') {
  944. try {
  945. const obj = JSON.parse(value)
  946. if (obj && typeof obj === 'object' && obj.imgType && obj.src) {
  947. return '{img' + idx + '|}'
  948. }
  949. }
  950. catch (e) {
  951. // 非JSON字符串,直接返回
  952. // 如果文本文字超过8个字,换行
  953. if (typeof value === 'string') {
  954. // 判断value是否全是英文
  955. const isAllEnglish = /^[a-zA-Z0-9\s\p{P}]+$/u.test(value)
  956. let displayValue = value
  957. const maxLength = isAllEnglish ? 30 : 20
  958. const lineLength = isAllEnglish ? 16 : 8
  959. if (value.length > maxLength) {
  960. displayValue = value.substr(0, maxLength) + '...'
  961. }
  962. // 换行处理
  963. let output = ''
  964. for (let i = 0; i < displayValue.length; i += lineLength) {
  965. output += displayValue.substr(i, lineLength)
  966. if (i + lineLength < displayValue.length) {
  967. output += '\n'
  968. }
  969. }
  970. return output
  971. }
  972. return value
  973. }
  974. return value
  975. }
  976. // 兼容老格式(容错):value本身是对象,并有图片信息
  977. if (
  978. value &&
  979. typeof value === 'object' &&
  980. value.imgType &&
  981. value.src
  982. ) {
  983. return '{img' + idx + '|}'
  984. }
  985. // 其他类型直接空
  986. return ''
  987. },
  988. rich: (() => {
  989. // 动态生成所有图片的 rich 格式
  990. const richObj: any = {}
  991. _work.choiceUser.forEach((op: any, idx: number) => {
  992. if (
  993. op.option &&
  994. typeof op.option === 'object' &&
  995. op.option.imgType &&
  996. op.option.src
  997. ) {
  998. richObj['img' + idx] = {
  999. height: 40,
  1000. width: 40,
  1001. align: 'center',
  1002. backgroundColor: {
  1003. image: op.option.src,
  1004. },
  1005. }
  1006. }
  1007. })
  1008. return richObj
  1009. })(),
  1010. },
  1011. },
  1012. series: [
  1013. {
  1014. name: '',
  1015. type: 'bar',
  1016. data: [],
  1017. barMaxWidth: 80, // 柱体最宽80px,数量多则自适应
  1018. itemStyle: {
  1019. color: 'rgba(252, 207, 0, 1)',
  1020. },
  1021. label: {
  1022. show: true,
  1023. position: 'top',
  1024. color: 'rgba(116, 139, 115, 1)',
  1025. fontSize: 22,
  1026. fontWeight: 500,
  1027. lineHeight: 24,
  1028. },
  1029. },
  1030. ],
  1031. }
  1032. _work.choiceUser.forEach((i: any, idx: number) => {
  1033. // 如果是图片,存src对象,否则为字符串
  1034. if (
  1035. i.option &&
  1036. typeof i.option === 'object' &&
  1037. i.option.imgType &&
  1038. i.option.src
  1039. ) {
  1040. (option.xAxis.data as any[]).push(
  1041. JSON.stringify({ imgType: i.option.imgType, src: i.option.src })
  1042. ) // 仅保留相关字段
  1043. }
  1044. else if (typeof i.option === 'string') {
  1045. (option.xAxis.data as any[]).push(i.option)
  1046. }
  1047. else {
  1048. (option.xAxis.data as any[]).push('')
  1049. }
  1050. (option.series[0].data as any[]).push(i.user.length)
  1051. })
  1052. // console.log(option)
  1053. // {
  1054. // title: {
  1055. // text: 'ECharts 入门示例'
  1056. // },
  1057. // tooltip: {},
  1058. // xAxis: {
  1059. // data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
  1060. // },
  1061. // yAxis: {},
  1062. // series: [
  1063. // {
  1064. // name: '销量',
  1065. // type: 'bar',
  1066. // data: [5, 20, 36, 10, 10, 20]
  1067. // }
  1068. // ]
  1069. // }
  1070. myChart.value.setOption(option)
  1071. myChart.value.off('click')
  1072. myChart.value.on('click', (params: any) => {
  1073. const idx = params.dataIndex
  1074. const selectedOption = _work.choiceUser[idx]
  1075. if (selectedOption && selectUserDialogRef.value) {
  1076. // console.log(selectedOption)
  1077. console.log('selectedOption', selectedOption)
  1078. const selectedOption2 = {...selectedOption}
  1079. if (anonymousValue.value) {
  1080. selectedOption2.user = selectedOption2.user.map((item: any, index: number) => lang.ssAnonymousUser + (index + 1))
  1081. }
  1082. selectUserDialogRef.value.open(`${lang.ssSelectUser.replace('{a}', '<span>' + selectedOption2.index + '</span>')}`, selectedOption2)
  1083. }
  1084. })
  1085. }
  1086. }
  1087. // 获取分析
  1088. const getAnalysis = () => {
  1089. if (!props.workId) {
  1090. return
  1091. }
  1092. console.log('props.workId', props.workId)
  1093. const params = {
  1094. pid: props.workId + (props.cid ? ',' + props.cid : ''),
  1095. }
  1096. axios.get('https://pbl.cocorobo.cn/api/pbl/select_pptAnalysisByPid?pid=' + params.pid).then(res => {
  1097. const data = res[0]
  1098. if (data.length) {
  1099. data.forEach((item: any) => {
  1100. try {
  1101. item.json = JSON.parse(item.json)
  1102. }
  1103. catch (error) {
  1104. item.json = { text: item.json, echartsData: '' }
  1105. }
  1106. })
  1107. aiAnalysisData.value = data
  1108. }
  1109. else {
  1110. aiAnalysisData.value = []
  1111. }
  1112. }).catch(err => {
  1113. console.log('get_pptAnalysis_err', err)
  1114. })
  1115. }
  1116. // 监听选择题数据变化
  1117. watch(
  1118. () => props.showData,
  1119. (newVal, oldVal) => {
  1120. console.log('发生变化,showData')
  1121. if (
  1122. newVal &&
  1123. newVal.choiceQuestionListData[newVal.workIndex] &&
  1124. (props.showData.workDetail.type === '45' || props.showData.workDetail.type === '78')
  1125. ) {
  1126. if (
  1127. oldVal &&
  1128. newVal.choiceQuestionListData[newVal.workIndex] &&
  1129. oldVal.choiceQuestionListData[oldVal.workIndex]
  1130. ) {
  1131. if (
  1132. JSON.stringify(newVal.choiceQuestionListData[newVal.workIndex]) !==
  1133. JSON.stringify(oldVal.choiceQuestionListData[oldVal.workIndex])
  1134. ) {
  1135. setEchartsArea1()
  1136. }
  1137. }
  1138. }
  1139. else {
  1140. myChart.value = null
  1141. }
  1142. // console.log('newVal', newVal)
  1143. // if(newVal && newVal.workDetail && newVal.workDetail.id){
  1144. // getAnalysis()
  1145. // }
  1146. // getAnalysis()
  1147. },
  1148. { immediate: true, deep: true }
  1149. )
  1150. // 监听作业变化
  1151. watch(
  1152. () => props.showData?.choiceQuestionListData,
  1153. (newVal, oldVal) => {
  1154. console.log('choiceQuestionListData变化了')
  1155. if (
  1156. (newVal || newVal === 0) &&
  1157. props.showData.workDetail &&
  1158. (props.showData.workDetail.type === '45' || props.showData.workDetail.type === '78')
  1159. ) {
  1160. if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
  1161. setEchartsArea1()
  1162. }
  1163. else {
  1164. console.log('choiceQuestionListData没有变化')
  1165. }
  1166. }
  1167. else {
  1168. myChart.value = null
  1169. }
  1170. },
  1171. { deep: true }
  1172. )
  1173. // 监听作业变化
  1174. watch(
  1175. () => props.showData?.workIndex,
  1176. (newVal) => {
  1177. if (
  1178. (newVal || newVal === 0) &&
  1179. props.showData.workDetail &&
  1180. (props.showData.workDetail.type === '45' || props.showData.workDetail.type === '78')
  1181. ) {
  1182. setEchartsArea1()
  1183. }
  1184. else {
  1185. myChart.value = null
  1186. }
  1187. }
  1188. )
  1189. // 监听echartsArea1变化
  1190. watch(
  1191. () => echartsArea1.value,
  1192. (newVal) => {
  1193. if (
  1194. newVal &&
  1195. props.showData &&
  1196. props.showData.workDetail &&
  1197. (props.showData.workDetail.type === '45' || props.showData.workDetail.type === '78')
  1198. ) {
  1199. setEchartsArea1()
  1200. }
  1201. else {
  1202. myChart.value = null
  1203. }
  1204. }
  1205. )
  1206. // 监听页面宽度变化
  1207. watch(
  1208. () => props.slideWidth,
  1209. (newVal) => {
  1210. if (
  1211. newVal &&
  1212. props.showData &&
  1213. props.showData.workDetail &&
  1214. (props.showData.workDetail.type === '45' || props.showData.workDetail.type === '78')
  1215. ) {
  1216. handleChartResize()
  1217. }
  1218. }
  1219. )
  1220. // 查看未提交学生
  1221. const viewUnsubmittedStudents = () => {
  1222. selectUserDialogRef.value.open(lang.ssSubmitStatus, { user: props.showData.unsubmittedStudents.map((item: any) => item.name), notFiledUser: props.showData.unsubmittedStudents.map((item: any) => item.name), isSubmitUser: props.workArray.map((item: any) => item.name) })
  1223. // if (props.unsubmittedStudents.length > 0) {
  1224. // unsubmittedStudentsDialogRef.value.open(props.unsubmittedStudents)
  1225. // }
  1226. }
  1227. // ai生成选择题分析 选择题
  1228. const aiAnalysisRefresh45 = () => {
  1229. const _work = props.showData.choiceQuestionListData[props.showData.workIndex]
  1230. const msg = `# CONTEXT #
  1231. 你是K-12阶段的AI教育课堂分析助手,基于上传的课件、逐字稿,以及当页的学生答题数据(选择题/问答题/智能体对话)进行智能分析。
  1232. # OBJECTIVE #
  1233. 输出当前学生答题的分析报告:整体表现、核心发现(共性问题/误区)、教学优化(改进方向),为教师提供教学策略的建议和支持。
  1234. #INPUT#
  1235. 课程数据:
  1236. - 课程名称:${props.courseDetail.title}
  1237. - 课程学科:${props.courseDetail.name}
  1238. 当前页面答题数据(选择题):【分析重点】
  1239. - 选择题题目:${_work.teststitle}
  1240. - 选项数据:${JSON.stringify(_work.choiceUser)}
  1241. - 题目图片:${_work.timuList.lenght ? _work.timuList[0].src : ''}
  1242. - 未提交学生:${JSON.stringify(props.showData.unsubmittedStudents.map((item: any) => item.name))}
  1243. # ANALYSIS RULES #
  1244. 1. **问题定位**:明确指出哪个知识点/概念/步骤掌握不佳
  1245. 2. **建议具体**:给出可执行的教学动作(如“增加XX实例演练”“补充XX对比图”)
  1246. # RESPONSE #
  1247. 采用段落叙述,数据量化呈现,突出可操作建议,严格控制输出为80词内。采用三段式论述:
  1248. 1. 整体表现-1句话
  1249. 2. 核心发现-1-2句,指出共性问题+典型案例
  1250. 3. 改进建议-1句话,提出具体教学动作
  1251. # EXAMPLES #
  1252. 样例:
  1253. 选择题正确率62%,核心概念“机器学习三步骤”(输入数据→训练模型→预测结果)掌握尚可,但“训练与预测区分”混淆率达38%;建议强化训练vs预测对比教学。`
  1254. if (!currentAnalysis.value) {
  1255. aiAnalysisData.value.push({
  1256. pid: props.workId + (props.cid ? ',' + props.cid : ''),
  1257. index: props.showData.workIndex,
  1258. loading: true,
  1259. generatingContent: true,
  1260. json: { text: '', echartsData: '' },
  1261. noEnd: true,
  1262. update_at: '',
  1263. create_at: '',
  1264. })
  1265. }
  1266. else {
  1267. aiAnalysisData.value.find((item: any) => {
  1268. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1269. }).loading = true
  1270. aiAnalysisData.value.find((item: any) => {
  1271. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1272. }).json = { text: '', echartsData: '' }
  1273. }
  1274. chat_stream(msg, 'a7741704-ba56-40b7-a6b8-62a423ef9376', props.userId, lang.lang, (event) => {
  1275. if (event.type === 'message') {
  1276. aiAnalysisData.value.find((item: any) => {
  1277. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1278. }).json.text = event.data
  1279. aiAnalysisData.value.find((item: any) => {
  1280. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1281. }).loading = false
  1282. }
  1283. else if (event.type === 'messageEnd') {
  1284. aiAnalysisData.value.find((item: any) => {
  1285. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1286. }).json.text = event.data
  1287. aiAnalysisData.value.find((item: any) => {
  1288. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1289. }).noEnd = false
  1290. aiAnalysisData.value.find((item: any) => {
  1291. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1292. }).update_at = new Date().toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).replace(/\//g, '-')
  1293. saveAnalysis()
  1294. }
  1295. }).catch(err => {
  1296. console.log('err', err)
  1297. })
  1298. }
  1299. // ai生成投票分析 投票
  1300. const aiAnalysisRefresh78 = () => {
  1301. const _work = props.showData.choiceQuestionListData[props.showData.workIndex]
  1302. const msg = `# CONTEXT #
  1303. 你是K-12阶段的AI教育课堂分析助手,基于上传的课件、逐字稿,以及当页的学生答题数据(选择题/问答题/智能体对话/投票)进行智能分析。
  1304. # OBJECTIVE #
  1305. 输出当前学生答题的分析报告:整体表现、核心发现(共性问题/误区)、教学优化(改进方向),为教师提供教学策略的建议和支持。
  1306. #INPUT#
  1307. 课程数据:
  1308. - 课程名称:${props.courseDetail.title}
  1309. - 课程学科:${props.courseDetail.name}
  1310. 当前页面答题数据(投票):【分析重点】
  1311. - 投票题目:${_work.teststitle}
  1312. - 选项数据:${JSON.stringify(_work.choiceUser)}
  1313. - 题目图片:${_work.timuList.lenght ? _work.timuList[0].src : ''}
  1314. - 未提交学生:${JSON.stringify(props.showData.unsubmittedStudents.map((item: any) => item.name))}
  1315. # ANALYSIS RULES #
  1316. 1. **问题定位**:明确指出哪个知识点/概念/步骤掌握不佳
  1317. 2. **建议具体**:给出可执行的教学动作(如“增加XX实例演练”“补充XX对比图”)
  1318. # RESPONSE #
  1319. 采用段落叙述,数据量化呈现,突出可操作建议,严格控制输出为80词内。采用三段式论述:
  1320. 1. 整体表现-1句话
  1321. 2. 核心发现-1-2句,指出共性问题+典型案例
  1322. 3. 改进建议-1句话,提出具体教学动作
  1323. # EXAMPLES #
  1324. 样例:
  1325. 选择题正确率62%,核心概念“机器学习三步骤”(输入数据→训练模型→预测结果)掌握尚可,但“训练与预测区分”混淆率达38%;建议强化训练vs预测对比教学。`
  1326. if (!currentAnalysis.value) {
  1327. aiAnalysisData.value.push({
  1328. pid: props.workId + (props.cid ? ',' + props.cid : ''),
  1329. index: props.showData.workIndex,
  1330. loading: true,
  1331. generatingContent: true,
  1332. json: { text: '', echartsData: '' },
  1333. noEnd: true,
  1334. update_at: '',
  1335. create_at: '',
  1336. })
  1337. }
  1338. else {
  1339. aiAnalysisData.value.find((item: any) => {
  1340. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1341. }).loading = true
  1342. aiAnalysisData.value.find((item: any) => {
  1343. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1344. }).json = { text: '', echartsData: '' }
  1345. }
  1346. chat_stream(msg, 'a7741704-ba56-40b7-a6b8-62a423ef9376', props.userId, lang.lang, (event) => {
  1347. if (event.type === 'message') {
  1348. aiAnalysisData.value.find((item: any) => {
  1349. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1350. }).json.text = event.data
  1351. aiAnalysisData.value.find((item: any) => {
  1352. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1353. }).loading = false
  1354. }
  1355. else if (event.type === 'messageEnd') {
  1356. aiAnalysisData.value.find((item: any) => {
  1357. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1358. }).json.text = event.data
  1359. aiAnalysisData.value.find((item: any) => {
  1360. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1361. }).noEnd = false
  1362. aiAnalysisData.value.find((item: any) => {
  1363. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1364. }).update_at = new Date().toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).replace(/\//g, '-')
  1365. saveAnalysis()
  1366. }
  1367. }).catch(err => {
  1368. console.log('err', err)
  1369. })
  1370. }
  1371. // 问答题
  1372. const aiAnalysisRefresh15 = () => {
  1373. let flag = 0
  1374. const msg = `# CONTEXT #
  1375. 你是K-12阶段的AI教育课堂分析助手,基于上传的课件、逐字稿,以及当页的学生答题数据(选择题/问答题/智能体对话)进行智能分析。
  1376. # OBJECTIVE #
  1377. 输出当前学生答题的分析报告:整体表现、核心发现(共性问题/误区)、教学优化(改进方向),为教师提供教学策略的建议和支持。
  1378. #INPUT#
  1379. 课程数据:
  1380. - 课程名称:${props.courseDetail.title}
  1381. - 课程学科:${props.courseDetail.name}
  1382. 当前页面答题数据(问答题):【分析重点】
  1383. - 问答题题目:${props.showData.workDetail.json.answerQ}
  1384. - 回答数据:${JSON.stringify(processedWorkArray.value.map((i) => ({ user: i.name, answer: i.content.answer })))}
  1385. - 未提交学生:${JSON.stringify(props.showData.unsubmittedStudents.map((item: any) => item.name))}
  1386. # ANALYSIS RULES #
  1387. 1. **问题定位**:明确指出哪个知识点/概念/步骤掌握不佳
  1388. 2. **建议具体**:给出可执行的教学动作(如“增加XX实例演练”“补充XX对比图”)
  1389. # RESPONSE #
  1390. 采用段落叙述,数据量化呈现,突出可操作建议,严格控制输出为80词内。采用三段式论述:
  1391. 1. 整体表现-1句话
  1392. 2. 核心发现-1-2句,指出共性问题+典型案例
  1393. 3. 改进建议-1句话,提出具体教学动作
  1394. # EXAMPLES #
  1395. 样例:
  1396. 30人中15人提交问答题(参与率50%),核心概念“同理心地图”掌握薄弱。发现学生13在智能体对话中6次答“不知道”,需单独辅导设计思维基础概念。建议课程增加POV框架实例演练,强化痛点识别能力训练。`
  1397. if (!currentAnalysis.value) {
  1398. aiAnalysisData.value.push({
  1399. pid: props.workId + (props.cid ? ',' + props.cid : ''),
  1400. index: props.showData.workIndex,
  1401. loading: true,
  1402. generatingContent: true,
  1403. json: { text: '', echartsData: '' },
  1404. noEnd: true,
  1405. update_at: '',
  1406. create_at: '',
  1407. })
  1408. }
  1409. else {
  1410. aiAnalysisData.value.find((item: any) => {
  1411. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1412. }).loading = true
  1413. aiAnalysisData.value.find((item: any) => {
  1414. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1415. }).json = { text: '', echartsData: '' }
  1416. aiAnalysisData.value.find((item: any) => {
  1417. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1418. }).generatingContent = true
  1419. }
  1420. getWordCloud15().then((res) => {
  1421. flag += 1
  1422. aiAnalysisData.value.find((item: any) => {
  1423. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1424. }).generatingContent = false
  1425. if (flag == 2) {
  1426. saveAnalysis()
  1427. }
  1428. })
  1429. chat_stream(msg, 'a7741704-ba56-40b7-a6b8-62a423ef9376', props.userId, lang.lang, (event) => {
  1430. console.log(event)
  1431. if (event.type === 'message') {
  1432. aiAnalysisData.value.find((item: any) => {
  1433. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1434. }).json.text = event.data
  1435. aiAnalysisData.value.find((item: any) => {
  1436. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1437. }).loading = false
  1438. }
  1439. else if (event.type === 'messageEnd') {
  1440. aiAnalysisData.value.find((item: any) => {
  1441. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1442. }).json.text = event.data
  1443. aiAnalysisData.value.find((item: any) => {
  1444. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1445. }).noEnd = false
  1446. aiAnalysisData.value.find((item: any) => {
  1447. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1448. }).update_at = new Date().toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).replace(/\//g, '-')
  1449. flag += 1
  1450. if (flag == 2) {
  1451. saveAnalysis()
  1452. }
  1453. }
  1454. }).catch(err => {
  1455. console.log('err', err)
  1456. })
  1457. }
  1458. // 打开词云图弹窗
  1459. const openEchatsDialog = () => {
  1460. if (echartsDialogRef.value && currentAnalysis.value.json.echartsData) {
  1461. echartsDialogRef.value.open(lang.ssKeywordCloud, currentAnalysis.value.json.echartsData)
  1462. }
  1463. }
  1464. // 问答题获取词云图与关键词
  1465. const getWordCloud15 = () => {
  1466. return new Promise((resolve,) => {
  1467. const msg = `## 任务
  1468. 请针对文本中学生提交的问答题回答内容进行深度分析,提炼出 10 - 30 个核心关键词,用于绘制词云图。
  1469. ## 提取准则
  1470. 1. 聚焦内容主体:仅从学生的具体回答文本中提取关键词。
  1471. 2. 严格排除杂质:禁止提取任何属于系统元数据或固定格式的词汇,包括但不限于:“课程数据”、“学生姓名”、“回答结果”、“课程标题”、“提交时间”、“作业名称”、“分数”等。
  1472. 3. 语义去重:将意思相近的词进行合并(例如“高效”与“效率高”),保留最具代表性的词条。
  1473. 4. 涵盖核心:关键词应准确反映学生回答中的核心观点、关键知识点、高频论据或情感倾向。
  1474. ## 任务要求
  1475. 1. 词频统计:计算每个有效关键字在回答内容中出现的频率。
  1476. 2. 词汇大小:根据词频,确定每个关键字在词云中的权重。词频越高,数值越大,范围 1 - 100。
  1477. 3. 输出格式:请严格按照 JSON 格式输出,包含关键词、词频及对应的词汇大小。
  1478. ## 文本
  1479. 课程数据:
  1480. - 课程名称:${props.courseDetail.title}
  1481. - 课程学科:${props.courseDetail.name}
  1482. - 需要提交人数:${props.showData.workArray.length + props.showData.unsubmittedStudents.length}
  1483. - 已提交人数:${props.showData.workArray.length}
  1484. 当前页面答题数据(问答题):【分析重点】
  1485. - 问答题题目:${props.showData.workDetail.json.answerQ}
  1486. - 回答数据:${JSON.stringify(processedWorkArray.value.map((i) => ({ answer: i.content.answer })))}
  1487. ## 输出示例
  1488. {"tooltip":{"show":false},"series":[{"type":"wordCloud","sizeRange":[14,38],"rotationRange":[0,0],"keepAspect":false,"shape":"circle","left":"center","top":"center","right":null,"bottom":null,"width":"100%","height":"100%","rotationStep":20,"data":[{"value":"词汇大小,数值范围1-100","name":"词汇","textStyle":{"color":"词汇颜色(16进制)"}},{"value":"词汇大小,数值范围1-100","name":"词汇","textStyle":{"color":"(16进制)"}}]}]}`
  1489. chat_no_stream(msg, 'a7741704-ba56-40b7-a6b8-62a423ef9376', props.userId, lang.lang).promise.then((res) => {
  1490. aiAnalysisData.value.find((item: any) => {
  1491. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1492. }).json.echartsData = JSON.parse(res)
  1493. resolve(1)
  1494. }).catch(err => {
  1495. console.log('err', err)
  1496. resolve(0)
  1497. })
  1498. })
  1499. }
  1500. // ai应用
  1501. const aiAnalysisRefresh72 = async () => {
  1502. let chatMsg = ``
  1503. const agentId = 'a7741704-ba56-40b7-a6b8-62a423ef9376'
  1504. console.log('processedWorkArray.value', processedWorkArray.value)
  1505. processedWorkArray.value.forEach((i) => {
  1506. if (typeof i.content === 'object') {
  1507. i.content.forEach(j => {
  1508. if (j.messages) {
  1509. j.messages.forEach((a) => {
  1510. chatMsg += `\n${a.sender}:
  1511. ${a.content}\n`
  1512. })
  1513. }
  1514. if (j.imageUrls) {
  1515. j.imageUrls.forEach((a) => {
  1516. chatMsg += `\n${a}\n`
  1517. })
  1518. }
  1519. })
  1520. }
  1521. })
  1522. // if(props.userId)
  1523. // - 未提交学生:${JSON.stringify(props.showData.unsubmittedStudents.map((item: any) => item.name))}
  1524. let msg = `# CONTEXT #
  1525. 你是K-12阶段的AI教育课堂分析助手,基于上传的课件、逐字稿,以及当页的学生答题数据(选择题/问答题/智能体对话)进行智能分析。
  1526. # OBJECTIVE #
  1527. 输出当前学生答题的分析报告:整体表现、核心发现(共性问题/误区)、教学优化(改进方向),为教师提供教学策略的建议和支持。
  1528. #INPUT#
  1529. 课程数据:
  1530. - 课程名称:${props.courseDetail.title}
  1531. - 课程学科:${props.courseDetail.name}
  1532. - 需要提交人数:${props.showData.workArray.length + props.showData.unsubmittedStudents.length}
  1533. - 已提交人数:${props.showData.workArray.length}
  1534. 当前页面答题数据(问答题):【分析重点】
  1535. - AI应用
  1536. - 对话数据:${chatMsg}
  1537. # ANALYSIS RULES #
  1538. 1. **问题定位**:明确指出哪个知识点/概念/步骤掌握不佳
  1539. 2. **建议具体**:给出可执行的教学动作(如“增加XX实例演练”“补充XX对比图”)
  1540. # RESPONSE #
  1541. 采用段落叙述,数据量化呈现,突出可操作建议,严格控制输出为80词内。采用三段式论述:
  1542. 1. 整体表现-1句话
  1543. 2. 核心发现-1-2句,指出共性问题+典型案例
  1544. 3. 改进建议-1句话,提出具体教学动作
  1545. # EXAMPLES #
  1546. 样例:
  1547. 智能体对话显示学生对“模型训练”概念模糊,多次询问“为什么不能直接告诉机器答案”。针对概念混淆学生,补充“人类学习类比”相关解释,巩固“从数据中学习规律”核心认知。`
  1548. if (['9c236d45-49cd-11f1-9985-005056924926'].includes(props.userId)) {
  1549. msg = `你是K-12阶段的AI教育课堂分析助手,基于当前课程信息以及当页的学生与单/多智能体对话数据,进行深入的智能分析。
  1550. ### 任务目标
  1551. 1. **总体统计分析**:
  1552. - 分析学生表现数据,例如全班学生互动数据,包括但不限于参与度、互动轮次、作文批改分布、作业完成情况等。
  1553. - 提取核心统计指标,例如发现共性问题、互动模式、分层水平分布、关键评分、完成度、优秀或需关注的学生。
  1554. 2. **洞察(Key Insights)**:
  1555. - 不是所有模块都需要的
  1556. - 输出的模块使用1~3句快速完成核心发现输出
  1557. - 保持简短、直观、易快速理解。
  1558. 3. **不输出教学建议或干预措施**。
  1559. ### 输出格式
  1560. 1. Markdown表格:展示关键统计指标(发言次数、互动频率、提问数量、主题分布)。
  1561. 2. ASCII条形图(可选):展示各项指标对比情况(绝对不要ASCII条形图,应该显示指标名字)
  1562. 3. 洞察与建议:分点呈现,每点对应具体统计指标或数据来源,保持精简,直观、易快速理解。
  1563. **注意,不必输出多余的开场白(可以有非常简短的),转场,铺垫,形容词等,尽可能把输出留给有价值的发现**
  1564. **对于重点要注意的内容,可以用 <span style="color:red"> 内容 </span> 以及 markdown的强调语法来highlight**
  1565. ### 注意事项
  1566. - 输出简洁明了,重点突出。
  1567. - 所有数字列右对齐,必要时显示百分比。
  1568. - 避免冗长文字和详细案例描述。
  1569. - 保持专业、友好语气,可使用 Emoji 提示情绪、课堂氛围或学生表现状态。
  1570. - 输出保持在600字左右
  1571. #INPUT#
  1572. 课程数据:
  1573. - 课程名称:${props.courseDetail.title}
  1574. - 课程学科:${props.courseDetail.name}
  1575. 当前页面答题数据(问答题):【分析重点】
  1576. - AI应用
  1577. - 对话数据:${chatMsg}
  1578. `
  1579. }
  1580. else if (['6c56ec0e-2c74-11ef-bee5-005056b86db5', 'aea65da6-4399-11f1-9985-005056924926'].includes(props.userId)) {
  1581. if (props.workUrl == 'https://knowledge.cocorobo.cn/zh-CN/story-telling/a1a339d4-f522-4336-9aa9-e8394bea9731') {
  1582. msg = `# 角色定位
  1583. 你是K-12阶段的AI课堂分析助手,负责基于学生对世界名画的英语宣传稿(promotional text)批改记录生成课堂学情分析报告。
  1584. 本次分析的内容来自六年级英语Art课堂,学生选择一幅画作并完成英语宣传稿写作,由AI智能体完成批改,分为 Level A(独立完成)、Level B(信息辅助)、Level C(支架辅助)两个等级。
  1585. ---
  1586. # 重要:数据解读规则(必须在生成报告前完成)
  1587. 在输出任何报告内容之前,必须先完成以下两步结构化提取。
  1588. 所有报告数字必须来源于此,禁止前后矛盾。
  1589. ---
  1590. ## 第一步:逐学生提取数据
  1591. (此步骤为内部处理步骤,不输出提取结果。)
  1592. ### 有效作文判断
  1593. 在提取每位学生数据之前,先判断该学生是否提交了有效作文:
  1594. **有效作文:** AI批改记录中出现了完整的"作文批改报告"结构(包含信息完整性表格、表达鲜活度、文化小触角、语法小诊断中至少两项),视为学生已提交有效内容,正常提取数据。
  1595. **无效提交:** 以下情况均视为无效提交,不纳入各维度统计,仅在总结部分单独列出:
  1596. - AI输出"未检测到有效的写作内容"
  1597. - AI批改记录缺失或仅有对话内容而无批改报告结构
  1598. - 学生仅回复单个词语、符号或与写作任务完全无关的内容
  1599. **注意:** 不得根据学生与AI的后续对话内容(如学生补充回复、追问等)判断写作有效性,仅以AI是否输出完整批改报告为准。
  1600. ### 等级识别
  1601. 从批改记录中识别学生选择的等级:
  1602. - 选择"I can wtite. 我可以自己写。" → Level A
  1603. - 选择"I need information. 我需要信息支持。" → Level B
  1604. - 选择"I need structure. 我需要支架。" → Level C
  1605. ### 信息完整与准确性提取
  1606. 检查批改报告中的信息完整性表格,逐项记录每位学生的情况:
  1607. | 信息点 | 是否正确 |
  1608. |---|---|
  1609. | 画名 | 是/否 |
  1610. | 画家 | 是/否 |
  1611. | 绘画种类 | 是/否 |
  1612. | 画面描述(颜色/内容) | 是/否 |
  1613. | 个人感受 | 是/否 |
  1614. 对每位学生统计:
  1615. - 全部正确的信息点数量(满分5项)
  1616. - 有错误或遗漏的具体信息点
  1617. ### 表达鲜活度提取
  1618. 从批改记录的"表达鲜活度"部分,判断:
  1619. - ✅ 表达生动:使用了形容词、比喻、比较句或个人联想
  1620. - ⚠️ 表达平淡:仅使用简单句型,缺乏个人想法
  1621. ### 文化小触角提取
  1622. 从批改记录的"文化小触角"部分,判断:
  1623. - ✅ 有涉及:自然提到中西艺术差异或文化感悟
  1624. - — 未涉及:未提及任何文化对比
  1625. ### 语法情况提取
  1626. 从批改记录的"语法小诊断"部分,记录:
  1627. - 是否存在明显语法错误
  1628. - 错误类型(主谓一致 / 时态 / 冠词 / 其他)
  1629. ---
  1630. ## 第二步:汇总数据
  1631. 将所有学生数据按等级分组汇总,形成统计表。
  1632. **一旦汇总完成,报告中所有数字必须与汇总表严格一致,禁止前后矛盾。**
  1633. ---
  1634. # 输出格式
  1635. ## 第一步输出
  1636. 输出以下一句话,然后立即继续输出完整报告,不得停止:
  1637. "正在逐个提取学生数据中,请稍候……"
  1638. ## 第二步输出:完整报告
  1639. 紧接上一句,输出以下完整报告内容:
  1640. ---
  1641. ## 英语写作 课堂学情分析报告
  1642. **数据来源:** 批改记录 | **统计人数:** X 人
  1643. ---
  1644. ### 一、分层总览
  1645. | 等级 | 人数 | 信息完整率均值 | 表达生动人数 | 文化触角人数 | 有语法问题人数 |
  1646. |---|---|---|---|---|---|
  1647. | Level A | X | XX% | X人(XX%) | X人(XX%) | X人(XX%) |
  1648. | Level B | X | XX% | X人(XX%) | X人(XX%) | X人(XX%) |
  1649. | Level C | X | XX% | X人(XX%) | X人(XX%) | X人(XX%) |
  1650. ---
  1651. ### 二、信息完整与准确性明细(A / B / C 合并)
  1652. | 信息点 | 正确人数 | 正确率 |
  1653. |---|---|---|
  1654. | 画名 | X | XX% |
  1655. | 画家 | X | XX% |
  1656. | 绘画种类 | X | XX% |
  1657. | 画面描述(颜色/内容) | X | XX% |
  1658. | 个人感受 | X | XX% |
  1659. [正确率最低项:<span style="color:red">⚠️ [信息点名称]正确率最低,仅 XX%,说明学生在该项普遍存在遗漏或错误。</span>]
  1660. ---
  1661. ### 三、表达与文化维度
  1662. | 维度 | A 达成人数 | A 达成率 | B 达成人数 | B 达成率 | C 达成人数 | C 达成率 |
  1663. |---|---|---|---|---|
  1664. | 表达生动(含比喻/形容词/个人联想) | X | XX% | X | XX% | X | XX% |
  1665. | 文化小触角(含中西艺术对比) | X | XX% | X | XX% | X | XX% |
  1666. [若文化触角整体达成率低于50%:<span style="color:red">⚠️ 文化对比意识普遍薄弱,全班达成率仅 XX%。</span>]
  1667. ---
  1668. ### 四、语法问题汇总
  1669. | 语法问题类型 | A 出现人次 | B 出现人次 | C 出现人次 |
  1670. |---|---|---|
  1671. | 主谓一致错误 | X | X | X |
  1672. | 时态错误 | X | X | X |
  1673. | 冠词错误 | X | X | X |
  1674. | 其他 | X | X | X |
  1675. *若无明显语法问题,写:"本次无明显高频语法问题。✅"*
  1676. ---
  1677. ### 五、亮点摘录
  1678. **表达生动的例句:**
  1679. [列出2–3句来自学生作文的优秀表达原文,注明等级和画作名称。]
  1680. **文化感悟的例句:**
  1681. [列出1–2句来自学生作文的文化对比原文,注明等级和画作名称。若无,写"本次暂无。"]
  1682. ---
  1683. ### 六、总结
  1684. **整体:** [1句,简述全班整体写作完成情况。]
  1685. **突出:** [1句,指出全班表现最好的维度,例如信息完整率高或表达生动人数较多。]
  1686. **关注:** <span style="color:red">[1句,指出最薄弱的维度,例如文化触角普遍缺失或某信息点遗漏率高。]</span>
  1687. **跟进:**
  1688. - <span style="color:red">无效提交学生:[姓名列表],AI未能识别其提交内容,建议教师查看原图并确认是否需要重新上传。</span>
  1689. - <span style="color:red">写作内容需关注的学生(有效提交中):[姓名及原因,例如信息缺失3项以上、存在多处语法问题等];若无,写"有效提交学生中暂无需特别跟进。"</span>
  1690. *若全员有效提交且表现均衡,写:"本次全员提交有效内容,整体表现均衡,暂无需特别跟进。"*
  1691. ---
  1692. # 注意事项
  1693. - 所有数字来源于结构化提取,输出前核对一致性,禁止前后矛盾。
  1694. - 对需要教师重点关注的内容使用 <span style="color:red"> 内容 </span> 高亮。
  1695. - 禁止输出"如需进一步生成"等对话式内容。
  1696. - 不输出教学建议或干预措施。
  1697. - 若某等级无学生数据,对应列填"—",不单独说明。
  1698. #INPUT#
  1699. 课程数据:
  1700. - 课程名称:${props.courseDetail.title}
  1701. - 课程学科:${props.courseDetail.name}
  1702. - 需要提交人数:${props.showData.workArray.length + props.showData.unsubmittedStudents.length}
  1703. - 已提交人数:${props.showData.workArray.length}
  1704. 当前页面答题数据(AI应用):【分析重点】
  1705. - AI应用
  1706. - 对话数据:${chatMsg}`
  1707. }
  1708. else if (props.workUrl == 'https://knowledge.cocorobo.cn/zh-CN/story-telling/0d04cef1-876a-41b4-9768-6547088bc162') {
  1709. msg = `# 角色定位
  1710. 你是K-12阶段的AI课堂分析助手,负责基于学生词句训练对话记录生成课堂学情分析报告。
  1711. 本次分析的环节为:学生与AI就画作内容进行词句问答训练,分为 Level A、Level B、Level C 三个等级。
  1712. ---
  1713. # 重要:数据解读规则(必须在生成报告前完成)
  1714. 在输出任何报告内容之前,必须先完成以下两步结构化提取。
  1715. 所有报告数字必须来源于此,禁止前后矛盾。
  1716. ---
  1717. ## 第一步:逐学生提取数据
  1718. (此步骤为内部处理步骤,不输出提取结果。)
  1719. ### 等级识别
  1720. 从对话记录中的 sender 字段识别等级:
  1721. - sender 含"Level A" → Level A
  1722. - sender 含"Level B" → Level B
  1723. - sender 含"Level C" → Level C
  1724. ### 完成状态判断
  1725. - **完整完成**:所有句子/问题均有学生回应记录
  1726. - **部分完成**:至少一条学生回应,但未完成全部
  1727. - **未完成**:对话记录中仅有 AI 开场消息,无任何学生回应内容
  1728. ### Level A 提取项目
  1729. **主题覆盖性:** 检查学生是否主动提问了以下 6 个主题:
  1730. ① name ② artist ③ kind ④ scene ⑤ colours ⑥ why
  1731. - ✅ 已提问 / — 未提问
  1732. **问题准确性(语法):** 识别以下错误类型并记录人次:
  1733. - 疑问句结构错误 / 主谓一致错误 / 时态错误 / 其他
  1734. **创新性:** 6 个主题之外的问题,记录原文。
  1735. ### Level B 提取项目
  1736. **主题覆盖性:**(同 Level A,6个主题)
  1737. **问题准确性(语法):**(同 Level A)
  1738. ### Level C 提取项目
  1739. **流程完成性:** 逐句核对学生是否跟读了全部 6 个问句。
  1740. - ✅ 跟读基本正确 / ⚠️ 跟读明显偏差 / — 未跟读
  1741. **创新亮点:** 学生是否有自发延伸表达,记录原文。
  1742. ---
  1743. ## 第二步:汇总数据
  1744. 将所有学生数据按等级分组汇总。
  1745. **报告中所有数字必须与汇总表严格一致,禁止前后矛盾。**
  1746. ---
  1747. # 输出格式
  1748. ## 第一步输出
  1749. 输出以下一句话,然后立即继续输出完整报告,不得停止:
  1750. "正在逐个提取学生数据中,请稍候……"
  1751. ## 第二步输出:完整报告
  1752. 紧接上一句,输出以下完整报告内容:
  1753. ---
  1754. ## 词句问答训练 课堂学情分析报告
  1755. **数据来源:** 学生对话记录 | **统计人数:** X 人
  1756. ---
  1757. ### 一、分层总览
  1758. | 等级 | 人数 | 完整完成 | 主题覆盖率均值 | 语法问题人数 | 创新提问/亮点 |
  1759. |---|---|---|---|---|---|
  1760. | Level A | X | X人(XX%) | XX% | X人 | X人 |
  1761. | Level B | X | X人(XX%) | XX% | X人 | — |
  1762. | Level C | X | X人(XX%) | — | — | X人 |
  1763. [若有未完成学生:<span style="color:red">⚠️ 未完成学生:[姓名列表]</span>]
  1764. ---
  1765. ### 二、主题覆盖明细(Level A / B)
  1766. | 主题 | A 覆盖率 | B 覆盖率 |
  1767. |---|---|---|
  1768. | name | XX% | XX% |
  1769. | artist | XX% | XX% |
  1770. | kind | XX% | XX% |
  1771. | scene | XX% | XX% |
  1772. | colours | XX% | XX% |
  1773. | why | XX% | XX% |
  1774. *若本次无某等级学生,对应列填"—"。*
  1775. ---
  1776. ### 三、语法问题(Level A / B)
  1777. | 问题类型 | A 出现人次 | B 出现人次 |
  1778. |---|---|---|
  1779. | 疑问句结构错误 | X | X |
  1780. | 主谓一致错误 | X | X |
  1781. | 时态错误 | X | X |
  1782. | 其他 | X | X |
  1783. *若无语法问题,写:"本次无明显语法问题。✅"*
  1784. ---
  1785. ### 四、创新与亮点
  1786. **Level A 创新提问:**
  1787. [列出学生姓名及原文;若无,写"本次暂无。"]
  1788. **Level C 自发延伸:**
  1789. [列出学生姓名及原文;若无,写"本次暂无。"]
  1790. ---
  1791. ### 五、总结
  1792. **整体:** [1句,简述全班完成情况。]
  1793. **突出:** [1句,指出表现最好的维度或等级。]
  1794. **关注:** <span style="color:red">[1句,指出覆盖率最低的主题或问题最集中的点。]</span>
  1795. **跟进:** <span style="color:red">[列出需个别跟进的学生姓名及原因;若无,写"全员表现均衡,暂无需特别跟进。"]</span>
  1796. ---
  1797. # 注意事项
  1798. - 所有数字来源于结构化提取,输出前核对一致性,禁止前后矛盾。
  1799. - 对需要教师重点关注的内容使用 <span style="color:red"> 内容 </span> 高亮。
  1800. - 若某等级无学生数据,相关行/列填"—",不单独输出该等级报告。
  1801. - 禁止输出"如需进一步生成"等对话式内容。
  1802. - 不输出教学建议或干预措施。
  1803. #INPUT#
  1804. 课程数据:
  1805. - 课程名称:${props.courseDetail.title}
  1806. - 课程学科:${props.courseDetail.name}
  1807. - 需要提交人数:${props.showData.workArray.length + props.showData.unsubmittedStudents.length}
  1808. - 已提交人数:${props.showData.workArray.length}
  1809. 当前页面答题数据(AI应用):【分析重点】
  1810. - AI应用
  1811. - 对话数据:${chatMsg}`
  1812. }
  1813. // msg = `# 角色定位
  1814. // 你是K-12阶段的AI课堂分析助手,负责基于学生词句训练对话记录生成课堂学情分析报告。
  1815. // 本次分析的环节为:学生与AI就画作内容进行词句问答训练,分为 Level A、Level B、Level C 三个等级。
  1816. // ---
  1817. // # 重要:数据解读规则(必须在生成报告前完成)
  1818. // 在输出任何报告内容之前,必须先完成以下两步结构化提取。
  1819. // 所有报告数字必须来源于此,禁止前后矛盾。
  1820. // ---
  1821. // ## 第一步:逐学生提取数据
  1822. // (此步骤为内部处理步骤,不输出提取结果。)
  1823. // ### 等级识别
  1824. // 从对话记录中的 sender 字段识别等级:
  1825. // - sender 含"Level A" → Level A
  1826. // - sender 含"Level B" → Level B
  1827. // - sender 含"Level C" → Level C
  1828. // ### 完成状态判断
  1829. // - **完整完成**:所有句子/问题均有学生回应记录
  1830. // - **部分完成**:至少一条学生回应,但未完成全部
  1831. // - **未完成**:对话记录中仅有 AI 开场消息,无任何学生回应内容
  1832. // ### Level A 提取项目
  1833. // **主题覆盖性:** 检查学生是否主动提问了以下 6 个主题:
  1834. // ① name ② artist ③ kind ④ scene ⑤ colours ⑥ why
  1835. // - ✅ 已提问 / — 未提问
  1836. // **问题准确性(语法):** 识别以下错误类型并记录人次:
  1837. // - 疑问句结构错误 / 主谓一致错误 / 时态错误 / 其他
  1838. // **创新性:** 6 个主题之外的问题,记录原文。
  1839. // ### Level B 提取项目
  1840. // **主题覆盖性:**(同 Level A,6个主题)
  1841. // **问题准确性(语法):**(同 Level A)
  1842. // ### Level C 提取项目
  1843. // **流程完成性:** 逐句核对学生是否跟读了全部 6 个问句。
  1844. // - ✅ 跟读基本正确 / ⚠️ 跟读明显偏差 / — 未跟读
  1845. // **创新亮点:** 学生是否有自发延伸表达,记录原文。
  1846. // ---
  1847. // ## 第二步:汇总数据
  1848. // 将所有学生数据按等级分组汇总。
  1849. // **报告中所有数字必须与汇总表严格一致,禁止前后矛盾。**
  1850. // ---
  1851. // # 输出格式
  1852. // ## 第一步输出
  1853. // 输出以下一句话,然后立即继续输出完整报告,不得停止:
  1854. // "正在逐个提取学生数据中,请稍候……"
  1855. // ## 第二步输出:完整报告
  1856. // 紧接上一句,输出以下完整报告内容:
  1857. // ---
  1858. // ## 词句问答训练 课堂学情分析报告
  1859. // **数据来源:** 学生对话记录 | **统计人数:** X 人
  1860. // ---
  1861. // ### 一、分层总览
  1862. // | 等级 | 人数 | 完整完成 | 主题覆盖率均值 | 语法问题人数 | 创新提问/亮点 |
  1863. // |---|---|---|---|---|---|
  1864. // | Level A | X | X人(XX%) | XX% | X人 | X人 |
  1865. // | Level B | X | X人(XX%) | XX% | X人 | — |
  1866. // | Level C | X | X人(XX%) | — | — | X人 |
  1867. // [若有未完成学生:<span style="color:red">⚠️ 未完成学生:[姓名列表]</span>]
  1868. // ---
  1869. // ### 二、主题覆盖明细(Level A / B)
  1870. // | 主题 | A 覆盖率 | B 覆盖率 |
  1871. // |---|---|---|
  1872. // | name | XX% | XX% |
  1873. // | artist | XX% | XX% |
  1874. // | kind | XX% | XX% |
  1875. // | scene | XX% | XX% |
  1876. // | colours | XX% | XX% |
  1877. // | why | XX% | XX% |
  1878. // *若本次无某等级学生,对应列填"—"。*
  1879. // ---
  1880. // ### 三、语法问题(Level A / B)
  1881. // | 问题类型 | A 出现人次 | B 出现人次 |
  1882. // |---|---|---|
  1883. // | 疑问句结构错误 | X | X |
  1884. // | 主谓一致错误 | X | X |
  1885. // | 时态错误 | X | X |
  1886. // | 其他 | X | X |
  1887. // *若无语法问题,写:"本次无明显语法问题。✅"*
  1888. // ---
  1889. // ### 四、创新与亮点
  1890. // **Level A 创新提问:**
  1891. // [列出学生姓名及原文;若无,写"本次暂无。"]
  1892. // **Level C 自发延伸:**
  1893. // [列出学生姓名及原文;若无,写"本次暂无。"]
  1894. // ---
  1895. // ### 五、总结
  1896. // **整体:** [1句,简述全班完成情况。]
  1897. // **突出:** [1句,指出表现最好的维度或等级。]
  1898. // **关注:** <span style="color:red">[1句,指出覆盖率最低的主题或问题最集中的点。]</span>
  1899. // **跟进:** <span style="color:red">[列出需个别跟进的学生姓名及原因;若无,写"全员表现均衡,暂无需特别跟进。"]</span>
  1900. // ---
  1901. // # 注意事项
  1902. // - 所有数字来源于结构化提取,输出前核对一致性,禁止前后矛盾。
  1903. // - 对需要教师重点关注的内容使用 <span style="color:red"> 内容 </span> 高亮。
  1904. // - 若某等级无学生数据,相关行/列填"—",不单独输出该等级报告。
  1905. // - 禁止输出"如需进一步生成"等对话式内容。
  1906. // - 不输出教学建议或干预措施。
  1907. // #INPUT#
  1908. // 课程数据:
  1909. // - 课程名称:${props.courseDetail.title}
  1910. // - 课程学科:${props.courseDetail.name}
  1911. // - 需要提交人数:${props.showData.workArray.length + props.showData.unsubmittedStudents.length}
  1912. // - 已提交人数:${props.showData.workArray.length}
  1913. // 当前页面答题数据(AI应用):【分析重点】
  1914. // - AI应用
  1915. // - 对话数据:${chatMsg}`
  1916. }
  1917. console.log('workUrl', props.workUrl)
  1918. console.log('ai应用提示词', msg)
  1919. if (!currentAnalysis.value) {
  1920. aiAnalysisData.value.push({
  1921. pid: props.workId + (props.cid ? ',' + props.cid : ''),
  1922. index: props.showData.workIndex,
  1923. loading: true,
  1924. json: { text: '', echartsData: '' },
  1925. noEnd: true,
  1926. update_at: '',
  1927. create_at: '',
  1928. })
  1929. }
  1930. else {
  1931. aiAnalysisData.value.find((item: any) => {
  1932. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1933. }).loading = true
  1934. aiAnalysisData.value.find((item: any) => {
  1935. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1936. }).json = { text: '', echartsData: '' }
  1937. }
  1938. chat_stream(msg, 'a7741704-ba56-40b7-a6b8-62a423ef9376', props.userId, lang.lang, (event) => {
  1939. if (event.type === 'message') {
  1940. aiAnalysisData.value.find((item: any) => {
  1941. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1942. }).json.text = md.render(event.data)
  1943. aiAnalysisData.value.find((item: any) => {
  1944. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1945. }).loading = false
  1946. }
  1947. else if (event.type === 'messageEnd') {
  1948. aiAnalysisData.value.find((item: any) => {
  1949. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1950. }).json.text = md.render(event.data)
  1951. aiAnalysisData.value.find((item: any) => {
  1952. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1953. }).noEnd = false
  1954. aiAnalysisData.value.find((item: any) => {
  1955. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1956. }).update_at = new Date().toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).replace(/\//g, '-')
  1957. saveAnalysis()
  1958. }
  1959. }, '', [], 'open-qwen-plus-latest').catch(err => {
  1960. console.log('err', err)
  1961. })
  1962. }
  1963. // 当前分析
  1964. const currentAnalysis = computed(() => {
  1965. const _result = aiAnalysisData.value.find((item: any) => {
  1966. return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
  1967. })
  1968. if (_result?.json?.echartsData) {
  1969. _result.json.keyword = _result.json.echartsData?.series?.[0]?.data?.slice(0, 5).map((item: any) => item.name)
  1970. }
  1971. if (_result) {
  1972. return _result
  1973. }
  1974. return null
  1975. })
  1976. // 保存分析
  1977. const saveAnalysis = () => {
  1978. if (!currentAnalysis.value) {
  1979. return
  1980. }
  1981. const params = [{
  1982. pid: props.workId + (props.cid ? ',' + props.cid : ''),
  1983. idx: props.showData.workIndex,
  1984. json: JSON.stringify(currentAnalysis.value.json),
  1985. }]
  1986. console.log(params)
  1987. axios.post('https://pbl.cocorobo.cn/api/pbl/insert_pptAnalysis', params).then(res => {
  1988. if (res == 1) {
  1989. console.log('保存成功')
  1990. }
  1991. }).catch(err => {
  1992. console.log('insert_pptAnalysis_err', err)
  1993. })
  1994. }
  1995. // 点击边框
  1996. const clickContent = (flag: boolean) => {
  1997. if (flag && lookWorkDetail.value && workDetail.value?.type !== '45' && workDetail.value?.type !== '78') {
  1998. if (props.roleType != 1 && isCastScreen.value) {
  1999. return
  2000. }
  2001. lookWork('')
  2002. }
  2003. }
  2004. // 监听 props.showData.workDetail.id 变化
  2005. watch(
  2006. () => props.showData?.workDetail,
  2007. (newId, oldId) => {
  2008. getAnalysis()
  2009. },
  2010. { immediate: true }
  2011. )
  2012. // 组件卸载时清理ECharts实例
  2013. onUnmounted(() => {
  2014. // 清除定时器
  2015. if (resizeTimer) {
  2016. clearTimeout(resizeTimer)
  2017. resizeTimer = null
  2018. }
  2019. // 销毁ECharts实例
  2020. if (myChart.value && !myChart.value.isDisposed()) {
  2021. myChart.value.dispose()
  2022. myChart.value = null
  2023. }
  2024. })
  2025. </script>
  2026. <style lang="scss" scoped>
  2027. .choiceQuestionDetailDialog {
  2028. background: none;
  2029. position: relative;
  2030. width: 100%;
  2031. height: 100%;
  2032. z-index: 1;
  2033. .content {
  2034. width: 100%;
  2035. height: 100%;
  2036. position: relative;
  2037. background: #fff;
  2038. box-sizing: border-box;
  2039. padding: 40px;
  2040. overflow: auto;
  2041. .closeIcon {
  2042. position: absolute;
  2043. right: 20px;
  2044. top: 20px;
  2045. cursor: pointer;
  2046. width: 20px;
  2047. height: 20px;
  2048. img {
  2049. width: 100%;
  2050. height: 100%;
  2051. }
  2052. }
  2053. .c_t45 {
  2054. width: 100%;
  2055. min-height: 100%;
  2056. display: flex;
  2057. // align-items: center;
  2058. flex-direction: column;
  2059. height: auto;
  2060. .c_t45_title {
  2061. color: rgba(0, 0, 0, 0.9);
  2062. font-weight: 600;
  2063. font-size: 24px;
  2064. line-height: 24px;
  2065. position: relative;
  2066. width: 100%;
  2067. display: flex;
  2068. flex-direction: column;
  2069. // align-items: center;
  2070. // justify-content: center;
  2071. user-select: none;
  2072. gap: .4rem;
  2073. &>div {
  2074. max-width: calc(100%);
  2075. }
  2076. &>span {
  2077. position: absolute;
  2078. top: 20px;
  2079. cursor: pointer;
  2080. &:nth-of-type(1) {
  2081. left: 0;
  2082. }
  2083. &:nth-of-type(2) {
  2084. right: 0;
  2085. }
  2086. }
  2087. .c_t45_t_btn_noActive {
  2088. color: #CCCCCC;
  2089. }
  2090. .c_t45_msg {
  2091. display: flex;
  2092. align-items: center;
  2093. font-size: .9rem;
  2094. font-weight: 400;
  2095. gap: 1rem;
  2096. &>span {
  2097. text-decoration: underline;
  2098. cursor: pointer;
  2099. }
  2100. }
  2101. }
  2102. .c_t45_img {
  2103. max-width: 200px;
  2104. max-height: 200px;
  2105. object-fit: cover;
  2106. margin-top: 20px;
  2107. }
  2108. .c_t45_type {
  2109. font-weight: 400;
  2110. font-size: 15px;
  2111. line-height: 21px;
  2112. letter-spacing: 0.5px;
  2113. color: rgba(0, 0, 0, 1);
  2114. opacity: 0.5;
  2115. margin-top: 20px;
  2116. }
  2117. .c_t45_echarts {
  2118. width: 100%;
  2119. max-width: 100%;
  2120. flex: 1;
  2121. min-height: 400px;
  2122. display: flex;
  2123. align-items: center;
  2124. box-sizing: border-box;
  2125. &>div {
  2126. width: 100%;
  2127. height: 400px;
  2128. }
  2129. }
  2130. .cq_changeBtn {
  2131. display: flex;
  2132. align-items: center;
  2133. gap: 1.5rem;
  2134. margin: 1rem auto;
  2135. &>div {
  2136. padding: .6rem;
  2137. border-radius: .5rem;
  2138. border: solid 2px #F6C82B;
  2139. display: flex;
  2140. justify-content: center;
  2141. align-items: center;
  2142. cursor: pointer;
  2143. &>svg {
  2144. fill: #F6C82D;
  2145. width: 1rem;
  2146. height: 1rem;
  2147. }
  2148. &.cq_cb_disabled {
  2149. cursor: not-allowed !important;
  2150. border-color: #FEF8E9 !important;
  2151. }
  2152. &.cq_cb_disabled>svg {
  2153. fill: #A3A3A3 !important;
  2154. }
  2155. }
  2156. &>span {
  2157. font-weight: 500;
  2158. }
  2159. }
  2160. }
  2161. .c_t15 {
  2162. width: 100%;
  2163. min-height: 100%;
  2164. display: flex;
  2165. // align-items: center;
  2166. flex-direction: column;
  2167. height: auto;
  2168. padding: 40px;
  2169. .c_t15_title {
  2170. color: rgba(0, 0, 0, 0.9);
  2171. font-weight: 600;
  2172. font-size: 24px;
  2173. line-height: 24px;
  2174. }
  2175. .c_t15_msg {
  2176. display: flex;
  2177. align-items: center;
  2178. font-size: .9rem;
  2179. font-weight: 400;
  2180. gap: 1rem;
  2181. &>span {
  2182. text-decoration: underline;
  2183. cursor: pointer;
  2184. }
  2185. }
  2186. .c_t15_type {
  2187. font-weight: 400;
  2188. font-size: 15px;
  2189. line-height: 21px;
  2190. letter-spacing: 0.5px;
  2191. color: rgba(0, 0, 0, 1);
  2192. opacity: 0.5;
  2193. margin: 10px 0;
  2194. }
  2195. .c_t15_content {
  2196. width: 100%;
  2197. height: auto;
  2198. display: grid;
  2199. grid-template-columns: repeat(3, 1fr);
  2200. gap: 20px;
  2201. margin-top: 40px;
  2202. .c_t15_c_item {
  2203. width: 100%;
  2204. height: auto;
  2205. box-shadow: 2px 4px 20px 0px rgba(0, 0, 0, 0.2);
  2206. box-sizing: border-box;
  2207. border-radius: 12px;
  2208. padding: 16px;
  2209. background: rgba(255, 255, 255, 0.6);
  2210. transition: 0.3s;
  2211. cursor: pointer;
  2212. overflow: hidden;
  2213. &:hover {
  2214. box-shadow: 4px 4px 14px 0px rgba(252, 207, 0, 0.5);
  2215. background: rgba(255, 255, 255, 0.6);
  2216. }
  2217. .c_t15_c_i_top {
  2218. display: flex;
  2219. align-items: center;
  2220. gap: 10px;
  2221. width: 100%;
  2222. overflow: hidden;
  2223. &>span {
  2224. min-width: 25px;
  2225. height: 25px;
  2226. display: flex;
  2227. align-items: center;
  2228. justify-content: center;
  2229. background: rgba(252, 207, 0, 1);
  2230. border-radius: 4px;
  2231. color: rgba(255, 255, 255, 1);
  2232. font-weight: bold;
  2233. font-size: 14px;
  2234. }
  2235. &>div {
  2236. color: rgba(0, 0, 0, 0.7);
  2237. font-weight: 800;
  2238. overflow: hidden;
  2239. text-overflow: ellipsis;
  2240. white-space: nowrap;
  2241. }
  2242. }
  2243. .c_t15_c_i_bottom {
  2244. margin-top: 15px;
  2245. font-weight: 300;
  2246. font-size: 14px;
  2247. height: 40px;
  2248. max-width: 100%;
  2249. overflow: hidden;
  2250. text-overflow: ellipsis;
  2251. display: -webkit-box;
  2252. -webkit-line-clamp: 2;
  2253. -webkit-box-orient: vertical;
  2254. }
  2255. .c_t73_c_i_bottom {
  2256. margin-top: 15px;
  2257. font-weight: 300;
  2258. font-size: 14px;
  2259. // height: 40px;
  2260. max-width: 100%;
  2261. overflow: hidden;
  2262. text-overflow: ellipsis;
  2263. display: -webkit-box;
  2264. -webkit-line-clamp: 2;
  2265. -webkit-box-orient: vertical;
  2266. img {
  2267. width: 100%;
  2268. height: 200px;
  2269. object-fit: cover;
  2270. }
  2271. span {
  2272. width: 100%;
  2273. height: 200px;
  2274. display: flex;
  2275. align-items: center;
  2276. justify-content: center;
  2277. }
  2278. }
  2279. }
  2280. }
  2281. .c_t15_workDetail {
  2282. width: 100%;
  2283. height: auto;
  2284. margin-top: 40px;
  2285. box-shadow: 4px 4px 14px 0px rgba(252, 207, 0, 0.5);
  2286. box-sizing: border-box;
  2287. padding: 16px;
  2288. border-radius: 12px;
  2289. display: flex;
  2290. flex-direction: column;
  2291. .c_t15_wd_top {
  2292. width: 100%;
  2293. display: flex;
  2294. align-items: center;
  2295. gap: 15px;
  2296. &>img {
  2297. width: 25px;
  2298. height: 25px;
  2299. cursor: pointer;
  2300. }
  2301. &>span {
  2302. display: block;
  2303. width: 30px;
  2304. height: 30px;
  2305. display: flex;
  2306. align-items: center;
  2307. justify-content: center;
  2308. background: rgba(252, 207, 0, 1);
  2309. border-radius: 4px;
  2310. color: rgba(255, 255, 255, 1);
  2311. font-weight: bold;
  2312. font-size: 16px;
  2313. }
  2314. &>div {
  2315. color: rgba(0, 0, 0, 0.7);
  2316. font-weight: 800;
  2317. font-size: 18px;
  2318. }
  2319. }
  2320. .c_t15_wd_content {
  2321. width: 100%;
  2322. margin-top: 20px;
  2323. max-height: 100%;
  2324. overflow: auto;
  2325. flex-wrap: wrap;
  2326. .c_t15_wd_c_imageList {
  2327. width: 100%;
  2328. gap: 20px;
  2329. margin-top: 20px;
  2330. &>img {
  2331. width: 100px;
  2332. height: auto;
  2333. cursor: pointer;
  2334. margin-right: 20px;
  2335. object-fit: cover;
  2336. }
  2337. }
  2338. }
  2339. }
  2340. .c_t79_workDetail {
  2341. width: 100%;
  2342. height: auto;
  2343. margin-top: 40px;
  2344. box-shadow: 4px 4px 14px 0px rgba(252, 207, 0, 0.5);
  2345. box-sizing: border-box;
  2346. padding: 16px;
  2347. border-radius: 12px;
  2348. display: flex;
  2349. flex-direction: column;
  2350. .c_t79_wd_top {
  2351. width: 100%;
  2352. display: flex;
  2353. align-items: center;
  2354. gap: 15px;
  2355. &>img {
  2356. width: 25px;
  2357. height: 25px;
  2358. cursor: pointer;
  2359. }
  2360. &>span {
  2361. display: block;
  2362. width: 30px;
  2363. height: 30px;
  2364. display: flex;
  2365. align-items: center;
  2366. justify-content: center;
  2367. background: rgba(252, 207, 0, 1);
  2368. border-radius: 4px;
  2369. color: rgba(255, 255, 255, 1);
  2370. font-weight: bold;
  2371. font-size: 16px;
  2372. }
  2373. &>div {
  2374. color: rgba(0, 0, 0, 0.7);
  2375. font-weight: 800;
  2376. font-size: 18px;
  2377. }
  2378. }
  2379. .c_t79_wd_content {
  2380. width: 100%;
  2381. margin-top: 20px;
  2382. max-height: 100%;
  2383. overflow: auto;
  2384. flex-wrap: wrap;
  2385. display: flex;
  2386. align-items: center;
  2387. justify-content: center;
  2388. &>img {
  2389. max-width: 100%;
  2390. height: 300px;
  2391. object-fit: cover;
  2392. }
  2393. }
  2394. }
  2395. .cq_changeBtn {
  2396. display: flex;
  2397. align-items: center;
  2398. gap: 1.5rem;
  2399. margin: 1rem auto;
  2400. &>div {
  2401. padding: .6rem;
  2402. border-radius: .5rem;
  2403. border: solid 2px #F6C82B;
  2404. display: flex;
  2405. justify-content: center;
  2406. align-items: center;
  2407. cursor: pointer;
  2408. &>svg {
  2409. fill: #F6C82D;
  2410. width: 1rem;
  2411. height: 1rem;
  2412. }
  2413. &.cq_cb_disabled {
  2414. cursor: not-allowed !important;
  2415. border-color: #FEF8E9 !important;
  2416. }
  2417. &.cq_cb_disabled>svg {
  2418. fill: #A3A3A3 !important;
  2419. }
  2420. }
  2421. &>span {
  2422. font-weight: 500;
  2423. }
  2424. }
  2425. }
  2426. .c_t72 {
  2427. width: 100%;
  2428. min-height: 100%;
  2429. display: flex;
  2430. // align-items: center;
  2431. flex-direction: column;
  2432. height: auto;
  2433. padding: 40px;
  2434. .c_t72_title {
  2435. color: rgba(0, 0, 0, 0.9);
  2436. font-weight: 600;
  2437. font-size: 24px;
  2438. line-height: 24px;
  2439. }
  2440. .c_t72_type {
  2441. font-weight: 400;
  2442. font-size: 15px;
  2443. line-height: 21px;
  2444. letter-spacing: 0.5px;
  2445. color: rgba(0, 0, 0, 1);
  2446. opacity: 0.5;
  2447. margin: 10px 0;
  2448. }
  2449. .c_t72_msg {
  2450. display: flex;
  2451. align-items: center;
  2452. font-size: .9rem;
  2453. font-weight: 400;
  2454. gap: 1rem;
  2455. &>span {
  2456. text-decoration: underline;
  2457. cursor: pointer;
  2458. }
  2459. }
  2460. .c_t72_content {
  2461. width: 100%;
  2462. height: auto;
  2463. display: grid;
  2464. grid-template-columns: repeat(4, 1fr);
  2465. gap: 20px;
  2466. margin-top: 40px;
  2467. .c_t72_c_item {
  2468. width: 100%;
  2469. height: auto;
  2470. box-shadow: 2px 4px 20px 0px rgba(0, 0, 0, 0.2);
  2471. box-sizing: border-box;
  2472. border-radius: 12px;
  2473. padding: 16px;
  2474. background: rgba(255, 255, 255, 0.6);
  2475. transition: 0.3s;
  2476. cursor: pointer;
  2477. overflow: hidden;
  2478. &:hover {
  2479. box-shadow: 4px 4px 14px 0px rgba(252, 207, 0, 0.5);
  2480. background: rgba(255, 255, 255, 0.6);
  2481. }
  2482. .c_t72_c_i_top {
  2483. display: flex;
  2484. align-items: center;
  2485. gap: 10px;
  2486. width: 100%;
  2487. overflow: hidden;
  2488. &>span {
  2489. min-width: 25px;
  2490. height: 25px;
  2491. display: flex;
  2492. align-items: center;
  2493. justify-content: center;
  2494. background: rgba(252, 207, 0, 1);
  2495. border-radius: 4px;
  2496. color: rgba(255, 255, 255, 1);
  2497. font-weight: bold;
  2498. font-size: 14px;
  2499. }
  2500. &>div {
  2501. color: rgba(0, 0, 0, 0.7);
  2502. font-weight: 800;
  2503. }
  2504. }
  2505. .c_t72_c_i_bottom {
  2506. margin-top: 15px;
  2507. font-weight: 300;
  2508. font-size: 14px;
  2509. // height: 40px;
  2510. max-width: 100%;
  2511. overflow: hidden;
  2512. text-overflow: ellipsis;
  2513. display: -webkit-box;
  2514. -webkit-line-clamp: 2;
  2515. -webkit-box-orient: vertical;
  2516. img {
  2517. width: 100%;
  2518. max-height: 200px;
  2519. object-fit: cover;
  2520. }
  2521. }
  2522. }
  2523. }
  2524. .c_t72_workDetail {
  2525. width: 100%;
  2526. height: auto;
  2527. margin-top: 40px;
  2528. box-shadow: 4px 4px 14px 0px rgba(252, 207, 0, 0.5);
  2529. box-sizing: border-box;
  2530. padding: 16px;
  2531. border-radius: 12px;
  2532. display: flex;
  2533. flex-direction: column;
  2534. .c_t72_wd_top {
  2535. width: 100%;
  2536. display: flex;
  2537. align-items: center;
  2538. gap: 15px;
  2539. &>img {
  2540. width: 25px;
  2541. height: 25px;
  2542. cursor: pointer;
  2543. }
  2544. &>span {
  2545. display: block;
  2546. width: 30px;
  2547. height: 30px;
  2548. display: flex;
  2549. align-items: center;
  2550. justify-content: center;
  2551. background: rgba(252, 207, 0, 1);
  2552. border-radius: 4px;
  2553. color: rgba(255, 255, 255, 1);
  2554. font-weight: bold;
  2555. font-size: 16px;
  2556. }
  2557. &>div {
  2558. color: rgba(0, 0, 0, 0.7);
  2559. font-weight: 800;
  2560. font-size: 18px;
  2561. }
  2562. }
  2563. .c_t72_wd_content {
  2564. width: 100%;
  2565. margin-top: 20px;
  2566. max-height: 100%;
  2567. overflow: auto;
  2568. flex-wrap: wrap;
  2569. display: flex;
  2570. align-items: center;
  2571. justify-content: center;
  2572. .na_m_item {
  2573. width: 100%;
  2574. height: auto;
  2575. margin: 10px 0;
  2576. }
  2577. .na_m_i_name {
  2578. width: fit-content;
  2579. max-width: 100%;
  2580. height: auto;
  2581. box-sizing: border-box;
  2582. padding: 10px 10px;
  2583. display: flex;
  2584. align-items: center;
  2585. border-radius: 10px 10px 0 0;
  2586. background-color: #9747ff;
  2587. color: #fff;
  2588. text-overflow: ellipsis;
  2589. overflow: hidden;
  2590. white-space: nowrap;
  2591. }
  2592. .aiName {
  2593. background-color: #0560fc;
  2594. }
  2595. .na_m_i_content {
  2596. padding: 10px;
  2597. border: solid 1px #e7e7e7;
  2598. box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.1);
  2599. border-radius: 0 0 12px 12px;
  2600. background-color: #fff;
  2601. :deep(img) {
  2602. max-width: 100%;
  2603. }
  2604. }
  2605. .messageNode {
  2606. width: 100%;
  2607. height: auto;
  2608. box-sizing: border-box;
  2609. padding: 10px 10px;
  2610. border: 0.5px solid #e7e7e7;
  2611. border-radius: 12px;
  2612. gap: 10px;
  2613. margin-top: 20px;
  2614. }
  2615. .messageNodeArea {
  2616. width: 100%;
  2617. height: auto;
  2618. }
  2619. }
  2620. }
  2621. }
  2622. .c_t73 {
  2623. width: 100%;
  2624. min-height: 100%;
  2625. display: flex;
  2626. // align-items: center;
  2627. flex-direction: column;
  2628. height: auto;
  2629. padding: 40px;
  2630. .c_t73_title {
  2631. color: rgba(0, 0, 0, 0.9);
  2632. font-weight: 600;
  2633. font-size: 24px;
  2634. line-height: 24px;
  2635. }
  2636. .c_t73_type {
  2637. font-weight: 400;
  2638. font-size: 15px;
  2639. line-height: 21px;
  2640. letter-spacing: 0.5px;
  2641. color: rgba(0, 0, 0, 1);
  2642. opacity: 0.5;
  2643. margin: 10px 0;
  2644. }
  2645. .c_t73_msg {
  2646. display: flex;
  2647. align-items: center;
  2648. font-size: .9rem;
  2649. font-weight: 400;
  2650. gap: 1rem;
  2651. &>span {
  2652. text-decoration: underline;
  2653. cursor: pointer;
  2654. }
  2655. }
  2656. .c_t73_content {
  2657. width: 100%;
  2658. height: auto;
  2659. display: grid;
  2660. grid-template-columns: repeat(4, 1fr);
  2661. gap: 20px;
  2662. margin-top: 40px;
  2663. .c_t73_c_item {
  2664. width: 100%;
  2665. height: auto;
  2666. box-shadow: 2px 4px 20px 0px rgba(0, 0, 0, 0.2);
  2667. box-sizing: border-box;
  2668. border-radius: 12px;
  2669. padding: 16px;
  2670. background: rgba(255, 255, 255, 0.6);
  2671. transition: 0.3s;
  2672. cursor: pointer;
  2673. overflow: hidden;
  2674. &:hover {
  2675. box-shadow: 4px 4px 14px 0px rgba(252, 207, 0, 0.5);
  2676. background: rgba(255, 255, 255, 0.6);
  2677. }
  2678. .c_t73_c_i_top {
  2679. display: flex;
  2680. align-items: center;
  2681. gap: 10px;
  2682. width: 100%;
  2683. overflow: hidden;
  2684. &>span {
  2685. min-width: 25px;
  2686. height: 25px;
  2687. display: flex;
  2688. align-items: center;
  2689. justify-content: center;
  2690. background: rgba(252, 207, 0, 1);
  2691. border-radius: 4px;
  2692. color: rgba(255, 255, 255, 1);
  2693. font-weight: bold;
  2694. font-size: 14px;
  2695. }
  2696. &>div {
  2697. color: rgba(0, 0, 0, 0.7);
  2698. font-weight: 800;
  2699. }
  2700. }
  2701. .c_t73_c_i_bottom {
  2702. margin-top: 15px;
  2703. font-weight: 300;
  2704. font-size: 14px;
  2705. // height: 40px;
  2706. max-width: 100%;
  2707. overflow: hidden;
  2708. text-overflow: ellipsis;
  2709. display: -webkit-box;
  2710. -webkit-line-clamp: 2;
  2711. -webkit-box-orient: vertical;
  2712. img {
  2713. width: 100%;
  2714. max-height: 200px;
  2715. object-fit: cover;
  2716. }
  2717. }
  2718. }
  2719. }
  2720. .c_t73_workDetail {
  2721. width: 100%;
  2722. height: auto;
  2723. margin-top: 40px;
  2724. box-shadow: 4px 4px 14px 0px rgba(252, 207, 0, 0.5);
  2725. box-sizing: border-box;
  2726. padding: 16px;
  2727. border-radius: 12px;
  2728. display: flex;
  2729. flex-direction: column;
  2730. .c_t73_wd_top {
  2731. width: 100%;
  2732. display: flex;
  2733. align-items: center;
  2734. gap: 15px;
  2735. &>img {
  2736. width: 25px;
  2737. height: 25px;
  2738. cursor: pointer;
  2739. }
  2740. &>span {
  2741. display: block;
  2742. width: 30px;
  2743. height: 30px;
  2744. display: flex;
  2745. align-items: center;
  2746. justify-content: center;
  2747. background: rgba(252, 207, 0, 1);
  2748. border-radius: 4px;
  2749. color: rgba(255, 255, 255, 1);
  2750. font-weight: bold;
  2751. font-size: 16px;
  2752. }
  2753. &>div {
  2754. color: rgba(0, 0, 0, 0.7);
  2755. font-weight: 800;
  2756. font-size: 18px;
  2757. }
  2758. }
  2759. .c_t73_wd_content {
  2760. width: 100%;
  2761. margin-top: 20px;
  2762. max-height: 100%;
  2763. overflow: auto;
  2764. flex-wrap: wrap;
  2765. display: flex;
  2766. align-items: center;
  2767. justify-content: center;
  2768. &>img {
  2769. max-width: 100%;
  2770. object-fit: cover;
  2771. }
  2772. }
  2773. }
  2774. }
  2775. }
  2776. }
  2777. .aiAnalysis {
  2778. width: 100%;
  2779. height: auto;
  2780. display: flex;
  2781. flex-direction: column;
  2782. padding: 1rem;
  2783. border: solid 1px #F6C82B;
  2784. border-left-width: 4px;
  2785. border-radius: 1rem;
  2786. gap: 1rem;
  2787. &>.ai_header {
  2788. display: flex;
  2789. align-items: center;
  2790. justify-content: space-between;
  2791. gap: 1rem;
  2792. &>div {
  2793. display: flex;
  2794. align-items: center;
  2795. gap: .5rem;
  2796. &>svg {
  2797. width: 1rem;
  2798. height: 1rem;
  2799. }
  2800. }
  2801. &>.ai_title {
  2802. color: #F7CD49;
  2803. font-weight: 500;
  2804. &>svg {
  2805. fill: #F7CD49;
  2806. width: 1.2rem;
  2807. height: 1.2rem;
  2808. }
  2809. }
  2810. &>.ai_refresh {
  2811. padding: .5rem 1rem;
  2812. border-radius: .5rem;
  2813. background: #F6C82B;
  2814. display: flex;
  2815. justify-content: center;
  2816. align-items: center;
  2817. cursor: pointer;
  2818. color: #000;
  2819. font-weight: bold;
  2820. font-size: .8rem;
  2821. gap: .5rem;
  2822. &>svg {
  2823. fill: #000;
  2824. width: .8rem;
  2825. height: .8rem;
  2826. }
  2827. &.disabled {
  2828. cursor: not-allowed !important;
  2829. background: #FEF8E9 !important;
  2830. }
  2831. }
  2832. }
  2833. &>.ai_content {
  2834. font-size: 1rem;
  2835. font-weight: 500;
  2836. :deep(table) {
  2837. border-collapse: collapse;
  2838. width: 100%;
  2839. margin: 0.5rem 0;
  2840. th,
  2841. td {
  2842. border: 1px solid #ddd;
  2843. padding: 0.5rem;
  2844. text-align: left;
  2845. }
  2846. th {
  2847. background: #f5f5f5;
  2848. }
  2849. }
  2850. }
  2851. &>.ai_echartsData {
  2852. display: flex;
  2853. flex-wrap: wrap;
  2854. gap: .5rem;
  2855. &>span {
  2856. padding: .2rem .5rem;
  2857. border-radius: .25rem;
  2858. background: #E6F4FF;
  2859. display: flex;
  2860. justify-content: center;
  2861. align-items: center;
  2862. color: #141517;
  2863. font-size: .75rem;
  2864. }
  2865. &>.title {
  2866. font-weight: 600;
  2867. }
  2868. &>.btn {
  2869. font-size: .9rem;
  2870. text-decoration: underline;
  2871. color: #F6C82B;
  2872. cursor: pointer;
  2873. }
  2874. }
  2875. &>.ai_updateTime {
  2876. font-size: .8rem;
  2877. font-weight: 500;
  2878. }
  2879. }
  2880. .nextAndUpBtn {
  2881. width: 100%;
  2882. height: auto;
  2883. display: grid;
  2884. grid-template-columns: 1fr 1fr;
  2885. margin-top: 20px;
  2886. gap: 15px;
  2887. &>span {
  2888. display: flex;
  2889. justify-content: center;
  2890. align-items: center;
  2891. width: 100%;
  2892. height: 40px;
  2893. border-radius: 5px;
  2894. font-size: 14px;
  2895. font-weight: 500;
  2896. color: #fff;
  2897. background: #f6c82b;
  2898. cursor: pointer;
  2899. }
  2900. &>.no_active {
  2901. background: #cccccc !important;
  2902. color: #999999 !important;
  2903. cursor: not-allowed !important;
  2904. pointer-events: none !important;
  2905. }
  2906. }
  2907. .c_title{
  2908. display: flex;
  2909. &>span {
  2910. flex: 1;
  2911. word-break: break-all;
  2912. }
  2913. }
  2914. .switch_btn{
  2915. display: flex;
  2916. align-items: center;
  2917. gap: .5rem;
  2918. &>.switch{
  2919. display: flex;
  2920. align-items: center;
  2921. gap: .5rem;
  2922. font-size: .8rem;
  2923. color: #141517;
  2924. +.switch{
  2925. margin-left: .5rem;
  2926. }
  2927. }
  2928. }
  2929. .bottom_btn{
  2930. display: flex;
  2931. align-items: center;
  2932. gap: 5px;
  2933. font-weight: 300;
  2934. font-size: 14px;
  2935. color: rgba(0, 0, 0, 0.7);
  2936. .bottom_like{
  2937. margin-left: auto;
  2938. cursor: pointer;
  2939. display: flex;
  2940. align-items: center;
  2941. gap: 5px;
  2942. color: rgba(0, 0, 0, 0.7);
  2943. &.active{
  2944. color: rgba(252, 207, 0, 1);
  2945. }
  2946. }
  2947. }
  2948. .cast_sreen_btn{
  2949. display: flex;
  2950. align-items: center;
  2951. gap: 5px;
  2952. font-weight: 300;
  2953. font-size: 14px;
  2954. color: rgba(0, 0, 0, 0.7);
  2955. cursor: pointer;
  2956. margin-left: auto;
  2957. border-radius: 5px;
  2958. border: solid 1px rgba(252, 207, 0, .7);
  2959. padding: .5rem 0.6rem;
  2960. min-width: 65px;
  2961. justify-content: center;
  2962. }
  2963. </style>