searchArea.vue 110 KB

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