aiLeader.vue 128 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839
  1. <template>
  2. <div class="ai_body">
  3. <div class="ai_b_addNewChat" v-if="fileList.length>0">
  4. <el-tooltip class="item" effect="light" content="新建会话" placement="right">
  5. <span @click="addNewChat">+</span>
  6. </el-tooltip>
  7. </div>
  8. <div class="ai_body_dialog" ref="chatDialog">
  9. <div
  10. class="dialog_content"
  11. v-for="(item, index) in array"
  12. :key="item.uid"
  13. >
  14. <div v-if="item.content" style="margin-left: auto;">
  15. <div class="content content2" v-html="item.content"></div>
  16. <div class="role">
  17. <img src="../../../../assets/icon/new/role2.png" />
  18. </div>
  19. </div>
  20. <div
  21. style="margin-top:20px;margin-bottom:20px ; margin-right: auto;"
  22. v-if="
  23. (item.aiContent || item.loading || fileList.length == 0) &&
  24. item.content !== 0
  25. "
  26. >
  27. <div class="role">
  28. <img
  29. :src="
  30. item.fileid
  31. ? item.fileid
  32. : require('../../../../assets/icon/new/role1.png')
  33. "
  34. />
  35. </div>
  36. <div
  37. element-loading-background="#f6f9ff"
  38. :style="{
  39. minHeight: item.loading ? '38px' : 'unset',
  40. minWidth: item.loading ? '50px' : 'unset'
  41. }"
  42. class="content"
  43. >
  44. <span class="vditor-reset" v-html="item.aiContent"></span>
  45. <span class="createTime" v-text="item.createtime"></span>
  46. <div
  47. style="width: 100%;margin-top: 10px;box-sizing: border-box;padding-left: 20px;"
  48. v-if="item.echartList && item.echartList.length > 0"
  49. >
  50. <div class="echartBtn" v-for="(item2, index2) in item.echartList" @click="choseEcharts(item, item2)" :key="index + '-' + index2">
  51. <img :src="require(`../../../../assets/icon/test/echart${item2.type}_icon.svg`)">
  52. <span>{{ (index2+1)+'、'+item2.name+':'+item2.title }}</span>
  53. </div>
  54. <!-- <el-button
  55. v-for="(item2, index2) in item.echartList"
  56. @click="choseEcharts(item, item2)"
  57. :key="index + '-' + index2"
  58. size="mini"
  59. class="echartBtn"
  60. >{{ index2+'、'+item2.name+':'+item.title }}</el-button
  61. > -->
  62. </div>
  63. <div class="eChartView" v-if="item.echartData">
  64. <eChartTemplate :ref="`eChartViewRef-${index}`" :data="item.echartData" v-if="!item.loading" />
  65. </div>
  66. <div class="loadingDiv" v-if="item.loading">
  67. <span>小可努力生成中,请稍等片刻</span>
  68. <img :src="loadingImg" class="loadingImg" />
  69. </div>
  70. </div>
  71. <div
  72. class="ai_btn_box"
  73. v-if="!pan(item.aiContent).length && !item.loading"
  74. >
  75. <!-- <div class="popoverBox" v-if="item.uid.length > 0">
  76. <div
  77. class="showBox"
  78. v-if="showPopoverUid === item.uid"
  79. v-click-outside="handleBlur"
  80. >
  81. <span @click="generateChart(item, 0)">柱状图</span>
  82. <span @click="generateChart(item, 1)">折线图</span>
  83. <span @click="generateChart(item, 2)">圆饼图</span>
  84. </div>
  85. <div
  86. class="btnBox"
  87. @click.stop="
  88. showPopoverUid === item.uid
  89. ? (showPopoverUid = null)
  90. : (showPopoverUid = item.uid)
  91. "
  92. >
  93. <img
  94. src="https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/default%2F%E5%9B%BE%E8%A1%A81735027853698.png"
  95. />
  96. </div>
  97. </div> -->
  98. <img
  99. src="../../../../assets/icon/course/pasete.png"
  100. @click="onCopy(item.aiContent,index)"
  101. />
  102. <!-- <img src="../../../../assets/icon/test/test_bianji.png" v-if="index >= 2" @click="edit(index)" /> -->
  103. </div>
  104. </div>
  105. <div
  106. style="margin-top:20px;margin-bottom:20px ; margin-right: auto;"
  107. v-if="item.content === 0"
  108. >
  109. <div class="role">
  110. <img
  111. :src="
  112. item.fileid
  113. ? item.fileid
  114. : require('../../../../assets/icon/new/role1.png')
  115. "
  116. />
  117. </div>
  118. <div
  119. element-loading-background="#f6f9ff"
  120. :style="{
  121. minHeight: item.loading ? '50px' : 'unset',
  122. minWidth: item.loading ? '50px' : 'unset'
  123. }"
  124. class="content"
  125. >
  126. <div v-if="getWangLoading" class="loadingDiv">
  127. <span>小可努力生成中,请稍等片刻</span>
  128. <img :src="loadingImg" class="loadingImg" />
  129. </div>
  130. <div v-else>
  131. <div class="guess_title">
  132. <img
  133. :src="require('../../../../assets/icon/course/idea.png')"
  134. />
  135. <span>猜你想问:</span>
  136. </div>
  137. <div
  138. class="guess_item"
  139. v-for="item in item.aiContent"
  140. :key="item.index"
  141. @click="copyText(item.label)"
  142. >
  143. {{ item.label }}
  144. </div>
  145. <span class="createTime" v-text="item.createtime"></span>
  146. </div>
  147. </div>
  148. </div>
  149. </div>
  150. <!-- 这里添加两个自定义 div -->
  151. <div
  152. v-if="fileList.length == 0"
  153. style="display: flex;
  154. justify-content: center;"
  155. >
  156. <div
  157. :class="['custom-div', { active: btnactive === 1 }]"
  158. @click="localTable()"
  159. >
  160. <p style="margin: 12px 0px 19px -23px;">从表单中选择</p>
  161. <span class="custom-icon"></span>
  162. </div>
  163. <div
  164. :class="['custom-div', { active: btnactive === 2 }]"
  165. @click="triggerFileInput()"
  166. >
  167. <p style="margin: 12px 0px 19px -54px;">本地上传</p>
  168. <span class="custom-icon"></span>
  169. </div>
  170. <input
  171. type="file"
  172. multiple="multiple"
  173. ref="fileInput"
  174. @change="beforeUploadInfo2"
  175. style="display: none;"
  176. />
  177. </div>
  178. <!-- 查看数据来源 -->
  179. <el-dialog
  180. title="教师管理"
  181. :visible.sync="dialogTableVisible"
  182. :modal="true"
  183. append-to-body
  184. :before-close="handleClose"
  185. class="dialog_diy"
  186. custom-class="dialog_diy"
  187. >
  188. <div class="dialog_contentArea">
  189. <div class="student_head">
  190. <div class="choose">
  191. <div class="student_search">
  192. <el-select
  193. v-model="typeCheck"
  194. placeholder="请选择类型"
  195. clearable
  196. @change="search"
  197. >
  198. <el-option
  199. v-for="(item, index) in typeArray"
  200. :key="index"
  201. :label="item.name"
  202. :value="item.id"
  203. ></el-option>
  204. </el-select>
  205. </div>
  206. <div class="student_search" style="width:100px" v-if="stype == 1">
  207. <el-select v-model="groupA" @change="search">
  208. <el-option value="0" label="我的"></el-option>
  209. <el-option value="2" label="他人"></el-option>
  210. <el-option value="4" label="所有人"></el-option>
  211. </el-select>
  212. </div>
  213. </div>
  214. <div class="student_right">
  215. <div class="head_left">
  216. <div style="margin-right: 10px;position: relative;">
  217. <el-input
  218. v-model="courseName"
  219. class="student_input"
  220. placeholder="请输入项目名称"
  221. ></el-input>
  222. <span class="serach_icon" @click="searchCourse"></span>
  223. </div>
  224. </div>
  225. </div>
  226. </div>
  227. <el-table
  228. ref="table"
  229. :data="course"
  230. border
  231. :key="1"
  232. :header-cell-style="{
  233. color: '#00000066',
  234. fontSize: '16px',
  235. fontWeight: 'unset'
  236. }"
  237. :row-class-name="tableRowClassName2"
  238. v-if="stype == 1"
  239. class="tableClass"
  240. v-loading="isLoading"
  241. >
  242. <el-table-column
  243. type="selection"
  244. :selectable="selectable"
  245. width="55"
  246. ></el-table-column>
  247. <el-table-column label="序号" width="100px" align="center">
  248. <template slot-scope="scope">
  249. {{ scope.$index + 1 }}
  250. </template>
  251. </el-table-column>
  252. <el-table-column
  253. prop="title"
  254. label="问卷名称"
  255. min-width="150"
  256. align="center"
  257. >
  258. </el-table-column>
  259. <el-table-column
  260. prop="uname"
  261. label="创建者"
  262. min-width="80"
  263. align="center"
  264. >
  265. </el-table-column>
  266. <el-table-column
  267. v-if="typeArray.length"
  268. prop="typeN"
  269. label="问卷类型"
  270. min-width="80"
  271. align="center"
  272. >
  273. <template slot-scope="scope">
  274. {{ scope.row.typeN ? scope.row.typeN : "未设置类型" }}
  275. </template>
  276. </el-table-column>
  277. <el-table-column
  278. prop="worksCount"
  279. label="已提交数量"
  280. min-width="80"
  281. align="center"
  282. >
  283. </el-table-column>
  284. <el-table-column label="表单状态" min-width="80" align="center">
  285. <template slot-scope="scope">
  286. <div
  287. class="test_type2"
  288. style="width: fit-content;margin: 0 auto;"
  289. :class="getLookType(scope.row)"
  290. >
  291. <span>{{ getLook(scope.row) }}</span>
  292. </div>
  293. </template>
  294. </el-table-column>
  295. </el-table>
  296. <!-- 遮罩层 -->
  297. <div v-if="isLoading2" class="mask"></div>
  298. <div v-if="isLoading2" class="loadingDiv2">
  299. <span>小可努力生成中,请稍等片刻</span>
  300. <img :src="loadingImg" class="loadingImg" />
  301. </div>
  302. </div>
  303. <div class="student_bottom">
  304. <div class="pageCount">
  305. <span>共{{ course.length }}条</span>
  306. <el-pagination
  307. background
  308. layout="prev, pager, next"
  309. :page-size="pageSize"
  310. :current-page="page"
  311. :total="total"
  312. @current-change="handleCurrentChange"
  313. ></el-pagination>
  314. </div>
  315. <el-button type="primary" @click="confirmSelection">确认</el-button>
  316. </div>
  317. </el-dialog>
  318. </div>
  319. <div class="ai_body_select" v-if="false">
  320. <div class="checkBox" v-if="checkBool">
  321. <div class="task">
  322. <div class="title">选择需要优化的任务:</div>
  323. <div class="content">
  324. <div class="span" @click="addAllTask()">
  325. <div class="check">
  326. <img
  327. :src="checkImg"
  328. alt=""
  329. v-if="checkArray.length !== course.length"
  330. />
  331. <img :src="checkIsImg" alt="" v-else />
  332. </div>
  333. <span>全选</span>
  334. </div>
  335. <div
  336. class="span"
  337. v-for="(item, index) in course"
  338. :key="index"
  339. @click="addTask(index)"
  340. >
  341. <div class="check">
  342. <img
  343. :src="checkImg"
  344. alt=""
  345. v-if="checkArray.indexOf(index) === -1"
  346. />
  347. <img :src="checkIsImg" alt="" v-else />
  348. </div>
  349. <span>任务{{ index + 1 }}</span>
  350. </div>
  351. </div>
  352. </div>
  353. <div class="part">
  354. <div class="title">选择优化的部分:</div>
  355. <div class="content">
  356. <div
  357. class="span"
  358. v-for="(item, index) in partArray"
  359. :key="index"
  360. :class="{ active: part == item.name }"
  361. @click="checkPart(item.name)"
  362. >
  363. {{ item.name }}
  364. </div>
  365. </div>
  366. </div>
  367. </div>
  368. <span
  369. class="check"
  370. :class="{ isCheck: checkBool }"
  371. v-if="!checkArray.length && !part"
  372. @click="checkBool = !checkBool"
  373. >选择优化内容</span
  374. >
  375. <span
  376. class="check"
  377. :class="{ isCheck: checkBool }"
  378. @click="checkBool = !checkBool"
  379. v-else
  380. >
  381. <el-tooltip :content="taskName" placement="top" effect="dark">
  382. <!-- content to trigger tooltip here -->
  383. <span>{{ taskName }}</span>
  384. </el-tooltip>
  385. </span>
  386. </div>
  387. <div class="ai_body_input">
  388. <div class="ai_b_i_btnArea">
  389. <span class="clear" @click.stop="clear()">
  390. <svg
  391. width="20"
  392. height="20"
  393. viewBox="0 0 20 20"
  394. fill="none"
  395. xmlns="http://www.w3.org/2000/svg"
  396. >
  397. <path
  398. fill-rule="evenodd"
  399. clip-rule="evenodd"
  400. d="M2.5 3.125C2.5 2.77982 2.77982 2.5 3.125 2.5H16.875C17.2202 2.5 17.5 2.77982 17.5 3.125V8.02715C17.5 8.37233 17.2202 8.65215 16.875 8.65215C16.5298 8.65215 16.25 8.37233 16.25 8.02715V3.75H3.75V16.25H8.125C8.47018 16.25 8.75 16.5298 8.75 16.875C8.75 17.2202 8.47018 17.5 8.125 17.5H3.125C2.77982 17.5 2.5 17.2202 2.5 16.875V3.125Z"
  401. />
  402. <path
  403. fill-rule="evenodd"
  404. clip-rule="evenodd"
  405. d="M5.625 6.1521C5.625 5.80692 5.90482 5.5271 6.25 5.5271H13.125C13.4702 5.5271 13.75 5.80692 13.75 6.1521C13.75 6.49728 13.4702 6.7771 13.125 6.7771H6.25C5.90482 6.7771 5.625 6.49728 5.625 6.1521Z"
  406. />
  407. <path
  408. fill-rule="evenodd"
  409. clip-rule="evenodd"
  410. d="M5.625 9.2771C5.625 8.93192 5.90482 8.6521 6.25 8.6521H9.37496C9.72014 8.6521 9.99996 8.93192 9.99996 9.2771C9.99996 9.62228 9.72014 9.9021 9.37496 9.9021H6.25C5.90482 9.9021 5.625 9.62228 5.625 9.2771Z"
  411. />
  412. <path
  413. fill-rule="evenodd"
  414. clip-rule="evenodd"
  415. d="M12.465 11.507L15.9141 14.9048C16.1279 14.5365 16.25 14.1088 16.25 13.6521C16.25 12.2714 15.1307 11.1521 13.75 11.1521C13.2799 11.1521 12.8406 11.2815 12.465 11.507ZM15.0374 15.7957L11.5873 12.397C11.3726 12.7659 11.25 13.1944 11.25 13.6521C11.25 15.0328 12.3693 16.1521 13.75 16.1521C14.2211 16.1521 14.6613 16.0222 15.0374 15.7957ZM11.0797 11.0192C11.759 10.3303 12.7051 9.9021 13.75 9.9021C15.8211 9.9021 17.5 11.581 17.5 13.6521C17.5 14.6767 17.0882 15.6064 16.4226 16.2827C15.7431 16.9729 14.7961 17.4021 13.75 17.4021C11.6789 17.4021 10 15.7232 10 13.6521C10 12.6263 10.4127 11.6957 11.0797 11.0192Z"
  416. />
  417. </svg>
  418. <span>清屏</span>
  419. </span>
  420. <span
  421. class="clear"
  422. @click.stop="showjList = !showjList"
  423. v-if="jArray.length"
  424. >
  425. <span>查看</span>
  426. </span>
  427. <!-- <div style="margin-left: auto;">
  428. <el-switch v-model="continuous"></el-switch>
  429. <span @click.stop="continuous = !continuous">连续对话</span>
  430. </div> -->
  431. </div>
  432. <div
  433. class="ai_b_i_roleListBox"
  434. ref="roleListRef"
  435. v-if="showRoleList && choseRoleList.length > 0"
  436. >
  437. <div
  438. :class="[
  439. 'ai_b_i_rlb_item',
  440. index == choseRoleItem ? 'ai_b_i_rlb_itemActive' : ''
  441. ]"
  442. :ref="`roleItem${index}Ref`"
  443. v-for="(item, index) in choseRoleList"
  444. :key="item.id"
  445. @mouseover="choseRoleItem = index"
  446. @click.stop="choseRole(item)"
  447. >
  448. <div class="ai_b_i_rlb_itemTop">
  449. <img
  450. :src="
  451. item.headUrl
  452. ? item.headUrl
  453. : require('../../../../assets/icon/new/role1.png')
  454. "
  455. alt=""
  456. />
  457. <div class="ai_b_i_rlb_i_name">
  458. <span>{{ item.assistantName }}</span>
  459. <span>作者:{{ item.username }}</span>
  460. </div>
  461. </div>
  462. <div class="ai_b_i_rlb_itemBottom">
  463. {{ item.prologue }}
  464. </div>
  465. </div>
  466. </div>
  467. <!-- <div class="ai_b_i_textListBox">
  468. <div class="ai_b_i_tlb_left"></div>
  469. <div class="ai_b_i_tlb_right"></div>
  470. </div> -->
  471. <!-- @input="inputChange" -->
  472. <textarea
  473. @input="inputChange"
  474. class="ai_body_input_textarea"
  475. @keydown="textareaKeydown"
  476. :disabled="isVoice"
  477. ref="textareaRef"
  478. v-model.trim="courseText"
  479. :placeholder="
  480. isVoice
  481. ? isTalk
  482. ? ''
  483. : '点击按钮开始录音'
  484. : '在此输入您想了解的内容'
  485. "
  486. ></textarea>
  487. <span
  488. class="c_voiceBtn"
  489. v-if="!courseText && !isVoice"
  490. @click.stop="changeVoice(true)"
  491. >
  492. <svg
  493. width="22"
  494. height="22"
  495. viewBox="0 0 22 22"
  496. fill="none"
  497. xmlns="http://www.w3.org/2000/svg"
  498. >
  499. <path
  500. fill-rule="evenodd"
  501. clip-rule="evenodd"
  502. d="M11.4583 14.0308C13.8381 14.0308 15.7551 12.0651 15.7551 9.62496V6.23588C15.7551 3.79574 13.8381 1.83008 11.4583 1.83008C9.07845 1.83008 7.16138 3.79574 7.16138 6.23588V9.62496C7.16138 12.0651 9.07845 14.0308 11.4583 14.0308ZM8.4835 6.23588C8.4835 4.54134 9.80561 3.18571 11.4583 3.18571C13.1109 3.18571 14.433 4.54134 14.433 6.23588V9.62496C14.433 11.3195 13.1109 12.6751 11.4583 12.6751C9.80561 12.6751 8.4835 11.3195 8.4835 9.62496V6.23588ZM18.3333 10.6405C18.3333 10.2677 18.0358 9.96264 17.6722 9.96264C17.3417 9.96264 17.0442 10.2338 17.0111 10.5727C16.5484 13.3178 14.2347 15.3852 11.4583 15.3852C8.68181 15.3852 6.36811 13.3178 5.90537 10.5727C5.87231 10.2338 5.57484 9.96264 5.24431 9.96264C4.88073 9.96264 4.58325 10.2677 4.58325 10.6405V10.7421C5.1121 13.9279 7.65717 16.4019 10.7972 16.7069V19.635H7.93254C7.54315 19.635 7.22748 19.9587 7.22748 20.358C7.22748 20.7572 7.54315 21.0809 7.93254 21.0809H14.9832C15.3726 21.0809 15.6883 20.7572 15.6883 20.358C15.6883 19.9587 15.3726 19.635 14.9832 19.635H12.1193V16.7069C15.2593 16.4019 17.8044 13.9279 18.3002 10.776C18.3002 10.7591 18.3085 10.7337 18.3167 10.7082L18.3167 10.7082L18.3167 10.7082C18.325 10.6828 18.3333 10.6574 18.3333 10.6405Z"
  503. fill="black"
  504. fill-opacity="0.9"
  505. />
  506. </svg>
  507. </span>
  508. <span
  509. class="c_voiceBtn"
  510. style="right: 70px;"
  511. v-if="!courseText && isVoice && !isTalk"
  512. @click.stop="changeVoice(false)"
  513. >
  514. <svg
  515. width="22"
  516. height="22"
  517. viewBox="0 0 22 22"
  518. fill="none"
  519. xmlns="http://www.w3.org/2000/svg"
  520. >
  521. <path
  522. fill-rule="evenodd"
  523. clip-rule="evenodd"
  524. d="M2.75 3.4375C2.75 3.0578 3.0578 2.75 3.4375 2.75H18.5625C18.9422 2.75 19.25 3.0578 19.25 3.4375V18.5625C19.25 18.9422 18.9422 19.25 18.5625 19.25H3.4375C3.0578 19.25 2.75 18.9422 2.75 18.5625V3.4375ZM4.125 4.125V17.875H17.875V4.125H4.125Z"
  525. fill="black"
  526. fill-opacity="0.9"
  527. />
  528. <path
  529. fill-rule="evenodd"
  530. clip-rule="evenodd"
  531. d="M6.875 6.875C6.875 6.4953 7.1828 6.1875 7.5625 6.1875H14.4375C14.8172 6.1875 15.125 6.4953 15.125 6.875V8.25C15.125 8.6297 14.8172 8.9375 14.4375 8.9375C14.0578 8.9375 13.75 8.6297 13.75 8.25V7.5625H11.6875V14.4375H12.375C12.7547 14.4375 13.0625 14.7453 13.0625 15.125C13.0625 15.5047 12.7547 15.8125 12.375 15.8125H9.625C9.2453 15.8125 8.9375 15.5047 8.9375 15.125C8.9375 14.7453 9.2453 14.4375 9.625 14.4375H10.3125V7.5625H8.25V8.25C8.25 8.6297 7.9422 8.9375 7.5625 8.9375C7.1828 8.9375 6.875 8.6297 6.875 8.25V6.875Z"
  532. fill="black"
  533. fill-opacity="0.9"
  534. />
  535. </svg>
  536. </span>
  537. <div
  538. :class="[
  539. 'c_pub_button_confirm',
  540. courseText ? '' : 'c_pub_button_confirmDisabled'
  541. ]"
  542. v-if="!curRequestController && !isVoice"
  543. @click="addContent"
  544. >
  545. 发送
  546. </div>
  547. <div
  548. :class="['c_pub_button_confirmVoice']"
  549. v-if="!faloading && isVoice && !isTalk"
  550. @click="startVoice"
  551. >
  552. <svg
  553. width="22"
  554. height="22"
  555. viewBox="0 0 22 22"
  556. fill="none"
  557. xmlns="http://www.w3.org/2000/svg"
  558. >
  559. <path
  560. fill-rule="evenodd"
  561. clip-rule="evenodd"
  562. d="M11.4583 14.0308C13.8381 14.0308 15.7551 12.0651 15.7551 9.62496V6.23588C15.7551 3.79574 13.8381 1.83008 11.4583 1.83008C9.07845 1.83008 7.16138 3.79574 7.16138 6.23588V9.62496C7.16138 12.0651 9.07845 14.0308 11.4583 14.0308ZM8.4835 6.23588C8.4835 4.54134 9.80561 3.18571 11.4583 3.18571C13.1109 3.18571 14.433 4.54134 14.433 6.23588V9.62496C14.433 11.3195 13.1109 12.6751 11.4583 12.6751C9.80561 12.6751 8.4835 11.3195 8.4835 9.62496V6.23588ZM18.3333 10.6405C18.3333 10.2677 18.0358 9.96264 17.6722 9.96264C17.3417 9.96264 17.0442 10.2338 17.0111 10.5727C16.5484 13.3178 14.2347 15.3852 11.4583 15.3852C8.68181 15.3852 6.36811 13.3178 5.90537 10.5727C5.87231 10.2338 5.57484 9.96264 5.24431 9.96264C4.88073 9.96264 4.58325 10.2677 4.58325 10.6405V10.7421C5.1121 13.9279 7.65717 16.4019 10.7972 16.7069V19.635H7.93254C7.54315 19.635 7.22748 19.9587 7.22748 20.358C7.22748 20.7572 7.54315 21.0809 7.93254 21.0809H14.9832C15.3726 21.0809 15.6883 20.7572 15.6883 20.358C15.6883 19.9587 15.3726 19.635 14.9832 19.635H12.1193V16.7069C15.2593 16.4019 17.8044 13.9279 18.3002 10.776C18.3002 10.7591 18.3085 10.7337 18.3167 10.7082L18.3167 10.7082L18.3167 10.7082C18.325 10.6828 18.3333 10.6574 18.3333 10.6405Z"
  563. fill-opacity="0.9"
  564. />
  565. </svg>
  566. </div>
  567. <div
  568. :class="['c_pub_button_StopConfirmVoice']"
  569. v-if="!faloading && isVoice && isTalk"
  570. @click="stopVoice"
  571. >
  572. <svg
  573. width="22"
  574. height="22"
  575. viewBox="0 0 22 22"
  576. fill="none"
  577. xmlns="http://www.w3.org/2000/svg"
  578. >
  579. <path
  580. d="M11 19.25C6.4625 19.25 2.75 15.5375 2.75 11C2.75 6.4625 6.4625 2.75 11 2.75C15.5375 2.75 19.25 6.4625 19.25 11C19.25 15.5375 15.5375 19.25 11 19.25ZM11 17.1875C14.4031 17.1875 17.1875 14.4031 17.1875 11C17.1875 7.59687 14.4031 4.8125 11 4.8125C7.59687 4.8125 4.8125 7.59687 4.8125 11C4.8125 14.4031 7.59687 17.1875 11 17.1875Z"
  581. fill="#EE3E3E"
  582. />
  583. <path
  584. d="M12.75 8.25H9.25C8.69772 8.25 8.25 8.69772 8.25 9.25V12.75C8.25 13.3023 8.69772 13.75 9.25 13.75H12.75C13.3023 13.75 13.75 13.3023 13.75 12.75V9.25C13.75 8.69772 13.3023 8.25 12.75 8.25Z"
  585. fill="#EE3E3E"
  586. />
  587. </svg>
  588. </div>
  589. <div v-if="!faloading && isVoice"></div>
  590. <div
  591. class="c_pub_button_confirm"
  592. v-if="curRequestController"
  593. @click="stopCurRequestController"
  594. >
  595. 终止
  596. </div>
  597. </div>
  598. <iframe
  599. allow="camera *; microphone *;display-capture;midi;encrypted-media;"
  600. src="https://beta.cloud.cocorobo.cn/browser/public/index.html"
  601. ref="iiframe"
  602. v-show="false"
  603. ></iframe>
  604. <!-- <div class="ai_body_input">
  605. <textarea
  606. style="padding-right: 85px;"
  607. rows="3"
  608. @keyup.enter="addContent"
  609. class="binfo_input binfo_textarea"
  610. cols
  611. v-model.trim="courseText"
  612. placeholder="在此输入您想了解的内容"
  613. ></textarea>
  614. <div
  615. class="c_pub_button_confirm"
  616. v-if="!loading && courseText"
  617. @click="addContent"
  618. >
  619. 发送
  620. </div>
  621. <div class="c_pub_button_confirm" @click="promptTit" v-else>发送</div>
  622. </div> -->
  623. </div>
  624. </template>
  625. <script>
  626. import checkImg from "../../../../assets/icon/sourceFile/check.png";
  627. import checkIsImg from "../../../../assets/icon/sourceFile/check_is.png";
  628. import { v4 as uuidv4 } from "uuid";
  629. import MarkdownIt from "markdown-it";
  630. import TurndownService from "turndown";
  631. import eChartTemplate from "./eChartTemplate.vue";
  632. const OpenCC = require("opencc-js");
  633. let converter = OpenCC.Converter({
  634. from: "cn",
  635. to: "hk"
  636. });
  637. import { fetchEventSource } from "@microsoft/fetch-event-source";
  638. const clickOutside = {
  639. bind(el, binding) {
  640. // 在元素上绑定一个点击事件监听器
  641. el.clickOutsideEvent = function(event) {
  642. // 检查点击事件是否发生在元素的内部
  643. if (!(el === event.target || el.contains(event.target))) {
  644. // 如果点击事件发生在元素的外部,则触发指令绑定的方法,将点击的event数据传过去
  645. binding.value(event);
  646. }
  647. };
  648. // 在文档上添加点击事件监听器
  649. document.addEventListener("click", el.clickOutsideEvent);
  650. },
  651. unbind(el) {
  652. // 在元素上解除点击事件监听器
  653. document.removeEventListener("click", el.clickOutsideEvent);
  654. }
  655. };
  656. export default {
  657. components: {
  658. eChartTemplate
  659. },
  660. props: {
  661. courseId: {
  662. type: String,
  663. default: ""
  664. },
  665. formList: {
  666. type: Array
  667. }
  668. },
  669. directives: {
  670. "click-outside": clickOutside // 注册自定义指令
  671. },
  672. data() {
  673. return {
  674. stype: 1,
  675. typeArray: [],
  676. array: [],
  677. jArray: [],
  678. course: [],
  679. loadingImg: require("../../../../assets/KekeLoading.gif"),
  680. courseText: "",
  681. checkImg: checkImg,
  682. checkIsImg: checkIsImg,
  683. userid: this.$route.query.userid,
  684. oid: this.$route.query.oid,
  685. org: this.$route.query.org,
  686. role: this.$route.query.role,
  687. isLoading: false,
  688. isLoading2: false,
  689. checkArray: [],
  690. partArray: [
  691. { name: "全部内容" },
  692. { name: "任务设计" },
  693. { name: "评价设计" }
  694. ],
  695. part: "全部内容",
  696. checkBool: false,
  697. loading: false,
  698. pageSize: 10,
  699. page: 1,
  700. total: 0,
  701. selectedForms: [],
  702. textareaHeight: 50,
  703. publicRoleList: [],
  704. roleList: [],
  705. page2: 1,
  706. textList: [
  707. {
  708. title: "项目式学习",
  709. dataList: [
  710. "请给我一些学生开展项目式学习可以使用的主题或问题参考,请说出学生将要解决的问题,以及学生要经历怎样的学习活动。",
  711. "请将一个关于生态保护项目的项目式学习展开描述,你需要描述学生如何解决这个问题,你需要至少写出四个活动,这些活动需要按照前后逻辑关系排列。",
  712. "请对驱动问题为“如何为学校建造一个富有特色的花坛?”的项目式学习进行子问题拆解,至少拆解为5个子问题,并根据子问题对应写出各环节的主要活动。"
  713. ]
  714. },
  715. {
  716. title: "教学评价",
  717. dataList: [
  718. "如果需要给学生的社区服务进行评价,给出评价维度和至少3个等级的表现描述。",
  719. "为6年级学生设计一份关于梧桐山研究报告的评估任务表,并给出参考的报告流程,至少包含8个步骤,并包括地图、图片和至少300个词。",
  720. "创建一个给5年级学生使用的课堂小测试,包含5道多选题,评价学生对于太阳能这个概念的理解。你需要给出题目和正确答案。"
  721. ]
  722. },
  723. {
  724. title: "教学设计",
  725. dataList: [
  726. "如果需要5年级学生感受“移步换景”的景观写作手法,你有什么合适的阅读材料推荐?你需要给出材料名称,以及材料的哪部分内容。",
  727. "设计一个针对8年级学生且关于人类迁徙主题的地理课,并在课程中设计至少1项小组活动。",
  728. "设计一个针对5年级学生的课程,课程综合科学和信息技术领域,解决生物与环境领域的生活问题,你需要给出完整的课程框架和活动。",
  729. "如果3年级的学生不能理解光合作用的实现过程,需要你帮我设计一个支持他们理解的教学活动,需要包含活动的形式、实施材料和清单。",
  730. "请基于贝叶斯定理为8年级学生出三道题目。",
  731. "如果需要八年级学生了解尼罗河流域的文化发展史,你有哪些推荐的网站或参考书籍?"
  732. ]
  733. },
  734. {
  735. title: "班级管理",
  736. dataList: [
  737. "创建一组给一年级学生使用的班级口号,要求大家注意卫生、保护环境,口号需要对仗工整,符合一年级学生的理解水平。",
  738. " 设计一套用于6年级学生的班级管理规章制度,内容需要包括学习、纪律、卫生、思想品德方面。"
  739. ]
  740. },
  741. {
  742. title: "课堂组织",
  743. dataList: [
  744. "请为“制作垃圾分类宣传单”的小组活动设计小组分工表,每个小组的成员为4-6人。",
  745. "请给5年级“校园植物图鉴”社团课程设计一份小组合作公约,需包含小组成员信息、小组项目目标、填写日期,总长度不超过300字,并且提供至少3处学生自行填写的部分。",
  746. "请用苏格拉底提问的方式,引导5年级学生拆解驱动问题:如何解决教室黑板反光的问题?其中需包含对于反光原因的分析与实验探究。"
  747. ]
  748. },
  749. {
  750. title: "教师发展",
  751. dataList: [
  752. "教师需要理解项目式学习的理论基础和基础概念,你需要生成一份阅读清单,要求内容为中文书籍或文献。",
  753. "设计一个教师进行个人学期总结的框架,需要体现在教学、教研、个人学习方面的进步。"
  754. ]
  755. },
  756. {
  757. title: "代码分析",
  758. dataList: [
  759. "这段代码实现了什么效果?",
  760. "请描述这段代码。",
  761. "根据这段代码,给我一些修改意见。"
  762. ]
  763. }
  764. ],
  765. showTextList: false,
  766. showRoleList: false,
  767. choseRoleItem: 0,
  768. choseTextItem: 0,
  769. continuous: true,
  770. showjList: false,
  771. faloading: false,
  772. fasource: null,
  773. // aiText: "",
  774. saveUid: "",
  775. isVoice: false,
  776. isTalk: false,
  777. languageSetting: 0,
  778. username: "",
  779. options2: {
  780. 1: "选择题",
  781. // 2: "问答题",
  782. 3: "问答题",
  783. 4: "添加文档",
  784. 5: "附件",
  785. 6: "课程",
  786. 7: "评分",
  787. 8: "日期",
  788. 9: "单选题",
  789. 10: "多选题",
  790. 11: "课程"
  791. },
  792. answerArray: [],
  793. fileList: [],
  794. chatList: [],
  795. fileId: [],
  796. btnactive: null,
  797. dialogTableVisible: false,
  798. typeCheck: "",
  799. groupA: "0",
  800. courseName: "",
  801. cid: "",
  802. formId: "",
  803. courseInfoList: [],
  804. worksArray: [],
  805. copyWorksArray: null,
  806. stopTalkToken: false,
  807. getWangLoading: false,
  808. wangData: [],
  809. canUseWangData: true,
  810. hasGeneratedGuess: false,
  811. showPopoverUid: null,
  812. curRequestController:null,
  813. };
  814. },
  815. watch: {
  816. // worksArray: {
  817. // immediate: false,
  818. // deep: true,
  819. // handler(newValue, oldValue) {
  820. // if (
  821. // newValue.length &&
  822. // JSON.stringify(newValue) !== this.copyWorksArray
  823. // ) {
  824. // this.$emit("clearFileData");
  825. // this.fileId = [];
  826. // this.fileList = [];
  827. // this.copyWorksArray = JSON.stringify(newValue);
  828. // newValue.forEach(el => {
  829. // // console.log("👉el",el)
  830. // this.setJson(el);
  831. // });
  832. // // console.log("👈👉",newValue)
  833. // // this.setJson(newValue)
  834. // }
  835. // }
  836. // }
  837. },
  838. methods: {
  839. delFileList(index) {
  840. this.fileList.splice(index, 1);
  841. },
  842. handleCurrentChange(newPage) {
  843. this.page = newPage;
  844. this.getCourse();
  845. },
  846. selectable(row, index) {
  847. return row.worksCount > 0;
  848. },
  849. async confirmSelection() {
  850. // 获取用户选择的表单
  851. const selectedForms = this.$refs.table.selection; // 获取选中的行
  852. console.log("用户选择的表单:", selectedForms); // 打印用户选择的表单
  853. // this.cid = selectedForms.reduce((lastArr, item) => {
  854. // lastArr.push(item.courseId);
  855. // return lastArr
  856. // }, []).join(',');
  857. this.cid = selectedForms.map(i => i.courseId).join(",");
  858. const names = selectedForms.map(item => item.title).join(",");
  859. console.log(names);
  860. this.formId = selectedForms.map(i => i.courseId).join(",");
  861. console.log("cid", this.cid);
  862. let _fileValue = await this.getData(this.cid);
  863. this.isLoading = true;
  864. this.isLoading2 = true;
  865. await this.getChatList(this.cid);
  866. this.$nextTick(() => {
  867. this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
  868. });
  869. this.guessAskJson(_fileValue);
  870. this.addChat(names);
  871. setTimeout(() => {
  872. this.dialogTableVisible = false;
  873. this.isLoading = false;
  874. this.isLoading2 = false;
  875. }, 500);
  876. // this.getChatList()
  877. },
  878. handleClose(done) {
  879. done();
  880. },
  881. triggerFileInput() {
  882. this.btnactive = 2;
  883. this.guessAskJson();
  884. this.$refs.fileInput.click();
  885. },
  886. // 处理文件选择
  887. handleFileChange(event) {
  888. const file = event.target.files[0];
  889. if (file) {
  890. // 这里可以添加文件处理逻辑,例如上传文件
  891. console.log("选择的文件:", file.name);
  892. }
  893. },
  894. async addChat(names) {
  895. return new Promise(async(resolve)=>{
  896. let _uid = uuidv4();
  897. let cid = `${_uid}-testSmarter`; // 生成的 cid
  898. this.cid = cid;
  899. let params = [
  900. {
  901. uid: this.userid,
  902. name: names,
  903. cid: cid,
  904. j: this.localFormList
  905. }
  906. ];
  907. try {
  908. const res = await this.ajax.post(
  909. this.$store.state.api + "addChat",
  910. params
  911. );
  912. resolve()
  913. } catch (err) {
  914. console.error(err);
  915. }
  916. })
  917. },
  918. async guessAskJson(fileData) {
  919. console.log("👉👉👈", fileData);
  920. const names = this.worksArray.map(item => item.name).join(", ");
  921. console.log("获取猜你想搜", names);
  922. let _uid = uuidv4();
  923. this.getWangLoading = true;
  924. this.canUseWangData = false;
  925. this.wangData = "";
  926. let fileText = ``;
  927. fileData.forEach(i => {
  928. fileText += `表单名称:${i.filename}
  929. 表单内容:
  930. ${i.content}
  931. `;
  932. });
  933. let _msg = `Language: ${this.getLang()} ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example". Instruction: Based on the context, follow "Format example", write content
  934. ## 任务 你的任务是根据“表单信息”,提供用户需要的搜索建议,将搜索建议的结果以有序列表的形式返回给用户。
  935. ## 规则 输出结果基于“表单信息”,避免提供无关的信息。 搜索建议的结果符合伦理规范。
  936. ## 输出 输出应包括6个相关的搜索建议,每个搜索建议需要以问号的方式结束。 请一步步思考如何根据现有信息推送搜索建议,但是不需要输出搜索建议以外的内容。
  937. ## 输出格式 搜索建议应以有序列表形式呈现,每个建议包括关键词和简短描述。输出JSON格式的内容,不要有多余的内容。
  938. ## 表单信息
  939. ${fileText}
  940. ## Format example
  941. [{"index": 1,"title": "垃圾分类标准","label": "不同国家的垃圾分类标准和方法?"},{"index": 2,"title":"可回收垃圾处理","label": "可回收垃圾的处理流程和再利用方法?"},{ "index": 3, "title": "有害垃圾的影响", "label": "有害垃圾对环境和人体健康的潜在影响?"},{ "index": 4, "title": "垃圾分类标准", "label": "不同国家的垃圾分类标准和方法?"},{ "index": 5, "title": "可回收垃圾处理", "label": "可回收垃圾的处理流程和再利用方法?"},{ "index": 6, "title": "有害垃圾的影响", "label": "有害垃圾对环境和人体健康的潜在影响?"}]`;
  942. console.log(_msg);
  943. let params = {
  944. assistant_id: "6063369f-289a-11ef-8bf4-12e77c4cb76b",
  945. userId: this.userid,
  946. message: _msg,
  947. session_name: `${this.formId}-testSmarter`,
  948. // uid: _uuid,
  949. file_ids: this.fileId,
  950. model: "gpt-4o-2024-08-06"
  951. };
  952. this.array.push({
  953. loading: false,
  954. role: "user",
  955. content: 0,
  956. uid: _uid,
  957. AI: "AI",
  958. aiContent: "",
  959. oldContent: "",
  960. isShowSynchronization: false,
  961. filename: "",
  962. index: this.array.length,
  963. is_mind_map: false,
  964. fileid: "",
  965. createtime: new Date().toLocaleString().replaceAll("/", "-")
  966. });
  967. console.log(this.array);
  968. this.ajax
  969. // .post("https://gpt4.cocorobo.cn/chat", params)
  970. // .post("https://claude3.cocorobo.cn/chat", params)
  971. .post("https://gpt4.cocorobo.cn/ai_agent_park_chat", params)
  972. .then(res => {
  973. // console.log(res);
  974. let _data = res.data.FunctionResponse.message;
  975. _data = _data.replaceAll("```json", "").replaceAll("```", "");
  976. const match = _data.match(/\[\s*{[^]*}\s*\]/);
  977. // console.log("this.wangData",this.wangData);
  978. // console.log("match",match);
  979. this.wangData = JSON.parse(match[0]);
  980. this.canUseWangData = true;
  981. this.getWangLoading = false;
  982. console.log("wangData", this.wangData);
  983. this.array.find(i => i.uid == _uid).aiContent = JSON.parse(match[0]);
  984. })
  985. .catch(e => {
  986. this.chatLoading = false;
  987. this.canUseWangData = false;
  988. this.getWangLoading = false;
  989. console.log(e);
  990. });
  991. // this.getWAntSearchContent(_uuid);
  992. },
  993. beforeUploadInfo2(event, type, tindex) {
  994. // const loading = this.openLoading();
  995. let file = "";
  996. let fileNames = [];
  997. let cfindex2 = 0;
  998. for (var cfindex = 0; cfindex < event.target.files.length; cfindex++) {
  999. // var file = event.target.files[0];
  1000. file = event.target.files[cfindex];
  1001. let fileName = file.name;
  1002. let fileUid = file.uid;
  1003. fileNames.push(fileName);
  1004. var credentials = {
  1005. accessKeyId: "AKIATLPEDU37QV5CHLMH",
  1006. secretAccessKey: "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"
  1007. }; //秘钥形式的登录上传
  1008. window.AWS.config.update(credentials);
  1009. window.AWS.config.region = "cn-northwest-1"; //设置区域
  1010. var bucket = new window.AWS.S3({ params: { Bucket: "ccrb" } }); //选择桶
  1011. var _this = this;
  1012. var xianObj = ["CSV"];
  1013. if (
  1014. xianObj.indexOf(
  1015. file.name
  1016. .split(".")
  1017. [file.name.split(".").length - 1].toLocaleUpperCase()
  1018. ) == -1
  1019. ) {
  1020. this.$message.error("请上传.csv文件!");
  1021. this.inputShow = true;
  1022. // var a = _this.$refs.upload1.uploadFiles;
  1023. // a.splice(a.length - 1, a.length);
  1024. // loading.close();
  1025. return;
  1026. }
  1027. _this.$forceUpdate();
  1028. if (file) {
  1029. var params = {
  1030. Key:
  1031. file.name.split(".")[0] +
  1032. new Date().getTime() +
  1033. "." +
  1034. file.name.split(".")[file.name.split(".").length - 1],
  1035. ContentType: file.type,
  1036. Body: file,
  1037. "Access-Control-Allow-Credentials": "*",
  1038. ACL: "public-read"
  1039. }; //key可以设置为桶的相抵路径,Body为文件, ACL最好要设置
  1040. var options = {
  1041. partSize: 2048 * 1024 * 1024,
  1042. queueSize: 2,
  1043. leavePartsOnError: true
  1044. };
  1045. bucket
  1046. .upload(params, options)
  1047. .on("httpUploadProgress", function(evt) {
  1048. //这里可以写进度条
  1049. // console.log("Uploaded : " + parseInt((evt.loaded * 80) / evt.total) + '%');
  1050. // if(type == 14){
  1051. // _this.teacherinfoprogress = parseInt((evt.loaded / evt.total) * 100);
  1052. // _this.teacherinfoisFinishSize = (evt.loaded / 1024 / 1024).toFixed(2);
  1053. // }else if(type == 16){
  1054. // _this.mubiaoinfoprogress = parseInt((evt.loaded / evt.total) * 100);
  1055. // _this.mubiaoinfoisFinishSize = (evt.loaded / 1024 / 1024).toFixed(2);
  1056. // }else if(type == 17){
  1057. // _this.xuanzeinfoprogress = parseInt((evt.loaded / evt.total) * 100);
  1058. // _this.xuanzeinfoisFinishSize = (evt.loaded / 1024 / 1024).toFixed(2);
  1059. // }else if(type == 18){
  1060. // _this.pingjiainfoprogress[tindex] = parseInt((evt.loaded / evt.total) * 100);
  1061. // _this.pingjiainfoisFinishSize[tindex] = (evt.loaded / 1024 / 1024).toFixed(2);
  1062. // }else {
  1063. // _this.infoprogress = parseInt((evt.loaded / evt.total) * 100);
  1064. // _this.infoisFinishSize = (evt.loaded / 1024 / 1024).toFixed(2);
  1065. // }
  1066. _this.$forceUpdate();
  1067. })
  1068. .send(async function(err, data) {
  1069. // loading.close();
  1070. // if(type == 14){
  1071. // _this.teacherinfoprogress = 100;
  1072. // _this.teacherinfoisFinishSize = _this.teacherinfoisAllSize;
  1073. // }else if(type == 16){
  1074. // _this.mubiaoinfoprogress = 100;
  1075. // _this.mubiaoinfoisFinishSize = _this.mubiaoinfoisAllSize;
  1076. // }else if(type == 17){
  1077. // _this.xuanzeinfoprogress = 100;
  1078. // _this.xuanzeinfoisFinishSize = _this.xuanzeinfoisAllSize;
  1079. // }else if(type == 18){
  1080. // _this.pingjiainfoprogress[tindex] = 100;
  1081. // _this.pingjiainfoisFinishSize[tindex] = _this.pingjiainfoisAllSize[tindex];
  1082. // }else {
  1083. // _this.infoprogress = 100;
  1084. // _this.infoisFinishSize = _this.infoisAllSize;
  1085. // }
  1086. _this.$forceUpdate();
  1087. _this.inputShow = true;
  1088. if (err) {
  1089. console.error("上传失败:", err);
  1090. } else {
  1091. console.log("上传成功:", data);
  1092. _this.fileList.push(data.Location);
  1093. _this.$emit("pushFileData", {
  1094. fileId: "",
  1095. name: fileName,
  1096. url: data.Location
  1097. });
  1098. }
  1099. });
  1100. }
  1101. }
  1102. let allFileNames = fileNames.join("");
  1103. console.log("文件名拼接", allFileNames);
  1104. this.addChat(allFileNames);
  1105. },
  1106. selectTestType() {
  1107. this.isLoadingData = true;
  1108. let params = {
  1109. oid: this.oid
  1110. };
  1111. this.ajax
  1112. .get(this.$store.state.api + "selectTestType", params)
  1113. .then(res => {
  1114. this.typeArray = res.data[0];
  1115. this.getData();
  1116. })
  1117. .catch(err => {
  1118. console.error(err);
  1119. });
  1120. },
  1121. search() {
  1122. if (this.stype == 1) {
  1123. this.page = 1;
  1124. this.getCourse();
  1125. } else if (this.stype == 2) {
  1126. this.page2 = 1;
  1127. this.getCourse2();
  1128. }
  1129. },
  1130. searchCourse() {
  1131. if (this.stype == 1) {
  1132. this.page = 1;
  1133. this.getCourse();
  1134. } else if (this.stype == 2) {
  1135. this.page2 = 1;
  1136. this.getCourse2();
  1137. }
  1138. },
  1139. goToCourse2(item) {
  1140. if (item.worksCount > 0) {
  1141. this.$confirm(
  1142. "该表单已存在数据,如果修改题目可能会清空已提交数据,是否重新编辑?",
  1143. "提示",
  1144. {
  1145. confirmButtonText: "确定",
  1146. cancelButtonText: "取消",
  1147. type: "warning"
  1148. }
  1149. )
  1150. .then(() => {
  1151. this.$router.push(
  1152. "/addTest?cid=" +
  1153. item.courseId +
  1154. "&userid=" +
  1155. this.userid +
  1156. "&oid=" +
  1157. this.oid +
  1158. "&org=" +
  1159. this.org +
  1160. "&type=2" +
  1161. "&role=" +
  1162. this.role
  1163. );
  1164. })
  1165. .catch(() => {
  1166. return;
  1167. });
  1168. } else {
  1169. this.$router.push(
  1170. "/addTest?cid=" +
  1171. item.courseId +
  1172. "&userid=" +
  1173. this.userid +
  1174. "&oid=" +
  1175. this.oid +
  1176. "&org=" +
  1177. this.org +
  1178. "&type=2" +
  1179. "&role=" +
  1180. this.role
  1181. );
  1182. }
  1183. },
  1184. checkToTest(cid) {
  1185. this.$router.push(
  1186. "/checkToTest?cid=" +
  1187. cid +
  1188. "&userid=" +
  1189. this.userid +
  1190. "&oid=" +
  1191. this.oid +
  1192. "&org=" +
  1193. this.org +
  1194. "&type=2" +
  1195. "&role=" +
  1196. this.role
  1197. );
  1198. },
  1199. getCourse() {
  1200. this.isLoading = true;
  1201. let params = {
  1202. type: this.groupA,
  1203. uid: this.userid,
  1204. oid: this.oid,
  1205. org: this.org,
  1206. typea: "",
  1207. typeb: "",
  1208. typec: "",
  1209. typed: "",
  1210. typef: this.typeCheck,
  1211. typeE: "",
  1212. cu: "",
  1213. cn: this.courseName,
  1214. page: this.page,
  1215. pageSize: this.pageSize
  1216. };
  1217. this.ajax
  1218. .get(this.$store.state.api + "selectTesttCourse", params)
  1219. .then(res => {
  1220. console.log("API返回的数据", res.data);
  1221. this.total = res.data[0].length > 0 ? res.data[0][0].num : 0;
  1222. this.course = res.data[0];
  1223. for (var i = 0; i < this.course.length; i++) {
  1224. let a = "";
  1225. if (this.course[i].juriP) {
  1226. a = this.course[i].juriP;
  1227. }
  1228. if (this.course[i].juriP2) {
  1229. if (a) {
  1230. a = this.course[i].juriP + "," + this.course[i].juriP2;
  1231. } else {
  1232. a = this.course[i].juriP2;
  1233. }
  1234. }
  1235. this.course[i].juriP = a;
  1236. }
  1237. this.isLoading = false;
  1238. })
  1239. .catch(err => {
  1240. this.isLoading = false;
  1241. console.error(err);
  1242. });
  1243. },
  1244. shareTest(cid) {
  1245. this.scid = cid;
  1246. this.dialogVisibleShare = true;
  1247. },
  1248. localTable() {
  1249. this.btnactive = 1;
  1250. this.dialogTableVisible = true;
  1251. this.getCourse();
  1252. },
  1253. uploadFile({ file, name }) {
  1254. var credentials = {
  1255. accessKeyId: "AKIATLPEDU37QV5CHLMH",
  1256. secretAccessKey: "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"
  1257. }; //秘钥形式的登录上传
  1258. window.AWS.config.update(credentials);
  1259. window.AWS.config.region = "cn-northwest-1"; //设置区域
  1260. var bucket = new window.AWS.S3({ params: { Bucket: "ccrb" } }); //选择桶
  1261. var _this = this;
  1262. if (file) {
  1263. // this.loading = true;
  1264. var params = {
  1265. Key:
  1266. file.name.split(".")[0] +
  1267. new Date().getTime() +
  1268. "." +
  1269. file.name.split(".")[file.name.split(".").length - 1],
  1270. ContentType: file.type,
  1271. Body: file,
  1272. "Access-Control-Allow-Credentials": "*",
  1273. ACL: "public-read"
  1274. }; //key可以设置为桶的相抵路径,Body为文件, ACL最好要设置
  1275. var options = {
  1276. partSize: 2048 * 1024 * 1024,
  1277. queueSize: 2,
  1278. leavePartsOnError: true
  1279. };
  1280. bucket
  1281. .upload(params, options)
  1282. .on("httpUploadProgress", function(evt) {
  1283. //这里可以写进度条
  1284. _this.progressData.value = parseInt((evt.loaded * 100) / evt.total);
  1285. // console.log("Uploaded : " + parseInt((evt.loaded * 80) / evt.total) + '%');
  1286. })
  1287. .send(function(err, data) {
  1288. if (err) {
  1289. _this.$message.error("上传失败");
  1290. } else {
  1291. console.log(data.Location);
  1292. console.log("提交");
  1293. _this.fileList.push(data.Location);
  1294. console.log(_this.fileList);
  1295. _this.$emit("pushFileData", {
  1296. fileId: "",
  1297. name: name,
  1298. url: data.Location
  1299. });
  1300. }
  1301. });
  1302. }
  1303. },
  1304. getLang() {
  1305. let lang = "";
  1306. if (this.languageSetting == 0) {
  1307. lang = "Chinese.";
  1308. } else if (this.languageSetting == 1) {
  1309. lang = "Traditional Chinese.";
  1310. } else if (this.languageSetting == 2) {
  1311. lang = "English.";
  1312. }
  1313. return lang;
  1314. },
  1315. promptTit() {
  1316. if (!this.loading && !this.courseText) {
  1317. this.$message({
  1318. message: "请输入您想要了解的内容",
  1319. type: "warning"
  1320. });
  1321. } else {
  1322. this.$message({
  1323. message: "请回答完毕后再次发送",
  1324. type: "warning"
  1325. });
  1326. }
  1327. },
  1328. addContent2() {
  1329. if (this.courseText.trim().length == 0) {
  1330. return this.$message.error("请输入内容");
  1331. } else if (this.fileList.length == 0) {
  1332. return this.$message.error("请选择表单");
  1333. }
  1334. let message = this.courseText;
  1335. if (this.courseText) {
  1336. let msg = ``;
  1337. if (this.answerArray.length) {
  1338. // msg += `
  1339. // ## 表单资料
  1340. // ${JSON.stringify(this.answerArray)}
  1341. // `;
  1342. // msg += `
  1343. // ## 要求
  1344. // 根据<参考资料>中的内容实现以下要求:${this.courseText}
  1345. // `;
  1346. msg += `## 要求
  1347. 根据上传文件中的内容实现以下要求:${this.courseText}`;
  1348. message = msg;
  1349. }
  1350. this.faloading = true;
  1351. let _uuid = uuidv4();
  1352. this.array.push({
  1353. role: "user",
  1354. content: `${this.courseText}`,
  1355. uid: _uuid,
  1356. AI: "AI",
  1357. aiContent: "",
  1358. oldContent: "",
  1359. isShowSynchronization: false,
  1360. filename: "",
  1361. index: this.array.length,
  1362. is_mind_map: false,
  1363. createtime: new Date().toLocaleString().replaceAll("/", "-"),
  1364. loading: true
  1365. });
  1366. // let history = [];
  1367. // if (this.continuous) {
  1368. // this.array.forEach((i, index) => {
  1369. // if (i.content) history.push({ role: "user", content: index == this.array.length - 1 ? message : i.content });
  1370. // if (i.aiContent)
  1371. // history.push({ role: "assistant", content: i.aiContent });
  1372. // });
  1373. // } else {
  1374. // history.push({ role: "user", content: message });
  1375. // }
  1376. // history = history.filter(
  1377. // i =>
  1378. // i.content !=
  1379. // "您好,我是您的助手小可"
  1380. // );
  1381. // history = history.map(i => ({
  1382. // role: i.role,
  1383. // content: `${i.content}`
  1384. // }));
  1385. // this.$nextTick(() => {
  1386. // this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
  1387. // });
  1388. // let params = JSON.stringify({
  1389. // // model: "gpt-3.5-turbo",
  1390. // // model: "gpt-4o-mini",
  1391. // model: "qwen-plus",
  1392. // temperature: 0,
  1393. // max_tokens: 4096,
  1394. // top_p: 1,
  1395. // frequency_penalty: 0,
  1396. // presence_penalty: 0,
  1397. // messages: history,
  1398. // uid: _uuid,
  1399. // mind_map_question: ""
  1400. // });
  1401. // this.courseText = "";
  1402. // this.ajax
  1403. // .post("https://gpt4.cocorobo.cn/chat", params)
  1404. // .then(res => {
  1405. // if (
  1406. // converter(res.data.FunctionResponse.result) ==
  1407. // converter("发送成功")
  1408. // ) {
  1409. // } else {
  1410. // this.$message.warning(res.data.FunctionResponse.result);
  1411. // }
  1412. // })
  1413. // .catch(e => {
  1414. // console.log(e);
  1415. // });
  1416. // this.getAiContent(_uuid);\
  1417. let params = {
  1418. prompt: message,
  1419. messages: [],
  1420. file: this.fileList ? this.fileList : []
  1421. };
  1422. this.stopTalkToken = this.ajax.setCancelSource();
  1423. this.$nextTick(() => {
  1424. this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
  1425. });
  1426. this.courseText = "";
  1427. this.saveUid = _uuid;
  1428. this.ajax
  1429. // .post("https://gpt4.cocorobo.cn/ai_agent_park_chat_new", params)
  1430. .post(
  1431. "https://gpt4.cocorobo.cn/csvaimessage",
  1432. params,
  1433. this.stopTalkToken
  1434. )
  1435. .then(res => {
  1436. // if (
  1437. // converter(res.data.FunctionResponse.result) ==
  1438. // converter("发送成功")
  1439. // ) {
  1440. // } else {
  1441. // this.$message.warning(res.data.FunctionResponse.result);
  1442. // }
  1443. let data = res.data.FunctionResponse;
  1444. const md = new MarkdownIt();
  1445. const text = md.render(data);
  1446. this.array.find(i => i.uid == _uuid).aiContent = text;
  1447. this.array.find(i => i.uid == _uuid).isalltext = true;
  1448. this.array.find(i => i.uid == _uuid).isShowSynchronization = true;
  1449. this.array.find(i => i.uid == _uuid).loading = false;
  1450. this.array.find(i => i.uid == _uuid).mdText = data;
  1451. this.stopTalkToken = null;
  1452. this.faloading = false;
  1453. this.generateChart(this.array.find(i => i.uid == _uuid));
  1454. this.$nextTick(() => {
  1455. this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
  1456. });
  1457. // if (this.courseId) {
  1458. this.insertChat(_uuid);
  1459. // this.$emit("pushAiContent",this.array)
  1460. // }
  1461. console.log("array👉", this.array);
  1462. })
  1463. .catch(err => {
  1464. console.log(err);
  1465. this.faloading = false;
  1466. this.stopTalkToken = null;
  1467. });
  1468. // this.getAtAuContent(_uuid);
  1469. // this.saveUid = _uuid;
  1470. }
  1471. },
  1472. async addContent() {
  1473. if (this.courseText.trim().length == 0) {
  1474. return this.$message.error("请输入内容");
  1475. } else if (this.fileList.length == 0) {
  1476. return this.$message.error("请选择表单");
  1477. }
  1478. let message = this.courseText;
  1479. if (this.courseText) {
  1480. let msg = ``;
  1481. if (this.answerArray.length) {
  1482. // msg += `
  1483. // ## 表单资料
  1484. // ${JSON.stringify(this.answerArray)}
  1485. // `;
  1486. // msg += `
  1487. // ## 要求
  1488. // 根据<参考资料>中的内容实现以下要求:${this.courseText}
  1489. // `;
  1490. msg += `## 要求
  1491. 根据上传文件中的内容实现以下要求:${this.courseText}`;
  1492. message = msg;
  1493. }
  1494. this.faloading = true;
  1495. let _uuid = uuidv4();
  1496. this.array.push({
  1497. role: "user",
  1498. content: `${this.courseText}`,
  1499. uid: _uuid,
  1500. AI: "AI",
  1501. aiContent: "",
  1502. oldContent: "",
  1503. isShowSynchronization: false,
  1504. filename: "",
  1505. index: this.array.length,
  1506. is_mind_map: false,
  1507. createtime: new Date().toLocaleString().replaceAll("/", "-"),
  1508. loading: true
  1509. });
  1510. let params = {
  1511. prompt: message,
  1512. messages: [],
  1513. file: this.fileList ? this.fileList : []
  1514. };
  1515. this.stopTalkToken = this.ajax.setCancelSource();
  1516. this.$nextTick(() => {
  1517. this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
  1518. });
  1519. this.courseText = "";
  1520. this.saveUid = _uuid;
  1521. let _addText = "";
  1522. const md = new MarkdownIt();
  1523. let _this = this;
  1524. // const curRequestController = new AbortController();
  1525. this.curRequestController = new AbortController();
  1526. // this.stopTalkToken = () => {
  1527. // curRequestController.abort();
  1528. // this.getMessageLoading = false;
  1529. // console.log("请求已终止");
  1530. // };
  1531. // this.getMessageLoading = true;
  1532. fetchEventSource("https://gpt4.cocorobo.cn/csvaimessagestream",{
  1533. method: "POST",
  1534. headers: {
  1535. "Content-Type": "application/json"
  1536. },
  1537. body: JSON.stringify(params),
  1538. signal: _this.curRequestController.signal,
  1539. onmessage(ev){
  1540. let _data = JSON.parse(ev.data);
  1541. console.log("👉>>>",_data)
  1542. let _text = _data.data;
  1543. let status = _data.event;
  1544. if(status=='on_chain_start'){
  1545. const text = md.render('开始分析数据\n')
  1546. _this.array.find(i => i.uid == _uuid).aiContent += text
  1547. }else if(status=='on_tool_start'){
  1548. const text = md.render('开始调用工具代码\n')
  1549. _this.array.find(i => i.uid == _uuid).aiContent += text
  1550. }else if(status=='on_tool_end'){
  1551. const text = md.render('调用工具代码成功返回数据\n')
  1552. _this.array.find(i => i.uid == _uuid).aiContent += text
  1553. }else if(status=='on_chat_model_stream'){
  1554. _addText+=_text;
  1555. const text = md.render(_addText);
  1556. _this.array.find(i => i.uid == _uuid).loading = false;
  1557. _this.array.find(i => i.uid == _uuid).aiContent = text;
  1558. }else if(status=='on_chain_end'){
  1559. const text = md.render(_text);
  1560. _this.array.find(i => i.uid == _uuid).aiContent = text;
  1561. _this.array.find(i => i.uid == _uuid).loading = false;
  1562. _this.array.find(i => i.uid == _uuid).mdText = _text;
  1563. _this.generateChart(_this.array.find(i => i.uid == _uuid));
  1564. _this.insertChat(_uuid);
  1565. _this.curRequestController = null;
  1566. }
  1567. _this.$nextTick(() => {
  1568. _this.$refs.chatDialog.scrollTop = _this.$refs.chatDialog.scrollHeight;
  1569. });;
  1570. },
  1571. onclose(){
  1572. _this.$forceUpdate();
  1573. _this.stopTalkToken = null;
  1574. _this.faloading = false;
  1575. _this.curRequestController = null;
  1576. console.log("连接关闭")
  1577. },
  1578. onerror(err){
  1579. console.log("连接错误",err)
  1580. }
  1581. })
  1582. // fetch("https://gpt4.cocorobo.cn/csvaimessagestream", {
  1583. // method: "POST",
  1584. // headers: {
  1585. // "Content-Type": "application/json"
  1586. // },
  1587. // body: JSON.stringify(params),
  1588. // signal: curRequestController.signal
  1589. // })
  1590. // .then(res => {
  1591. // let reader = res.body.getReader();
  1592. // let getStream = reader => {
  1593. // return reader.read().then(result => {
  1594. // if (result.done) {
  1595. // return;
  1596. // }
  1597. // //取出数据(二进制)
  1598. // let chunk = result.value;
  1599. // let _text = ``;
  1600. // for (let i = 0; i < chunk.byteLength; i++) {
  1601. // _text += String.fromCharCode(chunk[i]);
  1602. // }
  1603. // _text = _text.replace('data','"data"');
  1604. // console.log("👉!!!!",_text,"<<<👈")
  1605. // // let resultObj = JSON.parse(_text);
  1606. // // console.log("👉》》》",resultObj)
  1607. // // if (resultObj["event"]=='on_chat_model_stream') {
  1608. // // let data = resultObj["data"];
  1609. // // console.log("👉:",data)
  1610. // // const md = new MarkdownIt();
  1611. // // const text = md.render(data);
  1612. // // this.array.find(i => i.uid == _uuid).aiContent = text;
  1613. // // this.array.find(i => i.uid == _uuid).loading = false;
  1614. // // this.$nextTick(() => {
  1615. // // this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
  1616. // // });;
  1617. // // }
  1618. // // } else if (resultObj["steps"]) {
  1619. // // let data = resultObj["steps"];
  1620. // // console.log("👉:",data)
  1621. // // const md = new MarkdownIt();
  1622. // // const text = md.render(data);
  1623. // // this.array.find(i => i.uid == _uuid).aiContent = text;
  1624. // // this.array.find(i => i.uid == _uuid).loading = false;
  1625. // // this.$nextTick(() => {
  1626. // // this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
  1627. // // });
  1628. // // } else if (resultObj["output"]) {
  1629. // // let data = resultObj["output"];
  1630. // // console.log("👉:",data)
  1631. // // const md = new MarkdownIt();
  1632. // // const text = md.render(data);
  1633. // // this.array.find(i => i.uid == _uuid).aiContent = text;
  1634. // // this.array.find(i => i.uid == _uuid).isalltext = true;
  1635. // // this.array.find(i => i.uid == _uuid).isShowSynchronization = true;
  1636. // // this.array.find(i => i.uid == _uuid).loading = false;
  1637. // // this.array.find(i => i.uid == _uuid).mdText = data;
  1638. // // this.$forceUpdate();
  1639. // // this.stopTalkToken = null;
  1640. // // this.faloading = false;
  1641. // // this.generateChart(this.array.find(i => i.uid == _uuid));
  1642. // // this.$nextTick(() => {
  1643. // // this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
  1644. // // });
  1645. // // this.insertChat(_uuid);
  1646. // // }
  1647. // // 递归下一个
  1648. // return getStream(reader);
  1649. // });
  1650. // };
  1651. // getStream(reader);
  1652. // })
  1653. // .catch(err => {
  1654. // console.log(err);
  1655. // });
  1656. }
  1657. },
  1658. stopCurRequestController(){
  1659. if(this.curRequestController){
  1660. this.curRequestController.abort();
  1661. console.log("请求已终止");
  1662. this.curRequestController = null;
  1663. }
  1664. },
  1665. async getData() {
  1666. return new Promise(resolve => {
  1667. if (this.cid) {
  1668. this.loading = true;
  1669. let cidList = this.cid.split(",");
  1670. let promiseList = [];
  1671. cidList.forEach(el => {
  1672. promiseList.push(this.getCourseData(el));
  1673. });
  1674. Promise.all(promiseList).then(async res => {
  1675. console.log(this.courseInfoList);
  1676. console.log("res", res);
  1677. this.courseInfoList = res;
  1678. this.worksArray = this.courseInfoList;
  1679. console.log("👉worksArray", this.worksArray);
  1680. if (
  1681. this.worksArray.length &&
  1682. JSON.stringify(this.worksArray) !== this.copyWorksArray
  1683. ) {
  1684. this.$emit("clearFileData");
  1685. this.fileId = [];
  1686. this.fileList = [];
  1687. this.copyWorksArray = JSON.stringify(this.worksArray);
  1688. let fileValue = [];
  1689. for (let i = 0; i < this.worksArray.length; i++) {
  1690. let _fileValue = await this.setJson(this.worksArray[i]);
  1691. if (fileValue !== 0) {
  1692. fileValue.push(_fileValue);
  1693. }
  1694. }
  1695. resolve(fileValue);
  1696. // newValue.forEach(el => {
  1697. // // console.log("👉el",el)
  1698. // this.setJson(el);
  1699. // });
  1700. // console.log("👈👉",newValue)
  1701. // this.setJson(newValue)
  1702. }
  1703. this.loading = false;
  1704. });
  1705. } else {
  1706. resolve();
  1707. }
  1708. });
  1709. },
  1710. getCourseData(courseId) {
  1711. console.log("👉courseId", courseId);
  1712. return new Promise(resolve => {
  1713. let params = {
  1714. cid: courseId,
  1715. cn: "",
  1716. tim: "",
  1717. tea: ""
  1718. };
  1719. this.ajax
  1720. .get(this.$store.state.api + "getTestWorksNoPageCopy", params)
  1721. .then(async res => {
  1722. let testJson = res.data[0][0];
  1723. let works = res.data[1];
  1724. let chapters = this.setJSON(
  1725. this.setJson2(
  1726. JSON.parse(JSON.stringify(JSON.parse(res.data[0][0].chapters)))
  1727. )
  1728. );
  1729. console.log("chapters", chapters);
  1730. let courseCount11 = [];
  1731. let array = [];
  1732. let courseIds = []; // 初始化一个空数组来存储所有的courseId
  1733. for (let i = 0; i < works.length; i++) {
  1734. let cJson = this.setJSON(
  1735. JSON.parse(JSON.stringify(JSON.parse(works[i].courseJson)))
  1736. );
  1737. if (JSON.stringify(cJson) == JSON.stringify(chapters)) {
  1738. let _json = this.JSONSetting(
  1739. JSON.parse(JSON.stringify(JSON.parse(works[i].courseJson)))
  1740. );
  1741. for (var ja = 0; ja < _json.length; ja++) {
  1742. let _json2 = _json[ja].json;
  1743. if (_json[ja].type == 6) {
  1744. let courseId = _json2.answer2;
  1745. courseIds.push(courseId); // 将type为6的courseId添加到数组中
  1746. }
  1747. if (_json[ja].type == 11) {
  1748. let _answer = _json2.answer2;
  1749. _answer.length
  1750. ? (courseCount11 = courseCount11.concat(_answer))
  1751. : "";
  1752. _json[ja].json.courseId = _answer ? _answer : [];
  1753. courseIds = courseIds.concat(_answer); // 将type为11的courseId添加到数组中
  1754. }
  1755. }
  1756. }
  1757. }
  1758. // 将所有的courseId去重
  1759. courseIds = Array.from(new Set(courseIds));
  1760. // 使用一个数组来存储所有的courseId后,执行getCourseInfoTestAll
  1761. let courseTitles = {}; // 初始化一个空对象来存储所有的courseTitles
  1762. let params2 = [
  1763. {
  1764. cid: courseIds.join(",")
  1765. }
  1766. ];
  1767. let data2 = await this.ajax.post(
  1768. this.$store.state.api + "getCourseInfoTestAll2",
  1769. params2
  1770. );
  1771. let result2 = data2.data[0];
  1772. result2.forEach(i => {
  1773. courseTitles[i.courseId] = i.title;
  1774. });
  1775. for (let i = 0; i < works.length; i++) {
  1776. let cJson = this.setJSON(
  1777. JSON.parse(JSON.stringify(JSON.parse(works[i].courseJson)))
  1778. );
  1779. if (JSON.stringify(cJson) == JSON.stringify(chapters)) {
  1780. let _json = this.JSONSetting(
  1781. JSON.parse(JSON.stringify(JSON.parse(works[i].courseJson)))
  1782. );
  1783. _json.forEach(item => {
  1784. if (item.type == 11) {
  1785. let cid = item.json.answer2;
  1786. let _title = [];
  1787. for (var i = 0; i < cid.length; i++) {
  1788. _title.push(courseTitles[cid[i]]);
  1789. }
  1790. item.json.answer2 = _title.length ? _title.join(",") : "";
  1791. }
  1792. if (item.type == 6) {
  1793. let courseId = item.json.answer2;
  1794. item.json.answer2 = courseTitles[courseId] || "";
  1795. }
  1796. });
  1797. // 更新对应的_json对象的answer2
  1798. array.push({
  1799. courseid: works[i].courseid,
  1800. id: works[i].id,
  1801. userid: works[i].userid,
  1802. name: works[i].username ? works[i].username : "匿名",
  1803. time: works[i].time,
  1804. array: _json,
  1805. cut: 0,
  1806. uteaName: works[i].uteaName,
  1807. courseJson: JSON.parse(works[i].courseJson)
  1808. });
  1809. }
  1810. }
  1811. let obj = {
  1812. courseId: testJson.courseId,
  1813. name: testJson.title,
  1814. worksArray: array
  1815. };
  1816. // this.courseInfoList.push(obj)
  1817. resolve(obj);
  1818. })
  1819. .catch(err => {
  1820. resolve();
  1821. console.error(err);
  1822. });
  1823. });
  1824. },
  1825. setJson2(json) {
  1826. let _json = json;
  1827. // this.type = _json[0].ttype;
  1828. let checkArray = _json.filter(item => {
  1829. if (item.array) {
  1830. item.array = item.array.filter(item2 => {
  1831. if (item2.ttype == 1 && item2.json && !item2.json.answer2) {
  1832. item2.json.answer2 = [];
  1833. }
  1834. if (item2.array) {
  1835. item2.array = item2.array.filter(item3 => {
  1836. if (item3.ttype == 1 && item3.json && !item3.json.answer2) {
  1837. item3.json.answer2 = [];
  1838. }
  1839. return item3;
  1840. });
  1841. }
  1842. return (
  1843. (item2.ttype != 1 && item2.array.length > 0) || item2.ttype == 1
  1844. );
  1845. });
  1846. }
  1847. if (item.ttype == 1 && item.json && !item.json.answer2) {
  1848. item.json.answer2 = [];
  1849. }
  1850. return (item.ttype != 1 && item.array.length > 0) || item.ttype == 1;
  1851. });
  1852. return checkArray;
  1853. },
  1854. setJSON(json) {
  1855. return json.filter(item => {
  1856. if (item.array) {
  1857. item.array = item.array.filter(item2 => {
  1858. if (item2.ttype == 1 && item2.json) {
  1859. delete item2.json.answer2;
  1860. delete item2.json.score2;
  1861. delete item2.json.file;
  1862. }
  1863. if (item2.array) {
  1864. item2.array = item2.array.filter(item3 => {
  1865. if (item3.ttype == 1 && item3.json) {
  1866. delete item3.json.answer2;
  1867. delete item3.json.score2;
  1868. delete item3.json.file;
  1869. }
  1870. return item3;
  1871. });
  1872. }
  1873. return item2;
  1874. });
  1875. } else if (item.ttype == 1 && item.json) {
  1876. delete item.json.answer2;
  1877. delete item.json.score2;
  1878. delete item.json.file;
  1879. }
  1880. return item;
  1881. });
  1882. },
  1883. JSONSetting(json) {
  1884. let _json = json;
  1885. let array = [];
  1886. _json.filter(item => {
  1887. if (item.array) {
  1888. item.array = item.array.filter(item2 => {
  1889. if (item2.ttype == 1 && item2.json) {
  1890. array.push(item2);
  1891. }
  1892. if (item2.array) {
  1893. item2.array = item2.array.filter(item3 => {
  1894. if (item3.ttype == 1 && item3.json) {
  1895. array.push(item3);
  1896. }
  1897. return item3;
  1898. });
  1899. }
  1900. return item2;
  1901. });
  1902. }
  1903. if (item.ttype == 1 && item.json) {
  1904. array.push(item);
  1905. }
  1906. return item;
  1907. });
  1908. return array;
  1909. },
  1910. setJson(obj) {
  1911. return new Promise(resolve => {
  1912. console.log("👉", obj);
  1913. let array = obj.worksArray;
  1914. console.log("👉", array);
  1915. let name = obj.name;
  1916. if (!array || array.length === 0) {
  1917. this.$message.error("您选择的表单缺少数据,请重新选择!");
  1918. return resolve(0);
  1919. }
  1920. const getAnswer = j => {
  1921. if (j.type === 1) {
  1922. return j.json.array
  1923. .filter((_, idx) => j.json.answer2.includes(idx))
  1924. .map(item => `${item.img}${item.option}`)
  1925. .join(",");
  1926. } else if (
  1927. j.type === 3 ||
  1928. j.type === 6 ||
  1929. j.type === 7 ||
  1930. j.type === 8 ||
  1931. j.type === 11
  1932. ) {
  1933. return typeof j.json.answer2 === "string"
  1934. ? j.json.answer2.replace(/\n/g, " ")
  1935. : j.json.answer2;
  1936. } else if (j.type === 5) {
  1937. if (!Array.isArray(j.json.file) || j.json.file.length === 0) {
  1938. return "无附件";
  1939. }
  1940. return j.json.file
  1941. .map(file => `${file.name}(${file.url})`)
  1942. .join(",");
  1943. } else {
  1944. return "";
  1945. }
  1946. };
  1947. // 获取所有题目类型和题目
  1948. const questions = array[0].array.map((j, index) => ({
  1949. 序号: index + 1,
  1950. 题目类型: this.options2[j.type],
  1951. 题目: j.json.title
  1952. }));
  1953. console.log("我是questions", questions);
  1954. // let csvContent = "data:text/csv;charset=utf-8,"
  1955. // 构建CSV内容
  1956. // let csvContent = "用户名 | 提交时间 | " + questions.map(q => `${q.序号}-${q.题目类型}-${q.题目}`).join(' | ') + "\n";
  1957. let csvContent =
  1958. "用户名,提交时间," +
  1959. questions.map(q => `${q.序号}-${q.题目类型}-${q.题目}`).join(",") +
  1960. "\n";
  1961. // 添加每个用户的答案
  1962. array.forEach(i => {
  1963. let row = [i.name, i.time];
  1964. i.array.forEach(j => {
  1965. row.push(getAnswer(j));
  1966. });
  1967. // csvContent += row.join(' | ') + "\n";
  1968. csvContent += row.join(",") + "\n";
  1969. });
  1970. // 创建Blob对象
  1971. // const blob = new Blob([csvContent], { type: "text/plain;charset=utf-8" });
  1972. // blob.lastModifiedDate = new Date();
  1973. // blob.name = `${name}_表单数据.txt`;
  1974. // 创建Blob对象
  1975. const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8" });
  1976. resolve({ filename: `${name}_表单数据.csv`, content: csvContent });
  1977. blob.lastModifiedDate = new Date();
  1978. blob.name = `${name}_表单数据.csv`;
  1979. // 如果仍需要上传文件,可以保留这行
  1980. return this.uploadFile({ file: blob, name: name });
  1981. });
  1982. },
  1983. async getUserName() {
  1984. let params = { uid: this.userid };
  1985. try {
  1986. let res = await this.ajax.get(
  1987. this.$store.state.api + "getUser",
  1988. params
  1989. );
  1990. this.username = res.data[0][0].name;
  1991. } catch (err) {
  1992. console.error(err);
  1993. }
  1994. },
  1995. //保存消息
  1996. async insertChat(_uid) {
  1997. let _data = this.array.find(i => i.uid == _uid);
  1998. this.saveUid = "";
  1999. this.faloading = false;
  2000. if (!this.username) {
  2001. await this.getUserName();
  2002. }
  2003. if (!_data) return;
  2004. let params = {
  2005. userId: this.userid,
  2006. userName: this.username,
  2007. groupId: "602def61-005d-11ee-91d8-005056b8q12w",
  2008. answer: _data.aiContent,
  2009. problem: _data.content,
  2010. file_id: _data.fileid ? _data.fileid : "",
  2011. alltext: _data.aiContent,
  2012. type: "chat",
  2013. filename: _data.filename,
  2014. session_name: this.cid
  2015. };
  2016. this.ajax
  2017. .post("https://gpt4.cocorobo.cn/insert_chat", params)
  2018. .then(res => {});
  2019. },
  2020. // 获取对应的聊天记录
  2021. async getChatList(cid) {
  2022. return new Promise((resolve, reject) => {
  2023. // if (this.loading) return;
  2024. this.array = [];
  2025. this.loading = true;
  2026. let params = {
  2027. userid: this.userid,
  2028. groupid: "602def61-005d-11ee-91d8-005056b8q12w",
  2029. // session_name:``
  2030. session_name: cid
  2031. };
  2032. this.ajax
  2033. .post("https://gpt4.cocorobo.cn/get_agent_park_chat", params)
  2034. .then(res => {
  2035. console.log(res);
  2036. let _data = JSON.parse(res.data.FunctionResponse).response;
  2037. console.log("data", _data);
  2038. if (_data.length > 0) {
  2039. let _chatList = [];
  2040. for (let i = 0; i < _data.length; i++) {
  2041. _chatList.push({
  2042. loading: false,
  2043. role: "user",
  2044. content: _data[i].problem,
  2045. uid: _data[i].id,
  2046. AI: "AI",
  2047. aiContent: _data[i].answer,
  2048. oldContent: _data[i].answer,
  2049. isShowSynchronization: false,
  2050. filename: _data[i].filename,
  2051. index: i,
  2052. is_mind_map: false,
  2053. fileid: _data[i].fileid,
  2054. createtime: _data[i].createtime
  2055. });
  2056. }
  2057. this.array = _chatList;
  2058. this.loading = false;
  2059. } else {
  2060. let _uid = uuidv4();
  2061. let _chatList = [];
  2062. _chatList.push({
  2063. loading: false,
  2064. role: "",
  2065. content: "",
  2066. uid: _uid,
  2067. AI: "AI",
  2068. aiContent: "选择需要分析的数据,我将为您分析:",
  2069. oldContent: "选择需要分析的数据,我将为您分析:",
  2070. isShowSynchronization: false,
  2071. filename: "",
  2072. index: 0,
  2073. is_mind_map: false,
  2074. fileid: ""
  2075. });
  2076. this.array = _chatList;
  2077. // if (this.courseId) {
  2078. // this.insertChat(_uid,cid);
  2079. // }
  2080. //没有对话记录
  2081. this.loading = false;
  2082. }
  2083. resolve();
  2084. })
  2085. .catch(err => {
  2086. console.log(err);
  2087. this.$message.error("获取对话记录失败");
  2088. this.loading = false;
  2089. resolve();
  2090. });
  2091. });
  2092. },
  2093. addTask(index) {
  2094. if (this.checkArray.indexOf(index) !== -1) {
  2095. this.checkArray.splice(this.checkArray.indexOf(index), 1);
  2096. } else {
  2097. this.checkArray.push(index);
  2098. }
  2099. console.log(index);
  2100. },
  2101. addAllTask() {
  2102. if (this.checkArray.length === this.course.length) {
  2103. this.checkArray = [];
  2104. } else {
  2105. this.checkArray = [];
  2106. this.course.forEach((item, index) => {
  2107. this.checkArray.push(index);
  2108. });
  2109. }
  2110. },
  2111. tableRowClassName2({ row, rowIndex }) {
  2112. if ((rowIndex + 1) % 2 === 0) {
  2113. return "rowClass";
  2114. } else {
  2115. return "rowClass";
  2116. }
  2117. },
  2118. checkPart(name) {
  2119. this.part = name;
  2120. },
  2121. inputChange() {
  2122. if (this.courseText.at(-1) == "@") {
  2123. // this.showRoleList = true;
  2124. }
  2125. if (this.courseText.at(-1) == "/") {
  2126. console.log("哇卡ka2");
  2127. }
  2128. this.$nextTick(() => {
  2129. this.$refs.textareaRef.style.height = "35px";
  2130. this.$refs.textareaRef.style.height =
  2131. this.$refs.textareaRef.scrollHeight + "px";
  2132. this.textareaHeight = this.$refs.textareaRef.style.height;
  2133. });
  2134. },
  2135. textareaKeydown(_e) {
  2136. if (this.showRoleList && this.choseRoleList.length > 0) {
  2137. console.log(_e.keyCode);
  2138. switch (_e.keyCode) {
  2139. case 38: //小键盘上
  2140. _e.preventDefault();
  2141. if (this.choseRoleItem == 0) return;
  2142. this.choseRoleItem--;
  2143. // 修改滚动条高度
  2144. this.$refs.roleListRef.scrollTo({
  2145. top:
  2146. this.$refs[`roleItem${this.choseRoleItem}Ref`][0].offsetTop -
  2147. 10,
  2148. behavior: "smooth"
  2149. });
  2150. // this.$refs.roleListRef.scrollTop = this.choseRoleItem * 107;
  2151. break;
  2152. case 40: //小键盘下
  2153. _e.preventDefault();
  2154. if (this.choseRoleItem == this.choseRoleList.length - 1) return;
  2155. this.choseRoleItem++;
  2156. this.$refs.roleListRef.scrollTo({
  2157. top:
  2158. this.$refs[`roleItem${this.choseRoleItem}Ref`][0].offsetTop -
  2159. 10,
  2160. behavior: "smooth"
  2161. });
  2162. // this.$refs.roleListRef.scrollTop = this.choseRoleItem * 107;
  2163. break;
  2164. case 13: //回车
  2165. _e.preventDefault();
  2166. this.choseRole(this.choseRoleList[this.choseRoleItem]);
  2167. break;
  2168. }
  2169. } else if (_e.key === "Enter") {
  2170. _e.preventDefault();
  2171. if (_e.shiftKey) {
  2172. this.courseText += "\n";
  2173. } else {
  2174. this.addContent();
  2175. }
  2176. }
  2177. },
  2178. clear() {
  2179. this.$confirm("确定清空聊天记录吗?", "提示", {
  2180. confirmButtonText: "确定",
  2181. cancelButtonText: "取消",
  2182. type: "warning"
  2183. })
  2184. .then(_ => {
  2185. this.loading = true;
  2186. let params = {
  2187. user_id: this.userid,
  2188. id: "602def61-005d-11ee-91d8-005056b8q12w",
  2189. session_name: `${this.courseId}-${this.userid}-test`
  2190. };
  2191. this.ajax
  2192. .post("https://gpt4.cocorobo.cn/delete_park_session", params)
  2193. .then(res => {
  2194. this.array = [];
  2195. this.$message.success("清除聊天记录成功");
  2196. this.loading = false;
  2197. })
  2198. .catch(err => {
  2199. this.loading = false;
  2200. this.$message.error("清除聊天记录失败");
  2201. });
  2202. })
  2203. .catch(_ => {});
  2204. },
  2205. choseRole(item) {
  2206. let _lastAtIndex = this.courseText.lastIndexOf("@");
  2207. this.courseText = `${this.courseText.slice(0, _lastAtIndex)}@${
  2208. item.assistantName
  2209. } `;
  2210. this.$refs.textareaRef.focus();
  2211. this.showRoleList = false;
  2212. },
  2213. copyText(text) {
  2214. this.courseText = text;
  2215. this.addContent();
  2216. },
  2217. onCopy(content,index) {
  2218. if(this.$refs[`eChartViewRef-${index}`]){
  2219. let _el = this.$refs[`eChartViewRef-${index}`][0].$el;
  2220. let _canvas = _el.querySelector('canvas');
  2221. let _echartBase64 = _canvas.toDataURL("image/png");
  2222. content = content + ' ' + _echartBase64
  2223. }
  2224. const turndownService = new TurndownService();
  2225. // 添加自定义规则来处理表格
  2226. turndownService.addRule("table", {
  2227. filter: "table",
  2228. replacement: (content, node) => {
  2229. const rows = node.querySelectorAll("tr");
  2230. let markdown = "";
  2231. rows.forEach(row => {
  2232. const cells = row.querySelectorAll("th, td");
  2233. const rowMarkdown = Array.from(cells)
  2234. .map(cell => cell.textContent)
  2235. .join(" | ");
  2236. markdown += `| ${rowMarkdown} |\n`;
  2237. if (cells && cells.length && cells[0].tagName == "TH") {
  2238. let a = Array.from(cells)
  2239. .map(cell => "")
  2240. .join(" --- |");
  2241. markdown += `| --- |${a}\n`;
  2242. }
  2243. });
  2244. // 添加分隔行
  2245. // markdown = markdown.replace(/^/, '| --- |\n');
  2246. return markdown;
  2247. }
  2248. });
  2249. // 创建临时textarea元素
  2250. const tempInput = document.createElement("textarea");
  2251. tempInput.value = turndownService.turndown(content); // 设置要复制的内容
  2252. // 隐藏元素
  2253. tempInput.style.position = "absolute";
  2254. tempInput.style.left = "-9999px";
  2255. // 将元素添加到DOM中
  2256. document.body.appendChild(tempInput);
  2257. // 选中元素内容
  2258. tempInput.select();
  2259. // 执行复制操作
  2260. document.execCommand("copy");
  2261. // 移除临时元素
  2262. document.body.removeChild(tempInput);
  2263. this.$message({
  2264. message: "复制成功",
  2265. type: "success"
  2266. });
  2267. },
  2268. // edit(index) {
  2269. // console.log("👉", this.array[index].content);
  2270. // const userAsk = this.array[index].content
  2271. // this.aiText = this.array[index].aiContent
  2272. // this.$emit("pushAiContent", this.aiText, userAsk)
  2273. // },
  2274. stopSend() {
  2275. if (this.fasource) {
  2276. this.fasource.close();
  2277. if (this.array[this.array.length - 1].content == "wanSearch") {
  2278. this.array.pop();
  2279. }
  2280. this.array.find(i => i.uid == this.saveUid).loading = false;
  2281. this.faloading = false;
  2282. this.fasource = null;
  2283. this.insertChat(this.saveUid);
  2284. } else if (this.stopTalkToken) {
  2285. this.stopTalkToken.cancel("Request canceled by the user.");
  2286. this.array = this.array.filter(i => i.uid !== this.saveUid);
  2287. this.stopTalkToken = null;
  2288. this.faloading = false;
  2289. }
  2290. },
  2291. changeVoice(flag) {
  2292. this.isVoice = flag;
  2293. },
  2294. startVoice() {
  2295. let iiframe = this.$refs["iiframe"];
  2296. iiframe.contentWindow.window.document.getElementById(
  2297. "languageOptions"
  2298. ).selectedIndex = 2; //普通话
  2299. iiframe.contentWindow.testdoContinuousPronunciationAssessment();
  2300. this.isTalk = true;
  2301. iiframe.contentWindow.onRecognizedResult = e => {
  2302. let _msg = e.privText;
  2303. console.log(_msg);
  2304. if (_msg) this.courseText += _msg;
  2305. };
  2306. },
  2307. stopVoice() {
  2308. try {
  2309. if (!this.isTalk) return this.$message.info("请先开始录音");
  2310. let iiframe = this.$refs["iiframe"];
  2311. iiframe.contentWindow.window.document
  2312. .getElementById("scenarioStopButton")
  2313. .click();
  2314. iiframe.contentWindow.onSessionStopped = (s, e) => {
  2315. this.isTalk = false;
  2316. if (this.courseText) {
  2317. this.addContent();
  2318. }
  2319. };
  2320. } catch (error) {
  2321. console.log(error);
  2322. this.isTalk = false;
  2323. if (this.courseText) {
  2324. this.addContent();
  2325. }
  2326. }
  2327. },
  2328. async generateChart(item) {
  2329. console.log("生成图表")
  2330. let _eChartsMsg = `
  2331. 折线图(type=0):{"xAxis":{"type":"category","data":["data1","data2","data3","data4","data5","data6","data7"]},"yAxis":{"type":"value"},"series":[{"data":[150,230,224,218,135,147,260],"type":"line"}]}
  2332. 折线图堆叠(type=1):{"tooltip":{"trigger":"axis"},"legend":{"data":["data1","data2","data3","data4","data5"]},"grid":{"left":"3%","right":"4%","bottom":"3%","containLabel":true},"toolbox":{"feature":{"saveAsImage":{}}},"xAxis":{"type":"category","boundaryGap":false,"data":["xdata1","xdata2","xdata3","xdata4","xdata5","xdata6","xdata7"]},"yAxis":{"type":"value"},"series":[{"name":"data1","type":"line","stack":"Total","data":[120,132,101,134,90,230,210]},{"name":"data2","type":"line","stack":"Total","data":[220,182,191,234,290,330,310]},{"name":"data3","type":"line","stack":"Total","data":[150,232,201,154,190,330,410]},{"name":"data4","type":"line","stack":"Total","data":[320,332,301,334,390,330,320]},{"name":"data5","type":"line","stack":"Total","data":[820,932,901,934,1290,1330,1320]}]}
  2333. 柱状图(type=2):{"xAxis":{"type":"category","data":["data1","data2","data2","data3","data4","data5","data6"]},"yAxis":{"type":"value"},"series":[{"data":[120,200,150,80,70,110,130],"type":"bar"}]}
  2334. 堆叠柱状图归一化(type=3):{"legend":{"selectedMode":false},"grid":{"left":100,"right":100,"top":50,"bottom":50},"yAxis":{"type":"value"},"xAxis":{"type":"category","data":["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]},"series":[{"name":"Direct","type":"bar","stack":"total","barWidth":"60%","label":{"show":true},"data":[100,302,301,334,390,330,320]},{"name":"Mail Ad","type":"bar","stack":"total","barWidth":"60%","label":{"show":true},"data":[320,132,101,134,90,230,210]},{"name":"Affiliate Ad","type":"bar","stack":"total","barWidth":"60%","label":{"show":true},"data":[220,182,191,234,290,330,310]},{"name":"Video Ad","type":"bar","stack":"total","barWidth":"60%","label":{"show":true},"data":[150,212,201,154,190,330,410]},{"name":"Search Engine","type":"bar","stack":"total","barWidth":"60%","label":{"show":true},"data":[820,832,901,934,1290,1330,1320]}]}
  2335. 分组柱状图(type=4):{"legend":{},"tooltip":{},"dataset":{"source":[["product","data1","data2","data3"],["xdata1",43.3,85.8,93.7],["xdata2",83.1,73.4,55.1],["xdata3",86.4,65.2,82.5],["xdata4",72.4,53.9,39.1]]},"xAxis":{"type":"category"},"yAxis":{},"series":[{"type":"bar"},{"type":"bar"},{"type":"bar"}]}
  2336. 饼状图(type=5):{"tooltip":{"trigger":"item"},"legend":{"orient":"vertical","left":"left"},"series":[{"name":"formTitle","type":"pie","radius":"50%","data":[{"value":1048,"name":"data1"},{"value":735,"name":"data2"},{"value":580,"name":"data3"},{"value":484,"name":"data4"},{"value":300,"name":"data5"}],"emphasis":{"itemStyle":{"shadowBlur":10,"shadowOffsetX":0,"shadowColor":"rgba(0, 0, 0, 0.5)"}}}]}
  2337. 环状图(type=6):{"tooltip":{"trigger":"item"},"legend":{"top":"5%","left":"center"},"series":[{"name":"formTitle","type":"pie","radius":["40%","70%"],"avoidLabelOverlap":false,"itemStyle":{"borderRadius":10,"borderColor":"#fff","borderWidth":2},"label":{"show":false,"position":"center"},"emphasis":{"label":{"show":true,"fontSize":40,"fontWeight":"bold"}},"labelLine":{"show":false},"data":[{"value":1048,"name":"data1"},{"value":735,"name":"data2"},{"value":580,"name":"data3"},{"value":484,"name":"data4"},{"value":300,"name":"data5"}]}]}
  2338. 散点图(type=7):{"xAxis":{},"yAxis":{},"series":[{"symbolSize":20,"data":[[10,8.04],[8.07,6.95],[13,7.58],[9.05,8.81],[11,8.33],[14,7.66],[13.4,6.81],[10,6.33],[14,8.96],[12.5,6.82],[9.15,7.2],[11.5,7.2],[3.03,4.23],[12.2,7.83],[2.02,4.47],[1.05,3.33],[4.05,4.96],[6.03,7.24],[12,6.26],[12,8.84],[7.08,5.82],[5.02,5.68]],"type":"scatter"}]}
  2339. 多轴气泡图(type=8):{"legend":{"data":["Punch Card"],"left":"right"},"tooltip":{"position":"top"},"grid":{"left":2,"bottom":10,"right":10,"containLabel":true},"xAxis":{"type":"category","data":["12a","1a","2a","3a","4a","5a","6a","7a","8a","9a","10a","11a","12p","1p","2p","3p","4p","5p","6p","7p","8p","9p","10p","11p"],"boundaryGap":false,"splitLine":{"show":true},"axisLine":{"show":false}},"yAxis":{"type":"category","data":["Saturday","Friday","Thursday","Wednesday","Tuesday","Monday","Sunday"],"axisLine":{"show":false}},"series":[{"name":"Punch Card","type":"scatter","data":[[0,0,5],[1,0,1],[2,0,0],[3,0,0],[4,0,0],[5,0,0],[6,0,0],[7,0,0],[8,0,0],[9,0,0],[10,0,0],[11,0,2],[12,0,4],[13,0,1],[14,0,1],[15,0,3],[16,0,4],[17,0,6],[18,0,4],[19,0,4],[20,0,3],[21,0,3],[22,0,2],[23,0,5],[0,1,7],[1,1,0],[2,1,0],[3,1,0],[4,1,0],[5,1,0],[6,1,0],[7,1,0],[8,1,0],[9,1,0],[10,1,5],[11,1,2],[12,1,2],[13,1,6],[14,1,9],[15,1,11],[16,1,6],[17,1,7],[18,1,8],[19,1,12],[20,1,5],[21,1,5],[22,1,7],[23,1,2],[0,2,1],[1,2,1],[2,2,0],[3,2,0],[4,2,0],[5,2,0],[6,2,0],[7,2,0],[8,2,0],[9,2,0],[10,2,3],[11,2,2],[12,2,1],[13,2,9],[14,2,8],[15,2,10],[16,2,6],[17,2,5],[18,2,5],[19,2,5],[20,2,7],[21,2,4],[22,2,2],[23,2,4],[0,3,7],[1,3,3],[2,3,0],[3,3,0],[4,3,0],[5,3,0],[6,3,0],[7,3,0],[8,3,1],[9,3,0],[10,3,5],[11,3,4],[12,3,7],[13,3,14],[14,3,13],[15,3,12],[16,3,9],[17,3,5],[18,3,5],[19,3,10],[20,3,6],[21,3,4],[22,3,4],[23,3,1],[0,4,1],[1,4,3],[2,4,0],[3,4,0],[4,4,0],[5,4,1],[6,4,0],[7,4,0],[8,4,0],[9,4,2],[10,4,4],[11,4,4],[12,4,2],[13,4,4],[14,4,4],[15,4,14],[16,4,12],[17,4,1],[18,4,8],[19,4,5],[20,4,3],[21,4,7],[22,4,3],[23,4,0],[0,5,2],[1,5,1],[2,5,0],[3,5,3],[4,5,0],[5,5,0],[6,5,0],[7,5,0],[8,5,2],[9,5,0],[10,5,4],[11,5,1],[12,5,5],[13,5,10],[14,5,5],[15,5,7],[16,5,11],[17,5,6],[18,5,0],[19,5,5],[20,5,3],[21,5,4],[22,5,2],[23,5,0],[0,6,1],[1,6,0],[2,6,0],[3,6,0],[4,6,0],[5,6,0],[6,6,0],[7,6,0],[8,6,0],[9,6,0],[10,6,1],[11,6,0],[12,6,2],[13,6,1],[14,6,3],[15,6,4],[16,6,0],[17,6,0],[18,6,0],[19,6,0],[20,6,1],[21,6,2],[22,6,2],[23,6,60]]}]}
  2340. 基础k线图(type=9):{"xAxis":{"data":["xdata1","xdata2","xdata3","xdata4"]},"yAxis":{},"series":[{"type":"candlestick","data":[[20,34,10,38],[40,35,30,50],[31,38,33,44],[38,15,5,42]]}]}
  2341. 基础盒须图(type=10):{"dataset":[{"source":[[850,740,900,1070,930,850,950,980,980,880,1000,980,930,650,760,810,1000,1000,960,960],[960,940,960,940,880,800,850,880,900,840,830,790,810,880,880,830,800,790,760,800],[880,880,880,860,720,720,620,860,970,950,880,910,850,870,840,840,850,840,840,840],[890,810,810,820,800,770,760,740,750,760,910,920,890,860,880,720,840,850,850,780],[890,840,780,810,760,810,790,810,820,850,870,870,810,740,810,940,950,800,810,870]]},{"transform":{"type":"boxplot","config":{"itemNameFormatter":"expr {value}"}}},{"fromDatasetIndex":1,"fromTransformResult":1}],"tooltip":{"trigger":"item","axisPointer":{"type":"shadow"}},"grid":{"left":"10%","right":"10%","bottom":"15%"},"xAxis":{"type":"category","boundaryGap":true,"nameGap":30,"splitArea":{"show":false},"splitLine":{"show":false}},"yAxis":{"type":"value","name":"km/s minus 299,000","splitArea":{"show":true}},"series":[{"name":"boxplot","type":"boxplot","datasetIndex":1},{"name":"outlier","type":"scatter","datasetIndex":2}]}
  2342. 热力图(type=11):{"tooltip":{"position":"top"},"grid":{"height":"50%","top":"10%"},"xAxis":{"type":"category","data":["12a","1a","2a","3a","4a","5a","6a","7a","8a","9a","10a","11a","12p","1p","2p","3p","4p","5p","6p","7p","8p","9p","10p","11p"],"splitArea":{"show":true}},"yAxis":{"type":"category","data":["Saturday","Friday","Thursday","Wednesday","Tuesday","Monday","Sunday"],"splitArea":{"show":true}},"visualMap":{"min":0,"max":10,"calculable":true,"orient":"horizontal","left":"center","bottom":"15%"},"series":[{"name":"Punch Card","type":"heatmap","data":[[0,0,5],[1,0,1],[2,0,"-"],[3,0,"-"],[4,0,"-"],[5,0,"-"],[6,0,"-"],[7,0,"-"],[8,0,"-"],[9,0,"-"],[10,0,"-"],[11,0,2],[12,0,4],[13,0,1],[14,0,1],[15,0,3],[16,0,4],[17,0,6],[18,0,4],[19,0,4],[20,0,3],[21,0,3],[22,0,2],[23,0,5],[0,1,7],[1,1,"-"],[2,1,"-"],[3,1,"-"],[4,1,"-"],[5,1,"-"],[6,1,"-"],[7,1,"-"],[8,1,"-"],[9,1,"-"],[10,1,5],[11,1,2],[12,1,2],[13,1,6],[14,1,9],[15,1,11],[16,1,6],[17,1,7],[18,1,8],[19,1,12],[20,1,5],[21,1,5],[22,1,7],[23,1,2],[0,2,1],[1,2,1],[2,2,"-"],[3,2,"-"],[4,2,"-"],[5,2,"-"],[6,2,"-"],[7,2,"-"],[8,2,"-"],[9,2,"-"],[10,2,3],[11,2,2],[12,2,1],[13,2,9],[14,2,8],[15,2,10],[16,2,6],[17,2,5],[18,2,5],[19,2,5],[20,2,7],[21,2,4],[22,2,2],[23,2,4],[0,3,7],[1,3,3],[2,3,"-"],[3,3,"-"],[4,3,"-"],[5,3,"-"],[6,3,"-"],[7,3,"-"],[8,3,1],[9,3,"-"],[10,3,5],[11,3,4],[12,3,7],[13,3,14],[14,3,13],[15,3,12],[16,3,9],[17,3,5],[18,3,5],[19,3,10],[20,3,6],[21,3,4],[22,3,4],[23,3,1],[0,4,1],[1,4,3],[2,4,"-"],[3,4,"-"],[4,4,"-"],[5,4,1],[6,4,"-"],[7,4,"-"],[8,4,"-"],[9,4,2],[10,4,4],[11,4,4],[12,4,2],[13,4,4],[14,4,4],[15,4,14],[16,4,12],[17,4,1],[18,4,8],[19,4,5],[20,4,3],[21,4,7],[22,4,3],[23,4,"-"],[0,5,2],[1,5,1],[2,5,"-"],[3,5,3],[4,5,"-"],[5,5,"-"],[6,5,"-"],[7,5,"-"],[8,5,2],[9,5,"-"],[10,5,4],[11,5,1],[12,5,5],[13,5,10],[14,5,5],[15,5,7],[16,5,11],[17,5,6],[18,5,"-"],[19,5,5],[20,5,3],[21,5,4],[22,5,2],[23,5,"-"],[0,6,1],[1,6,"-"],[2,6,"-"],[3,6,"-"],[4,6,"-"],[5,6,"-"],[6,6,"-"],[7,6,"-"],[8,6,"-"],[9,6,"-"],[10,6,1],[11,6,"-"],[12,6,2],[13,6,1],[14,6,3],[15,6,4],[16,6,"-"],[17,6,"-"],[18,6,"-"],[19,6,"-"],[20,6,1],[21,6,2],[22,6,2],[23,6,6]],"label":{"show":true},"emphasis":{"itemStyle":{"shadowBlur":10,"shadowColor":"rgba(0, 0, 0, 0.5)"}}}]}
  2343. 漏斗图(type=12):{"tooltip":{"trigger":"item","formatter":"{a} {b} : {c}%"},"toolbox":{"feature":{"dataView":{"readOnly":false},"restore":{},"saveAsImage":{}}},"legend":{"data":["Show","Click","Visit","Inquiry","Order"]},"series":[{"name":"Funnel","type":"funnel","left":"10%","top":60,"bottom":60,"width":"80%","min":0,"max":100,"minSize":"0%","maxSize":"100%","sort":"descending","gap":2,"label":{"show":true,"position":"inside"},"labelLine":{"length":10,"lineStyle":{"width":1,"type":"solid"}},"itemStyle":{"borderColor":"#fff","borderWidth":1},"emphasis":{"label":{"fontSize":20}},"data":[{"value":60,"name":"Visit"},{"value":40,"name":"Inquiry"},{"value":20,"name":"Order"},{"value":80,"name":"Click"},{"value":100,"name":"Show"}]}]}
  2344. 雷达图(type=13):{"legend":{"data":["Allocated Budget","Actual Spending"]},"radar":{"indicator":[{"name":"Sales","max":6500},{"name":"Administration","max":16000},{"name":"Information Technology","max":30000},{"name":"Customer Support","max":38000},{"name":"Development","max":52000},{"name":"Marketing","max":25000}]},"series":[{"name":"Budget vs spending","type":"radar","data":[{"value":[4200,3000,20000,35000,50000,18000],"name":"Allocated Budget"},{"value":[5000,14000,28000,26000,42000,21000],"name":"Actual Spending"}]}]}
  2345. 基础桑基图(type=14):{"series":{"type":"sankey","layout":"none","emphasis":{"focus":"adjacency"},"data":[{"name":"a"},{"name":"b"},{"name":"a1"},{"name":"a2"},{"name":"b1"},{"name":"c"}],"links":[{"source":"a","target":"a1","value":5},{"source":"a","target":"a2","value":3},{"source":"b","target":"b1","value":8},{"source":"a","target":"b1","value":3},{"source":"b1","target":"a1","value":1},{"source":"b1","target":"c","value":2}]}}
  2346. `;
  2347. let _msg = `ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example".
  2348. Instruction: Based on the context, follow "Format example", write content
  2349. #Context
  2350. ##角色描述
  2351. 你是一位数据分析师,你需要根据用户的提问与ai的回答,读取并统计回答内容中的信息,以所需要的格式输出JSON数据来生成echarts图表
  2352. ##上下文
  2353. 你需要学习《完整版图表类型》《可视化图表的源数据格式》,并理解不同图表类型适用的场景以及绘制不同图表需要源数据表的格式。
  2354. ##任务描述
  2355. 你需要理解用户需求,并通过筛选关键信息、读取并检索对话中的相关信息并进行数据分析与统计,最后以Format example的形式输出统计结果。具体步骤如下:
  2356. 1、读取对话数据或者数据信息,了解文档中的数据内容。
  2357. 2、根据用户的需求,选择合适的可视化图表的类型(图表类型的选择可以从 图表列表 中进行筛选)根据分析的内容筛选出可以生成的图表并输出。
  2358. 3、根据图表类型确定源数据格式,确定每行每列的字段,并在对话数据中,检索相关字段的信息,进行统计。源数据表的格式可以参考知识库中“可视化图表的源数据格式”进行统计。
  2359. 4、输出结果需要与Format example格式一致,只输出json格式的内容并且可以使用JSON.parse()转换成对象,不需要输出多余的内容
  2360. 5、如果没有合适的图表则返回空数组:'[]'。
  2361. 6、如果对话数据无图表的数据,则放回空数组:'[]'
  2362. ##对话数据
  2363. user:
  2364. ${item.content}
  2365. ai:
  2366. ${item.mdText}
  2367. ##图表列表
  2368. ${_eChartsMsg}
  2369. ##Format example
  2370. [{"name":"折线图","type":0,"index":0,"title":"图表内容标题","option":{"xAxis":{"type":"category","data":["data1","data2","data3","data4","data5","data6","data7"]},"yAxis":{"type":"value"},"series":[{"data":[150,230,224,218,135,147,260],"type":"line"}]}},{"name":"柱状图","type":2,"index":1,"title":"图表内容标题","option":{"xAxis":{"type":"category","data":["data1","data2","data2","data3","data4","data5","data6"]},"yAxis":{"type":"value"},"series":[{"data":[120,200,150,80,70,110,130],"type":"bar"}]}},{"name":"基础k线图","type":9,"index":2,"title":"图表内容标题","option":{"xAxis":{"data":["xdata1","xdata2","xdata3","xdata4"]},"yAxis":{},"series":[{"type":"candlestick","data":[[20,34,10,38],[40,35,30,50],[31,38,33,44],[38,15,5,42]]}]}}]
  2371. `;
  2372. let params = {
  2373. model: "gpt-4o-2024-11-20",
  2374. temperature: 0,
  2375. max_tokens: 4096,
  2376. top_p: 1,
  2377. frequency_penalty: 0,
  2378. presence_penalty: 0,
  2379. messages: [{ role: "user", content: _msg }],
  2380. uid: uuidv4(),
  2381. mind_map_question: "",
  2382. stream: false
  2383. };
  2384. this.array.find(i => i.uid === item.uid).loading = true;
  2385. this.ajax
  2386. .post("https://gpt4.cocorobo.cn/chat", params)
  2387. .then(res => {
  2388. let _data = res.data.FunctionResponse.choices[0].message.content;
  2389. _data = _data.replaceAll("```json", "").replaceAll("```", "");
  2390. // const match = _data.match(/{[^{}]*"start"[\s\S]*?"end":\s*""[^{}]*}/);
  2391. // let _result = JSON.parse(match[0]) || null;
  2392. console.log("👉!!!!!!!!!!", _data);
  2393. this.array.find(i => i.uid === item.uid).loading = false;
  2394. this.array.find(i => i.uid === item.uid).echartList = JSON.parse(
  2395. _data
  2396. );
  2397. // console.log("👉",_result)
  2398. // this.$forceUpdate();
  2399. // this.array.find(i => i.uid === item.uid).loading = false;
  2400. // this.array.find(i => i.uid === item.uid).echartData = JSON.parse(
  2401. // _data
  2402. // );
  2403. })
  2404. .catch(e => {
  2405. console.log(e);
  2406. this.array.find(i => i.uid === item.uid).loading = false;
  2407. this.$message.error(`生成图表失败`);
  2408. });
  2409. return;
  2410. //0:柱状图 1:折线图 2:圆饼图
  2411. let _tableData = await this.getContentTable(item.aiContent);
  2412. this.showPopoverUid = null;
  2413. if (_tableData && _tableData.length > 0) {
  2414. let _echartsType = {
  2415. "0": {
  2416. text: `{"xAxis":{"type":"category","data":["数据1","数据2","数据3","数据4","数据5","数据6","数据7"]},"yAxis":{"type":"value"},"series":[{"data":[120,200,150,80,70,110,130],"type":"bar"}]}`,
  2417. label: "柱状图"
  2418. },
  2419. "1": {
  2420. text: `{"xAxis":{"type":"category","data":["数据1","数据2","数据3","数据4","数据5","数据6","数据7"]},"yAxis":{"type":"value"},"series":[{"data":[150,230,224,218,135,147,260],"type":"line"}]}`,
  2421. label: "折线图"
  2422. },
  2423. "2": {
  2424. text: `{"tooltip":{"trigger":"item"},"series":[{"name":"表单名称","type":"pie","radius":"50%","data":[{"value":1048,"name":"数据1"},{"value":735,"name":"数据2"},{"value":580,"name":"数据3"},{"value":484,"name":"数据4"},{"value":300,"name":"数据5"}]}]}`,
  2425. label: "圆饼图"
  2426. }
  2427. };
  2428. let _msg = `ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example".
  2429. Instruction: Based on the context, follow "Format example", write content
  2430. #Context
  2431. ##角色描述
  2432. 你是一位数据分析师,你需要根据用户的提问,读取并统计表格内容中的信息,以所需要的格式输出JSON数据来生成echarts图表
  2433. ##上下文
  2434. 你需要学习《完整版图表类型》《可视化图表的源数据格式》,并理解不同图表类型适用的场景以及绘制不同图表需要源数据表的格式。
  2435. ##任务描述
  2436. 你需要理解用户需求,并通过筛选关键信息、读取并检索文档中的相关信息并进行数据分析与统计,最后以Format example的形式输出统计结果。具体步骤如下:
  2437. 1、读取内容表格信息,了解文档中的数据内容。
  2438. 2、根据用户的需求,选择合适的可视化图表的类型(图表类型的选择可以从柱状图、折线图、饼状图中进行选择。)如果用户提出的需求中已经指定图表类型,可以根据用户指定的输出。
  2439. 3、根据图表类型确定源数据格式,确定每行每列的字段,并在用户上传的数据文档中,检索相关字段的信息,进行统计。源数据表的格式可以参考知识库中“可视化图表的源数据格式”进行统计。
  2440. 4、输出结果需要与Format example格式一致,不需要输出多余的内容
  2441. ##表格内容
  2442. ${JSON.stringify(_tableData)}
  2443. ##图表类型
  2444. ${_echartsType[type].label}
  2445. ##Format example
  2446. ${_echartsType[type].text}
  2447. `;
  2448. let params = {
  2449. model: "gpt-4o-2024-11-20",
  2450. temperature: 0,
  2451. max_tokens: 4096,
  2452. top_p: 1,
  2453. frequency_penalty: 0,
  2454. presence_penalty: 0,
  2455. messages: [{ role: "user", content: _msg }],
  2456. uid: uuidv4(),
  2457. mind_map_question: "",
  2458. stream: false
  2459. };
  2460. this.array.find(i => i.uid === item.uid).loading = true;
  2461. this.ajax
  2462. .post("https://gpt4.cocorobo.cn/chat", params)
  2463. .then(res => {
  2464. let _data = res.data.FunctionResponse.choices[0].message.content;
  2465. _data = _data.replaceAll("```json", "").replaceAll("```", "");
  2466. // const match = _data.match(/{[^{}]*"start"[\s\S]*?"end":\s*""[^{}]*}/);
  2467. // let _result = JSON.parse(match[0]) || null;
  2468. console.log("👉", _data);
  2469. // console.log("👉",_result)
  2470. this.$forceUpdate();
  2471. this.array.find(i => i.uid === item.uid).loading = false;
  2472. this.array.find(i => i.uid === item.uid).echartData = JSON.parse(
  2473. _data
  2474. );
  2475. })
  2476. .catch(e => {
  2477. console.log(e);
  2478. this.$message.error(`生成${_echartsType[type].label}失败`);
  2479. });
  2480. } else {
  2481. return this.$message.error("未提取到表格内容");
  2482. }
  2483. },
  2484. choseEcharts(item1, item2) {
  2485. this.array.find(i => i.uid == item1.uid).loading = true;
  2486. this.array.find(i => i.uid == item1.uid).echartData = item2.option;
  2487. setTimeout(() => {
  2488. this.array.find(i => i.uid == item1.uid).loading = false;
  2489. this.$forceUpdate();
  2490. }, 100);
  2491. },
  2492. getContentTable(_content) {
  2493. return new Promise(resolve => {
  2494. // let _content = this.data.jsonData.content;
  2495. // const md = new markdownIt(); md.render(_content);
  2496. let _contentHtml = _content;
  2497. let _contentTableList = [];
  2498. const rowRegex = /<tr[^>]*>([\s\S]*?)<\/tr>/g; // 匹配表格行,[\s\S] 匹配所有字符
  2499. const cellRegex = /<(th|td)[^>]*>([\s\S]*?)<\/\1>/g; // 匹配单元格,[\s\S] 匹配所有字符
  2500. let rowMatch;
  2501. while ((rowMatch = rowRegex.exec(_contentHtml)) !== null) {
  2502. const rowContent = rowMatch[1]; // 每一行的内容
  2503. const rowData = [];
  2504. let cellMatch;
  2505. // 匹配每个单元格 (th 或 td)
  2506. while ((cellMatch = cellRegex.exec(rowContent)) !== null) {
  2507. let _text = cellMatch[2].trim();
  2508. _text = _text.replace(/&[a-zA-Z]+;/g, "");
  2509. _text = _text.replace(/<\/?[^>]+(>|$)/g, "");
  2510. rowData.push(_text); // 将每个单元格的内容添加到当前行的数组中
  2511. }
  2512. // 如果该行有数据,推送到 _contentTableList 中
  2513. if (rowData.length) {
  2514. _contentTableList.push(rowData);
  2515. }
  2516. }
  2517. // 输出提取的表格数据
  2518. resolve(_contentTableList);
  2519. });
  2520. },
  2521. handleBlur() {
  2522. this.showPopoverUid = null;
  2523. },
  2524. async addNewChat(){
  2525. this.array = [];
  2526. this.fileId = [];
  2527. this.fileList = [];
  2528. this.cid = "";
  2529. this.$parent.menuList = []
  2530. this.$parent.userAsk = "";
  2531. //await this.addChat(this.formList.map(i=>i.name).join(','))
  2532. this.$message.success("新建会话成功")
  2533. }
  2534. },
  2535. computed: {
  2536. localFormList() {
  2537. // 在 computed 属性中返回一个新的数组,而不是直接修改 prop
  2538. let localFormList = [...this.formList];
  2539. return JSON.stringify(localFormList);
  2540. },
  2541. pan() {
  2542. return content => {
  2543. try {
  2544. return JSON.parse(content);
  2545. } catch (error) {
  2546. return [];
  2547. }
  2548. };
  2549. },
  2550. getLook() {
  2551. return function(item) {
  2552. let content = "";
  2553. if (item.look == "1" || item.look == "") {
  2554. content = "未发布";
  2555. }
  2556. let now = new Date().getTime();
  2557. let isTime = item.over_at && new Date(item.over_at).getTime();
  2558. if (
  2559. item.over_at &&
  2560. item.look == "2" &&
  2561. now > isTime &&
  2562. ((item.isUserCount > 0 && item.isUserCount > item.worksPerson) ||
  2563. item.isUserCount == 0)
  2564. ) {
  2565. content = "逾期";
  2566. }
  2567. if (
  2568. ((item.over_at && item.look == "2" && isTime > now) ||
  2569. (!item.over_at && item.look == "2")) &&
  2570. ((item.isUserCount == 0 && item.worksPerson > 0) ||
  2571. (item.isUserCount > 0 &&
  2572. 0 < item.worksPerson &&
  2573. item.worksPerson < item.isUserCount))
  2574. ) {
  2575. content = "进行中";
  2576. }
  2577. if (
  2578. ((item.over_at && item.look == "2" && isTime > now) ||
  2579. (!item.over_at && item.look == "2")) &&
  2580. item.worksPerson == 0
  2581. ) {
  2582. content = "未进行";
  2583. }
  2584. if (
  2585. item.look == "2" &&
  2586. item.isUserCount > 0 &&
  2587. item.isUserCount <= item.worksPerson
  2588. ) {
  2589. content = "已完成";
  2590. }
  2591. return content;
  2592. };
  2593. },
  2594. getLookType() {
  2595. return function(item) {
  2596. let content = "";
  2597. if (item.look == "1" || item.look == "") {
  2598. // content = '未发布'
  2599. content = "no";
  2600. }
  2601. let now = new Date().getTime();
  2602. let isTime = item.over_at && new Date(item.over_at).getTime();
  2603. if (
  2604. item.over_at &&
  2605. item.look == "2" &&
  2606. now > isTime &&
  2607. ((item.isUserCount > 0 && item.isUserCount > item.worksPerson) ||
  2608. item.isUserCount == 0)
  2609. ) {
  2610. // content = '逾期'
  2611. content = "noTime";
  2612. }
  2613. if (
  2614. ((item.over_at && item.look == "2" && isTime > now) ||
  2615. (!item.over_at && item.look == "2")) &&
  2616. ((item.isUserCount == 0 && item.worksPerson > 0) ||
  2617. (item.isUserCount > 0 &&
  2618. 0 < item.worksPerson &&
  2619. item.worksPerson < item.isUserCount))
  2620. ) {
  2621. // content = '进行中'
  2622. content = "doing";
  2623. }
  2624. if (
  2625. ((item.over_at && item.look == "2" && isTime > now) ||
  2626. (!item.over_at && item.look == "2")) &&
  2627. item.worksPerson == 0
  2628. ) {
  2629. // content = '未进行'
  2630. content = "nodo";
  2631. }
  2632. if (
  2633. item.look == "2" &&
  2634. item.isUserCount > 0 &&
  2635. item.isUserCount <= item.worksPerson
  2636. ) {
  2637. // content = '已完成'
  2638. content = "is";
  2639. }
  2640. return content;
  2641. };
  2642. },
  2643. courseTextLength() {
  2644. return this.courseText.length;
  2645. },
  2646. taskName() {
  2647. let task = "";
  2648. if (this.checkArray.length) {
  2649. task = "任务";
  2650. this.checkArray = this.checkArray.sort((a, b) => a - b);
  2651. let a = JSON.parse(JSON.stringify(this.checkArray));
  2652. for (let index = 0; index < a.length; index++) {
  2653. a[index]++;
  2654. }
  2655. task += a.join("/");
  2656. }
  2657. return task + " " + this.part;
  2658. },
  2659. choseRoleList() {
  2660. let result = [...this.roleList, ...this.publicRoleList];
  2661. const _index = this.courseText.lastIndexOf("@");
  2662. if (_index !== -1) {
  2663. let roleName = this.courseText.substring(_index + 1);
  2664. result = result.filter(i => i.assistantName.indexOf(roleName) != -1);
  2665. } else {
  2666. return [];
  2667. }
  2668. this.choseRoleItem = 0;
  2669. return result;
  2670. }
  2671. },
  2672. mounted() {
  2673. // this.getChatList().then(_ => {
  2674. // this.$nextTick(() => {
  2675. // console.log(this.$refs.chatDialog.scrollHeight);
  2676. // this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
  2677. // });
  2678. // });
  2679. // if(this.worksArray.length){
  2680. // this.worksArray.forEach(el=>{
  2681. // this.setJson(el)
  2682. // })
  2683. // }
  2684. // this.selectTestType();
  2685. // 添加初始消息
  2686. this.array.push({
  2687. uid: "", // 生成唯一 ID
  2688. aiContent: "选择需要分析的数据,我将为您分析:", // 初始消息内容
  2689. content: "", // 用户内容为空
  2690. loading: false // 不加载
  2691. });
  2692. }
  2693. };
  2694. </script>
  2695. <style scoped>
  2696. .ai_body {
  2697. /* height: calc(100% - 158px - 46px);
  2698. width: 500px; */
  2699. height: 100%;
  2700. width: 100%;
  2701. /* margin: 0 auto; */
  2702. display: flex;
  2703. flex-direction: column;
  2704. /* position: fixed; */
  2705. /* z-index: 999; */
  2706. background: #fff;
  2707. /* right: 30px; */
  2708. /* bottom: 10px; */
  2709. padding: 10px 20px;
  2710. box-sizing: border-box;
  2711. /* box-shadow: 0 0 5px 2px #00000045;
  2712. border-radius: 5px; */
  2713. position: relative;
  2714. }
  2715. .binfo_input {
  2716. width: 100%;
  2717. margin: 0;
  2718. padding: 12px 14px;
  2719. display: block;
  2720. min-width: 0;
  2721. outline: none;
  2722. box-sizing: border-box;
  2723. background: none;
  2724. border: none;
  2725. border-radius: 4px;
  2726. background: #fff;
  2727. font-size: 14px;
  2728. resize: none;
  2729. font-family: "Microsoft YaHei";
  2730. min-height: 48px;
  2731. /* border: 1px solid #3682fc00; */
  2732. border: 1.5px solid #cad1dc;
  2733. }
  2734. .binfo_textarea {
  2735. border: 1.5px solid #cad1dc;
  2736. font-size: 14px;
  2737. resize: none;
  2738. /* background: #f6f6f6; */
  2739. font-family: "Microsoft YaHei";
  2740. }
  2741. .binfo_textarea::-webkit-scrollbar {
  2742. /*滚动条整体样式*/
  2743. width: 6px;
  2744. /*高宽分别对应横竖滚动条的尺寸*/
  2745. height: 6px;
  2746. }
  2747. /*定义滚动条轨道 内阴影+圆角*/
  2748. .binfo_textarea::-webkit-scrollbar-track {
  2749. border-radius: 10px;
  2750. background-color: rgba(0, 0, 0, 0.1);
  2751. }
  2752. /*定义滑块 内阴影+圆角*/
  2753. .binfo_textarea::-webkit-scrollbar-thumb {
  2754. border-radius: 10px;
  2755. -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
  2756. background-color: rgba(0, 0, 0, 0.1);
  2757. }
  2758. .binfo_input:focus-visible {
  2759. border: 1.5px solid #3681fc !important;
  2760. }
  2761. .ai_body_input {
  2762. position: relative;
  2763. display: flex;
  2764. margin-top: auto;
  2765. width: 100%;
  2766. /* height: auto; */
  2767. /* max-height: 80vh; */
  2768. justify-content: space-between;
  2769. align-items: flex-end;
  2770. border-radius: 10px;
  2771. border: 1.5px solid #3681fc !important;
  2772. /* padding: 10px;
  2773. padding-top: 20px; */
  2774. /* overflow: auto; */
  2775. }
  2776. .ai_b_i_btnArea {
  2777. width: calc(100% - 10px);
  2778. position: absolute;
  2779. bottom: calc(100% + 5px);
  2780. height: 30px;
  2781. display: flex;
  2782. /* justify-content: space-between; */
  2783. }
  2784. .ai_b_i_btnArea > div {
  2785. display: flex;
  2786. align-items: center;
  2787. }
  2788. .ai_b_i_btnArea > div > span {
  2789. margin-left: 5px;
  2790. cursor: pointer;
  2791. }
  2792. .ai_b_i_btnArea > .clear + .clear {
  2793. margin-left: 10px;
  2794. }
  2795. .ai_b_i_btnArea > .clear {
  2796. box-sizing: border-box;
  2797. padding: 5px 10px;
  2798. box-sizing: border-box;
  2799. cursor: pointer;
  2800. border: solid 1px #3781fb;
  2801. border-radius: 15px;
  2802. display: flex;
  2803. font-size: 15px;
  2804. align-items: center;
  2805. justify-content: center;
  2806. background-color: #fff;
  2807. }
  2808. .ai_b_i_btnArea > .clear > svg {
  2809. width: 17px;
  2810. height: 17px;
  2811. margin-right: 5px;
  2812. fill: black;
  2813. }
  2814. .ai_b_i_btnArea > .clear:hover {
  2815. background-color: #ebf4fe;
  2816. color: #409eff;
  2817. }
  2818. .ai_b_i_btnArea > .clear:hover > svg {
  2819. fill: #409eff;
  2820. }
  2821. .ai_b_i_textListBox {
  2822. width: 100%;
  2823. height: 300px;
  2824. background-color: #fff;
  2825. position: absolute;
  2826. bottom: calc(100% + 5px);
  2827. box-sizing: border-box;
  2828. padding: 10px;
  2829. overflow: auto;
  2830. border-radius: 8px;
  2831. border: 1px solid #e7e7e7;
  2832. box-shadow: 0 4px 10px 0 rgba(29, 57, 131, 0.08),
  2833. 1px 1px 20px 4px rgba(29, 57, 131, 0.05);
  2834. display: flex;
  2835. }
  2836. .ai_b_i_tlb_left {
  2837. width: 60px;
  2838. height: 100%;
  2839. background-color: red;
  2840. }
  2841. .ai_b_i_tlb_right {
  2842. flex: 1;
  2843. height: 100%;
  2844. background-color: yellow;
  2845. }
  2846. .ai_b_i_roleListBox {
  2847. width: 100%;
  2848. height: 300px;
  2849. background-color: #fff;
  2850. position: absolute;
  2851. bottom: calc(100% + 5px);
  2852. box-sizing: border-box;
  2853. padding: 10px;
  2854. overflow: auto;
  2855. border-radius: 8px;
  2856. border: 1px solid #e7e7e7;
  2857. box-shadow: 0 4px 10px 0 rgba(29, 57, 131, 0.08),
  2858. 1px 1px 20px 4px rgba(29, 57, 131, 0.05);
  2859. }
  2860. .ai_b_i_rlb_item {
  2861. width: calc(100% - 20px);
  2862. height: auto;
  2863. padding: 10px;
  2864. background-color: #f3f7fd;
  2865. margin-bottom: 20px;
  2866. border-radius: 8px;
  2867. display: flex;
  2868. flex-direction: column;
  2869. justify-content: center;
  2870. transition: 0.3s;
  2871. cursor: pointer;
  2872. }
  2873. .ai_b_i_rlb_itemActive {
  2874. background-color: #d1d5db !important;
  2875. }
  2876. /* .ai_b_i_rlb_item:hover{
  2877. background-color: #d1d5db;
  2878. } */
  2879. .ai_b_i_rlb_itemTop {
  2880. display: flex;
  2881. }
  2882. .ai_b_i_rlb_itemTop > img {
  2883. width: 40px;
  2884. height: 40px;
  2885. margin-right: 10px;
  2886. border-radius: 100%;
  2887. overflow: hidden;
  2888. }
  2889. .ai_b_i_rlb_itemTop > div {
  2890. display: flex;
  2891. flex-direction: column;
  2892. }
  2893. .ai_b_i_rlb_itemTop > div > span {
  2894. font-size: 16px;
  2895. font-weight: bold;
  2896. }
  2897. .ai_b_i_rlb_itemTop > div > span:last-child {
  2898. font-size: 14px;
  2899. color: #999;
  2900. }
  2901. .ai_b_i_rlb_itemBottom {
  2902. margin-top: 10px;
  2903. display: flex;
  2904. }
  2905. .ai_b_i_rlb_itemBottom > span {
  2906. width: 60px;
  2907. height: 30px;
  2908. border-radius: 15px;
  2909. display: flex;
  2910. }
  2911. .ai_body_input_textarea {
  2912. flex: 1;
  2913. margin: 10px 5px 10px 5px;
  2914. min-height: 35px;
  2915. height: 35px;
  2916. max-height: 100px;
  2917. border: none;
  2918. outline: none;
  2919. resize: none;
  2920. font-size: 16px;
  2921. overflow: auto;
  2922. padding-right: 100px;
  2923. background-color: #fff !important;
  2924. }
  2925. .ai_body_input_textarea::-webkit-input-placeholder {
  2926. font-size: 16px;
  2927. /* 修改placeholder字体大小 */
  2928. color: grey;
  2929. /* 修改placeholder文字颜色 */
  2930. }
  2931. .ai_body_input_textarea::-moz-placeholder {
  2932. font-size: 16px;
  2933. /* 修改placeholder字体大小 */
  2934. color: grey;
  2935. /* 修改placeholder文字颜色 */
  2936. opacity: 1;
  2937. /* 修复Firefox的透明度问题 */
  2938. }
  2939. .ai_body_input_textarea::-moz-placeholder {
  2940. font-size: 16px;
  2941. /* 修改placeholder字体大小 */
  2942. color: grey;
  2943. /* 修改placeholder文字颜色 */
  2944. opacity: 1;
  2945. /* 修复Firefox的透明度问题 */
  2946. }
  2947. .ai_body_input_textarea::-ms-input-placeholder {
  2948. font-size: 16px;
  2949. /* 修改placeholder字体大小 */
  2950. color: grey;
  2951. /* 修改placeholder文字颜色 */
  2952. }
  2953. .ai_body_input_textarea::-webkit-scrollbar {
  2954. width: 6px;
  2955. }
  2956. .ai_body_input_textarea::-webkit-scrollbar-track {
  2957. background: #d8d9dc;
  2958. border-radius: 2px;
  2959. }
  2960. .ai_body_input_textarea::-webkit-scrollbar-thumb {
  2961. background: #c9c9c9;
  2962. border-radius: 10px;
  2963. }
  2964. .ai_body_input_textarea::-webkit-scrollbar-thumb:hover {
  2965. background: #c9c9c9;
  2966. }
  2967. .dialog_diy {
  2968. position: fixed;
  2969. top: 45%;
  2970. left: 50%;
  2971. transform: translate(-50%, -50%) !important;
  2972. z-index: 1;
  2973. width: 150vw;
  2974. height: 100vh;
  2975. overflow: hidden;
  2976. transition: none !important;
  2977. }
  2978. .dialog_diy >>> .el-dialog__header {
  2979. background: #454545 !important;
  2980. padding: 15px 20px;
  2981. }
  2982. .dialog_diy >>> .el-dialog__header > span {
  2983. color: #fff;
  2984. }
  2985. .dialog_diy .el-dialog__header .el-dialog__title {
  2986. color: #fff !important;
  2987. /* 替换为您想要的颜色 */
  2988. line-height: 14px;
  2989. font-size: 14px;
  2990. }
  2991. /* 禁用过渡动画 */
  2992. .el-dialog__wrapper {
  2993. animation: none !important;
  2994. /* 禁用外部包裹层的过渡动画 */
  2995. }
  2996. .el-dialog {
  2997. transition: none !important;
  2998. /* 禁用弹窗内部的动画 */
  2999. }
  3000. .c_pub_button_confirm {
  3001. /* position: absolute;
  3002. bottom: 13px;
  3003. right: 13px; */
  3004. /* margin-top: 10px; */
  3005. width: 60px;
  3006. margin-right: 5px;
  3007. display: flex;
  3008. justify-content: center;
  3009. margin-bottom: 10px;
  3010. position: absolute;
  3011. right: 10px;
  3012. bottom: 0px;
  3013. white-space: nowrap;
  3014. border-radius: 10px;
  3015. }
  3016. .c_pub_button_confirmVoice {
  3017. width: 30px;
  3018. height: 36px;
  3019. min-width: auto;
  3020. margin-right: 5px;
  3021. display: flex;
  3022. justify-content: center;
  3023. align-items: center;
  3024. margin-bottom: 10px;
  3025. position: absolute;
  3026. right: 10px;
  3027. bottom: 0px;
  3028. white-space: nowrap;
  3029. border-radius: 10px;
  3030. background-color: #3681fc;
  3031. cursor: pointer;
  3032. padding: 0 10px;
  3033. }
  3034. .c_pub_button_confirmVoice > svg {
  3035. fill: #fff;
  3036. width: 25px;
  3037. height: 25px;
  3038. }
  3039. .c_pub_button_StopConfirmVoice {
  3040. width: 30px;
  3041. height: 36px;
  3042. min-width: auto;
  3043. margin-right: 5px;
  3044. display: flex;
  3045. justify-content: center;
  3046. align-items: center;
  3047. margin-bottom: 10px;
  3048. position: absolute;
  3049. right: 10px;
  3050. bottom: 0px;
  3051. white-space: nowrap;
  3052. border-radius: 10px;
  3053. background-color: #dde2e2;
  3054. cursor: pointer;
  3055. padding: 0 10px;
  3056. }
  3057. .c_pub_button_StopConfirmVoice > svg {
  3058. width: 25px;
  3059. height: 25px;
  3060. }
  3061. .c_voiceBtn {
  3062. width: 25px;
  3063. height: 25px;
  3064. position: absolute;
  3065. right: 85px;
  3066. bottom: 0px;
  3067. margin-bottom: 17px;
  3068. cursor: pointer;
  3069. }
  3070. .c_voiceBtn > svg {
  3071. width: 100%;
  3072. height: 100%;
  3073. }
  3074. .c_pub_button_confirmDisabled {
  3075. background-color: #aeccfe;
  3076. }
  3077. .ai_body_dialog {
  3078. padding: 10px 0;
  3079. box-sizing: border-box;
  3080. height: calc(100% - 70px);
  3081. overflow: auto;
  3082. /* min-height: calc(20vh - 10px); */
  3083. /* height: calc(100%); */
  3084. /* overflow: auto; */
  3085. margin-bottom: 10px;
  3086. }
  3087. .dialog_content {
  3088. width: 100%;
  3089. display: flex;
  3090. flex-direction: column;
  3091. }
  3092. .dialog_content > div {
  3093. display: flex;
  3094. align-items: flex-start;
  3095. width: 100%;
  3096. }
  3097. .dialog_content + .dialog_content {
  3098. margin: 15px 0;
  3099. }
  3100. .dialog_content > div .right {
  3101. flex-direction: row-reverse;
  3102. }
  3103. .dialog_content > div .right .role {
  3104. margin-right: 0;
  3105. margin-left: 10px;
  3106. }
  3107. .dialog_content > div .role {
  3108. min-width: 30px;
  3109. width: 30px;
  3110. height: 30px;
  3111. margin-right: 10px;
  3112. border-radius: 50%;
  3113. }
  3114. .dialog_content > div .role > img {
  3115. height: 100%;
  3116. width: 100%;
  3117. border-radius: 100%;
  3118. }
  3119. .dialog_content > div .content {
  3120. padding: 10px 10px;
  3121. border-radius: 2px 8px 8px 8px;
  3122. width: auto;
  3123. word-break: break-word;
  3124. box-sizing: border-box;
  3125. /* white-space: pre-line; */
  3126. max-width: calc(100% - 85px);
  3127. background: #f6f9ff;
  3128. /* overflow: hidden; */
  3129. margin: 0 10px;
  3130. position: relative;
  3131. }
  3132. .loadingDiv {
  3133. display: flex;
  3134. justify-content: center;
  3135. align-items: center;
  3136. }
  3137. /* 遮罩层样式 */
  3138. .mask {
  3139. position: fixed;
  3140. top: 0;
  3141. left: 0;
  3142. right: 0;
  3143. bottom: 0;
  3144. background: rgba(0, 0, 0, 0.5);
  3145. /* 半透明黑色 */
  3146. z-index: 10;
  3147. /* 层级 */
  3148. }
  3149. .loadingDiv2 {
  3150. background-color: #f6f9ff;
  3151. border-radius: 8px;
  3152. box-shadow: 10px 10px 15px rgba(0, 0, 0, 0.3);
  3153. z-index: 20;
  3154. position: fixed;
  3155. padding: 10px;
  3156. top: 50%;
  3157. left: 50%;
  3158. transform: translate(-50%, -50%) !important;
  3159. display: flex;
  3160. justify-content: center;
  3161. align-items: center;
  3162. transition: none !important;
  3163. }
  3164. .loadingImg {
  3165. width: 30px;
  3166. height: 30px;
  3167. }
  3168. .guess_title {
  3169. display: flex;
  3170. align-items: center;
  3171. }
  3172. .guess_title > img {
  3173. width: 16px;
  3174. height: 16px;
  3175. }
  3176. .guess_title > span {
  3177. font-weight: bold;
  3178. }
  3179. .guess_item {
  3180. width: 100%;
  3181. height: auto;
  3182. box-sizing: border-box;
  3183. padding: 10px;
  3184. background-color: #ffffff;
  3185. border-radius: 5px;
  3186. margin-top: 10px;
  3187. color: #666666;
  3188. font-size: 14px;
  3189. cursor: pointer;
  3190. border: solid #ffffff 1px;
  3191. box-shadow: 0 0 5px 2px #ffffff;
  3192. }
  3193. .guess_item:hover {
  3194. border: solid #b8d2fe 1px;
  3195. box-shadow: 0 0 5px 2px #b8d2fe;
  3196. }
  3197. .createTime {
  3198. width: 100%;
  3199. height: 20px;
  3200. position: absolute;
  3201. bottom: -25px;
  3202. left: 0;
  3203. font-size: 14px;
  3204. white-space: nowrap;
  3205. color: #919191;
  3206. }
  3207. .dialog_content > div .content2 {
  3208. background: #3681fc;
  3209. color: #fff;
  3210. border-radius: 8px 2px 8px 8px;
  3211. margin-left: auto;
  3212. }
  3213. .custom-div {
  3214. margin: 20px;
  3215. width: 154px;
  3216. height: 211px;
  3217. border: 2px solid #4398f1;
  3218. box-shadow: 0px 5px 10px rgba(128, 128, 128, 0.5);
  3219. cursor: pointer;
  3220. border-radius: 5px;
  3221. display: flex;
  3222. align-items: center;
  3223. flex-direction: column;
  3224. }
  3225. .custom-div.active {
  3226. border: 2px solid blue;
  3227. }
  3228. .dialog_contentArea {
  3229. margin-top: -17px;
  3230. min-height: 70vh;
  3231. max-height: 70vh;
  3232. /* 设置内容区域的最大高度 */
  3233. overflow-y: auto;
  3234. }
  3235. .custom-icon {
  3236. background: url("../../../../assets/icon/test/test_upload.png") no-repeat;
  3237. width: 142px;
  3238. height: 142px;
  3239. display: inline-block;
  3240. background-size: contain;
  3241. }
  3242. .tableClass {
  3243. margin-top: 10px;
  3244. z-index: 5;
  3245. }
  3246. .tableClass >>> .el-dialog__body {
  3247. padding: 13px 20px;
  3248. }
  3249. .is {
  3250. color: rgb(57, 204, 127);
  3251. background-color: rgba(57, 204, 127, 0.1);
  3252. }
  3253. .no {
  3254. color: rgb(235, 154, 96);
  3255. background-color: rgba(235, 154, 96, 0.1);
  3256. }
  3257. .noTime {
  3258. color: rgb(77, 77, 77);
  3259. background-color: rgba(77, 77, 77, 0.1);
  3260. }
  3261. .doing {
  3262. color: rgb(54, 116, 231);
  3263. background-color: rgba(54, 116, 231, 0.1);
  3264. }
  3265. .nodo {
  3266. color: rgb(97, 184, 255);
  3267. background-color: rgba(97, 184, 255, 0.1);
  3268. }
  3269. .test_type2 {
  3270. font-size: 14px;
  3271. border-radius: 5px;
  3272. /* border: 1.5px solid; */
  3273. padding: 3px 8px;
  3274. }
  3275. .student_bottom {
  3276. display: flex;
  3277. justify-content: space-between;
  3278. }
  3279. .pageCount {
  3280. display: flex;
  3281. align-items: center;
  3282. }
  3283. .student_head {
  3284. display: flex;
  3285. justify-content: space-between;
  3286. align-items: baseline;
  3287. flex-direction: row;
  3288. flex-wrap: wrap;
  3289. padding: 0 0 0;
  3290. }
  3291. .choose {
  3292. display: flex;
  3293. flex-direction: row;
  3294. flex-wrap: wrap;
  3295. align-content: space-between;
  3296. height: 100%;
  3297. justify-content: flex-start;
  3298. /* width: 60%; */
  3299. /* min-width: 868px; */
  3300. align-items: center;
  3301. }
  3302. .choose > div {
  3303. /* margin-left: 10px; */
  3304. width: 180px;
  3305. /* margin-top: 15px; */
  3306. }
  3307. .choose > div + div {
  3308. margin-left: 10px;
  3309. }
  3310. .choose > .clear {
  3311. width: 70px;
  3312. }
  3313. .student_search {
  3314. display: flex;
  3315. align-items: center;
  3316. /* width: calc(100% / 3); */
  3317. width: 190px;
  3318. }
  3319. .head_left {
  3320. display: flex;
  3321. }
  3322. .student_input >>> .el-input__inner {
  3323. height: 40px;
  3324. width: 190px;
  3325. font-size: 13px;
  3326. padding: 0 10px;
  3327. }
  3328. .serach_icon {
  3329. position: absolute;
  3330. right: 12px;
  3331. top: 50%;
  3332. transform: translateY(-50%);
  3333. width: 13px;
  3334. height: 13px;
  3335. background: url("../../../../assets/icon/test/test_search.png") no-repeat;
  3336. background-size: 100% 100%;
  3337. cursor: pointer;
  3338. }
  3339. .ai_body_select {
  3340. position: relative;
  3341. }
  3342. .ai_body_select > .check {
  3343. background: #e7e7e7;
  3344. display: flex;
  3345. width: fit-content;
  3346. padding: 0 10px;
  3347. height: 30px;
  3348. border-radius: 21px;
  3349. font-size: 14px;
  3350. align-items: center;
  3351. justify-content: center;
  3352. color: #0061ff;
  3353. font-weight: 700;
  3354. margin: 10px 0;
  3355. cursor: pointer;
  3356. }
  3357. .ai_body_select > .check::before {
  3358. content: "";
  3359. width: 15px;
  3360. height: 15px;
  3361. display: block;
  3362. background-image: url("../../../../assets/icon/course/aiPart.png");
  3363. background-size: 100% 100%;
  3364. margin-right: 5px;
  3365. }
  3366. .ai_body_select > .check::after {
  3367. content: "";
  3368. width: 15px;
  3369. height: 15px;
  3370. display: block;
  3371. background-image: url("../../../../assets/icon/course/aiPart_arrow.png");
  3372. background-size: 100% 100%;
  3373. margin-right: 5px;
  3374. }
  3375. .ai_body_select > .isCheck {
  3376. background: #0061ff;
  3377. display: flex;
  3378. width: fit-content;
  3379. padding: 0 10px;
  3380. height: 30px;
  3381. border-radius: 21px;
  3382. font-size: 14px;
  3383. align-items: center;
  3384. justify-content: center;
  3385. color: #fff;
  3386. font-weight: 700;
  3387. margin: 10px 0;
  3388. cursor: pointer;
  3389. max-width: 100%;
  3390. box-sizing: border-box;
  3391. }
  3392. .ai_body_select > .isCheck > span {
  3393. width: calc(100% - 40px);
  3394. display: block;
  3395. overflow: hidden;
  3396. white-space: nowrap;
  3397. text-overflow: ellipsis;
  3398. }
  3399. .ai_body_select > .isCheck::before {
  3400. content: "";
  3401. width: 15px;
  3402. height: 15px;
  3403. display: block;
  3404. background-image: url("../../../../assets/icon/course/aiPart_active.png");
  3405. background-size: 100% 100%;
  3406. margin-right: 5px;
  3407. }
  3408. .ai_body_select > .isCheck::after {
  3409. content: "";
  3410. width: 15px;
  3411. height: 15px;
  3412. display: block;
  3413. background-image: url("../../../../assets/icon/course/aiPart_arrow_active.png");
  3414. background-size: 100% 100%;
  3415. margin-right: 5px;
  3416. }
  3417. .ai_body_select > .checkBox {
  3418. position: absolute;
  3419. bottom: 40px;
  3420. border: 1px solid #e0eafb;
  3421. width: 100%;
  3422. height: 300px;
  3423. background: #fff;
  3424. border-radius: 5px;
  3425. padding: 10px;
  3426. box-sizing: border-box;
  3427. }
  3428. .ai_body_select > .checkBox > .task > .title,
  3429. .ai_body_select > .checkBox > .part > .title {
  3430. font-size: 14px;
  3431. font-weight: 700;
  3432. margin-bottom: 5px;
  3433. }
  3434. .ai_body_select > .checkBox > .task {
  3435. height: calc(100% - 60px);
  3436. }
  3437. .ai_body_select > .checkBox > .part {
  3438. }
  3439. .ai_body_select > .checkBox > .task > .content {
  3440. height: calc(100% - 40px);
  3441. overflow: auto;
  3442. }
  3443. .ai_body_select > .checkBox > .task > .content > .span + .span {
  3444. margin-top: 5px;
  3445. }
  3446. .ai_body_select > .checkBox > .task > .content > .span {
  3447. display: flex;
  3448. align-items: center;
  3449. font-size: 14px;
  3450. cursor: pointer;
  3451. }
  3452. .ai_body_select > .checkBox > .task > .content > .span > .check {
  3453. width: 13px;
  3454. height: 13px;
  3455. display: flex;
  3456. align-items: center;
  3457. margin-right: 5px;
  3458. }
  3459. .ai_body_select > .checkBox > .task > .content > .span > .check > img {
  3460. width: 100%;
  3461. height: 100%;
  3462. }
  3463. .ai_body_select > .checkBox > .part > .content {
  3464. display: flex;
  3465. align-items: center;
  3466. font-size: 14px;
  3467. justify-content: space-between;
  3468. }
  3469. .ai_body_select > .checkBox > .part > .content > .span {
  3470. padding: 3px 6px;
  3471. border: 1px solid #e0eafb;
  3472. border-radius: 40px;
  3473. cursor: pointer;
  3474. }
  3475. .ai_body_select > .checkBox > .part > .content > .span.active {
  3476. color: #0061ff;
  3477. border-color: #0061ff;
  3478. }
  3479. .jlist_box {
  3480. background: #f1f1f1;
  3481. border-radius: 5px;
  3482. margin-bottom: 10px;
  3483. padding: 8px 18px 8px 8px;
  3484. box-sizing: border-box;
  3485. width: 100%;
  3486. position: relative;
  3487. }
  3488. .jlist_box .cancel {
  3489. position: absolute;
  3490. top: 8px;
  3491. right: 5px;
  3492. cursor: pointer;
  3493. font-size: 14px;
  3494. }
  3495. .jlist_box > span {
  3496. display: -webkit-box;
  3497. -webkit-box-orient: vertical;
  3498. -webkit-line-clamp: 3;
  3499. text-overflow: ellipsis;
  3500. overflow: hidden;
  3501. word-break: break-all;
  3502. }
  3503. .ai_btn_box {
  3504. min-width: fit-content;
  3505. margin-top: auto;
  3506. display: flex;
  3507. flex-direction: column;
  3508. }
  3509. .ai_btn_box > img {
  3510. cursor: pointer;
  3511. width: 15px;
  3512. margin-bottom: 10px;
  3513. }
  3514. .iconfont {
  3515. font-family: "iconfont" !important;
  3516. font-size: 50px;
  3517. font-style: normal;
  3518. -webkit-font-smoothing: antialiased;
  3519. -moz-osx-font-smoothing: grayscale;
  3520. color: blue;
  3521. }
  3522. .popoverBox {
  3523. width: auto;
  3524. height: auto;
  3525. position: relative;
  3526. margin-bottom: 10px;
  3527. }
  3528. .btnBox {
  3529. width: 15px;
  3530. height: 15px;
  3531. }
  3532. .btnBox > img {
  3533. width: 100%;
  3534. height: 100%;
  3535. cursor: pointer;
  3536. }
  3537. .showBox {
  3538. width: 60px;
  3539. height: auto;
  3540. padding: 10px;
  3541. position: absolute;
  3542. left: calc(100% + 10px);
  3543. top: 0px;
  3544. background-color: #fff;
  3545. border-radius: 5px;
  3546. box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  3547. }
  3548. .showBox > span {
  3549. width: 100%;
  3550. height: auto;
  3551. padding: 5px 0;
  3552. display: flex;
  3553. align-items: center;
  3554. justify-content: center;
  3555. cursor: pointer;
  3556. border-radius: 4px;
  3557. background-color: #fff;
  3558. transition: 0.3s;
  3559. font-size: 16px;
  3560. }
  3561. .showBox > span:hover {
  3562. background-color: #e2e2e2;
  3563. }
  3564. .eChartView {
  3565. width: 100%;
  3566. min-width: 500px;
  3567. height: 400px;
  3568. }
  3569. .echartBtn {
  3570. /* border-color: #66b1ff;
  3571. background: none;
  3572. color: #66b1ff; */
  3573. color: #5087EC;
  3574. margin-top: 10px;
  3575. font-weight: bold;
  3576. cursor: pointer;
  3577. }
  3578. .echartBtn>img{
  3579. width: 15px;
  3580. height: 15px;
  3581. margin-right: 10px;
  3582. }
  3583. .echartBtn:hover{
  3584. text-decoration: underline;
  3585. }
  3586. .ai_b_addNewChat{
  3587. width: 40px;
  3588. height: 40px;
  3589. z-index: 99;
  3590. box-sizing: border-box;
  3591. }
  3592. .ai_b_addNewChat>span{
  3593. display: flex;
  3594. width: 100%;
  3595. height: 100%;
  3596. align-items: center;
  3597. justify-content: center;
  3598. font-size: 1.5em;
  3599. border-radius: 50%;
  3600. cursor: pointer;
  3601. color: #1296DB;
  3602. box-sizing: border-box;
  3603. /* border: solid 1px #1296DB; */
  3604. background-color: #fff;
  3605. box-shadow: rgba(0, 0, 0, .2) 2px 2px 8px 0px;
  3606. }
  3607. </style>