aiLeader.vue 108 KB

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