searchArea.vue 113 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815
  1. <template>
  2. <div class="search">
  3. <div class="s_top" ref="chatRef" v-if="cardType == 0">
  4. <div class="s_t_chat" v-for="(item, index) in chatList" :key="index">
  5. <div
  6. class="s_t_c_user"
  7. v-if="
  8. item.content &&
  9. item.content != 'wanSearch' &&
  10. item.content != 'getImage' &&
  11. item.content != 'addAsk'
  12. "
  13. >
  14. <div class="s_t_c_u_left">
  15. <div class="s_t_c_u_l_content">{{ item.content }}</div>
  16. <div class="s_t_c_u_l_time">{{ item.createtime }}</div>
  17. </div>
  18. <div class="s_t_c_u_right">
  19. <span>我</span>
  20. </div>
  21. </div>
  22. <div
  23. class="s_t_c_ai"
  24. v-if="
  25. item.content != 'wanSearch' &&
  26. item.content != 'getImage' &&
  27. item.content != 'addAsk'
  28. "
  29. >
  30. <div class="s_t_c_a_left">
  31. <el-avatar v-if="item.filename" :src="item.filename"></el-avatar>
  32. <span v-else>Ai</span>
  33. </div>
  34. <div class="s_t_c_a_right">
  35. <div
  36. class="s_t_c_a_r_content"
  37. v-if="pan(item.aiContent).length"
  38. style="display: flex;justify-content: space-between;flex-wrap: wrap;"
  39. >
  40. <div
  41. v-if="!pan(item.aiContent).length"
  42. class="d_t_c_a_r_content"
  43. v-loading="item.loading"
  44. v-html="item.aiContent"
  45. ></div>
  46. <div
  47. v-else
  48. v-for="(i, index) in pan(item.aiContent)"
  49. :key="index"
  50. style="position: relative;"
  51. class="d_t_c_a_r_c_img"
  52. >
  53. <img
  54. style="width: 130px;height: 130px;object-fit: cover;"
  55. :src="i.image"
  56. alt=""
  57. @error="setDefaultSrc"
  58. @click="previewImg(i.image)"
  59. />
  60. <span class="download_image" @click.stop="download(i.image)">
  61. <img
  62. :src="require('../../../assets/icon/fileIcon/download.png')"
  63. />
  64. </span>
  65. </div>
  66. <!-- {{ item }} -->
  67. <div
  68. style="margin-top: 10px;width: 100%;display: flex;justify-content: end;"
  69. v-if="
  70. pan(item.aiContent).length > 1 && chatList.length - 2 == index
  71. "
  72. >
  73. <img
  74. style="cursor: pointer;"
  75. @click="resetImg(item.content)"
  76. src="../../../assets/icon/course/resImg.png"
  77. alt=""
  78. />
  79. </div>
  80. </div>
  81. <div
  82. v-else
  83. class="s_t_c_a_r_content"
  84. v-loading="item.loading"
  85. v-html="htmlContent(item.aiContent)"
  86. ></div>
  87. <!-- {{ Array.isArray(JSON.parse(item.aiContent)) }} -->
  88. <!-- {{ JSON.parse(item) }} -->
  89. <div
  90. v-if="!pan(item.aiContent).length && !item.loading"
  91. class="aiCopy"
  92. >
  93. <img
  94. @click="onCopy(item.aiContent)"
  95. style="width: 30px;"
  96. src="../../../assets/icon/course/copyTxt.png"
  97. alt=""
  98. />
  99. <img
  100. @click.stop="aiTalkAll(item)"
  101. v-if="aiTalkUid == item.uid && aiIsTalk"
  102. style="width: 15px;margin-bottom:7px;"
  103. :src="require('../../../assets/icon/course/megaphone.svg')"
  104. />
  105. <img
  106. @click.stop="aiTalkAll(item)"
  107. v-else
  108. style="width: 15px;margin-bottom:7px;"
  109. :src="require('../../../assets/icon/course/megaphone3.svg')"
  110. />
  111. <img
  112. v-if="chatList.length - 2 == index"
  113. @click.stop="refresh(item)"
  114. style="width: 15px;margin-bottom:7px;"
  115. :src="require('../../../assets/icon/course/refresh.svg')"
  116. />
  117. </div>
  118. <!-- <div
  119. class="s_t_c_a_r_contentImage"
  120. v-loading="item.loading"
  121. >
  122. <span style="margin-bottom: 10px;">为您找到以下图片: {{ item.content }}</span> -->
  123. <!-- {{ item.aiContent }} -->
  124. <!-- <img
  125. v-for="(i, index) in item.aiContent"
  126. @click.stop="$hevueImgPreview(item)"
  127. :key="index"
  128. :src="i.image"
  129. /> -->
  130. <!-- <div class="imgNumberBlock">
  131. <div class="imgNumber" v-for="(i,index) in imgNumList" :key="index+'b'">
  132. {{ i }}
  133. </div>
  134. <div class="imgNumber" style="background: none;">
  135. <img style="width: 36px;height: 30px;" src="https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/Frame%20131715569413607.png" alt="">
  136. </div>
  137. </div> -->
  138. <!-- </div> -->
  139. <!-- <div class="s_t_c_a_r_time">{{ item.createtime }}</div> -->
  140. </div>
  141. </div>
  142. <div class="s_t_chat" v-if="item.content == 'wanSearch'">
  143. <div class="s_t_c_ai">
  144. <div class="s_t_c_a_left">
  145. <el-avatar v-if="item.filename" :src="item.filename"></el-avatar>
  146. <span v-else>Ai</span>
  147. </div>
  148. <div class="s_t_c_a_right">
  149. <div class="s_t_c_a_r_content2" v-loading="item.loading">
  150. <div class="s_t_c_a_r_c_title">
  151. <img :src="require('../../../assets/icon/course/idea.png')" />
  152. <span>猜你想搜:</span>
  153. </div>
  154. <div
  155. class="s_t_c_a_r_c_item"
  156. v-for="(item, index) in item.aiContent"
  157. :key="index"
  158. @click="sendAiIdea(item.label)"
  159. >
  160. {{ index + 1 }}.{{ item.title }}:{{ item.label }}
  161. </div>
  162. </div>
  163. <div class="s_t_c_a_r_time">{{ item.createtime }}</div>
  164. </div>
  165. </div>
  166. </div>
  167. <div
  168. class="s_t_addAsk"
  169. v-if="
  170. item.content == 'addAsk' &&
  171. !item.aiContent.questions &&
  172. item.aiContent.length &&
  173. !item.loading
  174. "
  175. >
  176. <span
  177. v-for="item2 in item.aiContent"
  178. :key="item2.index"
  179. @click.stop="send(item2.label)"
  180. >{{ item2.label }}</span
  181. >
  182. </div>
  183. <div
  184. class="s_t_addAsk"
  185. v-if="
  186. item.content == 'addAsk' &&
  187. item.aiContent.questions &&
  188. !item.loading
  189. "
  190. >
  191. <span
  192. v-for="(item2, index2) in item.aiContent.questions"
  193. :key="index2"
  194. @click.stop="send(item2.question ? item2.question : item2)"
  195. >{{ item2.question ? item2.question : item2 }}</span
  196. >
  197. </div>
  198. <div class="s_t_addAsk" v-if="item.content == 'addAsk' && item.loading">
  199. <span style="width:50px;height:50px" v-loading="true"></span>
  200. </div>
  201. </div>
  202. </div>
  203. <div class="s_bottom" v-if="cardType == 0">
  204. <div class="s_b_btnAreaTop">
  205. <div class="s_b_bat_left">
  206. <el-tooltip
  207. class="item"
  208. effect="dark"
  209. content="清空聊天记录"
  210. placement="top"
  211. >
  212. <img
  213. :src="require('../../../assets/icon/course/clean.svg')"
  214. @click.stop="clear()"
  215. />
  216. </el-tooltip>
  217. <el-tooltip
  218. class="item"
  219. effect="dark"
  220. :content="openMegaphone ? '关闭喇叭' : '打开喇叭'"
  221. placement="top"
  222. >
  223. <img
  224. v-if="!openMegaphone"
  225. :src="require('../../../assets/icon/course/megaphone2.svg')"
  226. @click.stop="$parent.changeMegaphone()"
  227. />
  228. <img
  229. v-else
  230. :src="require('../../../assets/icon/course/megaphone.svg')"
  231. @click.stop="$parent.changeMegaphone()"
  232. />
  233. </el-tooltip>
  234. </div>
  235. <div class="s_b_bat_right">
  236. <!-- <img :src="require('../../../assets/icon/course/bulb.svg')"> -->
  237. <img :src="require('../../../assets/icon/course/bulb2.svg')" />
  238. </div>
  239. </div>
  240. <div class="s_b_btnArea">
  241. <div class="s_b_ba-item" @click.stop="choiceRole()">
  242. <img
  243. style="width: 20px;"
  244. src="../../../assets/icon/course/role.png"
  245. alt=""
  246. />
  247. 智能体
  248. </div>
  249. <div
  250. :class="['s_b_ba-item', sendType == 3 ? 's_b_ba_active' : '']"
  251. @click="chooseType(3)"
  252. >
  253. <!-- <img src="../../../assets/icon/course/sImg.png" style="margin-right: 5px;" alt="" v-if="sendType!=3">
  254. <img src="../../../assets/icon/course/sImg2.png" style="margin-right: 5px;" alt="" v-else> -->
  255. 生成图片
  256. </div>
  257. <div
  258. :class="['s_b_ba-item', sendType == 1 ? 's_b_ba_active' : '']"
  259. @click="chooseType(1)"
  260. >
  261. <!-- <img src="../../../assets/icon/course/sImg.png" style="margin-right: 5px;" alt="" v-if="sendType!=1">
  262. <img src="../../../assets/icon/course/sImg2.png" style="margin-right: 5px;" alt="" v-else> -->
  263. 搜索图片
  264. </div>
  265. <div
  266. :class="['s_b_ba-item', sendType == 2 ? 's_b_ba_active' : '']"
  267. @click="chooseType(2)"
  268. >
  269. <!-- <img src="../../../assets/icon/course/sRio.png" style="margin-right: 5px;" alt="" v-if="sendType!=2">
  270. <img src="../../../assets/icon/course/sRio2.png" style="margin-right: 5px;" alt="" v-else> -->
  271. 搜索视频
  272. </div>
  273. </div>
  274. <div class="s_b_atBox" v-if="openAtBox" v-loading="loading">
  275. <div class="s_b_at_tag">
  276. <span
  277. :class="[atTagIndex == 0 ? 's_b_at_tag_active' : '']"
  278. @click.stop="atTagIndex = 0"
  279. >任务</span
  280. >
  281. <span
  282. :class="[[1, 2].includes(atTagIndex) ? 's_b_at_tag_active' : '']"
  283. @click.stop="atTagIndex = 1"
  284. >成员</span
  285. >
  286. </div>
  287. <div class="s_b_at_list">
  288. <template v-if="atTagIndex == 0">
  289. <div v-for="(item1, index1) in taskList" :key="index1">
  290. <div
  291. class="s_b_at_l_top"
  292. v-if="item1.dyName"
  293. @click="
  294. atTask(`阶段${index1 + 1} ${item1.dyName} `, index1, 0, item1)
  295. "
  296. >
  297. <span>阶段{{ index1 + 1 }} {{ item1.dyName }}</span>
  298. <span
  299. class="s_b_at_l_i_h_icon1"
  300. :style="
  301. `${!item1.isOpen ? 'transform: rotate(-90deg);' : ''}'`
  302. "
  303. @click.stop="item1.isOpen = !item1.isOpen"
  304. ></span>
  305. </div>
  306. <div
  307. class="s_b_at_l_item"
  308. v-for="(item2, index2) in item1.task"
  309. :key="index1 + '-' + index2"
  310. v-if="item1.isOpen"
  311. >
  312. <div
  313. class="s_b_at_l_i_header"
  314. v-if="item2.tool[0].tool != undefined"
  315. @click="
  316. atTask(
  317. `阶段${index1 + 1} ${item1.dyName}-任务${index2 + 1}:${
  318. item2.taskName
  319. } `,
  320. index2,
  321. 1,
  322. item2
  323. )
  324. "
  325. >
  326. <span
  327. class="s_b_at_l_i_h_icon1"
  328. :style="
  329. `${!item2.isOpen ? 'transform: rotate(-90deg);' : ''}'`
  330. "
  331. @click.stop="item2.isOpen = !item2.isOpen"
  332. ></span>
  333. <span>任务{{ index2 + 1 }}:{{ item2.taskName }}</span>
  334. </div>
  335. <div
  336. class="s_b_at_l_i_header"
  337. v-else
  338. @click="
  339. atTask(
  340. `阶段${index1 + 1} ${item1.dyName}-任务${index2 + 1}:${
  341. item2.taskName
  342. } `,
  343. index2,
  344. 1,
  345. item2
  346. )
  347. "
  348. >
  349. <span
  350. class="s_b_at_l_i_h_icon2"
  351. :style="
  352. `${!item2.isOpen ? 'transform: rotate(-90deg);' : ''}'`
  353. "
  354. @click.stop="item2.isOpen = !item2.isOpen"
  355. ></span>
  356. <span>任务{{ index2 + 1 }}:{{ item2.taskName }}</span>
  357. </div>
  358. <div
  359. class="s_b_at_l_i_content"
  360. v-if="item2.tool[0].tool != undefined && item2.isOpen"
  361. v-for="(item3, index3) in item2.tool"
  362. :key="index1 + '-' + index2 + '-' + index3"
  363. @click="
  364. atTask(
  365. `阶段${index1 + 1} ${item1.dyName}-任务${index2 + 1}:${
  366. item2.taskName
  367. }-工具${index3 + 1}:${toolsList[item3.tool]} `,
  368. index3,
  369. 2,
  370. item3
  371. )
  372. "
  373. >
  374. <span>工具{{ index3 + 1 }}:{{ toolsList[item3.tool] }}</span>
  375. </div>
  376. </div>
  377. </div>
  378. </template>
  379. <template v-if="atTagIndex == 1 && workSum != 0">
  380. <div v-if="userList.length == 0">暂无成员...</div>
  381. <div
  382. class="s_b_ab_user"
  383. v-for="(item, index) in userList"
  384. :key="item.id"
  385. v-else
  386. >
  387. <div class="s_b_ab_u_name">
  388. <el-tooltip
  389. class="item"
  390. effect="light:"
  391. :content="item.username"
  392. placement="top"
  393. >
  394. <span>{{ item.username }}</span>
  395. </el-tooltip>
  396. </div>
  397. <div class="s_b_ab_u_message">
  398. <span>作业提交情况</span>
  399. <div>
  400. <span>已提交:{{ item.count }}</span>
  401. <span>未提交:{{ workSum - item.count }}</span>
  402. </div>
  403. </div>
  404. <div class="s_b_ab_u_btnArea">
  405. <span @click="sumUpStudent(item)">总结分析</span>
  406. <span @click.stop="lookStudentDetail(item)">作业详细</span>
  407. </div>
  408. </div>
  409. </template>
  410. <template v-if="atTagIndex == 2">
  411. <div class="s_b_at_studentDetail">
  412. <img
  413. :src="require('../../../assets/icon/course/back.svg')"
  414. @click.stop="atTagIndex = 1"
  415. />
  416. <span>学生:{{ lookStudentData.userName }}</span>
  417. </div>
  418. <div class="s_b_at_studentList">
  419. <div
  420. class="s_b_at_sl_item"
  421. v-if="[3, 2, 8].includes(item.type)"
  422. v-for="(item, index) in lookStudentData.list"
  423. @click.stop="sumUpStudent2(item)"
  424. >
  425. <div class="s_b_at_sl_phase">
  426. {{
  427. `阶段${item.stage + 1}/任务${item.task +
  428. 1}/工具${item.tool + 1}`
  429. }}
  430. </div>
  431. <div class="s_b_at_sl_message" v-if="item.type === 3">
  432. <div>
  433. 题目:
  434. <el-tooltip
  435. class="item"
  436. effect="light:"
  437. :content="item.content.answerTitle"
  438. placement="top"
  439. ><span>{{ item.content.answerTitle }}</span></el-tooltip
  440. >
  441. </div>
  442. <div>
  443. 答题:
  444. <span>{{ item.content.answer }}</span>
  445. </div>
  446. </div>
  447. <div
  448. class="s_b_at_sl_message"
  449. v-if="item.type === 8"
  450. v-for="(item1, index1) in item.content.testJson
  451. ? item.content.testJson.testJson
  452. : []"
  453. :key="index1"
  454. >
  455. <div>
  456. 题目:
  457. <el-tooltip
  458. class="item"
  459. effect="light:"
  460. :content="item1.teststitle"
  461. placement="top"
  462. ><span>{{ item1.teststitle }}</span></el-tooltip
  463. >
  464. </div>
  465. <div>
  466. 选项:
  467. <span>
  468. <div v-for="(item2, index2) in item1.checkList">
  469. {{ index2 + 1 }}、{{ item2.src ? item2.src : item2 }}
  470. </div>
  471. </span>
  472. </div>
  473. <div>
  474. 答案:{{ answerData(item1.checkList, item1.answer) }}
  475. </div>
  476. <div>
  477. 答题:
  478. <span>{{
  479. answerData(item1.checkList, item.content.anwer[index1])
  480. }}</span>
  481. </div>
  482. </div>
  483. <div
  484. class="s_b_at_sl_message"
  485. v-if="item.type === 2"
  486. v-for="(item1, index1) in item.content.askJson
  487. ? item.content.askJson.askJson
  488. : []"
  489. :key="index1"
  490. >
  491. <div>
  492. 题目:
  493. <el-tooltip
  494. class="item"
  495. effect="light:"
  496. :content="item1.askstitle"
  497. placement="top"
  498. ><span>{{ item1.askstitle }}</span></el-tooltip
  499. >
  500. </div>
  501. <div>
  502. 选项:
  503. <span>
  504. <div v-for="(item2, index2) in item1.checkList">
  505. {{ index2 + 1 }}、{{ item2.src ? item2.src : item2 }}
  506. </div>
  507. </span>
  508. </div>
  509. <div>
  510. 答题:
  511. <span>{{
  512. answerData(item1.checkList, item.content.anwer[index1])
  513. }}</span>
  514. </div>
  515. </div>
  516. </div>
  517. </div>
  518. </template>
  519. </div>
  520. </div>
  521. <div class="s_b_inputArea">
  522. <!-- <div class="s_b_tape" @click="goTape()"></div> -->
  523. <div class="s_b_input">
  524. <el-input
  525. :disabled="loading || chatLoading || sendFnType == 1"
  526. v-loading="loading || chatLoading"
  527. @keyup.enter.native="send()"
  528. :placeholder="
  529. sendFnType == 0
  530. ? '请在此输入您想了解的内容'
  531. : '请点击录音按钮开始录音'
  532. "
  533. class="s_b_i_left"
  534. v-model="text"
  535. ref="textRef"
  536. ></el-input>
  537. <!-- <div class="s_b_i_right" @click="sendFile()">
  538. <span></span>
  539. </div> -->
  540. </div>
  541. <div class="voice_or_keyboard">
  542. <el-tooltip
  543. v-if="sendFnType == 0"
  544. class="item"
  545. effect="dark"
  546. content="使用语音"
  547. placement="top"
  548. >
  549. <img
  550. :src="require('../../../assets/icon/course/voice.svg')"
  551. @click.stop="changeFnType(1)"
  552. />
  553. </el-tooltip>
  554. <el-tooltip
  555. v-if="sendFnType == 1"
  556. class="item"
  557. effect="dark"
  558. content="使用键盘"
  559. placement="top"
  560. >
  561. <img
  562. :src="require('../../../assets/icon/course/keyboard.svg')"
  563. @click.stop="changeFnType(0)"
  564. />
  565. </el-tooltip>
  566. </div>
  567. <div class="s_b_btn" @click="send()" v-if="sendFnType == 0">
  568. <span v-if="!loading && !chatLoading"></span>
  569. <div v-else @click.stop="stopSend()">停止</div>
  570. </div>
  571. <div class="s_b_btn" v-if="sendFnType == 1">
  572. <img
  573. v-if="!loading && !chatLoading && !isTalk"
  574. @click.stop="talk()"
  575. :src="require('../../../assets/icon/course/voice2.svg')"
  576. />
  577. <img
  578. style="width:50px;height:50px"
  579. v-else-if="!loading && !chatLoading && isTalk"
  580. @click.stop="stopTalk()"
  581. :src="require('../../../assets/icon/course/isTape.svg')"
  582. />
  583. <div v-else @click.stop="stopSend()">停止</div>
  584. </div>
  585. <div class="s_b_btn2" @click.stop="openPhone">
  586. <img
  587. :src="require('../../../assets/icon/course/phone.svg')"
  588. />
  589. </div>
  590. </div>
  591. </div>
  592. <div class="choiceTopArea" v-if="cardType == 1">
  593. <div class="choiceTop">
  594. <div class="choiceRoleHeader">
  595. <div
  596. class="s_t_c_ai"
  597. >
  598. <div class="s_t_c_a_left">
  599. <el-avatar :src="require('../../../assets/icon/course/aiWait.svg')"></el-avatar>
  600. </div>
  601. <div class="s_t_c_a_right">
  602. <div
  603. class="s_t_c_a_r_content"
  604. >选择您需要的智能体,开始对话</div>
  605. </div>
  606. </div>
  607. </div>
  608. <div class="choiceSelect">
  609. <div style="width:100%">
  610. <div class="roleInput"> <el-input
  611. placeholder="请输入内容"
  612. v-model="roleText"
  613. prefix-icon="el-icon-search"
  614. clearable
  615. >
  616. </el-input></div>
  617. <div class="roleBtn"> <el-button
  618. class="option"
  619. :style="{
  620. background: sortOption == 0 ? '#36A9FC' : '',
  621. color: sortOption == 0 ? '#fff' : ''
  622. }"
  623. @click="optBtn(0)"
  624. plain
  625. >我的</el-button
  626. >
  627. <el-button
  628. class="option"
  629. :style="{
  630. background: sortOption == 1 ? '#36A9FC' : '',
  631. color: sortOption == 1 ? '#fff' : ''
  632. }"
  633. @click="optBtn(1)"
  634. plain
  635. >社区</el-button
  636. ></div>
  637. </div>
  638. <div class="roleListBox">
  639. <div
  640. class="characterBlock"
  641. v-for="(item, index) in showRoleList"
  642. :key="item.id"
  643. @click.stop="choseRole(item)"
  644. >
  645. <div class="imgLeft">
  646. <div class="img">
  647. <img
  648. style="width: 100%;height: 100%;"
  649. :src="
  650. item.headUrl && item.headUrl != ''
  651. ? item.headUrl
  652. : require('../../../assets/icon/course/ai.png')
  653. "
  654. />
  655. </div>
  656. </div>
  657. <div class="txtRight">
  658. <el-tooltip class="item" effect="dark" :content="item.assistantName" placement="top">
  659. <div class="bir">{{ item.assistantName }}</div>
  660. </el-tooltip>
  661. <div
  662. :style="{
  663. color: '#fff',
  664. display:
  665. choseRoleItem &&
  666. choseRoleItem.assistant_id == item.assistant_id
  667. ? 'block'
  668. : 'none'
  669. }"
  670. >
  671. 已选择
  672. </div>
  673. </div>
  674. </div>
  675. </div>
  676. </div>
  677. <!-- <div
  678. class="characterBlock"
  679. v-if="sortOption == 0"
  680. v-for="(item, index) in roleList"
  681. :key="item.id"
  682. @click.stop="choseRole(item)"
  683. >
  684. <div class="imgLeft">
  685. <div class="img">
  686. <img v-if="item.headUrl" style="width: 100%;height: 100%;" :src="item.headUrl" />
  687. <img v-else style="width: 100%;height: 100%;" :src="require('../../../assets/icon/course/ai.png')">
  688. </div>
  689. </div>
  690. <div class="txtRight">
  691. <div class="bir">{{ item.assistantName }}</div>
  692. <div
  693. :style="{
  694. color: '#fff',
  695. display:
  696. (choseRoleItem && choseRoleItem.assistant_id == item.assistant_id)
  697. ? 'block'
  698. : 'none'
  699. }"
  700. >
  701. 已选择
  702. </div>
  703. </div>
  704. </div> -->
  705. </div>
  706. <div class="choiceBottom">
  707. <el-button class="cb_btn" size="mini" @click="noChangeRole()"
  708. >取消</el-button
  709. >
  710. <el-button
  711. class="cb_btn"
  712. size="mini"
  713. type="primary"
  714. @click="changeRole()"
  715. >确定</el-button
  716. >
  717. </div>
  718. </div>
  719. <iframe
  720. allow="camera *; microphone *;display-capture;midi;encrypted-media;"
  721. src="https://beta.cloud.cocorobo.cn/browser/public/index.html"
  722. ref="iiframe"
  723. v-show="false"
  724. ></iframe>
  725. <!-- 文字转语音-->
  726. <iframe
  727. allow="camera *; microphone *;display-capture;midi;encrypted-media;"
  728. src="https://beta.cloud.cocorobo.cn/browser/public/index1.html"
  729. ref="iiframe2"
  730. v-show="false"
  731. ></iframe>
  732. </div>
  733. </template>
  734. <script>
  735. import { v4 as uuidv4 } from "uuid";
  736. import MarkdownIt from "markdown-it";
  737. import { tools } from "../../../common/tools";
  738. var OpenCC = require("opencc-js");
  739. let converter = OpenCC.Converter({
  740. from: "hk",
  741. to: "cn"
  742. });
  743. export default {
  744. props: {
  745. courseDetail: {
  746. type: Object,
  747. default: () => {}
  748. },
  749. recordType: {
  750. type: Number,
  751. default: 0
  752. },
  753. navList: {
  754. type: Array,
  755. default: () => []
  756. },
  757. tcid: {
  758. type: String,
  759. default: ""
  760. },
  761. fileId: {
  762. type: Array,
  763. default: () => []
  764. },
  765. openMegaphone: {
  766. type: Boolean,
  767. default: false
  768. }
  769. },
  770. data() {
  771. return {
  772. text: "",
  773. ppage: 1,
  774. sendType: 0,
  775. sendFnType: 0,
  776. isTalk: false,
  777. loading: false,
  778. chatLoading: false,
  779. imageCheck: false,
  780. videoCheck: false,
  781. userid: this.$route.query.userid,
  782. courseId: this.$route.query.courseId,
  783. imgNumList: ["U1", "U2", "U3", "U4"],
  784. chatList: [],
  785. nowChatList: [],
  786. atTagIndex: 0,
  787. source: null,
  788. saveUid: "",
  789. toolsList: {
  790. "58": "模拟驾驶",
  791. "59": "路径搜索",
  792. "60": "深度学习",
  793. "10": "倒计时",
  794. "65": "挑人",
  795. "7": "思维网格",
  796. "1": "电子白板",
  797. "52": "文档",
  798. "3": "思维导图",
  799. "48": "表格",
  800. "49": "学生分组",
  801. "4": "问卷调查",
  802. "45": "选择题",
  803. "15": "问答",
  804. "16": "作业提交",
  805. "50": "批量上传",
  806. "41": "选择匹配",
  807. "47": "排序",
  808. "40": "个人评价",
  809. "18": "训练平台",
  810. "21": "AIoT Blockly",
  811. "23": "AI Python",
  812. "24": "AI Blockly",
  813. "32": "源码编辑",
  814. "57": "CocoPi",
  815. "63": "海龟编程",
  816. "28": "翻译",
  817. "31": "数字画板",
  818. "39": "GeoGebra",
  819. "66": "公式编辑",
  820. "67": "分子结构",
  821. "68": "时间轴",
  822. "69": "英语写作",
  823. "70": "英语口语",
  824. "25": "目标管理",
  825. "26": "课程设计",
  826. "62": "交互视频",
  827. "71": "AI智能体"
  828. },
  829. lookStudentData: {},
  830. taskList: [],
  831. userList: [],
  832. tools: JSON.parse(converter(JSON.stringify(tools))),
  833. aiTalkList: [],
  834. aiIsTalk: false,
  835. aiTalkUid: "",
  836. choseRoleItem: null,
  837. cardType: 0,
  838. roleList: [],
  839. roleList2: [],
  840. sortOption: 0, //切换角色 0我的 1 社区
  841. roleText: ""
  842. };
  843. },
  844. computed: {
  845. showRoleList() {
  846. let _result = [];
  847. if (this.sortOption == 0) {
  848. _result = this.roleList;
  849. } else if (this.sortOption == 1) {
  850. _result = this.roleList2;
  851. }
  852. if (this.roleText) {
  853. _result = _result.filter(
  854. i => i.assistantName.indexOf(this.roleText) != -1
  855. );
  856. }
  857. return _result;
  858. },
  859. openAtBox() {
  860. // return false;
  861. if (this.text.length == 0) return false;
  862. if (this.text.lastIndexOf("@") == this.text.length - 1) {
  863. return true;
  864. } else {
  865. return false;
  866. }
  867. },
  868. atTaskList() {
  869. let _result = [];
  870. this.taskList.forEach((item1, index1) => {
  871. if (item1.dyName) {
  872. _result.push({
  873. name: `阶段${index1 + 1} ${item1.dyName}`,
  874. tool: null,
  875. type: 0
  876. });
  877. }
  878. item1.task.forEach((item2, index2) => {
  879. if (item2.taskName) {
  880. _result.push({
  881. name: `任务${index2 + 1}:${item2.taskName}`,
  882. tool: null,
  883. type: 1,
  884. superiors: {
  885. name: `阶段${index1 + 1} ${item1.dyName}`,
  886. type: 0
  887. }
  888. });
  889. }
  890. item2.tool.forEach((item3, index3) => {
  891. if (item3.tool != undefined) {
  892. _result.push({
  893. name: `工具${index3 + 1}:${this.toolsList[item3.tool]}`,
  894. tool: item3.tool,
  895. type: 2,
  896. superiors: {
  897. name: `任务${index2 + 1}:${item2.taskName}`,
  898. type: 1,
  899. superiors: {
  900. name: `阶段${index1 + 1} ${item1.dyName}`,
  901. type: 0
  902. }
  903. }
  904. });
  905. }
  906. });
  907. });
  908. });
  909. return _result;
  910. },
  911. pan() {
  912. return content => {
  913. try {
  914. return JSON.parse(content);
  915. } catch (error) {
  916. return [];
  917. }
  918. };
  919. },
  920. htmlContent() {
  921. const md = new MarkdownIt();
  922. return _md => {
  923. return md.render(_md);
  924. };
  925. },
  926. answerData() {
  927. return (checkList, answer) => {
  928. if (typeof answer == "number") {
  929. return answer + 1;
  930. } else {
  931. let _result = ``;
  932. answer.forEach((item, index) => {
  933. _result += `${item + 1}`;
  934. if (index != answer.length - 1) {
  935. _result += `、`;
  936. }
  937. });
  938. return _result;
  939. }
  940. };
  941. },
  942. workSum() {
  943. let sum = 0;
  944. this.atTaskList.forEach(i => {
  945. if (i.type != 2) return;
  946. if ([4, 15, 45].includes(i.tool)) {
  947. return (sum += 1);
  948. }
  949. });
  950. return sum;
  951. }
  952. },
  953. watch: {
  954. navList() {
  955. this.initTaskList();
  956. },
  957. atTagIndex(newValue) {
  958. if (newValue != 2) {
  959. this.lookStudentData = {};
  960. }
  961. }
  962. },
  963. methods: {
  964. insertMemorandum(_html){//保存行为操作
  965. //variable
  966. //btn
  967. return;
  968. let params = [{
  969. uid:this.userid,
  970. courseId:this.courseId,
  971. content:_html
  972. }]
  973. this.ajax.post(this.$store.state.api+'insert_systemOperation_countdownBehavior',params).then(res=>{
  974. if(res.data==1){
  975. console.log('保存操作成功')
  976. }else{
  977. console.log('保存操作失败')
  978. }
  979. }).catch(e=>{
  980. console.log('保存操作失败')
  981. console.log(e)
  982. })
  983. },
  984. openPhone(){
  985. // this.$message.info("打开电话面板")
  986. this.$parent.changeItemType(4)
  987. },
  988. setDefaultSrc(e){
  989. e.target.src = require('../../../assets/icon/course/404.png')
  990. },
  991. refresh(item) {
  992. this.send(item.content);
  993. },
  994. changeFnType(newValue) {
  995. if (this.isTalk) return this.$message.info("请先停止录音");
  996. this.sendFnType = newValue;
  997. },
  998. chooseType(type) {
  999. if (this.sendType == type) {
  1000. this.sendType = 0;
  1001. } else {
  1002. this.sendType = type;
  1003. }
  1004. },
  1005. talk() {
  1006. let iiframe = this.$refs["iiframe"];
  1007. iiframe.contentWindow.window.document.getElementById(
  1008. "languageOptions"
  1009. ).selectedIndex = 2; //普通话
  1010. iiframe.contentWindow.testdoContinuousPronunciationAssessment();
  1011. this.isTalk = true;
  1012. iiframe.contentWindow.onRecognizedResult = e => {
  1013. let _msg = e.privText;
  1014. console.log(_msg);
  1015. if (_msg) this.text += _msg;
  1016. };
  1017. },
  1018. stopTalk() {
  1019. if (!this.isTalk) return this.$message.info("请先开始录音");
  1020. let iiframe = this.$refs["iiframe"];
  1021. iiframe.contentWindow.window.document
  1022. .getElementById("scenarioStopButton")
  1023. .click();
  1024. iiframe.contentWindow.onSessionStopped = (s, e) => {
  1025. this.isTalk = false;
  1026. this.send();
  1027. };
  1028. },
  1029. resetImg(_text) {
  1030. this.ppage++;
  1031. let _uuid = uuidv4();
  1032. this.chatList.push({
  1033. role: "user",
  1034. content: `${_text}`,
  1035. uid: _uuid,
  1036. AI: "AI",
  1037. aiContent: "",
  1038. oldContent: "",
  1039. isShowSynchronization: false,
  1040. filename: "",
  1041. index: this.chatList.length,
  1042. is_mind_map: false,
  1043. loading: true
  1044. });
  1045. this.text = "";
  1046. let params = {
  1047. page: this.ppage,
  1048. pagesize: 6,
  1049. query: _text
  1050. };
  1051. // this.$message.info(_text);
  1052. this.chatList.push({
  1053. role: "user",
  1054. content: `getImage`,
  1055. uid: _uuid,
  1056. AI: "AI",
  1057. aiContent: "",
  1058. oldContent: "",
  1059. isShowSynchronization: false,
  1060. filename: "",
  1061. index: this.chatList.length,
  1062. is_mind_map: false,
  1063. loading: true
  1064. });
  1065. this.scrollBottom();
  1066. this.ajax
  1067. .post("https://gpt.cocorobo.cn/search_image", params)
  1068. .then(res => {
  1069. let data = res.data.FunctionResponse.result;
  1070. // console.log('res',res.data.FunctionResponse.result);
  1071. this.chatList.find(i => i.uid == _uuid).aiContent = JSON.stringify(
  1072. data
  1073. );
  1074. this.chatList.find(i => i.uid == _uuid).loading = false;
  1075. this.chatLoading = false;
  1076. this.insertChat(_uuid);
  1077. });
  1078. },
  1079. stopSend() {
  1080. if (this.source) {
  1081. this.source.close();
  1082. if (this.chatList[this.chatList.length - 1].content == "wanSearch") {
  1083. this.chatList.pop();
  1084. }
  1085. this.loading = false;
  1086. this.chatLoading = false;
  1087. this.source = null;
  1088. this.insertChat(this.saveUid);
  1089. }
  1090. },
  1091. onCopy(content) {
  1092. // 创建临时textarea元素
  1093. const tempInput = document.createElement("textarea");
  1094. tempInput.value = content; // 设置要复制的内容
  1095. // 隐藏元素
  1096. tempInput.style.position = "absolute";
  1097. tempInput.style.left = "-9999px";
  1098. // 将元素添加到DOM中
  1099. document.body.appendChild(tempInput);
  1100. // 选中元素内容
  1101. tempInput.select();
  1102. // 执行复制操作
  1103. document.execCommand("copy");
  1104. // 移除临时元素
  1105. document.body.removeChild(tempInput);
  1106. this.$message({
  1107. message: "复制成功",
  1108. type: "success"
  1109. });
  1110. },
  1111. previewImg(url) {
  1112. this.$hevueImgPreview(url);
  1113. },
  1114. clear() {
  1115. // this.chatList = [];
  1116. this.$confirm("确定清空聊天记录吗?", "提示", {
  1117. confirmButtonText: "确定",
  1118. cancelButtonText: "取消",
  1119. type: "warning"
  1120. })
  1121. .then(_ => {
  1122. this.loading = true;
  1123. let params = {
  1124. user_id: this.userid,
  1125. id: "602def61-005d-11ee-91d8-005056b8q12w",
  1126. session_name: `${this.courseId}-studyStudent-md`
  1127. };
  1128. this.ajax
  1129. .post("https://gpt4.cocorobo.cn/delete_park_session", params)
  1130. .then(res => {
  1131. this.chatList = [];
  1132. this.stopSend();
  1133. this.$message.success("清除聊天记录成功");
  1134. this.loading = false;
  1135. })
  1136. .catch(err => {
  1137. this.loading = false;
  1138. this.$message.error("清除聊天记录失败");
  1139. });
  1140. })
  1141. .catch(_ => {});
  1142. },
  1143. atTask(name, index, type, data) {
  1144. let _result = name;
  1145. // if(type == 1){
  1146. // _result=`任务${index+1}:${name} `
  1147. // }else if(type==2){
  1148. // _result=`工具${index+1}:${name} `
  1149. // }else if(type==0){
  1150. // _result=`阶段${index+1} ${name} `
  1151. // }
  1152. this.text += _result;
  1153. this.$refs.textRef.focus();
  1154. },
  1155. send(_text = this.text, val = 0) {
  1156. this.ppage = 1;
  1157. if (this.loading || this.chatLoading) return this.$message.info("请稍等");
  1158. if (_text.trim().length == 0) return this.$message.info("请输入内容");
  1159. let _atRoleList = [];
  1160. this.atTaskList.forEach(i => {
  1161. let _result = ``;
  1162. if (i.type == 0) {
  1163. _result = `${i.name} `;
  1164. } else if (i.type == 1) {
  1165. _result = `${i.superiors.name}-${i.name} `;
  1166. } else if (i.type == 2) {
  1167. _result = `${i.superiors.superiors.name}-${i.superiors.name}-${i.name} `;
  1168. }
  1169. if (_text.indexOf(`@${_result}`) != -1) {
  1170. _atRoleList.push(i);
  1171. }
  1172. });
  1173. if (_atRoleList.length > 0) {
  1174. return this.atSend(_text, _atRoleList);
  1175. }
  1176. let _msg = ``;
  1177. this.chatLoading = true;
  1178. let _uuid = uuidv4();
  1179. // if(this.sendType==3){
  1180. // _text = `帮我生成一张图片:`
  1181. // }
  1182. this.chatList.push({
  1183. role: "user",
  1184. content: `${this.sendType == 3 ? `帮我生成一张图片:${_text}` : _text}`,
  1185. uid: _uuid,
  1186. AI: "AI",
  1187. aiContent: "",
  1188. oldContent: "",
  1189. isShowSynchronization: false,
  1190. filename: this.choseRoleItem ? this.choseRoleItem.headUrl : "",
  1191. index: this.chatList.length,
  1192. is_mind_map: false,
  1193. loading: true
  1194. });
  1195. this.scrollBottom();
  1196. if (this.sendType == 2 || _text.indexOf("视频") != -1) {
  1197. this.insertMemorandum(`<span class="btn">搜索视频</span>`)
  1198. return this.ajax
  1199. .post(`https://gpt4.cocorobo.cn/get_network_search`, {
  1200. engine: "bilibili",
  1201. keyword: _text
  1202. })
  1203. .then(res => {
  1204. console.log(res);
  1205. let _dataList = res.data.FunctionResponse;
  1206. let _resultText = ``;
  1207. _dataList.forEach(i => {
  1208. i.title = i.title
  1209. .replaceAll('<em class="keyword">', "")
  1210. .replaceAll("</em>", "");
  1211. _resultText += `名称:${i.title}\n简介:${i.description}\n地址:[${i.arcurl}](${i.arcurl})\n\n`;
  1212. });
  1213. this.chatList.find(i => i.uid == _uuid).aiContent = _resultText;
  1214. this.chatList.find(i => i.uid == _uuid).loading = false;
  1215. this.chatLoading = false;
  1216. this.scrollBottom();
  1217. this.insertChat(_uuid);
  1218. this.text = "";
  1219. })
  1220. .catch(e => {
  1221. this.$message.error("获取视频失败");
  1222. this.chatLoading = false;
  1223. });
  1224. } else if (this.sendType == 3) {
  1225. this.insertMemorandum(`<span class="btn">生成图片</span>`)
  1226. this.text = "";
  1227. let params = {
  1228. n: 1,
  1229. prompt: _text,
  1230. quality: "standard",
  1231. size: "1024x1024",
  1232. style: "natural"
  1233. };
  1234. // this.$message.info(_text);
  1235. this.chatList.push({
  1236. role: "user",
  1237. content: `getImage`,
  1238. uid: _uuid,
  1239. AI: "AI",
  1240. aiContent: "",
  1241. oldContent: "",
  1242. isShowSynchronization: false,
  1243. filename: "",
  1244. index: this.chatList.length,
  1245. is_mind_map: false,
  1246. loading: true
  1247. });
  1248. this.ajax
  1249. .post("https://gpt4.cocorobo.cn/getImage", params)
  1250. .then(res => {
  1251. let data = res.data.FunctionResponse;
  1252. // console.log('res',res.data.FunctionResponse.result);
  1253. let _result = [];
  1254. if (!data.image_url_list.length) {
  1255. this.chatLoading = false;
  1256. this.chatList.pop();
  1257. this.chatList.pop();
  1258. return this.$message.error("生成图片失败");
  1259. }
  1260. data.image_url_list.forEach(i => {
  1261. _result.push({
  1262. image: i
  1263. });
  1264. });
  1265. this.chatList.find(i => i.uid == _uuid).aiContent = JSON.stringify(
  1266. _result
  1267. );
  1268. this.chatList.find(i => i.uid == _uuid).loading = false;
  1269. console.log(this.chatList.find(i => i.uid == _uuid).aiContent);
  1270. this.chatLoading = false;
  1271. this.insertChat(_uuid);
  1272. this.scrollBottom();
  1273. })
  1274. .catch(e => {
  1275. this.chatLoading = false;
  1276. this.chatList.pop();
  1277. this.chatList.pop();
  1278. this.$message.error("生成失败");
  1279. });
  1280. return;
  1281. } else if (this.sendType == 1 || _text.indexOf("图片") != -1) {
  1282. this.insertMemorandum(`<span class="btn">搜索图片</span>`)
  1283. // console.log("图片");
  1284. this.text = "";
  1285. let params = {
  1286. page: this.ppage,
  1287. pagesize: 6,
  1288. query: _text
  1289. };
  1290. // this.$message.info(_text);
  1291. this.chatList.push({
  1292. role: "user",
  1293. content: `getImage`,
  1294. uid: _uuid,
  1295. AI: "AI",
  1296. aiContent: "",
  1297. oldContent: "",
  1298. isShowSynchronization: false,
  1299. filename: "",
  1300. index: this.chatList.length,
  1301. is_mind_map: false,
  1302. loading: true
  1303. });
  1304. this.ajax
  1305. .post("https://gpt.cocorobo.cn/search_image", params)
  1306. .then(res => {
  1307. let data = res.data.FunctionResponse.result;
  1308. // console.log('res',res.data.FunctionResponse.result);
  1309. this.chatList.find(i => i.uid == _uuid).aiContent = JSON.stringify(
  1310. data
  1311. );
  1312. console.log("👇");
  1313. console.log(this.chatList.find(i => i.uid == _uuid).aiContent);
  1314. this.chatList.find(i => i.uid == _uuid).loading = false;
  1315. this.chatLoading = false;
  1316. this.insertChat(_uuid);
  1317. // console.log('resresresres',res);
  1318. // if (res.data.FunctionResponse.result == "发送成功") {
  1319. // } else {
  1320. // this.$message.warning(res.data.FunctionResponse.result);
  1321. // }
  1322. });
  1323. return;
  1324. }
  1325. let history = [];
  1326. this.nowChatList.forEach(i => {
  1327. if (i.content == "wanSearch") {
  1328. // history.push({
  1329. // role:"assistant",
  1330. // content: JSON.stringify(i.aiContent)
  1331. // })
  1332. return;
  1333. } else if (i.content == "getImage") {
  1334. return history.push({
  1335. type: "text",
  1336. text: i.aiContent
  1337. });
  1338. } else if (i.content == "addAsk") {
  1339. }
  1340. if (i.content) {
  1341. history.push({
  1342. type: "text",
  1343. text: i.content
  1344. });
  1345. }
  1346. if (i.aiContent) {
  1347. history.push({
  1348. type: "text",
  1349. text: i.aiContent
  1350. });
  1351. }
  1352. });
  1353. // history.pop();
  1354. if (_msg) {
  1355. history.push({ type: "text", text: _msg });
  1356. } else {
  1357. history.push({ type: "text", text: _text });
  1358. }
  1359. let params = {
  1360. assistant_id: this.choseRoleItem
  1361. ? this.choseRoleItem.assistant_id
  1362. : "f8e1ebb2-2e0d-11ef-8bf4-12e77c4cb76b",
  1363. userId: this.userid,
  1364. message: _text,
  1365. session_name: `${this.courseId}-studyStudent-md`,
  1366. uid: _uuid,
  1367. file_ids: this.fileId
  1368. };
  1369. // let params = {
  1370. // model: "gpt-3.5-turbo",
  1371. // temperature: 0,
  1372. // max_tokens: 4096,
  1373. // top_p: 1,
  1374. // frequency_penalty: 0,
  1375. // presence_penalty: 0,
  1376. // messages: history,
  1377. // uid: _uuid,
  1378. // mind_map_question: _text
  1379. // };
  1380. // let params = {
  1381. // message: {
  1382. // anthropic_version: "bedrock-2023-05-31",
  1383. // max_tokens: 4096,
  1384. // temperature: 0,
  1385. // top_p: 1,
  1386. // messages: history
  1387. // },
  1388. // uid: _uuid,
  1389. // model: "Claude 3 Sonnet" // Claude 3 Sonnet或者Claude 3 Haiku
  1390. // };
  1391. this.text = "";
  1392. this.ajax
  1393. // .post("https://claude3.cocorobo.cn/chat", params)
  1394. // .post("https://gpt4.cocorobo.cn/chat", params)
  1395. .post("https://gpt4.cocorobo.cn/ai_agent_park_chat_new", params)
  1396. .then(res => {
  1397. if (
  1398. converter(res.data.FunctionResponse.result) == converter("发送成功")
  1399. ) {
  1400. } else {
  1401. // this.$message.warning(res.data.FunctionResponse.result);
  1402. console.log(res.data.FunctionResponse.result);
  1403. this.chatLoading = false;
  1404. }
  1405. })
  1406. .catch(e => {
  1407. console.log(e);
  1408. this.chatLoading = false;
  1409. });
  1410. this.saveUid = _uuid;
  1411. this.getAtAuContent(_uuid);
  1412. },
  1413. atSend(_text, _atList) {
  1414. let _msg = ``;
  1415. let noAtText = _text;
  1416. _atList.forEach(i => {
  1417. let _result = ``;
  1418. if (i.type == 0) {
  1419. _result = `${i.name} `;
  1420. } else if (i.type == 1) {
  1421. _result = `${i.superiors.name}-${i.name} `;
  1422. } else if (i.type == 2) {
  1423. _result = `${i.superiors.superiors.name}-${i.superiors.name}-${i.name} `;
  1424. }
  1425. if (_text.indexOf(`@${_result}`) != -1) {
  1426. noAtText = noAtText.replaceAll(`@${_result}`, "");
  1427. }
  1428. });
  1429. this.chatLoading = true;
  1430. let _uuid = uuidv4();
  1431. this.chatList.push({
  1432. role: "user",
  1433. content: `${_text}`,
  1434. uid: _uuid,
  1435. AI: "AI",
  1436. aiContent: "",
  1437. oldContent: "",
  1438. isShowSynchronization: false,
  1439. filename: "",
  1440. index: this.chatList.length,
  1441. is_mind_map: false,
  1442. loading: true
  1443. });
  1444. this.scrollBottom();
  1445. _msg = `
  1446. NOTICE
  1447. Language: Please use the same language as the user requirement, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
  1448. ## 目的
  1449. 你是用户的课堂助手,你需要基于提供给你的课程相关信息,对用户的提问进行回答。
  1450. ---
  1451. ## 定义
  1452. 给你提供的课程发生在一个网络教学平台上,各元素存在以下的关系:课程⊇阶段⊇任务⊇工具。
  1453. 【课程】:课程通常是一个完整的项目,有一个或多个阶段。
  1454. 【阶段】:阶段表示课程的某一单独部分,通常包含一个或多个任务。
  1455. 【任务】:任务是课程的基本单元,包含一个或多个工具,通常写明了学生要具体完成的事项。
  1456. 【工具】:工具通常是指学生要完成任务的手段。比如“提交作业”表示学生需要提交一份文件;又比如“问答”,表示学生需要输入一个回答;再比如“选择题”,表示学生需要根据题目要求选择正确的答案。
  1457. ---
  1458. ## 工作流程
  1459. 1. 读取【课程信息】中的内容,了解课程说明、课程结构以及【任务】详情。
  1460. 2. 用户会询问你某个【任务】的具体信息,你需要总结该任务信息,并就用户的问题进行回答。
  1461. 3. 你的总结包括以下要点:
  1462. 3.1 任务从属于哪个阶段。
  1463. 3.2 任务包含哪些工具。
  1464. 3.3 该任务目标是什么,以及该任务的工具如何达成它的目标。
  1465. ---
  1466. ## 规则
  1467. 1.你和用户讨论的范围应当仅局限于课程相关内容。
  1468. 2.当用户的提问需要你对课程拥有完整的信息、而你又缺乏部分信息时,你应当向客户询问你缺少的信息,再回答用户的提问。
  1469. 3.你通常可以在【任务描述】中了解任务目标,但当【任务描述】不包含此内容的时候,你不需要总结这部分内容。
  1470. ---
  1471. ## 课程信息
  1472. ###课程说明与课程结构
  1473. 课程标题:${this.courseDetail.title}
  1474. 分类:${this.courseDetail.name ? this.courseDetail.name : "无"}
  1475. 学生年级:${this.courseDetail.classname ? this.courseDetail.classname : "无"}
  1476. 学习内容:${this.exportCourse()}
  1477. ## 要求
  1478. ${_atList
  1479. .map(i => {
  1480. let _result = ``;
  1481. if (i.type == 0) {
  1482. _result = `${i.name}`;
  1483. } else if (i.type == 1) {
  1484. _result = `${i.superiors.name}-${i.name}`;
  1485. } else if (i.type == 2) {
  1486. _result = `${i.superiors.superiors.name}-${i.superiors.name}-${i.name}`;
  1487. }
  1488. console.log(_result);
  1489. return _result;
  1490. })
  1491. .join(",")} ${noAtText}
  1492. `;
  1493. // this.chatLoading = false;
  1494. // console.log(_msg)
  1495. // return
  1496. // ${this._atList.map(i=>i.name).join(',')} ${noAtText}
  1497. let history = [];
  1498. this.nowChatList.forEach(i => {
  1499. if (i.content == "wanSearch") {
  1500. return;
  1501. } else if (i.content == "getImage") {
  1502. return history.push({
  1503. role: "assistant",
  1504. content: i.aiContent
  1505. });
  1506. }
  1507. if (i.content) {
  1508. history.push({
  1509. role: "user",
  1510. content: i.content
  1511. });
  1512. }
  1513. if (i.aiContent) {
  1514. history.push({
  1515. role: "assistant",
  1516. content: i.aiContent
  1517. });
  1518. }
  1519. });
  1520. // if (_msg) {
  1521. history.push({ role: "user", content: _msg });
  1522. // }
  1523. history.push({ role: "user", content: _text });
  1524. let params = {
  1525. assistant_id: "f8e1ebb2-2e0d-11ef-8bf4-12e77c4cb76b",
  1526. userId: this.userid,
  1527. message: _text,
  1528. session_name: `${this.courseId}-studyStudent-md`,
  1529. uid: _uuid,
  1530. file_ids: this.fileId
  1531. };
  1532. // let params = {
  1533. // model: "gpt-3.5-turbo",
  1534. // temperature: 0,
  1535. // max_tokens: 4096,
  1536. // top_p: 1,
  1537. // frequency_penalty: 0,
  1538. // presence_penalty: 0,
  1539. // messages: history,
  1540. // uid: _uuid,
  1541. // mind_map_question: noAtText
  1542. // };
  1543. // let params = {
  1544. // message: {
  1545. // anthropic_version: "bedrock-2023-05-31",
  1546. // max_tokens: 4096,
  1547. // temperature: 0,
  1548. // top_p: 1,
  1549. // messages: history
  1550. // },
  1551. // uid: _uuid,
  1552. // model: "Claude 3 Sonnet" // Claude 3 Sonnet或者Claude 3 Haiku
  1553. // };
  1554. this.text = "";
  1555. this.ajax
  1556. // .post("https://gpt4.cocorobo.cn/chat", params)
  1557. // .post("https://claude3.cocorobo.cn/chat", params)
  1558. .post("https://gpt4.cocorobo.cn/ai_agent_park_chat_new", params)
  1559. .then(res => {
  1560. if (
  1561. converter(res.data.FunctionResponse.result) == converter("发送成功")
  1562. ) {
  1563. } else {
  1564. // this.$message.warning(res.data.FunctionResponse.result);
  1565. console.log(res.data.FunctionResponse.result);
  1566. this.chatLoading = false;
  1567. }
  1568. })
  1569. .catch(e => {
  1570. console.log(e);
  1571. this.chatLoading = false;
  1572. });
  1573. this.saveUid = _uuid;
  1574. // this.getAiContent(_uuid);
  1575. this.getAtAuContent(_uuid);
  1576. },
  1577. exportCourse() {
  1578. let _user = `<div style="font-size:30px;margin-top:10px;"><span style="color: rgb(113, 124, 141); font-weight: 400;">创建者:</span><span>${this.courseDetail.username}</span></div>`;
  1579. const _chapInfo = JSON.parse(this.courseDetail.chapters);
  1580. let _chap = "";
  1581. for (let i = 0; i < _chapInfo.length; i++) {
  1582. _chap += `<div style="font-size:40px;margin-top:70px;"><span>第${i +
  1583. 1}阶段:${_chapInfo[i].dyName}</span></div>`;
  1584. let _task = _chapInfo[i].chapterInfo[0].taskJson;
  1585. for (let j = 0; j < _task.length; j++) {
  1586. _chap += `<div style="font-size:30px;margin-top:50px;"><span>任务${j +
  1587. 1}:${_task[j].task}</span></div>`;
  1588. if (_task[j].taskDetail) {
  1589. _chap += `<div style="font-size:25px;margin-top:40px;">任务描述</div>`;
  1590. _chap += `<div style="font-size:25px;margin-top:10px;">${_task[j].taskDetail}</div>`;
  1591. }
  1592. let _tool = _task[j].toolChoose;
  1593. if (_tool[0].tool.length) {
  1594. for (let z = 0; z < _tool.length; z++) {
  1595. _chap += `<div style="font-size:23px;margin-top:30px;"><span>步骤${z +
  1596. 1}:</span><span>${
  1597. tools[_tool[z].tool[0]] ? tools[_tool[z].tool[0]].name : ""
  1598. }</span></div>`;
  1599. if (_tool[z].toolDetail) {
  1600. _chap += `<div style="font-size:23px;margin-top:20px;">工具描述</div>`;
  1601. _chap += `<div style="font-size:23px;margin-top:10px;">${_tool[z].toolDetail}</div>`;
  1602. }
  1603. }
  1604. }
  1605. }
  1606. }
  1607. let _html = _user + _chap;
  1608. return _html;
  1609. },
  1610. // 获取ai对话
  1611. getAiContent(_uid) {
  1612. // this.source = new EventSource(
  1613. // `https://claude3.cocorobo.cn/streamChat/${_uid}`
  1614. // );
  1615. this.source = new EventSource(
  1616. `https://gpt4.cocorobo.cn/question/${_uid}`
  1617. );
  1618. // this.source = new EventSource(`https://gpt4.cocorobo.cn/stream/${_uid}`); //http://gpt4.cocorobo.cn:8011/stream/ https://gpt4.cocorobo.cn/stream/
  1619. let _allText = "";
  1620. let _mdText = "";
  1621. // const md = new MarkdownIt();
  1622. this.source.onmessage = _e => {
  1623. if (_e.data.replace("'", "").replace("'", "") == "[DONE]") {
  1624. //对话已经完成
  1625. _mdText = _mdText.replace("_", "");
  1626. this.source.close();
  1627. this.chatLoading = false;
  1628. this.scrollBottom();
  1629. this.chatList.find(i => i.uid == _uid).aiContent = _mdText;
  1630. this.chatList.find(i => i.uid == _uid).isalltext = true;
  1631. this.chatList.find(i => i.uid == _uid).isShowSynchronization = true;
  1632. this.chatList.find(i => i.uid == _uid).loading = false;
  1633. this.nowChatList.push(this.chatList.find(i => i.uid == _uid));
  1634. this.addAsk(this.chatList.find(i => i.uid == _uid).content);
  1635. // 这里保存对话
  1636. this.insertChat(_uid);
  1637. return;
  1638. } else {
  1639. //对话还在继续
  1640. let _text = "";
  1641. _text = _e.data.replaceAll("'", "");
  1642. if (_allText == "") {
  1643. _allText = _text.replace(/^\n+/, ""); //去掉回复消息中偶尔开头就存在的连续换行符
  1644. } else {
  1645. _allText += _text;
  1646. }
  1647. _mdText = _allText + "_";
  1648. _mdText = _mdText.replace(/\\n/g, "\n");
  1649. _mdText = _mdText.replace(/\\/g, "");
  1650. if (_allText.split("```").length % 2 == 0) _mdText += "\n```\n";
  1651. //转化返回的回复流数据
  1652. // _mdText = md.render(_mdText);
  1653. this.chatList.find(i => i.uid == _uid).aiContent = _mdText;
  1654. this.chatList.find(i => i.uid == _uid).loading = false;
  1655. this.scrollBottom();
  1656. // 处理流数据
  1657. }
  1658. };
  1659. },
  1660. getAtAuContent(_uid) {
  1661. this.source = new EventSource(
  1662. `https://gpt4.cocorobo.cn/question/${_uid}`
  1663. );
  1664. //http://gpt4.cocorobo.cn:8011/question/ https://gpt4.cocorobo.cn/question/
  1665. let _allText = "";
  1666. let _mdText = "";
  1667. let _index = 0;
  1668. let _talkText = "";
  1669. // const md = new MarkdownIt();
  1670. this.source.onmessage = _e => {
  1671. let _eData = JSON.parse(_e.data);
  1672. if (_eData.content.replace("'", "").replace("'", "") == "[DONE]") {
  1673. let _result = [];
  1674. if ("result" in _eData) {
  1675. _result = _eData.result;
  1676. for (let i = 0; i < _result.length; i++) {
  1677. _mdText = _mdText.replace(_result[i].text, _result[i].fileName);
  1678. }
  1679. }
  1680. _mdText = _mdText.replace("_", "");
  1681. if (this.openMegaphone && this.aiTalkUid == _uid) {
  1682. if (_talkText != "") {
  1683. let _resultText = this.removeMarkdown(_talkText);
  1684. this.aiTalkList.push(_resultText);
  1685. _talkText = "";
  1686. if (!this.aiIsTalk) this.aiTalk(1);
  1687. }
  1688. }
  1689. this.chatLoading = false;
  1690. this.chatList.find(i => i.uid == _uid).aiContent = _mdText;
  1691. this.chatList.find(i => i.uid == _uid).isalltext = true;
  1692. this.chatList.find(i => i.uid == _uid).isShowSynchronization = true;
  1693. this.chatList.find(i => i.uid == _uid).loading = false;
  1694. this.nowChatList.push(this.chatList.find(i => i.uid == _uid));
  1695. this.addAsk(this.chatList.find(i => i.uid == _uid).content);
  1696. this.source.close();
  1697. this.insertChat(_uid);
  1698. } else {
  1699. _index += 1;
  1700. let _text = _eData.content.replace("'", "").replace("'", "");
  1701. if (_allText == "") {
  1702. _allText = _text.replace(/^\n+/, ""); //去掉回复消息中偶尔开头就存在的连续换行符
  1703. _talkText += _text.replace(/^\n+/, "");
  1704. } else {
  1705. _allText += _text;
  1706. _talkText += _text;
  1707. }
  1708. _mdText = _allText + "_";
  1709. _mdText = _mdText.replace(/\\n/g, "\n");
  1710. _mdText = _mdText.replace(/\\/g, "");
  1711. if (_allText.split("```").length % 2 == 0) _mdText += "\n```\n";
  1712. //转化返回的回复流数据
  1713. // _mdText = md.render(_mdText);
  1714. if (_index == 10) {
  1715. this.chatList.find(i => i.uid == _uid).aiContent = _mdText;
  1716. this.chatList.find(i => i.uid == _uid).loading = false;
  1717. this.$nextTick(() => {
  1718. this.$refs.chatRef.scrollTop = this.$refs.chatRef.scrollHeight;
  1719. });
  1720. _index = 0;
  1721. }
  1722. if (this.openMegaphone && /[,。:;?!)]/.test(_talkText)) {
  1723. let _resultText = this.removeMarkdown(_talkText);
  1724. if (this.aiTalkUid != _uid) {
  1725. this.aiTalkList = [];
  1726. }
  1727. this.aiTalkList.push(_resultText);
  1728. _talkText = "";
  1729. if (this.aiTalkUid != _uid) {
  1730. this.aiTalkUid = _uid;
  1731. this.aiTalk(0);
  1732. } else if (!this.aiIsTalk) {
  1733. this.aiTalk(1);
  1734. }
  1735. }
  1736. // 处理流数据
  1737. }
  1738. };
  1739. },
  1740. getWAntSearchContent(_uid) {
  1741. // this.source = new EventSource(
  1742. // `https://claude3.cocorobo.cn/streamChat/${_uid}`
  1743. // );
  1744. let source = new EventSource(
  1745. `https://gpt4.cocorobo.cn/question/${_uid}`
  1746. );
  1747. // this.source = new EventSource(`https://gpt4.cocorobo.cn/stream/${_uid}`); //http://gpt4.cocorobo.cn:8011/stream/ https://gpt4.cocorobo.cn/stream/
  1748. let _allText = "";
  1749. let _mdText = "";
  1750. this.scrollBottom();
  1751. source.onmessage = _e => {
  1752. if (_e.data.replace("'", "").replace("'", "") == "[DONE]") {
  1753. //对话已经完成
  1754. _mdText = _mdText.replace("_", "");
  1755. _mdText = _mdText.replace("```json", "");
  1756. _mdText = _mdText.replace("```", "");
  1757. // 使用正则表达式匹配JSON数组
  1758. const regex = /\[\s*{[^]*}\s*\]/;
  1759. const match = _mdText.match(regex);
  1760. let _result = match[0];
  1761. source.close();
  1762. this.chatList.find(i => i.uid == _uid).aiContent = JSON.parse(
  1763. _result
  1764. );
  1765. this.chatList.find(i => i.uid == _uid).isalltext = true;
  1766. this.chatList.find(i => i.uid == _uid).isShowSynchronization = true;
  1767. this.chatList.find(i => i.uid == _uid).loading = false;
  1768. this.nowChatList.push(this.chatList.find(i => i.uid == _uid));
  1769. this.scrollBottom();
  1770. // 这里保存对话
  1771. return;
  1772. } else {
  1773. //对话还在继续
  1774. let _text = "";
  1775. _text = _e.data.replaceAll("'", "");
  1776. if (_allText == "") {
  1777. _allText = _text.replace(/^\n+/, ""); //去掉回复消息中偶尔开头就存在的连续换行符
  1778. } else {
  1779. _allText += _text;
  1780. }
  1781. _mdText = _allText + "_";
  1782. _mdText = _mdText.replace(/\\n/g, "\n");
  1783. _mdText = _mdText.replace(/\\/g, "");
  1784. if (_allText.split("```").length % 2 == 0) _mdText += "\n```\n";
  1785. //转化返回的回复流数据
  1786. this.scrollBottom();
  1787. }
  1788. };
  1789. },
  1790. //保存消息
  1791. insertChat(_uid) {
  1792. if (_uid == "") return;
  1793. let _data = this.chatList.find(i => i.uid == _uid);
  1794. if (!_data) return;
  1795. let params = {
  1796. userId: this.userid,
  1797. userName: "qgt",
  1798. groupId: "602def61-005d-11ee-91d8-005056b8q12w",
  1799. answer: _data.aiContent,
  1800. problem: _data.content,
  1801. file_id: _data.fileid ? _data.fileid : "",
  1802. alltext: _data.aiContent,
  1803. type: "chat",
  1804. filename: _data.filename,
  1805. session_name: `${this.courseId}-studyStudent-md` //这是对话记录位置
  1806. };
  1807. this.saveUid = "";
  1808. this.ajax
  1809. .post("https://gpt4.cocorobo.cn/insert_chat", params)
  1810. .then(res => {});
  1811. },
  1812. // 获取对应的聊天记录
  1813. getChatList() {
  1814. return new Promise((resolve, reject) => {
  1815. if (this.loading) return this.$message.info("请稍等...");
  1816. this.chatList = [];
  1817. this.loading = true;
  1818. let params = {
  1819. userid: this.userid,
  1820. groupid: "602def61-005d-11ee-91d8-005056b8q12w",
  1821. // session_name:``
  1822. session_name: `${this.courseId}-studyStudent-md`
  1823. };
  1824. this.ajax
  1825. .post("https://gpt4.cocorobo.cn/get_agent_park_chat", params)
  1826. .then(res => {
  1827. let _data = JSON.parse(res.data.FunctionResponse);
  1828. if (_data.length > 0) {
  1829. let _chatList = [];
  1830. for (let i = 0; i < _data.length; i++) {
  1831. _chatList.push({
  1832. loading: false,
  1833. role: "user",
  1834. content: _data[i].problem,
  1835. uid: _data[i].id,
  1836. AI: "AI",
  1837. aiContent: _data[i].answer,
  1838. oldContent: _data[i].answer,
  1839. isShowSynchronization: false,
  1840. filename: _data[i].filename,
  1841. index: i,
  1842. is_mind_map: false,
  1843. fileid: _data[i].fileid
  1844. });
  1845. }
  1846. this.chatList = _chatList;
  1847. this.loading = false;
  1848. } else {
  1849. //没有对话记录
  1850. this.loading = false;
  1851. }
  1852. resolve();
  1853. })
  1854. .catch(err => {
  1855. console.log(err);
  1856. this.$message.error("获取对话记录失败");
  1857. this.loading = false;
  1858. resolve();
  1859. });
  1860. });
  1861. },
  1862. sendAiIdea(text) {
  1863. if (this.loading) return this.$message.info("请稍等");
  1864. this.send(text);
  1865. },
  1866. getWantSearch() {
  1867. let _uuid = uuidv4();
  1868. let _msg = `
  1869. Language: Please use the same language as the user requirement, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
  1870. ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example".
  1871. Instruction: Based on the context, follow "Format example", write content
  1872. ## 任务
  1873. 你的任务是根据“课程信息”,提供用户需要的搜索建议,将搜索建议的结果以有序列表的形式返回给用户。
  1874. ## 课程信息
  1875. #### 课程标题:${this.courseDetail.title}
  1876. #### 分类:${this.courseDetail.name ? this.courseDetail.name : "无"}
  1877. #### 学生年级:${
  1878. this.courseDetail.classname ? this.courseDetail.classname : "无"
  1879. }
  1880. ## 规则
  1881. 输出结果基于“课程信息”,避免提供无关的信息。
  1882. 搜索建议的结果符合伦理规范。
  1883. ## 输出
  1884. 输出应包括6个相关的搜索建议,每个搜索建议需要以问号的方式结束。
  1885. 请一步步思考如何根据现有信息推送搜索建议,但是不需要输出搜索建议以外的内
  1886. ## 输出格式
  1887. 搜索建议应以有序列表形式呈现,每个建议包括关键词和简短描述。输出JSON格式的
  1888. ## Format example
  1889. [{"index": 1,"title": "垃圾分类标准","label": "不同国家的垃圾分类标准和方法?"},{"index": 2,"title":"可回收垃圾处理","label": "可回收垃圾的处理流程和再利用方法?"},{ "index": 3, "title": "有害垃圾的影响", "label": "有害垃圾对环境和人体健康的潜在影响?"},{ "index": 4, "title": "垃圾分类标准", "label": "不同国家的垃圾分类标准和方法?"},{ "index": 5, "title": "可回收垃圾处理", "label": "可回收垃圾的处理流程和再利用方法?"},{ "index": 6, "title": "有害垃圾的影响", "label": "有害垃圾对环境和人体健康的潜在影响?"}]
  1890. `;
  1891. this.chatList.push({
  1892. role: "user",
  1893. content: `wanSearch`,
  1894. uid: _uuid,
  1895. AI: "AI",
  1896. aiContent: "",
  1897. oldContent: "",
  1898. isShowSynchronization: false,
  1899. filename: "",
  1900. index: this.chatList.length,
  1901. is_mind_map: false,
  1902. loading: true
  1903. });
  1904. this.scrollBottom();
  1905. // let params = {
  1906. // model: "gpt-3.5-turbo",
  1907. // temperature: 0,
  1908. // max_tokens: 4096,
  1909. // top_p: 1,
  1910. // frequency_penalty: 0,
  1911. // presence_penalty: 0,
  1912. // messages: [{ role: "user", content: _msg }],
  1913. // uid: _uuid,
  1914. // mind_map_question: ""
  1915. // };
  1916. let params = {
  1917. assistant_id: "6063369f-289a-11ef-8bf4-12e77c4cb76b",
  1918. userId: this.userid,
  1919. message: [{ type: "text", text: _msg }],
  1920. session_name: _uuid,
  1921. // uid: _uuid,
  1922. file_ids: this.fileId
  1923. };
  1924. // let params = {
  1925. // message: {
  1926. // anthropic_version: "bedrock-2023-05-31",
  1927. // max_tokens: 4096,
  1928. // temperature: 0,
  1929. // top_p: 1,
  1930. // messages: [{ role: "user", content: _msg }]
  1931. // },
  1932. // uid: _uuid,
  1933. // model: "Claude 3 Sonnet" // Claude 3 Sonnet或者Claude 3 Haiku
  1934. // };
  1935. this.text = "";
  1936. this.ajax
  1937. // .post("https://gpt4.cocorobo.cn/chat", params)
  1938. // .post("https://claude3.cocorobo.cn/chat", params)
  1939. .post("https://gpt4.cocorobo.cn/ai_agent_park_chat", params)
  1940. .then(res => {
  1941. // console.log(res);
  1942. let _data = res.data.FunctionResponse.message;
  1943. _data = _data.replaceAll("```json", "").replaceAll("```", "");
  1944. const match = _data.match(/\[\s*{[^]*}\s*\]/);
  1945. // console.log(_data);
  1946. // console.log(match);
  1947. this.chatList.find(i => i.uid == _uuid).aiContent = JSON.parse(
  1948. match[0]
  1949. );
  1950. this.chatList.find(i => i.uid == _uuid).isalltext = true;
  1951. this.chatList.find(i => i.uid == _uuid).isShowSynchronization = true;
  1952. this.chatList.find(i => i.uid == _uuid).loading = false;
  1953. this.scrollBottom();
  1954. // this.chatLoading = false;
  1955. })
  1956. .catch(e => {
  1957. this.chatLoading = false;
  1958. console.log(e);
  1959. });
  1960. // this.getWAntSearchContent(_uuid);
  1961. },
  1962. addAsk(_text) {
  1963. // this.chatLoading = true;
  1964. let _uuid = uuidv4();
  1965. let _msg = `NOTICERole: 你是一个多功能的AI助手,能够根据学生的文本内容判断其情感状态,并提供相应的支持和引导。Output: Provide your output in json format.ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".Instruction: Based on the context, follow \"Format example\", write content.# Context## 任务1.学生文本内容,执行以下任务。首先,请你判断学生是否进行情感倾诉,比如心情不好、遭遇校园暴力、对他人进行人身攻击等。如果是,请扮演一个心理咨询师的角色,坚持人本主义的立场,善良、温柔地引导对方,安抚对方的情绪,为对方提供心理支持。剩下的其它情况,请你扮演提问引导者的角色,延续学生的提问,围绕问题本身,提出3个问题,激发学生的深度思考、创造性思考。2.人本主义心理学人本主义心理学强调个体的主观体验和自我实现,认为每个人都有内在的潜力和价值。心理咨询师应当以同理心、无条件积极关注和真诚的态度对待来访者,帮助他们发现自身的力量和解决问题的能力。3.提问引导技巧提问引导技巧包括开放性问题、反思性问题和假设性问题等,旨在通过提问激发对方的思考和探索,帮助他们深入理解问题并找到解决方案。## 工作流程1. 仔细阅读并分析学生提供的文本内容。2. 判断学生是否进行情感倾诉。3. 如果是情感倾诉,扮演心理咨询师的角色,提供情感支持和引导。4. 如果不是情感倾诉,扮演提问引导者的角色,围绕问题本身提出3个问题。## 限制/注意事项 1.在回答时应保持专业性和权威性,确保信息的准确性和可靠性。2.避免生成与问题无关或不恰当的回答,确保回答的相关性和实用性。3.在提供情感支持时,注意用词温柔,避免引起对方的负面情绪。## 要求1. 内容包含情感支持或追加问题。2. 情感支持部分应体现同理心和积极关注。3. 追加问题应具有启发性和深度。## 学生文本内容${_text}# Format example [{\"index\": 1,\"label\": \"不同国家的垃圾分类标准和方法?\"},{\"index\": 2, \"label\": \"可回收垃圾的处理流程和再利用方法?\"},{\"index\": 3,\"label\": \"有害垃圾对环境和人体健康的潜在影响?\"}]`;
  1966. _msg = _msg.replace(/[\r\n]/g, "");
  1967. this.chatList.push({
  1968. role: "user",
  1969. content: `addAsk`,
  1970. uid: _uuid,
  1971. AI: "AI",
  1972. aiContent: "",
  1973. oldContent: "",
  1974. isShowSynchronization: false,
  1975. filename: "",
  1976. index: this.chatList.length,
  1977. is_mind_map: false,
  1978. loading: true
  1979. });
  1980. this.scrollBottom();
  1981. let history = [];
  1982. // this.nowChatList.forEach(i => {
  1983. // if (i.content == "wanSearch") {
  1984. // // history.push({
  1985. // // role:"assistant",
  1986. // // content: JSON.stringify(i.aiContent)
  1987. // // })
  1988. // return;
  1989. // } else if (i.content == "getImage") {
  1990. // return history.push({
  1991. // role: "assistant",
  1992. // content: i.aiContent
  1993. // });
  1994. // }else if(i.content == "addAsk"){
  1995. // }
  1996. // if (i.content) {
  1997. // history.push({
  1998. // role: "user",
  1999. // content: i.content
  2000. // });
  2001. // }
  2002. // if (i.aiContent) {
  2003. // history.push({
  2004. // role: "assistant",
  2005. // content: i.aiContent
  2006. // });
  2007. // }
  2008. // });
  2009. history.push({ type: "text", text: _msg });
  2010. console.log(history);
  2011. // let params = {
  2012. // model: "gpt-3.5-turbo",
  2013. // temperature: 0,
  2014. // max_tokens: 4096,
  2015. // top_p: 1,
  2016. // frequency_penalty: 0,
  2017. // presence_penalty: 0,
  2018. // messages:history,
  2019. // stream: false,
  2020. // uid: _uuid,
  2021. // mind_map_question: ""
  2022. // };
  2023. let params = {
  2024. assistant_id: "6063369f-289a-11ef-8bf4-12e77c4cb76b",
  2025. userId: this.userid,
  2026. message: history,
  2027. session_name: _uuid,
  2028. // uid: _uuid,
  2029. file_ids: this.fileId
  2030. };
  2031. // let params = {
  2032. // message: {
  2033. // anthropic_version: "bedrock-2023-05-31",
  2034. // max_tokens: 4096,
  2035. // temperature: 0,
  2036. // top_p: 1,
  2037. // messages: [{ role: "user", content: _msg }]
  2038. // },
  2039. // uid: _uuid,
  2040. // model: "Claude 3 Sonnet" // Claude 3 Sonnet或者Claude 3 Haiku
  2041. // };
  2042. this.text = "";
  2043. this.ajax
  2044. // .post("https://gpt4.cocorobo.cn/chat", params)
  2045. // .post("https://claude3.cocorobo.cn/chat", params)
  2046. .post("https://gpt4.cocorobo.cn/ai_agent_park_chat", params)
  2047. .then(res => {
  2048. console.log(res);
  2049. let _data = res.data.FunctionResponse.message;
  2050. _data = _data.replaceAll("```json", "").replaceAll("```", "");
  2051. const match = _data.match(/\[\s*{[^]*}\s*\]/);
  2052. console.log(match[0]);
  2053. this.chatList.find(i => i.uid == _uuid).aiContent = JSON.parse(match[0]);
  2054. this.chatList.find(i => i.uid == _uuid).isalltext = true;
  2055. this.chatList.find(i => i.uid == _uuid).isShowSynchronization = true;
  2056. this.chatList.find(i => i.uid == _uuid).loading = false;
  2057. this.scrollBottom();
  2058. // this.chatLoading = false;
  2059. })
  2060. .catch(e => {
  2061. this.chatLoading = false;
  2062. this.chatList.find(i => i.uid == _uuid).loading = false;
  2063. console.log(e);
  2064. });
  2065. },
  2066. scrollBottom() {
  2067. this.$nextTick(() => {
  2068. this.$refs.chatRef.scrollTop = this.$refs.chatRef.scrollHeight;
  2069. });
  2070. },
  2071. initTaskList() {
  2072. this.taskList = [];
  2073. this.taskList = JSON.parse(JSON.stringify(this.navList));
  2074. this.taskList.forEach(i1 => {
  2075. i1.isOpen = true;
  2076. i1.task.forEach(i2 => {
  2077. i2.isOpen = true;
  2078. i2.tool.forEach(i3 => {
  2079. i3.isOpen = true;
  2080. });
  2081. });
  2082. });
  2083. },
  2084. getWorkData() {
  2085. if (this.workSum == 0) return;
  2086. let params = {
  2087. cid: this.courseId,
  2088. classid: this.tcid
  2089. };
  2090. this.userList = [];
  2091. this.ajax
  2092. .get(this.$store.state.api + "selectWorkBycidAi", params)
  2093. .then(res => {
  2094. let _data = res.data[0];
  2095. console.log(_data);
  2096. if (_data.length > 0) {
  2097. this.userList = _data;
  2098. }
  2099. })
  2100. .catch(e => {
  2101. // this.$message.error()
  2102. this.userList = [];
  2103. console.log(e);
  2104. });
  2105. },
  2106. lookStudentDetail(_data) {
  2107. this.loading = true;
  2108. let params = {
  2109. cid: this.courseId,
  2110. uid: _data.userid
  2111. };
  2112. this.ajax
  2113. .get(this.$store.state.api + "selectWorkBycidAiByUid", params)
  2114. .then(res => {
  2115. let _result = res.data[0];
  2116. this.atTagIndex = 2;
  2117. this.loading = false;
  2118. _result.forEach(i => {
  2119. i.content = JSON.parse(i.content)[0];
  2120. });
  2121. this.lookStudentData = {
  2122. userName: _data.username,
  2123. list: _result ? _result : []
  2124. };
  2125. console.log(this.lookStudentData);
  2126. });
  2127. },
  2128. sumUpStudent(_data) {
  2129. let params = {
  2130. cid: this.courseId,
  2131. uid: _data.userid
  2132. };
  2133. this.loading = true;
  2134. this.ajax
  2135. .get(this.$store.state.api + "selectWorkBycidAiByUid", params)
  2136. .then(res => {
  2137. let _result = res.data[0];
  2138. console.log(_result);
  2139. console.log("👆");
  2140. this.text += `${_data.username} 总结分析`;
  2141. let _msg = ``;
  2142. this.chatLoading = true;
  2143. let _uuid = uuidv4();
  2144. this.chatList.push({
  2145. role: "user",
  2146. content: `${this.text}`,
  2147. uid: _uuid,
  2148. AI: "AI",
  2149. aiContent: "",
  2150. oldContent: "",
  2151. isShowSynchronization: false,
  2152. filename: "",
  2153. index: this.chatList.length,
  2154. is_mind_map: false,
  2155. loading: true
  2156. });
  2157. this.text = "";
  2158. let _wordData = "";
  2159. _result.forEach(i => {
  2160. if (i.type == 3) {
  2161. let content = JSON.parse(i.content)[0];
  2162. return (_wordData += `问答题:\n题目:${content.answerTitle}\n学生回答:${content.answer}\n\n`);
  2163. } else if (i.type == 8) {
  2164. let content = JSON.parse(i.content)[0];
  2165. _wordData += `选择题:\n`;
  2166. let _json = content.testJson ? content.testJson.testJson : [];
  2167. _json.forEach((i2, index2) => {
  2168. _wordData += `题目:${i2.teststitle}\n选项:\n`;
  2169. i2.checkList.forEach((item, index) => {
  2170. _wordData += `${index + 1}:${item.src ? item.src : item}\n`;
  2171. });
  2172. if (typeof i2.answer != "number") {
  2173. i2.answer.forEach(a => {
  2174. a += 1;
  2175. });
  2176. content.anwer[index2].forEach(b => {
  2177. b += 1;
  2178. });
  2179. _wordData += `答案:${i2.answer.join("、")}`;
  2180. _wordData += `学生选择:${content.anwer[index2].join(
  2181. "、"
  2182. )}\n\n`;
  2183. } else {
  2184. _wordData += `答案:${i2.answer + 1}`;
  2185. _wordData += `学生选择:${content.anwer[index2] + 1}\n\n`;
  2186. }
  2187. });
  2188. return _wordData;
  2189. } else if (i.type == 2) {
  2190. let content = JSON.parse(i.content)[0];
  2191. _wordData += `问卷:${content.askJson.askTitle}\n`;
  2192. let _json = content.askJson ? content.askJson.askJson : [];
  2193. _json.forEach((i2, index2) => {
  2194. _wordData += `题目:${i2.askstitle}\n选项:\n`;
  2195. i2.checkList.forEach((item, index) => {
  2196. _wordData += `${index + 1}:${item.src ? item.src : item}\n`;
  2197. });
  2198. if (typeof content.anwer[index2] != "number") {
  2199. _wordData += `学生选择:${content.anwer[index2].join(
  2200. "、"
  2201. )}\n\n`;
  2202. } else {
  2203. _wordData += `学生选择:${content.anwer[index2] + 1}\n\n`;
  2204. }
  2205. });
  2206. }
  2207. });
  2208. // console.log(_wordData)
  2209. // this.loading = false;
  2210. // return this.chatLoading = false;
  2211. _msg = `
  2212. NOTICE
  2213. Language: Please use the same language as the user requirement, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
  2214. ## 目的
  2215. 你是教师用户的课堂助手,你需要基于提供给你的课程相关信息以及学生的作业数据,就某些具体作业对全班学生进行总结分析。
  2216. ---
  2217. ## 定义
  2218. 给你提供的课程发生在一个网络教学平台上,各元素存在以下的关系:课程⊇阶段⊇任务⊇工具。
  2219. 【课程】:课程通常是一个完整的项目,有一个或多个阶段。
  2220. 【阶段】:阶段表示课程的某一单独部分,包含一个或多个任务。
  2221. 【任务】:任务是课程的基本单元,包含一个或多个工具,通常写明了学生要具体完成的事项。
  2222. 【工具】:工具通常是指学生的作业(在课上要具体做的事情)。比如“提交作业”表示学生需要提交一份文件;又比如“问答”,表示学生需要输入一个回答;再比如“选择题”,表示学生需要根据题目要求选择正确的答案。工具中通常会包含学生的作业数据。
  2223. ---
  2224. ## 工作流程与规则
  2225. 1. 了解信息。读取【工具总览表格】以及【工具详情:总体数据】中的内容,了解学生作业详情。
  2226. 2. 确保信息的完整性和可解读性。当面对不确定信息时,你应当积极提问。这一点适用于以下两种情况:
  2227. 2.1 当用户的提问需要你对课程、任务或工具拥有完整的信息、而你又缺乏部分信息时,你应当向客户询问你缺少的信息,再回答用户的提问。
  2228. 2.2 当你不理解某个工具的设置时(比如当你发现题目、选项的表述不完整或者有不符合中文表达规则的符号;又比如你发现缺乏必要的统计信息),你应当积极向用户询问。
  2229. 2.3 **例外情况**:在告知用户并征得同意的情况下,你可以忽视上述问题并执行后续流程。
  2230. 3. 进行总结。
  2231. 3.1 对表格信息进行简单总结。包括任务、阶段、工具及其内容。
  2232. 3.2 进行结果分析。对于每一个工具,都从全班的角度出发进行简单总结。
  2233. 3.3 进行错因分析。仅仅针对于某些错误率较高的题目,从全班的角度出发,进行错因分析。
  2234. 4. 提供扩展题目。针对错误的题目,向用户提供同等水平的题目以起到举一反三的练习效果。
  2235. 5. 回答问题。当用户询问你某个【工具】的具体信息,这部分信息通常将就是学生的作业。你需要简单总结该部分信息,并就用户的问题进行回答。
  2236. ---
  2237. ## 做题信息
  2238. 学生名称:${_data.username}
  2239. ${_wordData}
  2240. `;
  2241. console.log(_msg);
  2242. // this.chatLoading = false;
  2243. // return;
  2244. let history = [];
  2245. this.nowChatList.forEach(i => {
  2246. if (i.content == "wanSearch") {
  2247. return;
  2248. } else if (i.content == "getImage") {
  2249. return history.push({
  2250. role: "assistant",
  2251. content: i.aiContent
  2252. });
  2253. }
  2254. if (i.content) {
  2255. history.push({
  2256. role: "user",
  2257. content: i.content
  2258. });
  2259. }
  2260. if (i.aiContent) {
  2261. history.push({
  2262. role: "assistant",
  2263. content: i.aiContent
  2264. });
  2265. }
  2266. });
  2267. // if (_msg) {
  2268. history.push({ role: "user", content: _msg });
  2269. let params = {
  2270. assistant_id: "f8e1ebb2-2e0d-11ef-8bf4-12e77c4cb76b",
  2271. userId: this.userid,
  2272. message: _text,
  2273. session_name: `${this.courseId}-studyStudent-md`,
  2274. uid: _uuid,
  2275. file_ids: this.fileId
  2276. };
  2277. // let params = {
  2278. // model: "gpt-3.5-turbo",
  2279. // temperature: 0,
  2280. // max_tokens: 4096,
  2281. // top_p: 1,
  2282. // frequency_penalty: 0,
  2283. // presence_penalty: 0,
  2284. // messages: history,
  2285. // uid: _uuid,
  2286. // mind_map_question: _text
  2287. // };
  2288. // let params = {
  2289. // message: {
  2290. // anthropic_version: "bedrock-2023-05-31",
  2291. // max_tokens: 4096,
  2292. // temperature: 0,
  2293. // top_p: 1,
  2294. // messages: history
  2295. // },
  2296. // uid: _uuid,
  2297. // model: "Claude 3 Sonnet" // Claude 3 Sonnet或者Claude 3 Haiku
  2298. // };
  2299. this.ajax
  2300. // .post("https://gpt4.cocorobo.cn/chat", params)
  2301. // .post("https://claude3.cocorobo.cn/chat", params)
  2302. .post("https://gpt4.cocorobo.cn/ai_agent_park_chat_new", params)
  2303. .then(res => {
  2304. if (
  2305. converter(res.data.FunctionResponse.result) ==
  2306. converter("发送成功")
  2307. ) {
  2308. this.loading = false;
  2309. } else {
  2310. // this.$message.warning(res.data.FunctionResponse.result);
  2311. console.log(res.data.FunctionResponse.result);
  2312. this.chatLoading = false;
  2313. this.loading = false;
  2314. }
  2315. })
  2316. .catch(e => {
  2317. console.log(e);
  2318. this.chatLoading = false;
  2319. this.loading = false;
  2320. });
  2321. this.saveUid = _uuid;
  2322. // this.getAiContent(_uuid);
  2323. this.getAtAuContent(_uuid);
  2324. });
  2325. },
  2326. sumUpStudent2(_data) {
  2327. this.text += `${_data.username} 作业分析`;
  2328. let _msg = ``;
  2329. this.chatLoading = true;
  2330. let _uuid = uuidv4();
  2331. this.chatList.push({
  2332. role: "user",
  2333. content: `${this.text}`,
  2334. uid: _uuid,
  2335. AI: "AI",
  2336. aiContent: "",
  2337. oldContent: "",
  2338. isShowSynchronization: false,
  2339. filename: "",
  2340. index: this.chatList.length,
  2341. is_mind_map: false,
  2342. loading: true
  2343. });
  2344. this.text = "";
  2345. let _wordData = "";
  2346. let content = _data.content;
  2347. if (_data.type == 3) {
  2348. _wordData += `问答题:\n题目:${content.answerTitle}\n学生回答:${content.answer}\n\n`;
  2349. } else if (_data.type == 8) {
  2350. _wordData += `选择题:\n`;
  2351. let _json = content.testJson ? content.testJson.testJson : [];
  2352. _json.forEach((i2, index2) => {
  2353. _wordData += `题目:${i2.teststitle}\n选项:\n`;
  2354. i2.checkList.forEach((item, index) => {
  2355. _wordData += `${index + 1}:${item.src ? item.src : item}\n`;
  2356. });
  2357. if (typeof i2.answer != "number") {
  2358. i2.answer.forEach(a => {
  2359. a += 1;
  2360. });
  2361. content.anwer[index2].forEach(b => {
  2362. b += 1;
  2363. });
  2364. _wordData += `答案:${i2.answer.join("、")}`;
  2365. _wordData += `学生选择:${content.anwer[index2].join("、")}\n\n`;
  2366. } else {
  2367. _wordData += `答案:${i2.answer + 1}`;
  2368. _wordData += `学生选择:${content.anwer[index2] + 1}\n\n`;
  2369. }
  2370. });
  2371. _wordData;
  2372. } else if (_data.type == 2) {
  2373. _wordData += `问卷:${content.askJson.askTitle}\n`;
  2374. let _json = content.askJson ? content.askJson.askJson : [];
  2375. _json.forEach((i2, index2) => {
  2376. _wordData += `题目:${i2.askstitle}\n选项:\n`;
  2377. i2.checkList.forEach((item, index) => {
  2378. _wordData += `${index + 1}:${item.src ? item.src : item}\n`;
  2379. });
  2380. if (typeof content.anwer[index2] != "number") {
  2381. _wordData += `学生选择:${content.anwer[index2].join("、")}\n\n`;
  2382. } else {
  2383. _wordData += `学生选择:${content.anwer[index2] + 1}\n\n`;
  2384. }
  2385. });
  2386. }
  2387. // if(_data.type==3){
  2388. // _wordData+=`问答题:\n题目:${content.answerTitle}\n学生回答:${content.answer}\n`
  2389. // }else if(_data.type==8){
  2390. // _wordData+=`选择题:\n`
  2391. // content.testJson.testJson.forEach((i2,index2)=>{
  2392. // _wordData += `题目:${i2.teststitle}\n选项:\n`
  2393. // i2.checkList.forEach((item,index)=>{
  2394. // _wordData+=`${index+1}:${item}\n`
  2395. // })
  2396. // _wordData +=`答案:${i2.answer}`
  2397. // _wordData +=`学生选择:${(content.anwer[index2])+1}\n`
  2398. // })
  2399. // }
  2400. // console.log("👇👇👇")
  2401. // console.log(_wordData)
  2402. // this.chatLoading = false;
  2403. // this.loading = false;
  2404. // return
  2405. _msg = `
  2406. NOTICE
  2407. Language: Please use the same language as the user requirement, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
  2408. ## 目的
  2409. 你是教师用户的课堂助手,你需要基于提供给你的课程相关信息以及学生的作业数据,就某些具体作业对全班学生进行总结分析。
  2410. ---
  2411. ## 定义
  2412. 给你提供的课程发生在一个网络教学平台上,各元素存在以下的关系:课程⊇阶段⊇任务⊇工具。
  2413. 【课程】:课程通常是一个完整的项目,有一个或多个阶段。
  2414. 【阶段】:阶段表示课程的某一单独部分,包含一个或多个任务。
  2415. 【任务】:任务是课程的基本单元,包含一个或多个工具,通常写明了学生要具体完成的事项。
  2416. 【工具】:工具通常是指学生的作业(在课上要具体做的事情)。比如“提交作业”表示学生需要提交一份文件;又比如“问答”,表示学生需要输入一个回答;再比如“选择题”,表示学生需要根据题目要求选择正确的答案。工具中通常会包含学生的作业数据。
  2417. ---
  2418. ## 工作流程与规则
  2419. 1. 了解信息。读取【工具总览表格】以及【工具详情:总体数据】中的内容,了解学生作业详情。
  2420. 2. 确保信息的完整性和可解读性。当面对不确定信息时,你应当积极提问。这一点适用于以下两种情况:
  2421. 2.1 当用户的提问需要你对课程、任务或工具拥有完整的信息、而你又缺乏部分信息时,你应当向客户询问你缺少的信息,再回答用户的提问。
  2422. 2.2 当你不理解某个工具的设置时(比如当你发现题目、选项的表述不完整或者有不符合中文表达规则的符号;又比如你发现缺乏必要的统计信息),你应当积极向用户询问。
  2423. 2.3 **例外情况**:在告知用户并征得同意的情况下,你可以忽视上述问题并执行后续流程。
  2424. 3. 进行总结。
  2425. 3.1 对表格信息进行简单总结。包括任务、阶段、工具及其内容。
  2426. 3.2 进行结果分析。对于每一个工具,都从全班的角度出发进行简单总结。
  2427. 3.3 进行错因分析。仅仅针对于某些错误率较高的题目,从全班的角度出发,进行错因分析。
  2428. 4. 提供扩展题目。针对错误的题目,向用户提供同等水平的题目以起到举一反三的练习效果。
  2429. 5. 回答问题。当用户询问你某个【工具】的具体信息,这部分信息通常将就是学生的作业。你需要简单总结该部分信息,并就用户的问题进行回答。
  2430. ---
  2431. ## 做题信息
  2432. 学生名称:${_data.username}
  2433. ${_wordData}
  2434. `;
  2435. console.log(_msg);
  2436. let history = [];
  2437. this.nowChatList.forEach(i => {
  2438. if (i.content == "wanSearch") {
  2439. return;
  2440. } else if (i.content == "getImage") {
  2441. return history.push({
  2442. role: "assistant",
  2443. content: i.aiContent
  2444. });
  2445. }
  2446. if (i.content) {
  2447. history.push({
  2448. role: "user",
  2449. content: i.content
  2450. });
  2451. }
  2452. if (i.aiContent) {
  2453. history.push({
  2454. role: "assistant",
  2455. content: i.aiContent
  2456. });
  2457. }
  2458. });
  2459. // if (_msg) {
  2460. history.push({ role: "user", content: _msg });
  2461. let params = {
  2462. assistant_id: "f8e1ebb2-2e0d-11ef-8bf4-12e77c4cb76b",
  2463. userId: this.userid,
  2464. message: _text,
  2465. session_name: `${this.courseId}-studyStudent-md`,
  2466. uid: _uuid,
  2467. file_ids: this.fileId
  2468. };
  2469. // let params = {
  2470. // model: "gpt-3.5-turbo",
  2471. // temperature: 0,
  2472. // max_tokens: 4096,
  2473. // top_p: 1,
  2474. // frequency_penalty: 0,
  2475. // presence_penalty: 0,
  2476. // messages: history,
  2477. // uid: _uuid,
  2478. // mind_map_question: _text
  2479. // };
  2480. // let params = {
  2481. // message: {
  2482. // anthropic_version: "bedrock-2023-05-31",
  2483. // max_tokens: 4096,
  2484. // temperature: 0,
  2485. // top_p: 1,
  2486. // messages: history
  2487. // },
  2488. // uid: _uuid,
  2489. // model: "Claude 3 Sonnet" // Claude 3 Sonnet或者Claude 3 Haiku
  2490. // };
  2491. this.ajax
  2492. // .post("https://gpt4.cocorobo.cn/chat", params)
  2493. // .post("https://claude3.cocorobo.cn/chat", params)
  2494. .post("https://gpt4.cocorobo.cn/ai_agent_park_chat_new", params)
  2495. .then(res => {
  2496. if (
  2497. converter(res.data.FunctionResponse.result) == converter("发送成功")
  2498. ) {
  2499. } else {
  2500. // this.$message.warning(res.data.FunctionResponse.result);
  2501. console.log(res.data.FunctionResponse.result);
  2502. this.chatLoading = false;
  2503. }
  2504. })
  2505. .catch(e => {
  2506. console.log(e);
  2507. this.chatLoading = false;
  2508. });
  2509. this.saveUid = _uuid;
  2510. // this.getAiContent(_uuid);
  2511. this.getAtAuContent(_uuid);
  2512. },
  2513. download(_url) {
  2514. let xhr = new XMLHttpRequest();
  2515. xhr.open("GET", _url, true);
  2516. xhr.responseType = "blob";
  2517. xhr.onload = () => {
  2518. if (xhr.status === 200) {
  2519. let blob = xhr.response;
  2520. // const _blob = new Blob([blob], { type: fileType });
  2521. const downloadElement = document.createElement("a");
  2522. const url = window.URL.createObjectURL(blob);
  2523. downloadElement.href = url;
  2524. downloadElement.download = "Image.jpg";
  2525. downloadElement.click();
  2526. window.URL.revokeObjectURL(url); // 释放内存
  2527. } else {
  2528. this.$message.error("此图片不支持下载");
  2529. }
  2530. };
  2531. xhr.onerror = e => {
  2532. console.log(e);
  2533. this.$message.error("此图片不支持下载");
  2534. };
  2535. xhr.send();
  2536. },
  2537. removeMarkdown(text) {
  2538. return text
  2539. .replace(/[#*_~`>+\-]/g, "") // 移除 #、*、_、~、`、>、+、- 符号
  2540. .replace(/!\[.*?\]\(.*?\)/g, "") // 移除图片
  2541. .replace(/\[.*?\]\(.*?\)/g, "") // 移除链接
  2542. .replace(/```[\s\S]*?```/g, "") // 移除代码块(不使用 s 标志)
  2543. .replace(/`[^`]*`/g, "") // 移除行内代码
  2544. .replace(/\d+\./g, "") // 移除有序列表
  2545. .replace(/^\s*[-*+]\s+/gm, "") // 移除无序列表
  2546. .replace(/\s+/g, " ") // 将多个空白字符替换为一个空格
  2547. .trim(); // 去除字符串两端的空白字符
  2548. },
  2549. aiTalk(type = 0) {
  2550. //0 新的 1继续
  2551. if (type == 0 && this.aiIsTalk) {
  2552. let _talkTextIiframe2 = this.$refs.iiframe2;
  2553. try {
  2554. _talkTextIiframe2.contentWindow.pausesynthesizer();
  2555. _talkTextIiframe2.contentWindow.closesynthesizer();
  2556. this.aiIsTalk = false;
  2557. if (this.aiTalkList.length) this.aiTalk(0);
  2558. else this.aiTalkUid = "";
  2559. } catch (error) {
  2560. // console.log("error")
  2561. this.aiIsTalk = false;
  2562. if (this.aiTalkList.length) this.aiTalk(0);
  2563. else this.aiTalkUid = "";
  2564. }
  2565. } else {
  2566. let _text = this.aiTalkList.shift();
  2567. let _talkTextIiframe2 = this.$refs.iiframe2;
  2568. if (_text) {
  2569. this.aiIsTalk = true;
  2570. // console.log("👇说👇");
  2571. // console.log(_text);
  2572. _talkTextIiframe2.contentWindow.texttospeech(
  2573. _text,
  2574. () => {
  2575. this.aiTalk(1);
  2576. },
  2577. () => {
  2578. this.aiTalk(0);
  2579. }
  2580. );
  2581. } else {
  2582. try {
  2583. _talkTextIiframe2.contentWindow.closesynthesizer();
  2584. } catch (error) {
  2585. return;
  2586. }
  2587. }
  2588. }
  2589. // if(_text){
  2590. // this.aiIsTalk = true;
  2591. // }
  2592. },
  2593. aiTalkAll(item) {
  2594. if (this.aiTalkUid == item.uid && this.aiIsTalk) {
  2595. try {
  2596. this.aiTalkList = [];
  2597. let _talkTextIiframe2 = this.$refs.iiframe2;
  2598. _talkTextIiframe2.contentWindow.pausesynthesizer();
  2599. _talkTextIiframe2.contentWindow.closesynthesizer();
  2600. this.aiIsTalk = false;
  2601. } catch (error) {
  2602. this.aiTalkList = [];
  2603. this.aiIsTalk = false;
  2604. }
  2605. } else {
  2606. let _resultText = this.removeMarkdown(item.aiContent);
  2607. this.aiTalkUid = item.uid;
  2608. this.aiTalkList = [];
  2609. this.aiTalkList.push(_resultText);
  2610. this.aiTalk(0);
  2611. }
  2612. },
  2613. choseRole(item) {
  2614. this.choseRoleItem = item;
  2615. console.log("选择角色", this.choseRoleItem);
  2616. this.scrollBottom();
  2617. },
  2618. noChangeRole() {
  2619. this.cardType = 0;
  2620. this.choseRoleItem = null;
  2621. this.scrollBottom();
  2622. },
  2623. changeRole() {
  2624. this.cardType = 0;
  2625. if (this.choseRoleItem && this.choseRoleItem.assistant_id) {
  2626. // this.chatList = [];
  2627. this.nowChatList = [];
  2628. let _uuid = uuidv4();
  2629. this.chatList.push({
  2630. role: "user",
  2631. content: `您好,${this.choseRoleItem.assistantName}`,
  2632. uid: _uuid,
  2633. AI: "AI",
  2634. aiContent: this.choseRoleItem.prologue
  2635. ? this.choseRoleItem.prologue
  2636. : "您好,有什么需要我帮忙的吗?",
  2637. oldContent: "",
  2638. isShowSynchronization: false,
  2639. filename: this.choseRoleItem.headUrl,
  2640. index: this.chatList.length,
  2641. is_mind_map: false,
  2642. loading: false
  2643. });
  2644. this.scrollBottom();
  2645. this.insertMemorandum(`选择智能体<span class="variable">${this.choseRoleItem.assistantName}</span>`)
  2646. }
  2647. },
  2648. optBtn(val) {
  2649. this.sortOption = val;
  2650. },
  2651. getRoleList() {
  2652. this.roleList = [];
  2653. let params = {
  2654. userId: this.userid
  2655. };
  2656. this.ajax
  2657. .post("https://gpt4.cocorobo.cn/get_ai_agent_assistant_list", params)
  2658. .then(res => {
  2659. let _data = res.data.FunctionResponse.result;
  2660. if (_data.length == 0) return;
  2661. if (_data) {
  2662. this.roleList = JSON.parse(_data);
  2663. }
  2664. })
  2665. .catch(e => {
  2666. console.log("获取角色列表失败");
  2667. this.roleList = [];
  2668. });
  2669. },
  2670. getPublicRoleList() {
  2671. this.roleList2 = [];
  2672. let params = {
  2673. userId: this.userid,
  2674. // organizeid: this.org,
  2675. organizeid: "45facc0a-1211-11ec-80ad-005056b86db5"
  2676. };
  2677. this.ajax
  2678. .post(
  2679. "https://gpt4.cocorobo.cn/get_ai_agent_assistant_share_list",
  2680. params
  2681. )
  2682. .then(res => {
  2683. let _data = res.data.FunctionResponse.result;
  2684. if (_data.length == 0) return;
  2685. if (_data) {
  2686. this.roleList2 = JSON.parse(_data);
  2687. }
  2688. })
  2689. .catch(e => {
  2690. this.roleList2 = [];
  2691. console.log("获取公共角色失败", e);
  2692. });
  2693. },
  2694. choiceRole() {
  2695. if (this.loading) return this.$message.info("请稍等");
  2696. this.cardType = 1;
  2697. }
  2698. },
  2699. mounted() {
  2700. this.getChatList().then(_ => {
  2701. this.scrollBottom();
  2702. this.getWantSearch();
  2703. });
  2704. this.nowChatList = [];
  2705. this.sendType = 0;
  2706. this.initTaskList();
  2707. this.getWorkData();
  2708. this.getPublicRoleList();
  2709. this.getRoleList();
  2710. this.insertMemorandum(`打开<span class="btn">任务</span>面板`)
  2711. }
  2712. };
  2713. </script>
  2714. <style scoped>
  2715. .search {
  2716. width: 100%;
  2717. height: 100%;
  2718. box-sizing: border-box;
  2719. }
  2720. .checkboxCss {
  2721. color: #fff;
  2722. background-color: #76a7f5 !important;
  2723. }
  2724. .imgNumberBlock {
  2725. width: 100%;
  2726. height: 30px;
  2727. display: flex;
  2728. justify-content: space-between;
  2729. box-sizing: border-box;
  2730. /* padding: 5px 10px; */
  2731. }
  2732. .imgNumberBlock > .imgNumber {
  2733. width: 18%;
  2734. height: 30px;
  2735. white-space: initial;
  2736. background: rgba(224, 234, 251, 1);
  2737. border-radius: 5px;
  2738. display: flex;
  2739. align-items: center;
  2740. cursor: pointer;
  2741. justify-content: center;
  2742. }
  2743. .s_top {
  2744. width: 100%;
  2745. height: calc(100% - 130px);
  2746. overflow-x: hidden;
  2747. box-sizing: border-box;
  2748. padding: 20px 0;
  2749. }
  2750. .s_t_chat {
  2751. width: 100%;
  2752. display: flex;
  2753. box-sizing: border-box;
  2754. padding: 10px;
  2755. flex-direction: column;
  2756. }
  2757. .s_t_chat > div {
  2758. display: flex;
  2759. align-items: flex-start;
  2760. width: 100%;
  2761. }
  2762. .s_t_c_user {
  2763. box-sizing: border-box;
  2764. padding-left: 35px;
  2765. }
  2766. .s_t_c_u_left {
  2767. width: 90%;
  2768. height: auto;
  2769. }
  2770. .s_t_c_u_l_content {
  2771. width: auto;
  2772. max-width: 100%;
  2773. height: auto;
  2774. box-sizing: border-box;
  2775. padding: 10px;
  2776. color: white;
  2777. background-color: #3681fc;
  2778. border-radius: 8px 2px 8px 8px;
  2779. white-space: pre-line;
  2780. word-break: break-all;
  2781. }
  2782. .s_t_c_a_r_contentImage > span {
  2783. display: block;
  2784. }
  2785. .s_t_c_a_r_contentImage > img {
  2786. width: 45%;
  2787. height: 125px;
  2788. margin: 1% 1.5%;
  2789. border-radius: 5px;
  2790. cursor: pointer;
  2791. }
  2792. .s_t_c_a_r_contentImage {
  2793. width: auto;
  2794. max-width: 100%;
  2795. height: auto;
  2796. box-sizing: border-box;
  2797. padding: 10px;
  2798. background-color: #f6f8ff;
  2799. border-radius: 2px 8px 8px 8px;
  2800. white-space: pre-line;
  2801. word-break: break-all;
  2802. }
  2803. .s_t_c_u_l_time {
  2804. width: 100%;
  2805. display: flex;
  2806. justify-content: flex-end;
  2807. font-size: 12px;
  2808. color: #9f9f9f;
  2809. margin-top: 5px;
  2810. }
  2811. .s_t_c_u_right {
  2812. width: 35px;
  2813. height: 35px;
  2814. display: flex;
  2815. justify-content: center;
  2816. margin-left: 5px;
  2817. }
  2818. .s_t_c_u_right > span {
  2819. width: 32px;
  2820. height: 32px;
  2821. display: flex;
  2822. justify-content: center;
  2823. align-items: center;
  2824. color: white;
  2825. background-color: #3681fc;
  2826. border-radius: 50%;
  2827. }
  2828. .s_t_c_ai {
  2829. box-sizing: border-box;
  2830. padding-right: 35px;
  2831. position: relative;
  2832. margin-top: 10px;
  2833. }
  2834. .aiCopy {
  2835. position: absolute;
  2836. right: 5px;
  2837. bottom: 0%;
  2838. /* transform: translate(0, -30%); */
  2839. }
  2840. .aiCopy > img {
  2841. margin-right: 5px;
  2842. cursor: pointer;
  2843. }
  2844. .s_t_c_a_right {
  2845. min-width: 90%;
  2846. height: auto;
  2847. position: relative;
  2848. }
  2849. .s_t_c_a_r_content {
  2850. width: auto;
  2851. max-width: 100%;
  2852. height: auto;
  2853. box-sizing: border-box;
  2854. padding: 10px;
  2855. background-color: #f6f8ff;
  2856. border-radius: 2px 8px 8px 8px;
  2857. white-space: pre-line;
  2858. word-break: break-all;
  2859. }
  2860. .s_t_c_a_r_content2 {
  2861. background-color: #f6f8ff;
  2862. width: 100%;
  2863. height: auto;
  2864. box-sizing: border-box;
  2865. padding: 10px;
  2866. border-radius: 2px 8px 8px 8px;
  2867. box-shadow: 0 0px 10px #c5cbee;
  2868. }
  2869. .s_t_c_a_r_c_title {
  2870. display: flex;
  2871. align-items: center;
  2872. }
  2873. .s_t_c_a_r_c_title > img {
  2874. width: 16px;
  2875. height: 16px;
  2876. }
  2877. .s_t_c_a_r_c_item {
  2878. width: 100%;
  2879. height: auto;
  2880. box-sizing: border-box;
  2881. padding: 10px;
  2882. background-color: #ffffff;
  2883. border-radius: 5px;
  2884. margin-top: 10px;
  2885. color: #666666;
  2886. font-size: 14px;
  2887. cursor: pointer;
  2888. border: solid #ffffff 1px;
  2889. box-shadow: 0 0 5px 2px #ffffff;
  2890. }
  2891. .s_t_c_a_r_c_item:hover {
  2892. border: solid #b8d2fe 1px;
  2893. box-shadow: 0 0 5px 2px #b8d2fe;
  2894. }
  2895. .s_t_c_a_r_c_title > span {
  2896. font-weight: bold;
  2897. }
  2898. .s_t_c_a_r_time {
  2899. width: 100%;
  2900. display: flex;
  2901. justify-content: flex-start;
  2902. font-size: 12px;
  2903. color: #9f9f9f;
  2904. margin-top: 5px;
  2905. }
  2906. .s_t_c_a_left {
  2907. width: 35px;
  2908. height: 35px;
  2909. display: flex;
  2910. justify-content: center;
  2911. margin-right: 5px;
  2912. }
  2913. .s_t_c_a_left > img {
  2914. width: 35px;
  2915. height: 35px;
  2916. border-radius: 50%;
  2917. }
  2918. .s_t_c_a_left > span {
  2919. width: 32px;
  2920. height: 32px;
  2921. display: flex;
  2922. justify-content: center;
  2923. align-items: center;
  2924. color: white;
  2925. background-color: #3681fc;
  2926. border-radius: 50%;
  2927. }
  2928. .s_bottom {
  2929. width: 100%;
  2930. height: 130px;
  2931. display: flex;
  2932. flex-direction: column;
  2933. justify-content: space-between;
  2934. position: relative;
  2935. }
  2936. .s_b_btnAreaTop {
  2937. width: 100%;
  2938. height: 35px;
  2939. margin-bottom: 5px;
  2940. display: flex;
  2941. align-items: center;
  2942. box-sizing: border-box;
  2943. padding: 0 10px;
  2944. overflow: auto;
  2945. display: flex;
  2946. justify-content: space-between;
  2947. }
  2948. .s_b_bat_left {
  2949. width: auto;
  2950. height: 100%;
  2951. display: flex;
  2952. align-items: flex-end;
  2953. }
  2954. .s_b_bat_left > img {
  2955. width: 25px;
  2956. height: 25px;
  2957. cursor: pointer;
  2958. margin-right: 5px;
  2959. }
  2960. .s_b_bat_right {
  2961. width: auto;
  2962. height: 100%;
  2963. display: flex;
  2964. align-items: flex-end;
  2965. }
  2966. .s_b_bat_right > img {
  2967. width: 25px;
  2968. height: 25px;
  2969. /* cursor: pointer; */
  2970. margin-right: 5px;
  2971. }
  2972. .s_b_btnArea {
  2973. width: 100%;
  2974. height: 30px;
  2975. display: flex;
  2976. align-items: center;
  2977. box-sizing: border-box;
  2978. padding: 0 10px;
  2979. overflow: auto;
  2980. }
  2981. .s_b_ba-item {
  2982. width: auto;
  2983. box-sizing: border-box;
  2984. padding: 0 10px;
  2985. height: 25px;
  2986. background-color: white;
  2987. display: flex;
  2988. justify-content: center;
  2989. align-items: center;
  2990. /* 阴影 */
  2991. box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.363);
  2992. border-radius: 15px;
  2993. font-size: 14px;
  2994. cursor: pointer;
  2995. margin-right: 10px;
  2996. white-space: nowrap;
  2997. }
  2998. .s_b_ba_active {
  2999. background-color: #3781fc;
  3000. color: #fff;
  3001. }
  3002. .s_b_inputArea {
  3003. width: 100%;
  3004. height: 55px;
  3005. box-sizing: border-box;
  3006. border-top: solid 1px #ededed;
  3007. display: flex;
  3008. justify-content: space-between;
  3009. align-items: center;
  3010. padding-right: 10px;
  3011. }
  3012. .s_b_tape {
  3013. width: 35px;
  3014. height: 35px;
  3015. background: url("../../../assets/icon/course/tape.png") no-repeat;
  3016. background-size: 50% 60%;
  3017. background-position: center;
  3018. cursor: pointer;
  3019. }
  3020. .s_b_input {
  3021. /* width: 65%; */
  3022. flex: 1;
  3023. height: 45px;
  3024. background-color: #f3f3f3;
  3025. border-radius: 50px;
  3026. margin: 0 10px;
  3027. display: flex;
  3028. align-items: center;
  3029. overflow: hidden;
  3030. }
  3031. .s_b_i_left {
  3032. width: 100%;
  3033. line-height: 45px;
  3034. height: 100%;
  3035. }
  3036. .s_b_i_left >>> .el-input__inner {
  3037. border: none;
  3038. background-color: #f3f3f3;
  3039. outline: none;
  3040. border-radius: 50px 0 0 50px;
  3041. }
  3042. .s_b_i_right {
  3043. width: 45px;
  3044. height: 45px;
  3045. display: flex;
  3046. justify-content: center;
  3047. align-items: center;
  3048. }
  3049. .s_b_i_right > span {
  3050. width: 35px;
  3051. height: 35px;
  3052. background: url("../../../assets/icon/course/file.png") no-repeat;
  3053. background-size: 50% 60%;
  3054. background-position: center;
  3055. cursor: pointer;
  3056. }
  3057. .voice_or_keyboard {
  3058. width: 35px;
  3059. height: 35px;
  3060. margin-right: 10px;
  3061. }
  3062. .voice_or_keyboard > img {
  3063. width: 100%;
  3064. height: 100%;
  3065. cursor: pointer;
  3066. }
  3067. .s_b_btn {
  3068. width: 40px;
  3069. height: 40px;
  3070. background-color: #3681fc;
  3071. display: flex;
  3072. justify-content: center;
  3073. align-items: center;
  3074. border-radius: 50%;
  3075. cursor: pointer;
  3076. }
  3077. .s_b_btn > div {
  3078. width: 100%;
  3079. height: 100%;
  3080. display: flex;
  3081. justify-content: center;
  3082. align-items: center;
  3083. color: #fff;
  3084. }
  3085. .s_b_btn > span {
  3086. width: 30px;
  3087. height: 30px;
  3088. background: url("../../../assets/icon/course/send.png") no-repeat;
  3089. background-size: 70% 70%;
  3090. background-position: center;
  3091. }
  3092. .s_b_btn > img {
  3093. width: 30px;
  3094. height: 30px;
  3095. }
  3096. .s_b_btn2 {
  3097. width: 40px;
  3098. height: 40px;
  3099. background-color: #fff;
  3100. display: flex;
  3101. justify-content: center;
  3102. align-items: center;
  3103. border-radius: 50%;
  3104. cursor: pointer;
  3105. box-sizing: 0 0 2px 2px gray;
  3106. margin-left:10px;
  3107. }
  3108. .s_b_btn2 > img {
  3109. width: 30px;
  3110. height: 30px;
  3111. }
  3112. .s_b_atBox {
  3113. width: 95%;
  3114. height: 450px;
  3115. position: absolute;
  3116. bottom: calc(100% - 30px);
  3117. left: 0;
  3118. max-height: 450px;
  3119. box-sizing: border-box;
  3120. border: solid 1px #d8d8d8;
  3121. box-shadow: 0 4px 4px 0 #00000040;
  3122. margin-left: 1.5%;
  3123. background-color: #fff;
  3124. }
  3125. .s_b_at_tag {
  3126. width: 100%;
  3127. height: 35px;
  3128. border-bottom: 1px solid #d8d8d8;
  3129. display: flex;
  3130. align-items: center;
  3131. padding: 0 10px;
  3132. box-sizing: border-box;
  3133. position: relative;
  3134. }
  3135. .s_b_at_tag > span {
  3136. margin: 0 10px;
  3137. font-weight: bold;
  3138. cursor: pointer;
  3139. transition: 0.1s;
  3140. position: relative;
  3141. }
  3142. .s_b_at_tag_active {
  3143. color: #3681fc;
  3144. }
  3145. .s_b_at_tag_active::after {
  3146. content: "";
  3147. width: 100%;
  3148. height: 3px;
  3149. border-radius: 3px;
  3150. bottom: -8px;
  3151. left: 0px;
  3152. background-color: #3681fc;
  3153. position: absolute;
  3154. }
  3155. .s_b_at_list {
  3156. width: 100%;
  3157. max-height: calc(100% - 35px);
  3158. overflow: auto;
  3159. box-sizing: border-box;
  3160. padding: 10px;
  3161. }
  3162. .s_b_at_l_top {
  3163. width: 100%;
  3164. box-sizing: border-box;
  3165. padding: 12px 10px;
  3166. height: 30px;
  3167. display: flex;
  3168. align-items: center;
  3169. justify-content: space-between;
  3170. margin: 10px 0;
  3171. border-radius: 5px;
  3172. cursor: pointer;
  3173. font-size: 16px;
  3174. border-bottom: solid 1px #e2f5fc;
  3175. }
  3176. .s_b_at_l_top > span:nth-child(1) {
  3177. display: block;
  3178. width: calc(100% - 30px);
  3179. overflow: hidden;
  3180. text-overflow: ellipsis;
  3181. white-space: nowrap;
  3182. }
  3183. .s_b_at_l_i_header {
  3184. width: 100%;
  3185. box-sizing: border-box;
  3186. padding: 10px 10px;
  3187. height: 30px;
  3188. display: flex;
  3189. align-items: center;
  3190. margin: 10px 0;
  3191. border-radius: 5px;
  3192. cursor: pointer;
  3193. font-size: 16px;
  3194. }
  3195. .s_b_at_l_i_header > span:nth-child(2) {
  3196. display: block;
  3197. width: calc(100% - 30px);
  3198. overflow: hidden;
  3199. text-overflow: ellipsis;
  3200. white-space: nowrap;
  3201. }
  3202. .s_b_at_l_top > hover {
  3203. background-color: #3781fc;
  3204. color: #fff;
  3205. }
  3206. .s_b_at_l_top > hover > .s_b_at_l_i_h_icon1 {
  3207. background-image: url("../../../assets/icon/course/bDown2.png");
  3208. }
  3209. .s_b_at_l_i_header:hover {
  3210. background-color: #3781fc;
  3211. color: #fff;
  3212. }
  3213. .s_b_at_l_i_header:hover > .s_b_at_l_i_h_icon1 {
  3214. background-image: url("../../../assets/icon/course/bDown2.png");
  3215. }
  3216. .s_b_at_l_i_header:hover > .s_b_at_l_i_h_icon2 {
  3217. background-color: #fff;
  3218. }
  3219. .s_b_at_l_i_h_icon1 {
  3220. min-width: 15px;
  3221. min-height: 15px;
  3222. background-image: url("../../../assets/icon/course/down.png");
  3223. background-repeat: no-repeat;
  3224. background-size: 100% 100%;
  3225. /* transform: rotate(90deg); */
  3226. margin-right: 10px;
  3227. transition: 0.2s;
  3228. }
  3229. .s_b_at_l_i_h_icon2 {
  3230. min-width: 10px;
  3231. min-height: 10px;
  3232. background-color: #3681fc;
  3233. border-radius: 50%;
  3234. margin-right: 15px;
  3235. transition: 0.2s;
  3236. }
  3237. .s_b_at_l_i_content {
  3238. width: 100%;
  3239. box-sizing: border-box;
  3240. padding: 8px 35px;
  3241. height: 25;
  3242. display: flex;
  3243. align-items: center;
  3244. margin: 5px 0;
  3245. border-radius: 5px;
  3246. cursor: pointer;
  3247. font-size: 14px;
  3248. }
  3249. .s_b_at_l_i_content:hover {
  3250. background-color: #3781fc;
  3251. color: #fff;
  3252. }
  3253. .s_b_ab_user {
  3254. width: 100%;
  3255. height: 100px;
  3256. box-sizing: border-box;
  3257. border: solid 1px #3781fc;
  3258. display: flex;
  3259. justify-content: center;
  3260. align-items: center;
  3261. position: relative;
  3262. margin-bottom: 20px;
  3263. }
  3264. .s_b_ab_u_name {
  3265. width: 25%;
  3266. max-width: 25%;
  3267. box-sizing: border-box;
  3268. margin: 0 20px;
  3269. padding: 5px 10px;
  3270. display: flex;
  3271. justify-content: center;
  3272. align-items: center;
  3273. border: solid 1px #3781fc;
  3274. border-radius: 2px;
  3275. }
  3276. .s_b_ab_u_name > span {
  3277. max-width: 100%;
  3278. overflow: hidden;
  3279. text-overflow: ellipsis;
  3280. white-space: nowrap;
  3281. display: block;
  3282. font-size: 14px;
  3283. color: #3681fc;
  3284. }
  3285. .s_b_ab_u_message {
  3286. flex: 1;
  3287. height: 100%;
  3288. display: flex;
  3289. flex-direction: column;
  3290. justify-content: center;
  3291. box-sizing: border-box;
  3292. padding-top: 10px;
  3293. padding-right: 10px;
  3294. }
  3295. .s_b_ab_u_message > span {
  3296. font-size: 16px;
  3297. font-weight: bold;
  3298. display: flex;
  3299. align-items: flex-end;
  3300. flex: 1;
  3301. }
  3302. .s_b_ab_u_message > div {
  3303. width: 100%;
  3304. display: flex;
  3305. justify-content: space-between;
  3306. align-items: center;
  3307. font-size: 16px;
  3308. font-weight: bold;
  3309. flex: 1;
  3310. }
  3311. .s_b_ab_u_btnArea {
  3312. width: auto;
  3313. height: auto;
  3314. position: absolute;
  3315. right: 0;
  3316. top: 5px;
  3317. }
  3318. .s_b_ab_u_btnArea > span {
  3319. box-sizing: border-box;
  3320. color: #3681fc;
  3321. border: solid 1px #3681fc;
  3322. padding: 2px;
  3323. margin-left: 2px;
  3324. font-size: 14px;
  3325. cursor: pointer;
  3326. }
  3327. .s_b_ab_u_btnArea > span:hover {
  3328. color: #fff;
  3329. border: solid 1px #fff;
  3330. background-color: #3681fc;
  3331. }
  3332. .s_b_at_studentDetail {
  3333. width: 100%;
  3334. height: 25px;
  3335. margin: 0 0 10px 0;
  3336. display: flex;
  3337. align-items: center;
  3338. }
  3339. .s_b_at_studentDetail > img {
  3340. width: 20px;
  3341. height: 15px;
  3342. margin-right: 10px;
  3343. cursor: pointer;
  3344. }
  3345. .s_b_at_studentDetail > span {
  3346. font-weight: bold;
  3347. }
  3348. .s_b_at_studentList {
  3349. width: 100%;
  3350. height: calc(100% - 25px);
  3351. overflow: auto;
  3352. }
  3353. .s_b_at_sl_item {
  3354. width: 100%;
  3355. height: auto;
  3356. box-sizing: border-box;
  3357. border: solid 1px #36a9fc;
  3358. padding: 10px;
  3359. margin-bottom: 10px;
  3360. cursor: pointer;
  3361. }
  3362. .s_b_at_sl_item > .s_b_at_sl_message:nth-child(n + 1) {
  3363. margin-top: 10px;
  3364. }
  3365. .s_b_at_sl_phase {
  3366. width: 100%;
  3367. display: flex;
  3368. justify-content: flex-end;
  3369. margin-bottom: 10px;
  3370. margin-right: 10px;
  3371. font-size: 14px;
  3372. font-weight: bold;
  3373. }
  3374. .s_b_at_sl_message {
  3375. font-weight: bold;
  3376. margin: 10px;
  3377. }
  3378. .s_b_at_sl_message > div {
  3379. display: flex;
  3380. width: 100%;
  3381. margin: 10px;
  3382. }
  3383. .s_b_at_sl_message > div > span {
  3384. width: calc(100% - 50px);
  3385. text-overflow: ellipsis;
  3386. overflow: hidden;
  3387. white-space: nowrap;
  3388. display: block;
  3389. }
  3390. .s_b_at_sl_message > div > span > div {
  3391. margin: 5px 0;
  3392. white-space: wrap;
  3393. }
  3394. .s_t_addAsk {
  3395. width: 100%;
  3396. height: auto;
  3397. padding: 10px 20px;
  3398. display: flex;
  3399. flex-direction: column;
  3400. justify-content: center;
  3401. align-items: center;
  3402. box-sizing: border-box;
  3403. }
  3404. .s_t_addAsk > span {
  3405. box-sizing: border-box;
  3406. width: auto;
  3407. height: auto;
  3408. padding: 15px;
  3409. margin-bottom: 10px;
  3410. background-color: #f5f6f7;
  3411. border-radius: 10px;
  3412. cursor: pointer;
  3413. border: solid 1px #e8e9ec;
  3414. transition: 0.3s;
  3415. }
  3416. .s_t_addAsk > span:hover {
  3417. background-color: #e8e9ec;
  3418. }
  3419. .d_t_c_a_r_c_img:hover .download_image {
  3420. display: block;
  3421. }
  3422. .download_image {
  3423. position: absolute;
  3424. display: none;
  3425. right: 5px;
  3426. bottom: 5px;
  3427. width: 30px;
  3428. height: 30px;
  3429. cursor: pointer;
  3430. }
  3431. .download_image > img {
  3432. width: 100%;
  3433. height: 100%;
  3434. }
  3435. .choiceTopArea {
  3436. width: 100%;
  3437. height: 100%;
  3438. }
  3439. .choiceTop {
  3440. width: 100%;
  3441. height: 95%;
  3442. overflow-x: hidden;
  3443. box-sizing: border-box;
  3444. padding: 10px;
  3445. }
  3446. .choiceBottom {
  3447. width: 100%;
  3448. height: 5%;
  3449. display: flex;
  3450. align-items: center;
  3451. justify-content: flex-end;
  3452. }
  3453. .cb_btn {
  3454. margin: 0 10px;
  3455. }
  3456. .choiceRoleHeader {
  3457. width: 100%;
  3458. height:100px;
  3459. display: flex;
  3460. /* margin: 10px; */
  3461. }
  3462. .choiceRoleHeader > div {
  3463. display: flex;
  3464. }
  3465. .choiceSelect {
  3466. width: 100%;
  3467. height:calc(100% - 100px);
  3468. display: flex;
  3469. flex-direction: column;
  3470. justify-content: flex-start;
  3471. align-items: center;
  3472. padding: 10px;
  3473. box-sizing: border-box;
  3474. border-radius: 10px;
  3475. background: #F2F2F2;
  3476. }
  3477. .choiceSelect > .option {
  3478. width: 80px;
  3479. height: 100%;
  3480. border-radius: 5px;
  3481. margin-right: 10px;
  3482. display: flex;
  3483. justify-content: center;
  3484. align-items: center;
  3485. cursor: pointer;
  3486. }
  3487. .roleInput{
  3488. width:100%;
  3489. height:50px;
  3490. }
  3491. .roleBtn{
  3492. width:100%;
  3493. height:50px;
  3494. margin: 5px 0;
  3495. }
  3496. .roleListBox{
  3497. width:100%;
  3498. height:calc(100% - 100px - 10px);
  3499. overflow-x: hidden;
  3500. display: flex;
  3501. flex-direction: column;
  3502. justify-content: flex-start;
  3503. align-items: center;
  3504. padding: 10px;
  3505. box-sizing: border-box;
  3506. }
  3507. .filterSubjects {
  3508. margin: 10px;
  3509. width: 100%;
  3510. height: auto;
  3511. }
  3512. .fs_box {
  3513. width: 100%;
  3514. display: flex;
  3515. flex-wrap: wrap;
  3516. margin-top: 10px;
  3517. }
  3518. .fs_b_item {
  3519. width: auto;
  3520. height: 35px;
  3521. font-size: 14px;
  3522. box-sizing: border-box;
  3523. padding: 0 9px;
  3524. background-color: #f3f7fd;
  3525. border: solid 1px #f3f7fd;
  3526. border-radius: 5px;
  3527. margin-right: 8px;
  3528. margin-bottom: 8px;
  3529. display: flex;
  3530. justify-content: center;
  3531. align-items: center;
  3532. cursor: pointer;
  3533. }
  3534. .fs_b_itemActive {
  3535. border: solid 1px #4d8ffc;
  3536. color: #4d8ffc;
  3537. background-color: #f3f7fd;
  3538. }
  3539. .roleList {
  3540. width: 100%;
  3541. height: auto;
  3542. margin: 10px;
  3543. }
  3544. .r_box {
  3545. width: 100%;
  3546. height: auto;
  3547. display: flex;
  3548. flex-wrap: wrap;
  3549. }
  3550. .r_b_item {
  3551. height: 40px;
  3552. font-size: 14px;
  3553. display: flex;
  3554. /* justify-content: center; */
  3555. align-items: center;
  3556. background-color: #f0f2f5;
  3557. border-radius: 5px;
  3558. margin: 5px;
  3559. cursor: pointer;
  3560. box-sizing: border-box;
  3561. padding: 0 4px;
  3562. border: solid 1px #f0f2f5;
  3563. }
  3564. .r_b_itemActive {
  3565. box-sizing: border-box;
  3566. border: solid 1px #aeccfe;
  3567. color: #4d8ffb;
  3568. }
  3569. .r_b_item > img {
  3570. min-width: 24px;
  3571. min-height: 24px;
  3572. width: 24px;
  3573. height: 24px;
  3574. border-radius: 50%;
  3575. margin-right: 10px;
  3576. /* margin-left: 10px; */
  3577. }
  3578. .characterBlock {
  3579. display: flex;
  3580. background: rgba(54, 169, 252, 1);
  3581. width: 100%;
  3582. height: auto;
  3583. padding:10px 0;
  3584. margin: 0 auto;
  3585. border-radius: 10px;
  3586. margin-bottom: 15px;
  3587. cursor: pointer;
  3588. }
  3589. .characterBlock > .imgLeft {
  3590. width: 100px;
  3591. display: flex;
  3592. justify-content: center;
  3593. align-items: center;
  3594. }
  3595. .characterBlock > .imgLeft > .img {
  3596. width: 60px;
  3597. height: 60px;
  3598. overflow: hidden;
  3599. border-radius: 50%;
  3600. }
  3601. .characterBlock > .imgLeft > .img2 {
  3602. width: 70px;
  3603. height: 70px;
  3604. overflow: hidden;
  3605. border-radius: 50%;
  3606. }
  3607. .characterBlock > .txtRight {
  3608. flex: 1;
  3609. display: flex;
  3610. justify-content: flex-start;
  3611. align-items: center;
  3612. }
  3613. .characterBlock > .txtRight > .bir {
  3614. width: 170px;
  3615. height: 35px;
  3616. display: flex;
  3617. align-items: center;
  3618. background-color: #fff;
  3619. border-radius: 10px;
  3620. box-sizing: border-box;
  3621. padding: 5px 10px;
  3622. box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
  3623. margin-right: 10px;
  3624. white-space: nowrap;
  3625. overflow: hidden;
  3626. text-overflow: ellipsis;
  3627. }
  3628. </style>