123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788 |
- <template>
- <div class="dialog">
- <div v-show="cardType == 0">
- <div class="d_top" ref="chatRef">
- <div class="d_t_chat" v-for="(item, index) in chatList" :key="index">
- <div
- class="d_t_c_user"
- v-if="item.content && item.content != 'addAsk'"
- >
- <div class="d_t_c_u_left">
- <div class="d_t_c_u_l_content">{{ item.content }}</div>
- <div class="d_t_c_u_l_time">{{ item.createtime }}</div>
- </div>
- <div class="d_t_c_u_right">
- <span>Me</span>
- </div>
- </div>
- <div class="d_t_c_ai" v-if="item.content != 'addAsk'">
- <div class="d_t_c_a_left">
- <el-avatar v-if="item.filename" :src="item.filename"></el-avatar>
- <span v-else>AI</span>
- </div>
- <div class="d_t_c_a_right">
- <div
- class="d_t_c_a_r_content"
- style="display: flex;justify-content: space-between;flex-wrap: wrap;"
- v-if="pan(item.aiContent).length"
- >
- <div
- v-if="!pan(item.aiContent).length"
- class="d_t_c_a_r_content"
- v-loading="item.loading"
- v-html="item.aiContent"
- ></div>
- <div
- v-else
- v-for="i in pan(item.aiContent)"
- style="position: relative;"
- class="d_t_c_a_r_c_img"
- >
- <img
- style="width: 130px;height: 130px;object-fit: cover;"
- :src="i.image"
- alt=""
- @click="previewImg(i.image)"
- />
- <span class="download_image" @click.stop="download(i.image)">
- <img
- :src="
- require('../../../assets/icon/fileIcon/download.png')
- "
- />
- </span>
- </div>
- </div>
- <div
- v-else
- class="d_t_c_a_r_content"
- v-loading="item.loading"
- v-html="htmlContent(item.aiContent)"
- ></div>
- <div
- v-if="!pan(item.aiContent).length && !item.loading"
- class="aiCopy"
- >
- <img
- @click="onCopy(item.aiContent)"
- style="width: 30px;"
- src="../../../assets/icon/course/copyTxt.png"
- alt=""
- />
- <img @click.stop="aiTalkAll(item)" v-if="aiTalkUid==item.uid && aiIsTalk" style="width: 15px;margin:7px 0 7px 7px;" :src="require('../../../assets/icon/course/megaphone.svg')">
- <img @click.stop="aiTalkAll(item)" v-else style="width: 15px;margin:7px 0 7px 7px;" :src="require('../../../assets/icon/course/megaphone3.svg')">
- <img v-if="chatList.length-2 == index" @click.stop="refresh(item)" style="width: 15px;margin:7px 0 7px 7px;" :src="require('../../../assets/icon/course/refresh.svg')">
- </div>
- <div class="d_t_c_a_r_time">{{ item.createtime }}</div>
- </div>
- </div>
- <div
- class="s_t_addAsk"
- v-if="
- item.content == 'addAsk' &&
- !item.aiContent.questions &&
- item.aiContent.length &&
- !item.loading
- "
- >
- <span
- v-for="item2 in item.aiContent"
- :key="item2.index"
- @click.stop="send(item2.label)"
- >{{ item2.label }}</span
- >
- </div>
- <div
- class="s_t_addAsk"
- v-if="
- item.content == 'addAsk' &&
- item.aiContent.questions &&
- !item.loading
- "
- >
- <span
- v-for="(item2, index2) in item.aiContent.questions"
- :key="index2"
- @click.stop="send(item2.question ? item2.question : item2)"
- >{{ item2.question ? item2.question : item2 }}</span
- >
- </div>
- <div
- class="s_t_addAsk"
- v-if="item.content == 'addAsk' && item.loading"
- >
- <span style="width:50px;height:50px" v-loading="true"></span>
- </div>
- </div>
- </div>
- <div class="d_bottom">
- <div class="s_b_btnAreaTop">
- <div class="s_b_bat_left">
- <el-tooltip
- class="item"
- effect="dark"
- content="Clear chat history"
- placement="top"
- >
- <img
- :src="require('../../../assets/icon/course/clean.svg')"
- @click.stop="clear()"
- />
- </el-tooltip>
- <el-tooltip
- class="item"
- effect="dark"
- :content="openMegaphone ? 'Turn off the megaphone' : 'Turn on the megaphone'"
- placement="top"
- >
- <img
- v-if="!openMegaphone"
- :src="require('../../../assets/icon/course/megaphone2.svg')"
- @click.stop="$parent.changeMegaphone()"
- />
- <img
- v-else
- :src="require('../../../assets/icon/course/megaphone.svg')"
- @click.stop="$parent.changeMegaphone()"
- />
- </el-tooltip>
- </div>
- <div class="s_b_bat_right">
- <!-- <img :src="require('../../../assets/icon/course/bulb.svg')"> -->
- <img :src="require('../../../assets/icon/course/bulb2.svg')">
- </div>
- </div>
- <div class="d_b_btnArea">
- <div class="d_b_ba-item" @click.stop="choiceRole()">
- <img
- style="width: 20px;"
- src="../../../assets/icon/course/role.png"
- alt=""
- />
- Choose Intelligent Agent
- </div>
- </div>
- <div class="d_b_inputArea">
- <!-- <div class="d_b_tape" @click="goTape()"></div> -->
- <div class="d_b_input">
- <el-input
- :disabled="loading || chatLoading || sendFnType == 1"
- v-loading="loading || chatLoading"
- @keyup.enter.native="send()"
- :placeholder="
- sendFnType == 0
- ? 'Please enter the content you want to know here'
- : 'Please click the recording button to start recording'
- "
- class="d_b_i_left"
- v-model="text"
- ></el-input>
- <!-- <div class="d_b_i_right" @click="sendFile()">
- <span></span>
- </div> -->
- </div>
- <div class="voice_or_keyboard">
- <el-tooltip
- v-if="sendFnType == 0"
- class="item"
- effect="dark"
- content="Use voice"
- placement="top"
- >
- <img
- :src="require('../../../assets/icon/course/voice.svg')"
- @click.stop="changeFnType(1)"
- />
- </el-tooltip>
- <el-tooltip
- v-if="sendFnType == 1"
- class="item"
- effect="dark"
- content="Use keyboard"
- placement="top"
- >
- <img
- :src="require('../../../assets/icon/course/keyboard.svg')"
- @click.stop="changeFnType(0)"
- />
- </el-tooltip>
- </div>
- <div class="d_b_btn" @click="send()" v-if="sendFnType == 0">
- <span v-if="!loading && !chatLoading"></span>
- <div v-else @click.stop="stopSend()">Stop</div>
- </div>
- <div class="d_b_btn" v-if="sendFnType == 1">
- <img
- v-if="!loading && !chatLoading && !isTalk"
- @click.stop="talk()"
- :src="require('../../../assets/icon/course/voice2.svg')"
- />
- <img
- style="width:50px;height:50px"
- v-else-if="!loading && !chatLoading && isTalk"
- @click.stop="stopTalk()"
- :src="require('../../../assets/icon/course/isTape.svg')"
- />
- <div v-else @click.stop="stopSend()">Stop</div>
- </div>
- </div>
- </div>
- </div>
- <div class="" v-show="cardType == 1">
- <div class="choiceTop">
- <div class="choiceRoleHeader">
- <div>Switch Role:</div>
- <span>Please choose which role you would like to answer your question:</span>
- </div>
- <div class="choiceSelect">
- <el-button
- class="option"
- :style="{
- background: sortOption == 0 ? '#36A9FC' : '',
- color: sortOption == 0 ? '#fff' : ''
- }"
- @click="optBtn(0)"
- plain
- >My</el-button
- >
- <el-button
- class="option"
- :style="{
- background: sortOption == 1 ? '#36A9FC' : '',
- color: sortOption == 1 ? '#fff' : ''
- }"
- @click="optBtn(1)"
- plain
- >Community</el-button
- >
- </div>
- <div
- class="characterBlock"
- v-if="sortOption == 0"
- v-for="(item, index) in roleList"
- :key="item.id"
- @click.stop="choseRole(item)"
- >
- <div class="imgLeft">
- <div class="img">
- <img style="width: 100%;height: 100%;" :src="item.avatar" />
- </div>
- </div>
- <div class="txtRight">
- <div class="bir">{{ item.assistantName }}</div>
- <div
- :style="{
- color: '#fff',
- display:
- choseRoleItem.assistant_id == item.assistant_id
- ? 'block'
- : 'none'
- }"
- >
- Selected
- </div>
- <!-- <span></span> -->
- </div>
- </div>
- <div
- class="characterBlock"
- v-if="sortOption == 1"
- v-for="(item, index) in roleList2"
- :key="item.id"
- @click.stop="choseRole(item)"
- >
- <div class="imgLeft">
- <div class="img">
- <img
- style="width: 100%;height: 100%;"
- :src="
- item.headUrl
- ? item.headUrl
- : require('../../../assets/icon/course/ai.png')
- "
- />
- </div>
- </div>
- <div class="txtRight">
- <div class="bir">{{ item.assistantName }}</div>
- <div
- :style="{
- color: '#fff',
- display:
- choseRoleItem.assistant_id == item.assistant_id
- ? 'block'
- : 'none'
- }"
- >
- Selected
- </div>
- <!-- <span></span> -->
- </div>
- </div>
- <!-- <div class="characterBlock" @click="addCharacter">
- <div class="imgLeft">
- <div class="img2">
- <img style="width: 100%;height: 100%;" src="https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/basil_add-outline1715564539170.png">
- </div>
- </div>
- <div class="txtRight">
- <div style="color: #fff;margin-left: 5px;">添加新角色</div>
- </div>
- </div> -->
- <!-- <div class="filterSubjects">
- <div class="fs_title">筛选科目</div>
- <div class="fs_box">
- <div :class="['fs_b_item',subjectsType==index?'fs_b_itemActive':'']" v-for="(item,index) in subjectsList" :key="index" @click="subjectsType = index">{{ item }}</div>
- </div>
- </div>
- <div class="roleList">
- <div class="r_title">角色列表 ({{ roleList.length }})</div>
- <div class="r_box">
- <div :class="['r_b_item',roleType==index?'r_b_itemActive':'']" v-for="(item,index) in roleList" :key="item.id" @click.stop="roleType=index">
- <img :src="item.avatar">
- <span>{{ item.name }}</span>
- </div>
- </div>
- </div> -->
- </div>
- <div class="choiceBottom">
- <el-button class="cb_btn" size="mini" @click="noChangeRole()"
- >Cancel</el-button
- >
- <el-button
- class="cb_btn"
- size="mini"
- type="primary"
- @click="changeRole()"
- >Confirm</el-button
- >
- </div>
- </div>
- <iframe
- allow="camera *; microphone *;display-capture;midi;encrypted-media;"
- src="https://beta.cloud.cocorobo.cn/browser/public/index.html"
- ref="iiframe"
- v-show="false"
- ></iframe>
- <!-- Text to Speech -->
- <iframe
- allow="camera *; microphone *;display-capture;midi;encrypted-media;"
- src="https://beta.cloud.cocorobo.cn/browser/public/index1.html"
- ref="iiframe2"
- v-show="false"
- ></iframe>
- </div>
- </template>
- <script>
- import { v4 as uuidv4 } from "uuid";
- import MarkdownIt from "markdown-it";
- var OpenCC = require("opencc-js");
- let converter = OpenCC.Converter({
- from: "hk",
- to: "cn"
- });
- export default {
- props: {
- fileId: {
- type: Array,
- default: () => []
- },
- openMegaphone: {
- type: Boolean,
- default: false
- }
- },
- data() {
- return {
- sendFnType: 0,
- isTalk: false,
- cardType: 0, //0-对话 1-选角色
- userid: this.$route.query.userid,
- courseId: this.$route.query.courseId,
- org: this.$route.query.org,
- choseRoleItem: {},
- text: "",
- sortOption: 0, //切换角色 0我的 1 社区
- subjectsList: [
- "语文",
- "数学",
- "英语",
- "科学",
- "信息",
- "历史",
- "地理",
- "政治",
- "生物",
- "化学",
- "物理",
- "其他"
- ],
- subjectsType: -1,
- rightSubjects: -1,
- roleType: -1,
- rightRole: -1,
- loading: false,
- chatLoading: false,
- roleList2: [],
- chatList: [],
- nowChatList: [],
- source: null,
- saveUid: "",
- aiTalkList: [],
- aiIsTalk: false,
- aiTalkUid: "",
- userName:"",
- };
- },
- computed: {
- pan() {
- return content => {
- try {
- return JSON.parse(content);
- } catch (error) {
- return [];
- }
- };
- },
- htmlContent() {
- const md = new MarkdownIt();
- return _md => {
- return md.render(_md);
- };
- }
- },
- methods: {
- refresh(item) {
- this.send(item.content);
- },
- changeFnType(newValue) {
- if (this.isTalk) return this.$message.info("Please stop recording first");
- this.sendFnType = newValue;
- },
- talk() {
- let iiframe = this.$refs["iiframe"];
- iiframe.contentWindow.window.document.getElementById(
- "languageOptions"
- ).selectedIndex = 2; //普通话
- iiframe.contentWindow.testdoContinuousPronunciationAssessment();
- this.isTalk = true;
- iiframe.contentWindow.onRecognizedResult = e => {
- let _msg = e.privText;
- console.log(_msg)
- if (_msg) this.text += _msg;
- };
- },
- stopTalk() {
- if (!this.isTalk) return this.$message.info("请先开始录音");
- //this.isTalk = false;
- let iiframe = this.$refs["iiframe"];
- iiframe.contentWindow.window.document
- .getElementById("scenarioStopButton")
- .click();
- iiframe.contentWindow.onSessionStopped = (s, e) => {
- this.isTalk = false;
- this.send();
- };
- },
- stopSend() {
- if (this.source) {
- this.source.close();
- if (this.chatList[this.chatList.length - 1].content == "wanSearch") {
- this.chatList.pop();
- }
- this.loading = false;
- this.chatLoading = false;
- this.source = null;
- this.insertChat(this.saveUid);
- }
- },
- onCopy(content) {
- // 创建临时textarea元素
- const tempInput = document.createElement("textarea");
- tempInput.value = content; // 设置要复制的内容
- // 隐藏元素
- tempInput.style.position = "absolute";
- tempInput.style.left = "-9999px";
- // 将元素添加到DOM中
- document.body.appendChild(tempInput);
- // 选中元素内容
- tempInput.select();
- // 执行复制操作
- document.execCommand("copy");
- // 移除临时元素
- document.body.removeChild(tempInput);
- this.$message({
- message: "复制成功",
- type: "success"
- });
- },
- previewImg(url) {
- this.$hevueImgPreview(url);
- },
- clear() {
- this.chatList = [];
- },
- // addCharacter(){
- // this.$message.info("点击了添加新角色")
- // },
- optBtn(val) {
- this.sortOption = val;
- },
- choiceRole() {
- if (this.loading) return this.$message.info("请稍等");
- this.cardType = 1;
- },
- // sendFile() {
- // if (this.loading) return this.$message.info("请稍等");
- // this.$message.info("点击了附件");
- // },
- // goTape() {
- // if (this.loading) return this.$message.info("请稍等");
- // this.$message.info(`点击了语音`);
- // },
- send(_text = this.text) {
- if (this.loading || this.chatLoading) return this.$message.info("请稍等");
- if (_text.trim().length == 0) return this.$message.info("请输入内容");
- this.chatLoading = true;
- if (this.choseRoleItem.assistant_id) {
- let _uid = uuidv4();
- let _item = this.choseRoleItem;
- this.chatList.push({
- loading: true,
- role: "user",
- content: `${_text}`,
- uid: _uid,
- AI: "AI",
- aiContent: "",
- oldContent: "",
- isShowSynchronization: false,
- filename: _item.headUrl,
- index: this.chatList.length,
- is_mind_map: false,
- fileid: _item.assistantName
- // createtime: new Date().toLocaleString().replaceAll("/", "-")
- });
- this.text = "";
- let params = {
- assistant_id: this.choseRoleItem.assistant_id,
- userId: this.userid,
- message: _text,
- session_name: `${this.courseId}-studyStudent-md`,
- uid: _uid,
- file_ids: this.fileId
- };
- this.ajax
- .post("https://gpt4.cocorobo.cn/ai_agent_park_chat_new", params)
- .then(res => {
- if (
- converter(res.data.FunctionResponse.result) ==
- converter("发送成功")
- ) {
- } else {
- this.chatLoading = false;
- console.log(res.data.FunctionResponse.result);
- //this.$message.warning(res.data.FunctionResponse.result);
- }
- })
- .catch(err => {
- this.chatLoading = false;
- console.log(err);
- });
- this.saveUid = _uid;
- this.getAtAuContent(_uid);
- } else {
- let _uuid = uuidv4();
- this.chatList.push({
- role: "user",
- content: `${_text}`,
- uid: _uuid,
- AI: "AI",
- aiContent: "",
- oldContent: "",
- isShowSynchronization: false,
- filename: "",
- index: this.chatList.length,
- is_mind_map: false,
- loading: true
- });
- this.scrollBottom();
- let history = [];
- this.nowChatList.forEach(i => {
- if (i.content == "wanSearch") {
- return history.push({
- role: "assistant",
- content: JSON.stringify(i.aiContent)
- });
- } else if (i.content == "getImage") {
- return history.push({
- role: "assistant",
- content: i.aiContent
- });
- }
- if (i.content) {
- history.push({
- role: "user",
- content: i.content
- });
- }
- if (i.aiContent) {
- history.push({
- role: "assistant",
- content: i.aiContent
- });
- }
- });
- history.push({ role: "user", content: _text });
- let params = {
- assistant_id: "f8e1ebb2-2e0d-11ef-8bf4-12e77c4cb76b",
- userId: this.userid,
- message: _text,
- session_name: `${this.courseId}-studyStudent-md`,
- uid: _uuid,
- file_ids: this.fileId
- };
- // history.pop();
- // let params = {
- // model: "gpt-3.5-turbo",
- // temperature: 0,
- // max_tokens: 4096,
- // top_p: 1,
- // frequency_penalty: 0,
- // presence_penalty: 0,
- // messages: history,
- // uid: _uuid,
- // mind_map_question: _text
- // };
- // let params = {
- // message: {
- // anthropic_version: "bedrock-2023-05-31",
- // max_tokens: 4096,
- // temperature: 0,
- // top_p: 1,
- // messages: history
- // },
- // uid: _uuid,
- // model: "Claude 3 Sonnet" // Claude 3 Sonnet或者Claude 3 Haiku
- // };
- this.text = "";
- console.log("发送信息", params);
- this.ajax
- // .post("https://claude3.cocorobo.cn/chat", params)
- // .post("https://gpt4.cocorobo.cn/chat", params)
- .post("https://gpt4.cocorobo.cn/ai_agent_park_chat_new", params)
- .then(res => {
- if (
- converter(res.data.FunctionResponse.result) ==
- converter("发送成功")
- ) {
- } else {
- this.chatLoading = false;
- // this.$message.warning(res.data.FunctionResponse.result);
- console.log(res.data.FunctionResponse.result);
- }
- })
- .catch(e => {
- this.chatLoading = false;
- console.log(e);
- });
- this.saveUid = _uuid;
- this.getAtAuContent(_uuid);
- // this.getAiContent(_uuid);
- }
- },
- // 获取ai对话
- getAiContent(_uid) {
- // this.source = new EventSource(`https://claude3.cocorobo.cn/streamChat/${_uid}`);
- // this.source = new EventSource(`https://gpt4.cocorobo.cn/question/${_uid}`);
- // this.source = new EventSource(`https://gpt4.cocorobo.cn/stream/${_uid}`); //http://gpt4.cocorobo.cn:8011/stream/ https://gpt4.cocorobo.cn/stream/
- let _allText = "";
- let _mdText = "";
- // const md = new MarkdownIt();
- this.source.onmessage = _e => {
- if (_e.data.replace("'", "").replace("'", "") == "[DONE]") {
- //对话已经完成
- _mdText = _mdText.replace("_", "");
- this.source.close();
- this.scrollBottom();
- this.chatLoading = false;
- this.chatList.find(i => i.uid == _uid).aiContent = _mdText;
- this.chatList.find(i => i.uid == _uid).isalltext = true;
- this.chatList.find(i => i.uid == _uid).isShowSynchronization = true;
- this.chatList.find(i => i.uid == _uid).loading = false;
- this.nowChatList.push(this.chatList.find(i => i.uid == _uid));
- this.addAsk(this.chatList.find(i => i.uid == _uid).content);
- // 这里保存对话
- this.insertChat(_uid);
- return;
- } else {
- //对话还在继续
- let _text = "";
- _text = _e.data.replaceAll("'", "");
- if (_allText == "") {
- _allText = _text.replace(/^\n+/, ""); //去掉回复消息中偶尔开头就存在的连续换行符
- } else {
- _allText += _text;
- }
- _mdText = _allText + "_";
- _mdText = _mdText.replace(/\\n/g, "\n");
- _mdText = _mdText.replace(/\\/g, "");
- if (_allText.split("```").length % 2 == 0) _mdText += "\n```\n";
- //转化返回的回复流数据
- // _mdText = md.render(_mdText);
- this.chatList.find(i => i.uid == _uid).aiContent = _mdText;
- this.chatList.find(i => i.uid == _uid).loading = false;
- this.scrollBottom();
- // 处理流数据
- }
- };
- },
- getAtAuContent(_uid) {
- this.source = new EventSource(
- `https://gpt4.cocorobo.cn/question/${_uid}`
- );
- //http://gpt4.cocorobo.cn:8011/question/ https://gpt4.cocorobo.cn/question/
- let _allText = "";
- let _mdText = "";
- let _index = 0;
- let _talkText = "";
- // const md = new MarkdownIt();
- this.source.onmessage = _e => {
- let _eData = JSON.parse(_e.data);
- if (_eData.content.replace("'", "").replace("'", "") == "[DONE]") {
- let _result = [];
- if ("result" in _eData) {
- _result = _eData.result;
- for (let i = 0; i < _result.length; i++) {
- _mdText = _mdText.replace(_result[i].text, _result[i].fileName);
- }
- }
- _mdText = _mdText.replace("_", "");
- if (this.openMegaphone && this.aiTalkUid == _uid) {
- this.aiTalkUid = "";
- if (_talkText != "") {
- let _resultText = this.removeMarkdown(_talkText);
- this.aiTalkList.push(_resultText);
- _talkText = "";
- if (!this.aiIsTalk) this.aiTalk(1);
- }
- }
- this.chatLoading = false;
- this.chatList.find(i => i.uid == _uid).aiContent = _mdText;
- this.chatList.find(i => i.uid == _uid).isalltext = true;
- this.chatList.find(i => i.uid == _uid).isShowSynchronization = true;
- this.chatList.find(i => i.uid == _uid).loading = false;
- this.nowChatList.push(this.chatList.find(i => i.uid == _uid));
- this.addAsk(this.chatList.find(i => i.uid == _uid).content);
- this.source.close();
- this.insertChat(_uid);
- } else {
- _index += 1;
- let _text = _eData.content.replace("'", "").replace("'", "");
- if (_allText == "") {
- _allText = _text.replace(/^\n+/, ""); //去掉回复消息中偶尔开头就存在的连续换行符
- _talkText += _text.replace(/^\n+/, "");
- } else {
- _allText += _text;
- _talkText += _text;
- }
- _mdText = _allText + "_";
- _mdText = _mdText.replace(/\\n/g, "\n");
- _mdText = _mdText.replace(/\\/g, "");
- if (_allText.split("```").length % 2 == 0) _mdText += "\n```\n";
- //转化返回的回复流数据
- // _mdText = md.render(_mdText);
- if (_index == 10) {
- this.chatList.find(i => i.uid == _uid).aiContent = _mdText;
- this.chatList.find(i => i.uid == _uid).loading = false;
- this.$nextTick(() => {
- this.$refs.chatRef.scrollTop = this.$refs.chatRef.scrollHeight;
- });
- _index = 0;
- }
- if (this.openMegaphone && /[,。:;?!)]/.test(_talkText)) {
- let _resultText = this.removeMarkdown(_talkText);
- if (this.aiTalkUid != _uid) {
- this.aiTalkList = [];
- }
- this.aiTalkList.push(_resultText);
- _talkText = "";
- if (this.aiTalkUid != _uid) {
- this.aiTalkUid = _uid;
- this.aiTalk(0);
- } else if (!this.aiIsTalk) {
- this.aiTalk(1);
- }
- }
- // 处理流数据
- }
- };
- },
- //保存消息
- async insertChat(_uid) {
- if (_uid == "") return;
- let _data = this.chatList.find(i => i.uid == _uid);
- if (!_data) return;
- let params = {
- userId: this.userid,
- userName: this.userName?this.userName:await this.getUser(this.userid),
- groupId: "602def61-005d-11ee-91d8-005056b8q12w",
- answer: _data.aiContent,
- problem: _data.content,
- file_id: _data.fileid ? _data.fileid : "",
- alltext: _data.aiContent,
- type: "chat",
- filename: _data.filename,
- session_name: `${this.courseId}-studyStudent-md` //这是对话记录位置
- };
- this.saveUid = "";
- this.ajax
- .post("https://gpt4.cocorobo.cn/insert_chat", params)
- .then(res => {});
- },
- getUser(uid) {
- return new Promise(resolve => {
- let params = { uid: uid };
- this.ajax
- .get(this.$store.state.api + "getUser", params)
- .then(res => {
- let data = res.data[0][0];
- this.userName = data.username;
- resolve(data.username)
- })
- .catch(err => {
- console.error(err);
- });
- });
- },
- // 获取对应的聊天记录
- getChatList() {
- return new Promise((resolve, reject) => {
- if (this.loading) return this.$message.info("请稍等...");
- this.chatList = [];
- this.loading = true;
- this.chatLoading = true;
- let params = {
- userid: this.userid,
- groupid: "602def61-005d-11ee-91d8-005056b8q12w",
- // session_name:``
- session_name: `${this.courseId}-studyStudent-md`
- };
- this.ajax
- .post("https://gpt4.cocorobo.cn/get_agent_park_chat", params)
- .then(res => {
- let _data = JSON.parse(res.data.FunctionResponse);
- if (_data.length > 0) {
- let _chatList = [];
- for (let i = 0; i < _data.length; i++) {
- _chatList.push({
- loading: false,
- role: "user",
- content: _data[i].problem,
- uid: _data[i].id,
- AI: "AI",
- aiContent: _data[i].answer,
- oldContent: _data[i].answer,
- isShowSynchronization: false,
- filename: _data[i].filename,
- index: i,
- is_mind_map: false,
- fileid: _data[i].fileid
- });
- }
- this.chatList = _chatList;
- // console.log(' this.chatList', this.chatList);
- this.loading = false;
- this.chatLoading = false;
- } else {
- //没有对话记录
- this.chatLoading = false;
- this.loading = false;
- }
- resolve();
- })
- .catch(err => {
- console.log(err);
- this.$message.error("获取对话记录失败");
- this.loading = false;
- this.chatLoading = false;
- resolve();
- });
- });
- },
- getRoleList() {
- this.roleList = [];
- let params = {
- userId: this.userid
- };
- this.ajax
- .post("https://gpt4.cocorobo.cn/get_ai_agent_assistant_list", params)
- .then(res => {
- let _data = res.data.FunctionResponse.result;
- if (_data.length == 0) return;
- if (_data) {
- this.roleList = JSON.parse(_data);
- }
- })
- .catch(e => {
- console.log("获取角色列表失败");
- this.roleList = [];
- });
- },
- getPublicRoleList() {
- this.roleList2 = [];
- let params = {
- userId: this.userid,
- // organizeid: this.org,
- organizeid: "45facc0a-1211-11ec-80ad-005056b86db5"
- };
- this.ajax
- .post(
- "https://gpt4.cocorobo.cn/get_ai_agent_assistant_share_list",
- params
- )
- .then(res => {
- let _data = res.data.FunctionResponse.result;
- if (_data.length == 0) return;
- if (_data) {
- this.roleList2 = JSON.parse(_data);
- }
- })
- .catch(e => {
- this.roleList2 = [];
- console.log("获取公共角色失败", e);
- });
- },
- addAsk(_text) {
- // this.chatLoading = true;
- let _uuid = uuidv4();
- let _msg = `NOTICERole: 你是一个多功能的AI助手,能够根据学生的文本内容判断其情感状态,并提供相应的支持和引导。Output: Provide your output in json format.ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced \"Format example\".Instruction: Based on the context, follow \"Format example\", write content.# Context## 任务1.学生文本内容,执行以下任务。首先,请你判断学生是否进行情感倾诉,比如心情不好、遭遇校园暴力、对他人进行人身攻击等。如果是,请扮演一个心理咨询师的角色,坚持人本主义的立场,善良、温柔地引导对方,安抚对方的情绪,为对方提供心理支持。剩下的其它情况,请你扮演提问引导者的角色,延续学生的提问,围绕问题本身,提出3个问题,激发学生的深度思考、创造性思考。2.人本主义心理学人本主义心理学强调个体的主观体验和自我实现,认为每个人都有内在的潜力和价值。心理咨询师应当以同理心、无条件积极关注和真诚的态度对待来访者,帮助他们发现自身的力量和解决问题的能力。3.提问引导技巧提问引导技巧包括开放性问题、反思性问题和假设性问题等,旨在通过提问激发对方的思考和探索,帮助他们深入理解问题并找到解决方案。## 工作流程1. 仔细阅读并分析学生提供的文本内容。2. 判断学生是否进行情感倾诉。3. 如果是情感倾诉,扮演心理咨询师的角色,提供情感支持和引导。4. 如果不是情感倾诉,扮演提问引导者的角色,围绕问题本身提出3个问题。## 限制/注意事项 1.在回答时应保持专业性和权威性,确保信息的准确性和可靠性。2.避免生成与问题无关或不恰当的回答,确保回答的相关性和实用性。3.在提供情感支持时,注意用词温柔,避免引起对方的负面情绪。## 要求1. 内容包含情感支持或追加问题。2. 情感支持部分应体现同理心和积极关注。3. 追加问题应具有启发性和深度。## 学生文本内容${_text}# Format example [{\"index\": 1,\"label\": \"不同国家的垃圾分类标准和方法?\"},{\"index\": 2, \"label\": \"可回收垃圾的处理流程和再利用方法?\"},{\"index\": 3,\"label\": \"有害垃圾对环境和人体健康的潜在影响?\"}]`;
- _msg = _msg.replace(/[\r\n]/g, "");
- this.chatList.push({
- role: "user",
- content: `addAsk`,
- uid: _uuid,
- AI: "AI",
- aiContent: "",
- oldContent: "",
- isShowSynchronization: false,
- filename: "",
- index: this.chatList.length,
- is_mind_map: false,
- loading: true
- });
- this.scrollBottom();
- let history = [];
- // this.nowChatList.forEach(i => {
- // if (i.content == "wanSearch") {
- // // history.push({
- // // role:"assistant",
- // // content: JSON.stringify(i.aiContent)
- // // })
- // return;
- // } else if (i.content == "getImage") {
- // return history.push({
- // role: "assistant",
- // content: i.aiContent
- // });
- // }else if(i.content == "addAsk"){
- // }
- // if (i.content) {
- // history.push({
- // role: "user",
- // content: i.content
- // });
- // }
- // if (i.aiContent) {
- // history.push({
- // role: "assistant",
- // content: i.aiContent
- // });
- // }
- // });
- history.push({ type: "text", text: _msg });
- console.log(history);
- // let params = {
- // model: "gpt-3.5-turbo",
- // temperature: 0,
- // max_tokens: 4096,
- // top_p: 1,
- // frequency_penalty: 0,
- // presence_penalty: 0,
- // messages:history,
- // stream: false,
- // uid: _uuid,
- // mind_map_question: ""
- // };
- let params = {
- assistant_id: "6063369f-289a-11ef-8bf4-12e77c4cb76b",
- userId: this.userid,
- message: history,
- session_name: _uuid,
- // uid: _uuid,
- file_ids: this.fileId
- };
- // let params = {
- // message: {
- // anthropic_version: "bedrock-2023-05-31",
- // max_tokens: 4096,
- // temperature: 0,
- // top_p: 1,
- // messages: [{ role: "user", content: _msg }]
- // },
- // uid: _uuid,
- // model: "Claude 3 Sonnet" // Claude 3 Sonnet或者Claude 3 Haiku
- // };
- this.text = "";
- this.ajax
- // .post("https://gpt4.cocorobo.cn/chat", params)
- // .post("https://claude3.cocorobo.cn/chat", params)
- .post("https://gpt4.cocorobo.cn/ai_agent_park_chat", params)
- .then(res => {
- console.log(res);
- let _data = res.data.FunctionResponse.message;
- console.log(_data);
- _data = _data.replaceAll("```json", "").replaceAll("```", "");
- this.chatList.find(i => i.uid == _uuid).aiContent = JSON.parse(_data);
- this.chatList.find(i => i.uid == _uuid).isalltext = true;
- this.chatList.find(i => i.uid == _uuid).isShowSynchronization = true;
- this.chatList.find(i => i.uid == _uuid).loading = false;
- this.scrollBottom();
- // this.chatLoading = false;
- })
- .catch(e => {
- this.chatLoading = false;
- this.chatList.find(i => i.uid == _uuid).loading = false;
- console.log(e);
- });
- },
- changeRole() {
- this.cardType = 0;
- // this.rightSubjects = this.subjectsType;
- // this.rightRole = this.roleType;
- if (this.choseRoleItem.assistant_id) {
- this.chatList = [];
- this.nowChatList = [];
- let _uuid = uuidv4();
- this.chatList.push({
- role: "user",
- content: `您好,${this.choseRoleItem.assistantName}`,
- uid: _uuid,
- AI: "AI",
- aiContent: this.choseRoleItem.prologue
- ? this.choseRoleItem.prologue
- : "您好,有什么需要我帮忙的吗?",
- oldContent: "",
- isShowSynchronization: false,
- filename: this.choseRoleItem.headUrl,
- index: this.chatList.length,
- is_mind_map: false,
- loading: false
- });
- this.scrollBottom();
- }
- },
- choseRole(item) {
- this.choseRoleItem = item;
- console.log("选择角色", this.choseRoleItem);
- },
- noChangeRole() {
- this.cardType = 0;
- this.choseRoleItem = {};
- // this.subjectsType = this.rightSubjects;
- // this.roleType = this.rightRole;
- },
- scrollBottom() {
- this.$nextTick(() => {
- this.$refs.chatRef.scrollTop = this.$refs.chatRef.scrollHeight;
- });
- },
- download(_url) {
- let xhr = new XMLHttpRequest();
- xhr.open("GET", _url, true);
- xhr.responseType = "blob";
- xhr.onload = () => {
- if (xhr.status === 200) {
- let blob = xhr.response;
- // const _blob = new Blob([blob], { type: fileType });
- const downloadElement = document.createElement("a");
- const url = window.URL.createObjectURL(blob);
- downloadElement.href = url;
- downloadElement.download = "Image.jpg";
- downloadElement.click();
- window.URL.revokeObjectURL(url); // 释放内存
- } else {
- this.$message.error("此图片不支持下载");
- }
- };
- xhr.onerror = e => {
- console.log(e);
- this.$message.error("此图片不支持下载");
- };
- xhr.send();
- },
- removeMarkdown(text) {
- return text
- .replace(/[#*_~`>+\-]/g, "") // 移除 #、*、_、~、`、>、+、- 符号
- .replace(/!\[.*?\]\(.*?\)/g, "") // 移除图片
- .replace(/\[.*?\]\(.*?\)/g, "") // 移除链接
- .replace(/```[\s\S]*?```/g, "") // 移除代码块(不使用 s 标志)
- .replace(/`[^`]*`/g, "") // 移除行内代码
- .replace(/\d+\./g, "") // 移除有序列表
- .replace(/^\s*[-*+]\s+/gm, "") // 移除无序列表
- .replace(/\s+/g, " ") // 将多个空白字符替换为一个空格
- .trim(); // 去除字符串两端的空白字符
- },
- aiTalk(type = 0) {
- //0 新的 1继续
- if (type == 0 && this.aiIsTalk) {
- let _talkTextIiframe2 = this.$refs.iiframe2;
- try {
- _talkTextIiframe2.contentWindow.pausesynthesizer();
- _talkTextIiframe2.contentWindow.closesynthesizer();
- this.aiIsTalk = false;
- if (this.aiTalkList.length) this.aiTalk(0);
- else this.aiTalkUid = ""
- } catch (error) {
- // console.log("error")
- this.aiIsTalk = false;
- if (this.aiTalkList.length) this.aiTalk(0);
- else this.aiTalkUid = ""
- }
- } else {
- let _text = this.aiTalkList.shift();
- let _talkTextIiframe2 = this.$refs.iiframe2;
- if (_text) {
- this.aiIsTalk = true;
- // console.log("👇说👇");
- // console.log(_text);
- _talkTextIiframe2.contentWindow.texttospeech(
- _text,
- () => {
- this.aiTalk(1);
- },
- () => {
- this.aiTalk(0);
- }
- );
- } else {
- try {
- _talkTextIiframe2.contentWindow.closesynthesizer();
- } catch (error) {
- return
- }
- }
- }
- // if(_text){
- // this.aiIsTalk = true;
- // }
- },
- aiTalkAll(item) {
- if (this.aiTalkUid == item.uid && this.aiIsTalk) {
- try {
- this.aiTalkList = [];
- let _talkTextIiframe2 = this.$refs.iiframe2;
- _talkTextIiframe2.contentWindow.pausesynthesizer();
- _talkTextIiframe2.contentWindow.closesynthesizer();
- this.aiIsTalk = false;
- } catch (error) {
- this.aiTalkList = [];
- this.aiIsTalk = false;
- }
- } else {
- let _resultText = this.removeMarkdown(item.aiContent);
- this.aiTalkUid = item.uid;
- this.aiTalkList = [];
- this.aiTalkList.push(_resultText);
- this.aiTalk(0);
- }
- // console.log(_resultText);
- }
- },
- mounted() {
- this.getRoleList();
- this.getPublicRoleList();
- this.getChatList().then(_ => {
- this.scrollBottom();
- });
- this.nowChatList = [];
- }
- };
- </script>
- <style scoped>
- .dialog {
- width: 100%;
- height: 100%;
- box-sizing: border-box;
- }
- .dialog > div {
- width: 100%;
- height: 100%;
- }
- .aiCopy {
- position: absolute;
- right: 5px;
- bottom: 0%;
- display: flex;
- flex-direction: column;
- justify-content: flex-end;
- /* transform: translate(0, -30%); */
- cursor: pointer;
- }
- .characterBlock {
- display: flex;
- background: rgba(54, 169, 252, 1);
- width: 100%;
- height: 80px;
- margin: 0 auto;
- border-radius: 10px;
- margin-bottom: 15px;
- cursor: pointer;
- }
- .characterBlock > .imgLeft {
- width: 100px;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .characterBlock > .imgLeft > .img {
- width: 60px;
- height: 60px;
- overflow: hidden;
- border-radius: 50%;
- }
- .characterBlock > .imgLeft > .img2 {
- width: 70px;
- height: 70px;
- overflow: hidden;
- border-radius: 50%;
- }
- .characterBlock > .txtRight {
- flex: 1;
- display: flex;
- justify-content: flex-start;
- align-items: center;
- }
- .characterBlock > .txtRight > .bir {
- width: 180px;
- height: 35px;
- display: flex;
- align-items: center;
- background-color: #fff;
- border-radius: 10px;
- box-sizing: border-box;
- padding: 5px 10px;
- box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
- margin-right: 10px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- .d_top {
- width: 100%;
- height: calc(100% - 130px);
- overflow: auto;
- box-sizing: border-box;
- padding: 20px 0;
- }
- .d_t_chat {
- width: 100%;
- display: flex;
- box-sizing: border-box;
- padding: 10px;
- flex-direction: column;
- }
- .d_t_chat > div {
- display: flex;
- align-items: flex-start;
- width: 100%;
- }
- .d_t_c_user {
- box-sizing: border-box;
- padding-left: 35px;
- }
- .d_t_c_u_left {
- width: 90%;
- height: auto;
- }
- .d_t_c_u_l_content {
- width: auto;
- max-width: 100%;
- height: auto;
- box-sizing: border-box;
- padding: 10px;
- color: white;
- background-color: #3681fc;
- border-radius: 8px 2px 8px 8px;
- white-space: pre-line;
- }
- .d_t_c_u_l_time {
- width: 100%;
- display: flex;
- justify-content: flex-end;
- font-size: 12px;
- color: #9f9f9f;
- margin-top: 5px;
- }
- .d_t_c_u_right {
- width: 35px;
- height: 35px;
- display: flex;
- justify-content: center;
- margin-left: 5px;
- }
- .d_t_c_u_right > span {
- width: 32px;
- height: 32px;
- display: flex;
- justify-content: center;
- align-items: center;
- color: white;
- background-color: #3681fc;
- border-radius: 50%;
- }
- .d_t_c_ai {
- box-sizing: border-box;
- padding-right: 35px;
- margin-top: 10px;
- position: relative;
- }
- .d_t_c_a_right {
- min-width: 90%;
- height: auto;
- }
- .d_t_c_a_r_content {
- width: auto;
- max-width: 100%;
- height: auto;
- box-sizing: border-box;
- padding: 10px;
- background-color: #f6f8ff;
- border-radius: 2px 8px 8px 8px;
- white-space: pre-line;
- word-break: break-all;
- }
- .d_t_c_a_r_time {
- width: 100%;
- display: flex;
- justify-content: flex-start;
- font-size: 12px;
- color: #9f9f9f;
- margin-top: 5px;
- }
- .d_t_c_a_left {
- width: 35px;
- height: 35px;
- display: flex;
- justify-content: center;
- margin-right: 5px;
- }
- .d_t_c_a_left > span {
- width: 32px;
- height: 32px;
- display: flex;
- justify-content: center;
- align-items: center;
- color: white;
- background-color: #3681fc;
- border-radius: 50%;
- }
- .d_bottom {
- width: 100%;
- height: 130px;
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- }
- .d_b_btnArea {
- width: 100%;
- height: 30px;
- display: flex;
- align-items: center;
- box-sizing: border-box;
- padding: 0 10px;
- }
- .d_b_ba-item {
- width: auto;
- box-sizing: border-box;
- padding: 0 10px;
- height: 25px;
- background-color: white;
- display: flex;
- justify-content: center;
- align-items: center;
- /* 阴影 */
- box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.363);
- border-radius: 15px;
- margin-right: 10px;
- font-size: 14px;
- cursor: pointer;
- }
- .d_b_inputArea {
- width: 100%;
- height: 55px;
- box-sizing: border-box;
- border-top: solid 1px #ededed;
- display: flex;
- justify-content: space-between;
- padding-right: 10px;
- align-items: center;
- }
- .d_b_tape {
- width: 35px;
- height: 35px;
- background: url("../../../assets/icon/course/tape.png") no-repeat;
- background-size: 50% 60%;
- background-position: center;
- cursor: pointer;
- }
- .d_b_input {
- /* width: 75%; */
- flex: 1;
- height: 45px;
- background-color: #f3f3f3;
- border-radius: 50px;
- margin: 0 10px;
- display: flex;
- overflow: hidden;
- align-items: center;
- }
- .d_b_i_left {
- width: 100%;
- line-height: 45px;
- height: 100%;
- }
- .d_b_i_left >>> .el-input__inner {
- border: none;
- background-color: #f3f3f3;
- outline: none;
- border-radius: 50px 0 0 50px;
- }
- .d_b_i_right {
- width: 45px;
- height: 45px;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .d_b_i_right > span {
- width: 35px;
- height: 35px;
- background: url("../../../assets/icon/course/file.png") no-repeat;
- background-size: 50% 60%;
- background-position: center;
- cursor: pointer;
- }
- .d_b_btn {
- width: 40px;
- height: 40px;
- background-color: #3681fc;
- display: flex;
- justify-content: center;
- align-items: center;
- border-radius: 50%;
- cursor: pointer;
- }
- .d_b_btn > div {
- color: white;
- width: 100%;
- height: 100%;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .d_b_btn > span {
- width: 30px;
- height: 30px;
- background: url("../../../assets/icon/course/send.png") no-repeat;
- background-size: 70% 70%;
- background-position: center;
- }
- .d_b_btn > img {
- width: 30px;
- height: 30px;
- }
- .choiceTop {
- width: 100%;
- height: 95%;
- overflow-x: hidden;
- box-sizing: border-box;
- padding: 10px;
- }
- .choiceBottom {
- width: 100%;
- height: 5%;
- display: flex;
- align-items: center;
- justify-content: flex-end;
- }
- .cb_btn {
- margin: 0 10px;
- }
- .choiceRoleHeader {
- width: 100%;
- /* margin: 10px; */
- margin-bottom: 20px;
- }
- .choiceRoleHeader > div {
- font-size: 16px;
- font-weight: bold;
- }
- .choiceRoleHeader > span {
- font-size: 14px;
- }
- .choiceSelect {
- width: 100%;
- display: flex;
- height: 35px;
- justify-content: flex-start;
- align-items: center;
- margin: 15px 0;
- }
- .choiceSelect > .option {
- width: 80px;
- height: 100%;
- border-radius: 5px;
- margin-right: 10px;
- display: flex;
- justify-content: center;
- align-items: center;
- cursor: pointer;
- }
- .filterSubjects {
- margin: 10px;
- width: 100%;
- height: auto;
- }
- .fs_box {
- width: 100%;
- display: flex;
- flex-wrap: wrap;
- margin-top: 10px;
- }
- .fs_b_item {
- width: auto;
- height: 35px;
- font-size: 14px;
- box-sizing: border-box;
- padding: 0 9px;
- background-color: #f3f7fd;
- border: solid 1px #f3f7fd;
- border-radius: 5px;
- margin-right: 8px;
- margin-bottom: 8px;
- display: flex;
- justify-content: center;
- align-items: center;
- cursor: pointer;
- }
- .fs_b_itemActive {
- border: solid 1px #4d8ffc;
- color: #4d8ffc;
- background-color: #f3f7fd;
- }
- .roleList {
- width: 100%;
- height: auto;
- margin: 10px;
- }
- .r_box {
- width: 100%;
- height: auto;
- display: flex;
- flex-wrap: wrap;
- }
- .r_b_item {
- height: 40px;
- font-size: 14px;
- display: flex;
- /* justify-content: center; */
- align-items: center;
- background-color: #f0f2f5;
- border-radius: 5px;
- margin: 5px;
- cursor: pointer;
- box-sizing: border-box;
- padding: 0 4px;
- border: solid 1px #f0f2f5;
- }
- .r_b_itemActive {
- box-sizing: border-box;
- border: solid 1px #aeccfe;
- color: #4d8ffb;
- }
- .r_b_item > img {
- min-width: 24px;
- min-height: 24px;
- width: 24px;
- height: 24px;
- border-radius: 50%;
- margin-right: 10px;
- /* margin-left: 10px; */
- }
- .s_t_addAsk {
- width: 100%;
- height: auto;
- padding: 10px 20px;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- box-sizing: border-box;
- }
- .s_t_addAsk > span {
- box-sizing: border-box;
- width: auto;
- height: auto;
- padding: 15px;
- margin-bottom: 10px;
- background-color: #f5f6f7;
- border-radius: 10px;
- cursor: pointer;
- border: solid 1px #e8e9ec;
- transition: 0.3s;
- }
- .s_t_addAsk > span:hover {
- background-color: #e8e9ec;
- }
- .d_t_c_a_r_c_img:hover .download_image {
- display: block;
- }
- .download_image {
- position: absolute;
- display: none;
- right: 5px;
- bottom: 5px;
- width: 30px;
- height: 30px;
- cursor: pointer;
- }
- .download_image > img {
- width: 100%;
- height: 100%;
- }
- .s_b_btnAreaTop {
- width: 100%;
- height: 35px;
- margin-bottom: 5px;
- display: flex;
- align-items: center;
- box-sizing: border-box;
- padding: 0 10px;
- overflow: auto;
- display: flex;
- justify-content: space-between;
- }
- .s_b_bat_left {
- width: auto;
- height: 100%;
- display: flex;
- align-items: flex-end;
- }
- .s_b_bat_left > img {
- width: 25px;
- height: 25px;
- cursor: pointer;
- margin-right: 5px;
- }
- .s_b_bat_right{
- width: auto;
- height: 100%;
- display: flex;
- align-items: flex-end;
- }
- .s_b_bat_right > img {
- width: 25px;
- height: 25px;
- /* cursor: pointer; */
- margin-right: 5px;
- }
- .voice_or_keyboard {
- width: 35px;
- height: 35px;
- margin-right: 10px;
- }
- .voice_or_keyboard > img {
- width: 100%;
- height: 100%;
- cursor: pointer;
- }
- </style>
|