languageAssistant.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  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="talkLoading"
  66. >
  67. <span @click.stop="stopTalk">
  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="talkAllText">
  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. };
  191. },
  192. computed: {
  193. htmlContent() {
  194. const md = new MarkdownIt();
  195. return (_md) => {
  196. return md.render(_md);
  197. };
  198. },
  199. },
  200. methods: {
  201. scrollBottom() {
  202. this.$nextTick(() => {
  203. this.$refs.messageRef.scrollTop = this.$refs.messageRef.scrollHeight;
  204. });
  205. },
  206. talkAllText() {
  207. if (this.talkLoading && this.aiText == "") return;
  208. let _resultText = this.removeMarkdown(this.aiText);
  209. this.talkTextList.push(_resultText);
  210. this.talkText();
  211. },
  212. recordStart(_text) {
  213. this.show = true;
  214. this.showIndex = 0;
  215. // return
  216. var OpenCC = require("opencc-js");
  217. let converter = OpenCC.Converter({
  218. from: "hk",
  219. to: "cn",
  220. });
  221. if (this.isOpen)
  222. return this.$message.info("已开启语音助手,无需重复开启");
  223. let iiframe = this.$refs["iiframe"];
  224. iiframe.contentWindow.window.document.getElementById(
  225. "languageOptions"
  226. ).selectedIndex = 2; //普通话
  227. iiframe.contentWindow.testdoContinuousPronunciationAssessment();
  228. this.isOpen = true;
  229. this.show = true;
  230. this.aiText = "我是可可同学,我是个小小百事通,你有什么想和我聊一聊?";
  231. iiframe.contentWindow.onRecognizedResult = (e) => {
  232. let _msg = converter(e.privText);
  233. console.log("👇");
  234. console.log(_msg);
  235. // _msg = converter(_msg)
  236. if (!_msg) return console.log("输出为空");
  237. if (this.show == true) {
  238. if (
  239. _msg.indexOf(converter("可可同学")) != -1 &&
  240. _msg.indexOf(converter("停止")) != -1
  241. ) {
  242. this.stopTalk();
  243. } else if (
  244. this.showTextIndex == 2 ||
  245. this.chatLoading ||
  246. this.talkLoading
  247. ) {
  248. return console.log("组织语言中");
  249. // }else if(_msg.indexOf('可可同学')!=-1 && _msg.indexOf("停止")!=-1){
  250. // this.stopTalk();
  251. } else {
  252. this.showTextIndex = 1;
  253. this.aiText = "";
  254. this.userText += _msg;
  255. this.scrollBottom();
  256. this.aiStatus = 1;
  257. if (this.timer) {
  258. clearTimeout(this.timer);
  259. this.timer = null;
  260. }
  261. this.timer = setTimeout(() => {
  262. if (this.userText.indexOf(converter("关闭语音助手")) != -1) {
  263. // return setTimeout(()=>{
  264. this.show = false;
  265. this.showTextIndex = 3;
  266. this.showIndex = 2;
  267. this.aiStatus = 2;
  268. this.aiText = "";
  269. this.userText = "";
  270. this.stopRecord();
  271. return;
  272. // },1000)
  273. }
  274. this.showTextIndex = 2;
  275. this.aiText = "";
  276. let regExp = new RegExp(
  277. converter("计时") + "(.+)" + converter("分钟")
  278. );
  279. if (false && regExp.test(this.userText)) {
  280. // setTimeout(() => {
  281. // let _number = this.userText.match(regExp)[1];
  282. // let _time = 0;
  283. // if (!/^\d+$/.test(_number)) {
  284. // _time = this.chineseToNumber(_number) * 60;
  285. // } else {
  286. // _time = parseInt(_numberList[1]) * 60;
  287. // }
  288. // this.$emit("startTime", _time);
  289. // this.aiStatus = 0;
  290. // this.showTextIndex = 0;
  291. // this.aiText =
  292. // "好的,我已为您计时" +
  293. // this.userText.match(regExp)[1] +
  294. // "分钟。";
  295. // this.userText = "";
  296. // this.timer = setTimeout(() => {
  297. // this.showTextIndex = 3;
  298. // this.aiStatus = 2;
  299. // this.aiText = "";
  300. // this.userText = "";
  301. // }, 3000);
  302. // }, 2000);
  303. } else {
  304. this.chatLoading = true;
  305. const _uuid = uuidv4();
  306. let params = {
  307. assistant_id: "f8e1ebb2-2e0d-11ef-8bf4-12e77c4cb76b",
  308. userId: this.userId,
  309. message: this.userText,
  310. session_name: _uuid + "-qgt",
  311. uid: _uuid,
  312. file_ids: [],
  313. model: "gpt-4o-2024-08-06",
  314. };
  315. this.ajax
  316. // .post("https://claude3.cocorobo.cn/chat", params)
  317. // .post("https://gpt4.cocorobo.cn/chat", params)
  318. .post(
  319. "https://gpt4.cocorobo.cn/ai_agent_park_chat_new",
  320. params
  321. )
  322. .then((res) => {
  323. if (
  324. converter(res.data.FunctionResponse.result) ==
  325. converter("发送成功")
  326. ) {
  327. this.userText = "";
  328. } else {
  329. // this.$message.warning(res.data.FunctionResponse.result);
  330. console.log(res.data.FunctionResponse.result);
  331. this.chatLoading = false;
  332. this.aiStatus = 0;
  333. this.showTextIndex = 0;
  334. this.showIndex = 0;
  335. this.aiText = "对不起,我无法理解您的问题,请重新提问";
  336. // this.timer = setTimeout(() => {
  337. // this.showTextIndex = 3;
  338. // this.aiStatus = 2;
  339. // this.aiText = "";
  340. // this.userText = "";
  341. // }, 3000);
  342. }
  343. })
  344. .catch((e) => {
  345. console.log(e);
  346. this.chatLoading = false;
  347. this.aiStatus = 0;
  348. this.showTextIndex = 0;
  349. this.showIndex = 0;
  350. this.aiText = "对不起,我无法理解您的问题,请重新提问";
  351. // this.timer = setTimeout(() => {
  352. // this.showTextIndex = 3;
  353. // this.aiStatus = 2;
  354. // this.aiText = "";
  355. // this.userText = "";
  356. // }, 3000);
  357. });
  358. // 通过流获取ai对话数据
  359. this.getAtAuContent(_uuid);
  360. }
  361. }, 5000);
  362. }
  363. } else {
  364. console.log("不响应");
  365. }
  366. };
  367. },
  368. stopRecord() {
  369. this.$parent.changeItemType(1)
  370. this.show = false;
  371. this.showIndex = 2;
  372. let iiframe = this.$refs["iiframe"];
  373. iiframe.contentWindow.window.document
  374. .getElementById("scenarioStopButton")
  375. .click();
  376. if (this.talkLoading) {
  377. this.stopTalk();
  378. }
  379. // this.stopTalk();
  380. // 录音借宿
  381. iiframe.contentWindow.onSessionStopped = (s, e) => {
  382. this.isOpen = false;
  383. this.show = false;
  384. this.showTextIndex = 3;
  385. this.showIndex = 2;
  386. this.$message.success("已关闭语音助手");
  387. if (this.talkLoading) {
  388. this.$refs.iiframe2.contentWindow.closesynthesizer();
  389. }
  390. this.userText = "";
  391. this.aiText = "";
  392. };
  393. },
  394. chineseToNumber(chinese) {
  395. var OpenCC = require("opencc-js");
  396. let converter = OpenCC.Converter({
  397. from: "hk",
  398. to: "cn",
  399. });
  400. chinese = converter(chinese);
  401. const chineseNumbers = {
  402. 零: 0,
  403. 一: 1,
  404. 二: 2,
  405. 三: 3,
  406. 四: 4,
  407. 五: 5,
  408. 六: 6,
  409. 七: 7,
  410. 八: 8,
  411. 九: 9,
  412. 十: 10,
  413. 百: 100,
  414. 千: 1000,
  415. 万: 10000,
  416. 亿: 100000000,
  417. };
  418. let result = 0;
  419. let tempNum = 0; // 用于累积处理
  420. let sectionNum = 0; // 每个段的值
  421. for (let i = 0; i < chinese.length; i++) {
  422. const char = chinese[i];
  423. const num = chineseNumbers[char];
  424. if (num === undefined) {
  425. throw new Error(`Unexpected character: ${char}`);
  426. }
  427. if (
  428. num === 10 ||
  429. num === 100 ||
  430. num === 1000 ||
  431. num === 10000 ||
  432. num === 100000000
  433. ) {
  434. if (tempNum === 0) tempNum = 1; // 如果前面没有数,默认是1
  435. tempNum *= num;
  436. if (num === 10000 || num === 100000000) {
  437. sectionNum += tempNum;
  438. result += sectionNum;
  439. tempNum = 0;
  440. sectionNum = 0;
  441. }
  442. } else {
  443. tempNum += num;
  444. }
  445. }
  446. result += sectionNum + tempNum;
  447. return result;
  448. },
  449. removeMarkdown(text) {
  450. return text
  451. .replace(/[#*_~`>+\-]/g, "") // 移除 #、*、_、~、`、>、+、- 符号
  452. .replace(/!\[.*?\]\(.*?\)/g, "") // 移除图片
  453. .replace(/\[.*?\]\(.*?\)/g, "") // 移除链接
  454. .replace(/```[\s\S]*?```/g, "") // 移除代码块(不使用 s 标志)
  455. .replace(/`[^`]*`/g, "") // 移除行内代码
  456. .replace(/\d+\./g, "") // 移除有序列表
  457. .replace(/^\s*[-*+]\s+/gm, "") // 移除无序列表
  458. .replace(/\s+/g, " ") // 将多个空白字符替换为一个空格
  459. .trim(); // 去除字符串两端的空白字符
  460. },
  461. getAtAuContent(_uid) {
  462. this.source = new EventSource(
  463. `https://gpt4.cocorobo.cn/question/${_uid}`
  464. );
  465. //http://gpt4.cocorobo.cn:8011/question/ https://gpt4.cocorobo.cn/question/
  466. let _allText = "";
  467. let _mdText = "";
  468. let _talkText = "";
  469. // let _talkIndex = 0;
  470. // const md = new MarkdownIt();
  471. this.source.onmessage = (_e) => {
  472. let _eData = JSON.parse(_e.data);
  473. if (_eData.content.replace("'", "").replace("'", "") == "[DONE]") {
  474. this.source.close();
  475. this.source = null;
  476. let _result = [];
  477. if ("result" in _eData) {
  478. _result = _eData.result;
  479. for (let i = 0; i < _result.length; i++) {
  480. _mdText = _mdText.replace(_result[i].text, _result[i].fileName);
  481. }
  482. }
  483. _mdText = _mdText.replace("_", "");
  484. this.aiText = _mdText;
  485. this.scrollBottom();
  486. if (_talkText != "") {
  487. let _resultText = this.removeMarkdown(_talkText);
  488. this.talkTextList.push(_resultText);
  489. _talkText = "";
  490. if (!this.talkLoading) this.talkText();
  491. }
  492. this.chatLoading = false;
  493. } else {
  494. // _talkIndex+=1;
  495. let _text = _eData.content.replace("'", "").replace("'", "");
  496. if (_allText == "") {
  497. _allText = _text.replace(/^\n+/, ""); //去掉回复消息中偶尔开头就存在的连续换行符
  498. _talkText += _text.replace(/^\n+/, "");
  499. } else {
  500. _allText += _text;
  501. _talkText += _text;
  502. }
  503. `~`;
  504. _mdText = _allText + "_";
  505. _mdText = _mdText.replace(/\\n/g, "\n");
  506. _mdText = _mdText.replace(/\\/g, "");
  507. if (_allText.split("```").length % 2 == 0) _mdText += "\n```\n";
  508. this.aiText = _mdText;
  509. this.showTextIndex = 0;
  510. this.scrollBottom();
  511. if (/[,。:;?!)]/.test(_talkText)) {
  512. let _resultText = this.removeMarkdown(_talkText);
  513. this.talkTextList.push(_resultText);
  514. _talkText = "";
  515. if (!this.talkLoading) this.talkText();
  516. }
  517. }
  518. };
  519. },
  520. talkText() {
  521. let _text = this.talkTextList.shift();
  522. let _talkTextIiframe2 = this.$refs.iiframe2;
  523. if (_text) {
  524. this.talkLoading = true;
  525. if (this.timer) {
  526. clearTimeout(this.timer);
  527. this.timer = null;
  528. }
  529. console.log(`👉转语音:${_text}`);
  530. _talkTextIiframe2.contentWindow.texttospeech(
  531. _text,
  532. this.talkText,
  533. this.endTalk
  534. );
  535. } else {
  536. _talkTextIiframe2.contentWindow.closesynthesizer();
  537. }
  538. },
  539. endTalk() {
  540. console.log("👉转语音结束👈");
  541. this.talkLoading = false;
  542. },
  543. stopTalk() {
  544. // return this.$message.info("停止")
  545. this.talkTextList = [];
  546. try {
  547. let _talkTextIiframe2 = this.$refs.iiframe2;
  548. _talkTextIiframe2.contentWindow.pausesynthesizer();
  549. _talkTextIiframe2.contentWindow.closesynthesizer();
  550. this.talkLoading = false;
  551. } catch (error) {
  552. this.talkLoading = false;
  553. }
  554. },
  555. interrupt() {
  556. // return this.$message.info("打断")
  557. if (this.source) {
  558. try {
  559. this.source.close();
  560. } catch (error) {
  561. console.log(error);
  562. }
  563. }
  564. this.stopTalk();
  565. },
  566. },
  567. mounted() {
  568. this.$nextTick(()=>{
  569. this.recordStart()
  570. })
  571. },
  572. };
  573. </script>
  574. <style scoped>
  575. .languageAssistant {
  576. width: 100%;
  577. height: 100%;
  578. border-radius: 10px 0 0 10px;
  579. /* background-image: linear-gradient(to top, #007adf 0%, #00ecbc 100%);
  580. */
  581. background-image: url("../../../assets/icon/course/aibgImage.png");
  582. background-repeat: no-repeat;
  583. background-size: 100% 100%;
  584. /* display: flex;
  585. flex-direction: column;
  586. align-items: center; */
  587. /* justify-content: center; */
  588. overflow: auto;
  589. text-align: center;
  590. }
  591. .la_coco {
  592. height: 170px;
  593. width: 100%;
  594. display: flex;
  595. justify-content: center;
  596. align-items: flex-end;
  597. }
  598. .la_message {
  599. /* max-height: 400px; */
  600. /* min-height: 400px; */
  601. height: auto;
  602. max-height: calc(100% - 170px - 200px - 40px);
  603. width: 100%;
  604. /* display: flex; */
  605. padding: 10px;
  606. box-sizing: border-box;
  607. margin: 20px 0;
  608. overflow: auto;
  609. }
  610. .la_m_talk {
  611. /* width:100%; */
  612. height: auto;
  613. /* max-height: calc(100% - 170px - 200px - 40px); */
  614. box-sizing: border-box;
  615. }
  616. .la_m_talk > div {
  617. /* padding: 10px; */
  618. padding: 20px 24px 20px 24px;
  619. box-sizing: border-box;
  620. border-radius: 12px;
  621. text-align: left;
  622. background: #00000042;
  623. color: #fff;
  624. }
  625. .la_btn {
  626. height: 220px;
  627. width: 100%;
  628. display: flex;
  629. flex-direction: column;
  630. justify-content: center;
  631. align-items: center;
  632. }
  633. .la_b_noTel {
  634. width: 100%;
  635. height: 100%;
  636. display: flex;
  637. justify-content: center;
  638. align-items: center;
  639. }
  640. .la_b_noTel > span > svg {
  641. fill: #52c41a;
  642. width: 80px;
  643. height: 80px;
  644. cursor: pointer;
  645. }
  646. .la_b_isTel {
  647. width: 100%;
  648. height: 100%;
  649. display: flex;
  650. justify-content: center;
  651. align-items: center;
  652. }
  653. .la_b_isTel > svg {
  654. fill: #ff0e55;
  655. width: 80px;
  656. height: 80px;
  657. cursor: pointer;
  658. transform: rotate(-135deg);
  659. }
  660. .la_b_isTel > span > svg,
  661. img {
  662. cursor: pointer;
  663. }
  664. .la_b_isTel > span {
  665. width: 56px;
  666. height: 56px;
  667. display: flex;
  668. justify-content: center;
  669. align-items: center;
  670. margin: 0 30px;
  671. }
  672. /* .readAloud {
  673. border-radius: 100%;
  674. background-color: #517291;
  675. cursor: pointer;
  676. box-shadow: 0px 2px 4px -1px #0000001f;
  677. box-shadow: 0px 4px 5px 0px #00000014;
  678. box-shadow: 0px 1px 10px 0px #0000000d;
  679. }
  680. .readAloud > svg {
  681. width: 22px;
  682. height: 22px;
  683. fill: #fff;
  684. } */
  685. .openMessage{
  686. width: 100%;
  687. height: auto;
  688. display: flex;
  689. justify-content: center;
  690. margin-top: -30px;
  691. }
  692. .openMessage >>> .el-checkbox{
  693. display: flex;
  694. align-items: center;
  695. justify-content: center;
  696. color: #fff !important;
  697. }
  698. .openMessage >>> .el-checkbox> .el-checkbox__label{
  699. color: #fff !important;
  700. }
  701. .openMessage >>> .el-checkbox>.el-checkbox__input> .el-checkbox__inner{
  702. color: #fff !important;
  703. background: none !important;
  704. border-color: #fff !important;
  705. border-radius: 100% !important;
  706. }
  707. </style>