languageAssistant.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794
  1. <template>
  2. <div class="languageAssistant" v-loading="loading">
  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: true,
  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. loading:false,
  192. };
  193. },
  194. computed: {
  195. htmlContent() {
  196. const md = new MarkdownIt();
  197. return _md => {
  198. return md.render(_md);
  199. };
  200. }
  201. },
  202. methods: {
  203. scrollBottom() {
  204. this.$nextTick(() => {
  205. this.$refs.messageRef.scrollTop = this.$refs.messageRef.scrollHeight;
  206. });
  207. },
  208. talkAllText() {
  209. if (this.talkLoading && this.aiText == "") return;
  210. let _resultText = this.removeMarkdown(this.aiText);
  211. this.talkTextList.push(_resultText);
  212. this.talkText();
  213. },
  214. recordStart(_text) {
  215. try {
  216. let iiframe = this.$refs["iiframe"];
  217. iiframe.contentWindow.window.document.getElementById(
  218. "languageOptions"
  219. ).selectedIndex = 2; //普通话
  220. iiframe.contentWindow.testdoContinuousPronunciationAssessment();
  221. // return
  222. var OpenCC = require("opencc-js");
  223. let converter = OpenCC.Converter({
  224. from: "hk",
  225. to: "cn"
  226. });
  227. this.show = true;
  228. this.showIndex = 0;
  229. this.showTextIndex = 0;
  230. this.chatLoading = false;
  231. this.talkLoading = false;
  232. this.isOpen = true;
  233. this.show = true;
  234. this.aiText = "我是可可同学,我是个小小百事通,你有什么想和我聊一聊?";
  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. setTimeout(()=>{
  375. this.recordStart()
  376. },1000)
  377. // this.recordStart();
  378. }
  379. },
  380. stopRecord() {
  381. this.$parent.changeItemType(1);
  382. this.show = false;
  383. this.showIndex = 2;
  384. let iiframe = this.$refs["iiframe"];
  385. iiframe.contentWindow.window.document
  386. .getElementById("scenarioStopButton")
  387. .click();
  388. if (this.talkLoading) {
  389. this.stopTalk();
  390. }
  391. // this.stopTalk();
  392. // 录音借宿
  393. iiframe.contentWindow.onSessionStopped = (s, e) => {
  394. this.isOpen = false;
  395. this.show = false;
  396. this.showTextIndex = 3;
  397. this.showIndex = 2;
  398. this.$message.success("已关闭语音助手");
  399. if (this.talkLoading) {
  400. this.$refs.iiframe2.contentWindow.closesynthesizer();
  401. }
  402. this.userText = "";
  403. this.aiText = "";
  404. };
  405. },
  406. chineseToNumber(chinese) {
  407. var OpenCC = require("opencc-js");
  408. let converter = OpenCC.Converter({
  409. from: "hk",
  410. to: "cn"
  411. });
  412. chinese = converter(chinese);
  413. const chineseNumbers = {
  414. 零: 0,
  415. 一: 1,
  416. 二: 2,
  417. 三: 3,
  418. 四: 4,
  419. 五: 5,
  420. 六: 6,
  421. 七: 7,
  422. 八: 8,
  423. 九: 9,
  424. 十: 10,
  425. 百: 100,
  426. 千: 1000,
  427. 万: 10000,
  428. 亿: 100000000
  429. };
  430. let result = 0;
  431. let tempNum = 0; // 用于累积处理
  432. let sectionNum = 0; // 每个段的值
  433. for (let i = 0; i < chinese.length; i++) {
  434. const char = chinese[i];
  435. const num = chineseNumbers[char];
  436. if (num === undefined) {
  437. throw new Error(`Unexpected character: ${char}`);
  438. }
  439. if (
  440. num === 10 ||
  441. num === 100 ||
  442. num === 1000 ||
  443. num === 10000 ||
  444. num === 100000000
  445. ) {
  446. if (tempNum === 0) tempNum = 1; // 如果前面没有数,默认是1
  447. tempNum *= num;
  448. if (num === 10000 || num === 100000000) {
  449. sectionNum += tempNum;
  450. result += sectionNum;
  451. tempNum = 0;
  452. sectionNum = 0;
  453. }
  454. } else {
  455. tempNum += num;
  456. }
  457. }
  458. result += sectionNum + tempNum;
  459. return result;
  460. },
  461. removeMarkdown(text) {
  462. return text
  463. .replace(/[#*_~`>+\-]/g, "") // 移除 #、*、_、~、`、>、+、- 符号
  464. .replace(/!\[.*?\]\(.*?\)/g, "") // 移除图片
  465. .replace(/\[.*?\]\(.*?\)/g, "") // 移除链接
  466. .replace(/```[\s\S]*?```/g, "") // 移除代码块(不使用 s 标志)
  467. .replace(/`[^`]*`/g, "") // 移除行内代码
  468. .replace(/\d+\./g, "") // 移除有序列表
  469. .replace(/^\s*[-*+]\s+/gm, "") // 移除无序列表
  470. .replace(/\s+/g, " ") // 将多个空白字符替换为一个空格
  471. .trim(); // 去除字符串两端的空白字符
  472. },
  473. getAtAuContent(_uid) {
  474. this.source = new EventSource(
  475. `https://gpt4.cocorobo.cn/question/${_uid}`
  476. );
  477. //http://gpt4.cocorobo.cn:8011/question/ https://gpt4.cocorobo.cn/question/
  478. let _allText = "";
  479. let _mdText = "";
  480. let _talkText = "";
  481. // let _talkIndex = 0;
  482. // const md = new MarkdownIt();
  483. this.source.onmessage = _e => {
  484. this.showIndex = 0;
  485. let _eData = JSON.parse(_e.data);
  486. if (_eData.content.replace("'", "").replace("'", "") == "[DONE]") {
  487. this.source.close();
  488. this.source = null;
  489. let _result = [];
  490. if ("result" in _eData) {
  491. _result = _eData.result;
  492. for (let i = 0; i < _result.length; i++) {
  493. _mdText = _mdText.replace(_result[i].text, _result[i].fileName);
  494. }
  495. }
  496. _mdText = _mdText.replace("_", "");
  497. this.aiText = _mdText;
  498. this.scrollBottom();
  499. if (_talkText != "") {
  500. let _resultText = this.removeMarkdown(_talkText);
  501. this.talkTextList.push(_resultText);
  502. _talkText = "";
  503. if (!this.talkLoading) this.talkText();
  504. }
  505. this.chatLoading = false;
  506. } else {
  507. // _talkIndex+=1;
  508. let _text = _eData.content.replace("'", "").replace("'", "");
  509. if (_allText == "") {
  510. _allText = _text.replace(/^\n+/, ""); //去掉回复消息中偶尔开头就存在的连续换行符
  511. _talkText += _text.replace(/^\n+/, "");
  512. } else {
  513. _allText += _text;
  514. _talkText += _text;
  515. }
  516. `~`;
  517. _mdText = _allText + "_";
  518. _mdText = _mdText.replace(/\\n/g, "\n");
  519. _mdText = _mdText.replace(/\\/g, "");
  520. if (_allText.split("```").length % 2 == 0) _mdText += "\n```\n";
  521. this.aiText = _mdText;
  522. this.showTextIndex = 0;
  523. this.scrollBottom();
  524. if (/[,。:;?!)]/.test(_talkText)) {
  525. let _resultText = this.removeMarkdown(_talkText);
  526. this.talkTextList.push(_resultText);
  527. _talkText = "";
  528. if (!this.talkLoading) this.talkText();
  529. }
  530. }
  531. };
  532. },
  533. talkText() {
  534. let _text = this.talkTextList.shift();
  535. let _talkTextIiframe2 = this.$refs.iiframe2;
  536. if (_text) {
  537. this.talkLoading = true;
  538. if (this.timer) {
  539. clearTimeout(this.timer);
  540. this.timer = null;
  541. }
  542. console.log(`👉转语音:${_text}`);
  543. _talkTextIiframe2.contentWindow.texttospeech(
  544. _text,
  545. this.talkText,
  546. this.endTalk
  547. );
  548. } else {
  549. _talkTextIiframe2.contentWindow.closesynthesizer();
  550. }
  551. },
  552. endTalk() {
  553. console.log("👉转语音结束👈");
  554. this.talkLoading = false;
  555. },
  556. stopTalk() {
  557. // return this.$message.info("停止")
  558. this.talkTextList = [];
  559. try {
  560. let _talkTextIiframe2 = this.$refs.iiframe2;
  561. _talkTextIiframe2.contentWindow.pausesynthesizer();
  562. _talkTextIiframe2.contentWindow.closesynthesizer();
  563. this.talkLoading = false;
  564. } catch (error) {
  565. this.talkLoading = false;
  566. }
  567. },
  568. interrupt() {
  569. // return this.$message.info("打断")
  570. if (this.source) {
  571. try {
  572. this.source.close();
  573. } catch (error) {
  574. console.log(error);
  575. }
  576. }
  577. this.stopTalk();
  578. },
  579. canNotTalk(){
  580. this.canTalk = false;
  581. this.showIndex = 2;
  582. this.chatLoading = false;
  583. this.stopTalk();
  584. if(this.source){
  585. this.source.close();
  586. this.source = null;
  587. }
  588. },
  589. canTalkFn(){
  590. this.canTalk = true;
  591. this.showIndex = 0;
  592. this.showTextIndex = 0;
  593. this.aiText = "我是可可同学,我是个小小百事通,你有什么想和我聊一聊";
  594. this.chatLoading = false;
  595. }
  596. },
  597. mounted() {
  598. this.loading = true;
  599. try {
  600. const iiframe = this.$refs.iiframe;
  601. if(iiframe.attachEvent){
  602. iiframe.attachEvent('onload',()=>{
  603. this.$nextTick(()=>{
  604. console.log("开启")
  605. this.loading = false;
  606. this.recordStart();
  607. })
  608. })
  609. }else{
  610. iiframe.onload = ()=>{
  611. this.$nextTick(()=>{
  612. this.loading = false;
  613. console.log("开启")
  614. this.recordStart();
  615. })
  616. }
  617. }
  618. } catch (error) {
  619. console.log('报错👇')
  620. console.log(error)
  621. this.loading = false;
  622. this.$message.error("开启语音助手失败")
  623. }
  624. }
  625. };
  626. </script>
  627. <style scoped>
  628. .languageAssistant {
  629. width: 100%;
  630. height: 100%;
  631. border-radius: 10px 0 0 10px;
  632. /* background-image: linear-gradient(to top, #007adf 0%, #00ecbc 100%);
  633. */
  634. background-image: url("../../../assets/icon/course/aibgImage.png");
  635. background-repeat: no-repeat;
  636. background-size: 100% 100%;
  637. /* display: flex;
  638. flex-direction: column;
  639. align-items: center; */
  640. /* justify-content: center; */
  641. overflow: auto;
  642. text-align: center;
  643. }
  644. .la_coco {
  645. height: 170px;
  646. width: 100%;
  647. display: flex;
  648. justify-content: center;
  649. align-items: flex-end;
  650. }
  651. .la_message {
  652. /* max-height: 400px; */
  653. /* min-height: 400px; */
  654. height: auto;
  655. max-height: calc(100% - 170px - 200px - 40px);
  656. width: 100%;
  657. /* display: flex; */
  658. padding: 10px;
  659. box-sizing: border-box;
  660. margin: 20px 0;
  661. overflow: auto;
  662. }
  663. .la_m_talk {
  664. /* width:100%; */
  665. height: auto;
  666. /* max-height: calc(100% - 170px - 200px - 40px); */
  667. box-sizing: border-box;
  668. }
  669. .la_m_talk > div {
  670. /* padding: 10px; */
  671. padding: 20px 24px 20px 24px;
  672. box-sizing: border-box;
  673. border-radius: 12px;
  674. text-align: left;
  675. background: #00000042;
  676. color: #fff;
  677. }
  678. .la_btn {
  679. height: 220px;
  680. width: 100%;
  681. display: flex;
  682. flex-direction: column;
  683. justify-content: center;
  684. align-items: center;
  685. }
  686. .la_b_noTel {
  687. width: 100%;
  688. height: 100%;
  689. display: flex;
  690. justify-content: center;
  691. align-items: center;
  692. }
  693. .la_b_noTel > span > svg {
  694. fill: #52c41a;
  695. width: 80px;
  696. height: 80px;
  697. cursor: pointer;
  698. }
  699. .la_b_isTel {
  700. width: 100%;
  701. height: 100%;
  702. display: flex;
  703. justify-content: center;
  704. align-items: center;
  705. }
  706. .la_b_isTel > svg {
  707. fill: #ff0e55;
  708. width: 80px;
  709. height: 80px;
  710. cursor: pointer;
  711. transform: rotate(-135deg);
  712. }
  713. .la_b_isTel > span > svg,
  714. img {
  715. cursor: pointer;
  716. }
  717. .la_b_isTel > span {
  718. width: 56px;
  719. height: 56px;
  720. display: flex;
  721. justify-content: center;
  722. align-items: center;
  723. margin: 0 30px;
  724. }
  725. /* .readAloud {
  726. border-radius: 100%;
  727. background-color: #517291;
  728. cursor: pointer;
  729. box-shadow: 0px 2px 4px -1px #0000001f;
  730. box-shadow: 0px 4px 5px 0px #00000014;
  731. box-shadow: 0px 1px 10px 0px #0000000d;
  732. }
  733. .readAloud > svg {
  734. width: 22px;
  735. height: 22px;
  736. fill: #fff;
  737. } */
  738. .openMessage {
  739. width: 100%;
  740. height: auto;
  741. display: flex;
  742. justify-content: center;
  743. margin-top: -30px;
  744. }
  745. .openMessage >>> .el-checkbox {
  746. display: flex;
  747. align-items: center;
  748. justify-content: center;
  749. color: #fff !important;
  750. }
  751. .openMessage >>> .el-checkbox > .el-checkbox__label {
  752. color: #fff !important;
  753. }
  754. .openMessage >>> .el-checkbox > .el-checkbox__input > .el-checkbox__inner {
  755. color: #fff !important;
  756. background: none !important;
  757. border-color: #fff !important;
  758. border-radius: 100% !important;
  759. }
  760. </style>