languageAssistant.vue 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  1. <template>
  2. <div class="languageAssistant">
  3. <div class="la_coco">
  4. <el-image
  5. style="width: 105px; height: 105px"
  6. v-show="showIndex == 2"
  7. :src="require('../../../assets/icon/course/aiVanish.svg')"
  8. fit="fill"
  9. ></el-image>
  10. <el-image
  11. style="width: 105px; height: 105px;transform: scale(1.7,1.7);"
  12. v-show="showIndex == 0"
  13. :src="require('../../../assets/icon/course/aiWait2.svg')"
  14. fit="fill"
  15. ></el-image>
  16. <el-image
  17. style="width: 105px; height: 105px"
  18. v-show="showIndex == 1"
  19. :src="require('../../../assets/icon/course/aiTalk.svg')"
  20. fit="fill"
  21. ></el-image>
  22. </div>
  23. <div
  24. class="la_message"
  25. :style="show ? '' : 'height:calc(100% - 170px - 200px - 40px)'"
  26. ref="messageRef"
  27. >
  28. <div class="la_m_talk" v-if="show && openMessage">
  29. <div v-if="showTextIndex == 0" v-html="htmlContent(aiText)"></div>
  30. <div v-if="showTextIndex == 1">{{ userText }}</div>
  31. <div v-if="showTextIndex == 2">正在组织语言...</div>
  32. </div>
  33. <div class="la_m_talk" v-if="!openMessage">
  34. <div>你好,我是可可同学,是个小小百事通,你有什么想和我聊一聊?</div>
  35. </div>
  36. </div>
  37. <div class="la_btn">
  38. <div class="la_b_noTel" v-if="!show">
  39. <el-tooltip class="item" effect="light" content="通话" placement="top">
  40. <span>
  41. <svg
  42. @click.stop="recordStart"
  43. t="1721367811838"
  44. viewBox="0 0 1024 1024"
  45. version="1.1"
  46. xmlns="http://www.w3.org/2000/svg"
  47. p-id="4525"
  48. width="64"
  49. height="64"
  50. >
  51. <path
  52. d="M65.771 502.182c0 246.632 199.937 446.566 446.57 446.565 246.613 0 446.549-199.934 446.551-446.565 0-246.633-199.936-446.549-446.55-446.55-246.635 0.001-446.57 199.917-446.571 446.55z m651.885-173.77c31.489 31.473 1.642 148.828-114.292 264.773C487.396 709.131 370.06 738.929 338.589 707.492c-27.278-27.315-74.96-60.574-12.892-110.423 62.087-49.886 79.429-25.343 107.582 2.772 19.674 19.711 69.436-21.368 112.394-64.328 42.94-42.996 83.986-92.719 64.368-112.43-28.155-28.153-52.679-45.511-2.792-107.562 49.904-62.049 83.125-14.405 110.406 12.891z"
  53. p-id="4526"
  54. ></path>
  55. </svg>
  56. </span>
  57. </el-tooltip>
  58. </div>
  59. <div class="la_b_isTel" v-else>
  60. <el-tooltip
  61. class="item"
  62. effect="light"
  63. content="暂停"
  64. placement="top"
  65. v-if="canTalk"
  66. >
  67. <span @click.stop="canNotTalk">
  68. <img :src="require('../../../assets/icon/course/stop1.png')" />
  69. <!-- <svg
  70. @click.stop="recordStart"
  71. t="1721367811838"
  72. viewBox="0 0 1024 1024"
  73. version="1.1"
  74. xmlns="http://www.w3.org/2000/svg"
  75. p-id="4525"
  76. width="64"
  77. height="64"
  78. >
  79. <path
  80. d="M65.771 502.182c0 246.632 199.937 446.566 446.57 446.565 246.613 0 446.549-199.934 446.551-446.565 0-246.633-199.936-446.549-446.55-446.55-246.635 0.001-446.57 199.917-446.571 446.55z m651.885-173.77c31.489 31.473 1.642 148.828-114.292 264.773C487.396 709.131 370.06 738.929 338.589 707.492c-27.278-27.315-74.96-60.574-12.892-110.423 62.087-49.886 79.429-25.343 107.582 2.772 19.674 19.711 69.436-21.368 112.394-64.328 42.94-42.996 83.986-92.719 64.368-112.43-28.155-28.153-52.679-45.511-2.792-107.562 49.904-62.049 83.125-14.405 110.406 12.891z"
  81. p-id="4526"
  82. ></path>
  83. </svg> -->
  84. </span>
  85. </el-tooltip>
  86. <el-tooltip
  87. class="item"
  88. effect="light"
  89. content="开启"
  90. placement="top"
  91. v-else
  92. >
  93. <span class="readAloud" @click.stop="canTalkFn">
  94. <img :src="require('../../../assets/icon/course/start2.png')" />
  95. <!-- <svg
  96. t="1721117381559"
  97. viewBox="0 0 1024 1024"
  98. version="1.1"
  99. xmlns="http://www.w3.org/2000/svg"
  100. p-id="12941"
  101. width="64"
  102. height="64"
  103. >
  104. <path
  105. d="M161.2 839.9v-654c0-56.1 60.7-91.1 109.3-63.1l566.3 327c48.6 28 48.6 98.1 0 126.2L270.4 903c-48.5 28-109.2-7.1-109.2-63.1z"
  106. p-id="12942"
  107. ></path>
  108. </svg> -->
  109. </span>
  110. </el-tooltip>
  111. <el-tooltip class="item" effect="light" content="挂断" placement="top">
  112. <svg
  113. @click.stop="stopRecord"
  114. t="1721367811838"
  115. viewBox="0 0 1024 1024"
  116. version="1.1"
  117. xmlns="http://www.w3.org/2000/svg"
  118. p-id="4525"
  119. width="64"
  120. height="64"
  121. >
  122. <path
  123. d="M65.771 502.182c0 246.632 199.937 446.566 446.57 446.565 246.613 0 446.549-199.934 446.551-446.565 0-246.633-199.936-446.549-446.55-446.55-246.635 0.001-446.57 199.917-446.571 446.55z m651.885-173.77c31.489 31.473 1.642 148.828-114.292 264.773C487.396 709.131 370.06 738.929 338.589 707.492c-27.278-27.315-74.96-60.574-12.892-110.423 62.087-49.886 79.429-25.343 107.582 2.772 19.674 19.711 69.436-21.368 112.394-64.328 42.94-42.996 83.986-92.719 64.368-112.43-28.155-28.153-52.679-45.511-2.792-107.562 49.904-62.049 83.125-14.405 110.406 12.891z"
  124. p-id="4526"
  125. ></path>
  126. </svg>
  127. </el-tooltip>
  128. <el-tooltip class="item" effect="light" content="中断" placement="top">
  129. <span @click.stop="interrupt">
  130. <img :src="require('../../../assets/icon/course/stop2.png')" />
  131. <!-- <svg
  132. t="1721372012678"
  133. class="icon"
  134. viewBox="0 0 1024 1024"
  135. version="1.1"
  136. xmlns="http://www.w3.org/2000/svg"
  137. p-id="5554"
  138. width="64"
  139. height="64"
  140. >
  141. <path
  142. d="M885.6 413.8c-32.3 0-60.1 19.8-71.9 47.9h-18.1c-16.6 0-30 13.4-30 30s13.4 30 30 30h18.1c11.8 28.1 39.5 47.9 71.9 47.9 42.9 0 77.9-34.9 77.9-77.9 0-42.9-35-77.9-77.9-77.9zM690.4 461.7h-21.1c-16.6 0-30 13.4-30 30s13.4 30 30 30h21.1c16.6 0 30-13.4 30-30s-13.4-30-30-30zM564.1 461.7h-10c-16.6 0-30 13.4-30 30s13.4 30 30 30h10c16.6 0 30-13.4 30-30s-13.4-30-30-30zM709.7 115.7c-13.7-9.4-32.3-5.9-41.7 7.8L436.5 461.8c-0.8-0.1-1.6-0.1-2.3-0.1H212.5c-11.8-28.1-39.5-47.9-71.9-47.9-39.4 0-72.1 29.5-77.2 67.5-1.2 3.2-1.8 6.7-1.8 10.3 0 3.6 0.6 7.1 1.8 10.3 5.1 38.1 37.7 67.5 77.2 67.5 32.3 0 60.1-19.8 71.9-47.9h183l-240.1 351c-9.4 13.7-5.9 32.3 7.8 41.7 5.2 3.5 11.1 5.2 16.9 5.2 9.6 0 19-4.6 24.8-13.1l512.6-749c9.4-13.5 5.9-32.2-7.8-41.6z"
  143. p-id="5555"
  144. ></path>
  145. </svg> -->
  146. </span>
  147. </el-tooltip>
  148. </div>
  149. <div class="openMessage" v-if="show">
  150. <el-checkbox v-model="openMessage">开启字幕</el-checkbox>
  151. </div>
  152. </div>
  153. <!-- 录音转文字 -->
  154. <iframe
  155. allow="camera *; microphone *;display-capture;midi;encrypted-media;"
  156. src="https://beta.cloud.cocorobo.cn/browser/public/index.html"
  157. ref="iiframe"
  158. v-show="false"
  159. ></iframe>
  160. <!-- 文字转语音-->
  161. <iframe
  162. allow="camera *; microphone *;display-capture;midi;encrypted-media;"
  163. src="https://beta.cloud.cocorobo.cn/browser/public/index1.html"
  164. ref="iiframe2"
  165. v-show="false"
  166. ></iframe>
  167. </div>
  168. </template>
  169. <script>
  170. import { v4 as uuidv4 } from "uuid";
  171. import MarkdownIt from "markdown-it";
  172. export default {
  173. props: {},
  174. data() {
  175. return {
  176. show: false,
  177. showIndex: 2, //0 :在说话 1 : 接收 2:待命
  178. aiStatus: 0,
  179. aiText: "我是可可同学,我是个小小百事通,你有什么想和我聊一聊?",
  180. userText: "",
  181. showTextIndex: 0, //0:ai,1:用户, 2:组织语言 3: 无
  182. timer: null,
  183. isOpen: false,
  184. userId: this.$route.query.userid,
  185. chatLoading: false,
  186. talkLoading: false,
  187. source: null,
  188. talkTextList: [],
  189. openMessage: true,
  190. canTalk:true,
  191. };
  192. },
  193. computed: {
  194. htmlContent() {
  195. const md = new MarkdownIt();
  196. return _md => {
  197. return md.render(_md);
  198. };
  199. }
  200. },
  201. methods: {
  202. scrollBottom() {
  203. this.$nextTick(() => {
  204. this.$refs.messageRef.scrollTop = this.$refs.messageRef.scrollHeight;
  205. });
  206. },
  207. talkAllText() {
  208. if (this.talkLoading && this.aiText == "") return;
  209. let _resultText = this.removeMarkdown(this.aiText);
  210. this.talkTextList.push(_resultText);
  211. this.talkText();
  212. },
  213. recordStart(_text) {
  214. try {
  215. // let iiframe = this.$refs["iiframe"];
  216. // iiframe.contentWindow.window.document.getElementById(
  217. // "languageOptions"
  218. // ).selectedIndex = 2; //普通话
  219. // iiframe.contentWindow.testdoContinuousPronunciationAssessment();
  220. // // return
  221. // var OpenCC = require("opencc-js");
  222. // let converter = OpenCC.Converter({
  223. // from: "hk",
  224. // to: "cn"
  225. // });
  226. this.show = true;
  227. this.showIndex = 0;
  228. this.showTextIndex = 0;
  229. this.chatLoading = false;
  230. this.talkLoading = false;
  231. this.isOpen = true;
  232. this.show = true;
  233. this.aiText = "我是可可同学,我是个小小百事通,你有什么想和我聊一聊?";
  234. return;
  235. iiframe.contentWindow.onRecognizedResult = e => {
  236. let _msg = converter(e.privText);
  237. console.log("👇");
  238. console.log(_msg);
  239. // _msg = converter(_msg)
  240. if(!this.canTalk)return;
  241. if (!_msg) return console.log("输出为空");
  242. if (this.show == true) {
  243. if (
  244. _msg.indexOf(converter("可可同学")) != -1 &&
  245. _msg.indexOf(converter("停止")) != -1
  246. ) {
  247. this.stopTalk();
  248. } else if (
  249. this.showTextIndex == 2 ||
  250. this.chatLoading ||
  251. this.talkLoading
  252. ) {
  253. return console.log("组织语言中");
  254. // }else if(_msg.indexOf('可可同学')!=-1 && _msg.indexOf("停止")!=-1){
  255. // this.stopTalk();
  256. } else {
  257. this.showTextIndex = 1;
  258. this.aiText = "";
  259. this.userText += _msg;
  260. this.scrollBottom();
  261. this.aiStatus = 1;
  262. if (this.timer) {
  263. clearTimeout(this.timer);
  264. this.timer = null;
  265. }
  266. this.timer = setTimeout(() => {
  267. if (this.userText.indexOf(converter("关闭语音助手")) != -1) {
  268. // return setTimeout(()=>{
  269. this.show = false;
  270. this.showTextIndex = 3;
  271. this.showIndex = 2;
  272. this.aiStatus = 2;
  273. this.aiText = "";
  274. this.userText = "";
  275. this.stopRecord();
  276. return;
  277. // },1000)
  278. }
  279. this.showTextIndex = 2;
  280. this.aiText = "";
  281. let regExp = new RegExp(
  282. converter("计时") + "(.+)" + converter("分钟")
  283. );
  284. if (false && regExp.test(this.userText)) {
  285. // setTimeout(() => {
  286. // let _number = this.userText.match(regExp)[1];
  287. // let _time = 0;
  288. // if (!/^\d+$/.test(_number)) {
  289. // _time = this.chineseToNumber(_number) * 60;
  290. // } else {
  291. // _time = parseInt(_numberList[1]) * 60;
  292. // }
  293. // this.$emit("startTime", _time);
  294. // this.aiStatus = 0;
  295. // this.showTextIndex = 0;
  296. // this.aiText =
  297. // "好的,我已为您计时" +
  298. // this.userText.match(regExp)[1] +
  299. // "分钟。";
  300. // this.userText = "";
  301. // this.timer = setTimeout(() => {
  302. // this.showTextIndex = 3;
  303. // this.aiStatus = 2;
  304. // this.aiText = "";
  305. // this.userText = "";
  306. // }, 3000);
  307. // }, 2000);
  308. } else {
  309. this.chatLoading = true;
  310. const _uuid = uuidv4();
  311. let params = {
  312. assistant_id: "f8e1ebb2-2e0d-11ef-8bf4-12e77c4cb76b",
  313. userId: this.userId,
  314. message: this.userText,
  315. session_name: _uuid + "-qgt",
  316. uid: _uuid,
  317. file_ids: [],
  318. model: "gpt-4o-2024-08-06"
  319. };
  320. this.ajax
  321. // .post("https://claude3.cocorobo.cn/chat", params)
  322. // .post("https://gpt4.cocorobo.cn/chat", params)
  323. .post(
  324. "https://gpt4.cocorobo.cn/ai_agent_park_chat_new",
  325. params
  326. )
  327. .then(res => {
  328. if (
  329. converter(res.data.FunctionResponse.result) ==
  330. converter("发送成功")
  331. ) {
  332. this.userText = "";
  333. this.showIndex = 0;
  334. } else {
  335. // this.$message.warning(res.data.FunctionResponse.result);
  336. console.log(res.data.FunctionResponse.result);
  337. this.chatLoading = false;
  338. this.aiStatus = 0;
  339. this.showTextIndex = 0;
  340. this.showIndex = 0;
  341. this.aiText = "对不起,我无法理解您的问题,请重新提问";
  342. // this.timer = setTimeout(() => {
  343. // this.showTextIndex = 3;
  344. // this.aiStatus = 2;
  345. // this.aiText = "";
  346. // this.userText = "";
  347. // }, 3000);
  348. }
  349. })
  350. .catch(e => {
  351. console.log(e);
  352. this.chatLoading = false;
  353. this.aiStatus = 0;
  354. this.showTextIndex = 0;
  355. this.showIndex = 0;
  356. this.aiText = "对不起,我无法理解您的问题,请重新提问";
  357. // this.timer = setTimeout(() => {
  358. // this.showTextIndex = 3;
  359. // this.aiStatus = 2;
  360. // this.aiText = "";
  361. // this.userText = "";
  362. // }, 3000);
  363. });
  364. // 通过流获取ai对话数据
  365. this.getAtAuContent(_uuid);
  366. }
  367. }, 5000);
  368. }
  369. } else {
  370. console.log("不响应");
  371. }
  372. };
  373. } catch (error) {
  374. console.log(error)
  375. this.recordStart();
  376. }
  377. },
  378. stopRecord() {
  379. this.$parent.changeItemType(1);
  380. this.show = false;
  381. this.showIndex = 2;
  382. let iiframe = this.$refs["iiframe"];
  383. iiframe.contentWindow.window.document
  384. .getElementById("scenarioStopButton")
  385. .click();
  386. if (this.talkLoading) {
  387. this.stopTalk();
  388. }
  389. // this.stopTalk();
  390. // 录音借宿
  391. iiframe.contentWindow.onSessionStopped = (s, e) => {
  392. this.isOpen = false;
  393. this.show = false;
  394. this.showTextIndex = 3;
  395. this.showIndex = 2;
  396. this.$message.success("已关闭语音助手");
  397. if (this.talkLoading) {
  398. this.$refs.iiframe2.contentWindow.closesynthesizer();
  399. }
  400. this.userText = "";
  401. this.aiText = "";
  402. };
  403. },
  404. chineseToNumber(chinese) {
  405. var OpenCC = require("opencc-js");
  406. let converter = OpenCC.Converter({
  407. from: "hk",
  408. to: "cn"
  409. });
  410. chinese = converter(chinese);
  411. const chineseNumbers = {
  412. 零: 0,
  413. 一: 1,
  414. 二: 2,
  415. 三: 3,
  416. 四: 4,
  417. 五: 5,
  418. 六: 6,
  419. 七: 7,
  420. 八: 8,
  421. 九: 9,
  422. 十: 10,
  423. 百: 100,
  424. 千: 1000,
  425. 万: 10000,
  426. 亿: 100000000
  427. };
  428. let result = 0;
  429. let tempNum = 0; // 用于累积处理
  430. let sectionNum = 0; // 每个段的值
  431. for (let i = 0; i < chinese.length; i++) {
  432. const char = chinese[i];
  433. const num = chineseNumbers[char];
  434. if (num === undefined) {
  435. throw new Error(`Unexpected character: ${char}`);
  436. }
  437. if (
  438. num === 10 ||
  439. num === 100 ||
  440. num === 1000 ||
  441. num === 10000 ||
  442. num === 100000000
  443. ) {
  444. if (tempNum === 0) tempNum = 1; // 如果前面没有数,默认是1
  445. tempNum *= num;
  446. if (num === 10000 || num === 100000000) {
  447. sectionNum += tempNum;
  448. result += sectionNum;
  449. tempNum = 0;
  450. sectionNum = 0;
  451. }
  452. } else {
  453. tempNum += num;
  454. }
  455. }
  456. result += sectionNum + tempNum;
  457. return result;
  458. },
  459. removeMarkdown(text) {
  460. return text
  461. .replace(/[#*_~`>+\-]/g, "") // 移除 #、*、_、~、`、>、+、- 符号
  462. .replace(/!\[.*?\]\(.*?\)/g, "") // 移除图片
  463. .replace(/\[.*?\]\(.*?\)/g, "") // 移除链接
  464. .replace(/```[\s\S]*?```/g, "") // 移除代码块(不使用 s 标志)
  465. .replace(/`[^`]*`/g, "") // 移除行内代码
  466. .replace(/\d+\./g, "") // 移除有序列表
  467. .replace(/^\s*[-*+]\s+/gm, "") // 移除无序列表
  468. .replace(/\s+/g, " ") // 将多个空白字符替换为一个空格
  469. .trim(); // 去除字符串两端的空白字符
  470. },
  471. getAtAuContent(_uid) {
  472. this.source = new EventSource(
  473. `https://gpt4.cocorobo.cn/question/${_uid}`
  474. );
  475. //http://gpt4.cocorobo.cn:8011/question/ https://gpt4.cocorobo.cn/question/
  476. let _allText = "";
  477. let _mdText = "";
  478. let _talkText = "";
  479. // let _talkIndex = 0;
  480. // const md = new MarkdownIt();
  481. this.source.onmessage = _e => {
  482. this.showIndex = 0;
  483. let _eData = JSON.parse(_e.data);
  484. if (_eData.content.replace("'", "").replace("'", "") == "[DONE]") {
  485. this.source.close();
  486. this.source = null;
  487. let _result = [];
  488. if ("result" in _eData) {
  489. _result = _eData.result;
  490. for (let i = 0; i < _result.length; i++) {
  491. _mdText = _mdText.replace(_result[i].text, _result[i].fileName);
  492. }
  493. }
  494. _mdText = _mdText.replace("_", "");
  495. this.aiText = _mdText;
  496. this.scrollBottom();
  497. if (_talkText != "") {
  498. let _resultText = this.removeMarkdown(_talkText);
  499. this.talkTextList.push(_resultText);
  500. _talkText = "";
  501. if (!this.talkLoading) this.talkText();
  502. }
  503. this.chatLoading = false;
  504. } else {
  505. // _talkIndex+=1;
  506. let _text = _eData.content.replace("'", "").replace("'", "");
  507. if (_allText == "") {
  508. _allText = _text.replace(/^\n+/, ""); //去掉回复消息中偶尔开头就存在的连续换行符
  509. _talkText += _text.replace(/^\n+/, "");
  510. } else {
  511. _allText += _text;
  512. _talkText += _text;
  513. }
  514. `~`;
  515. _mdText = _allText + "_";
  516. _mdText = _mdText.replace(/\\n/g, "\n");
  517. _mdText = _mdText.replace(/\\/g, "");
  518. if (_allText.split("```").length % 2 == 0) _mdText += "\n```\n";
  519. this.aiText = _mdText;
  520. this.showTextIndex = 0;
  521. this.scrollBottom();
  522. if (/[,。:;?!)]/.test(_talkText)) {
  523. let _resultText = this.removeMarkdown(_talkText);
  524. this.talkTextList.push(_resultText);
  525. _talkText = "";
  526. if (!this.talkLoading) this.talkText();
  527. }
  528. }
  529. };
  530. },
  531. talkText() {
  532. let _text = this.talkTextList.shift();
  533. let _talkTextIiframe2 = this.$refs.iiframe2;
  534. if (_text) {
  535. this.talkLoading = true;
  536. if (this.timer) {
  537. clearTimeout(this.timer);
  538. this.timer = null;
  539. }
  540. console.log(`👉转语音:${_text}`);
  541. _talkTextIiframe2.contentWindow.texttospeech(
  542. _text,
  543. this.talkText,
  544. this.endTalk
  545. );
  546. } else {
  547. _talkTextIiframe2.contentWindow.closesynthesizer();
  548. }
  549. },
  550. endTalk() {
  551. console.log("👉转语音结束👈");
  552. this.talkLoading = false;
  553. },
  554. stopTalk() {
  555. // return this.$message.info("停止")
  556. this.talkTextList = [];
  557. try {
  558. let _talkTextIiframe2 = this.$refs.iiframe2;
  559. _talkTextIiframe2.contentWindow.pausesynthesizer();
  560. _talkTextIiframe2.contentWindow.closesynthesizer();
  561. this.talkLoading = false;
  562. } catch (error) {
  563. this.talkLoading = false;
  564. }
  565. },
  566. interrupt() {
  567. // return this.$message.info("打断")
  568. if (this.source) {
  569. try {
  570. this.source.close();
  571. } catch (error) {
  572. console.log(error);
  573. }
  574. }
  575. this.stopTalk();
  576. },
  577. canNotTalk(){
  578. this.canTalk = false;
  579. this.showIndex = 2;
  580. this.chatLoading = false;
  581. this.stopTalk();
  582. if(this.source){
  583. this.source.close();
  584. this.source = null;
  585. }
  586. },
  587. canTalkFn(){
  588. this.canTalk = true;
  589. this.showIndex = 0;
  590. this.showTextIndex = 0;
  591. this.aiText = "我是可可同学,我是个小小百事通,你有什么想和我聊一聊";
  592. this.chatLoading = false;
  593. }
  594. },
  595. mounted() {
  596. this.$nextTick(() => {
  597. this.recordStart();
  598. });
  599. }
  600. };
  601. </script>
  602. <style scoped>
  603. .languageAssistant {
  604. width: 100%;
  605. height: 100%;
  606. border-radius: 10px 0 0 10px;
  607. /* background-image: linear-gradient(to top, #007adf 0%, #00ecbc 100%);
  608. */
  609. background-image: url("../../../assets/icon/course/aibgImage.png");
  610. background-repeat: no-repeat;
  611. background-size: 100% 100%;
  612. /* display: flex;
  613. flex-direction: column;
  614. align-items: center; */
  615. /* justify-content: center; */
  616. overflow: auto;
  617. text-align: center;
  618. }
  619. .la_coco {
  620. height: 170px;
  621. width: 100%;
  622. display: flex;
  623. justify-content: center;
  624. align-items: flex-end;
  625. }
  626. .la_message {
  627. /* max-height: 400px; */
  628. /* min-height: 400px; */
  629. height: auto;
  630. max-height: calc(100% - 170px - 200px - 40px);
  631. width: 100%;
  632. /* display: flex; */
  633. padding: 10px;
  634. box-sizing: border-box;
  635. margin: 20px 0;
  636. overflow: auto;
  637. }
  638. .la_m_talk {
  639. /* width:100%; */
  640. height: auto;
  641. /* max-height: calc(100% - 170px - 200px - 40px); */
  642. box-sizing: border-box;
  643. }
  644. .la_m_talk > div {
  645. /* padding: 10px; */
  646. padding: 20px 24px 20px 24px;
  647. box-sizing: border-box;
  648. border-radius: 12px;
  649. text-align: left;
  650. background: #00000042;
  651. color: #fff;
  652. }
  653. .la_btn {
  654. height: 220px;
  655. width: 100%;
  656. display: flex;
  657. flex-direction: column;
  658. justify-content: center;
  659. align-items: center;
  660. }
  661. .la_b_noTel {
  662. width: 100%;
  663. height: 100%;
  664. display: flex;
  665. justify-content: center;
  666. align-items: center;
  667. }
  668. .la_b_noTel > span > svg {
  669. fill: #52c41a;
  670. width: 80px;
  671. height: 80px;
  672. cursor: pointer;
  673. }
  674. .la_b_isTel {
  675. width: 100%;
  676. height: 100%;
  677. display: flex;
  678. justify-content: center;
  679. align-items: center;
  680. }
  681. .la_b_isTel > svg {
  682. fill: #ff0e55;
  683. width: 80px;
  684. height: 80px;
  685. cursor: pointer;
  686. transform: rotate(-135deg);
  687. }
  688. .la_b_isTel > span > svg,
  689. img {
  690. cursor: pointer;
  691. }
  692. .la_b_isTel > span {
  693. width: 56px;
  694. height: 56px;
  695. display: flex;
  696. justify-content: center;
  697. align-items: center;
  698. margin: 0 30px;
  699. }
  700. /* .readAloud {
  701. border-radius: 100%;
  702. background-color: #517291;
  703. cursor: pointer;
  704. box-shadow: 0px 2px 4px -1px #0000001f;
  705. box-shadow: 0px 4px 5px 0px #00000014;
  706. box-shadow: 0px 1px 10px 0px #0000000d;
  707. }
  708. .readAloud > svg {
  709. width: 22px;
  710. height: 22px;
  711. fill: #fff;
  712. } */
  713. .openMessage {
  714. width: 100%;
  715. height: auto;
  716. display: flex;
  717. justify-content: center;
  718. margin-top: -30px;
  719. }
  720. .openMessage >>> .el-checkbox {
  721. display: flex;
  722. align-items: center;
  723. justify-content: center;
  724. color: #fff !important;
  725. }
  726. .openMessage >>> .el-checkbox > .el-checkbox__label {
  727. color: #fff !important;
  728. }
  729. .openMessage >>> .el-checkbox > .el-checkbox__input > .el-checkbox__inner {
  730. color: #fff !important;
  731. background: none !important;
  732. border-color: #fff !important;
  733. border-radius: 100% !important;
  734. }
  735. </style>