当前位置:   article > 正文

类似于gpt的聊天效果,打字机_聊天对话框类似于gpt 流式输出

聊天对话框类似于gpt 流式输出

下载第三课库 typed.js

把这个组件命名TypedEffect,应用这个组件,放在第二个代码片段里面去

  1. <template>
  2. <div class="typed-container">
  3. <span ref="typedElement"></span>
  4. </div>
  5. </template>
  6. <script>
  7. import Typed from 'typed.js';
  8. export default {
  9. name:'TypedEffect',
  10. props: {
  11. strings: {
  12. type: Array,
  13. required: true
  14. },
  15. typeSpeed: {
  16. type: Number,
  17. default: 50
  18. },
  19. backSpeed: {
  20. type: Number,
  21. default: 50
  22. },
  23. loop: {
  24. type: Boolean,
  25. default: false
  26. }
  27. },
  28. mounted() {
  29. this.initTyped();
  30. },
  31. beforeDestroy() {
  32. if (this.typed) {
  33. this.typed.destroy();
  34. }
  35. },
  36. watch: {
  37. strings(newStrings) {
  38. if (this.typed) {
  39. this.typed.destroy();
  40. }
  41. this.initTyped();
  42. }
  43. },
  44. methods: {
  45. initTyped() {
  46. const options = {
  47. strings: this.strings,
  48. typeSpeed: this.typeSpeed,
  49. backSpeed: this.backSpeed,
  50. loop: this.loop
  51. };
  52. this.typed = new Typed(this.$refs.typedElement, options);
  53. }
  54. }
  55. };
  56. </script>
  57. <style scoped>
  58. .typed-container {
  59. font-family: 'Courier New', Courier, monospace;
  60. font-size: 16px;
  61. }
  62. </style>
  1. <template>
  2. <div class="chatbot">
  3. <div class="chat-window" v-loading="loading"
  4. element-loading-text="拼命加载中"
  5. element-loading-spinner="el-icon-loading"
  6. element-loading-background="rgba(0, 0, 0, 0.8)">
  7. <div v-for="(message, index) in messages" :key="index" :class="['message', message.type]">
  8. <div v-if="message.type === 'question'" class="user-message">
  9. <span class="tiwen">{{ message.text }}</span> <span class="tiwenTox"></span>
  10. </div>
  11. <div v-else class="bot-message">
  12. <span class="ecwfwfTx"></span> <TypedEffect v-if="index === messages.length - 1 && !showNextMessage" :strings="[message.text]" :typeSpeed="50" :backSpeed="50" :loop="false" />
  13. <span class="ecwfwf" v-else> {{ message.text }}</span>
  14. </div>
  15. </div>
  16. </div>
  17. <input class="cwedcw" v-model="userInput" @keyup.enter="handleInput" placeholder="输入你的问题后,敲回车键" />
  18. </div>
  19. </template>
  20. <script>
  21. import TypedEffect from './TypedEffect.vue';
  22. import { interpretTheContentOfTheDocument } from "@/api/wenjian";
  23. export default {
  24. name:'chatbot',
  25. components: {
  26. TypedEffect
  27. },
  28. props: {
  29. // text: {
  30. // type: String,
  31. // required: true
  32. // },
  33. name: {
  34. type: String,
  35. required: true
  36. },
  37. size: {
  38. type: String,
  39. required: true
  40. },
  41. type: {
  42. type: String,
  43. required: true
  44. },
  45. },
  46. data() {
  47. return {
  48. userInput: '',
  49. messages: [],
  50. responses: {
  51. '你好': '你好!有什么我可以帮助你的吗?',
  52. '天气': '今天天气很好,适合外出。',
  53. '再见': '再见!祝你有美好的一天!'
  54. },
  55. showNextMessage: true,
  56. dataObject:null,
  57. text:null,
  58. loading:false
  59. };
  60. },
  61. created(){
  62. // console.log(this.text);
  63. console.log(this.name);
  64. console.log(this.size);
  65. console.log(this.type);
  66. this.text = sessionStorage.getItem('text');
  67. },
  68. beforeDestroy() {
  69. this.dataObject.text =null
  70. },
  71. methods: {
  72. async handleInput() {
  73. this.loading=true
  74. const userQuestion = this.userInput.trim();
  75. if (userQuestion) {
  76. console.log('User question:', userQuestion);
  77. let query={
  78. busKgFile:{
  79. text:this.text,
  80. name:this.name,
  81. size:this.size,
  82. type:this.type
  83. },
  84. q:userQuestion
  85. }
  86. const res= await interpretTheContentOfTheDocument(query)
  87. console.log(res,"相关回答");
  88. const originalString = res
  89. // 数据处理
  90. // 定义正则表达式来匹配 data 字段
  91. const regex = /data: (\{.*\})/s;
  92. // 使用正则表达式匹配内容
  93. const match = originalString.match(regex);
  94. // 如果匹配成功,提取第一个捕获组内容作为 data 字段的字符串
  95. if (match) {
  96. const dataString = match[1];
  97. // 将 data 字符串解析为对象
  98. try {
  99. this.dataObject = JSON.parse(dataString);
  100. // console.log(dataObject);
  101. } catch (error) {
  102. console.error('Failed to parse data object:', error);
  103. }
  104. } else {
  105. console.error('No data field found in the input string.');
  106. }
  107. if(this.dataObject.text){
  108. this.loading=false
  109. }else{
  110. this.loading=false
  111. }
  112. // console.log(dataObject.text,"相关回答");
  113. this.messages.push({ type: 'question', text: userQuestion });
  114. const response = this.dataObject.text || '对不起,我不明白你的问题。';
  115. this.userInput = ''; // 清空输入框
  116. this.showNextMessage = false; // 隐藏下一条信息
  117. setTimeout(() => {
  118. this.messages.push({ type: 'answer', text: response });
  119. this.$nextTick(() => {
  120. this.showNextMessage = true; // 显示下一条信息
  121. });
  122. }, 500); // 模拟回复延迟
  123. }
  124. }
  125. }
  126. };
  127. </script>
  128. <style scoped>
  129. .chatbot {
  130. display: flex;
  131. flex-direction: column;
  132. align-items: center;
  133. margin-top: 20px;
  134. }
  135. .chat-window {
  136. border: 1px solid #ccc;
  137. border-radius: 5px;
  138. width: 100%;
  139. height: 80vh;
  140. overflow-y: auto;
  141. padding: 10px;
  142. background-color: #f9f9f9;
  143. }
  144. .message {
  145. margin: 10px 0;
  146. }
  147. .user-message {
  148. text-align: right;
  149. padding: 10px;
  150. /* background-color: #d1e7dd; */
  151. border-radius: 10px;
  152. align-self: flex-end;
  153. max-width: 80%;
  154. display: flex;
  155. align-items: center
  156. }
  157. ::v-deep .message .question{
  158. }
  159. .tiwen{
  160. display: inline-block;
  161. width: 90%;
  162. border-radius: 10px;
  163. text-align: right;
  164. padding: 10px;
  165. background-color: #d1e7dd;
  166. }
  167. .tiwenTox{
  168. width: 40px;
  169. height: 40px;
  170. display: inline-block;
  171. background: url(../../../../assets/wendong/66135a5a1bfb5b0037b2bd52.png) no-repeat;
  172. background-size: 100% 100%;
  173. margin-left: 5px;
  174. }
  175. .bot-message {
  176. text-align: left;
  177. padding: 10px;
  178. /* background-color: #f8d7da; */
  179. border-radius: 10px;
  180. align-self: flex-start;
  181. max-width: 80%;
  182. }
  183. .ecwfwf{
  184. display: inline-block;
  185. width: 90%;
  186. border-radius: 10px;
  187. text-align: left;
  188. padding: 10px;
  189. background-color: #f8d7da;
  190. }
  191. .ecwfwfTx{
  192. width: 40px;
  193. height: 40px;
  194. display: inline-block;
  195. background: url(../../../../assets/wendong/logo.png) no-repeat;
  196. background-size: 100% 100%;
  197. margin-left: 5px;
  198. }
  199. input {
  200. margin-top: 20px;
  201. padding: 10px;
  202. font-size: 16px;
  203. width: 400px;
  204. border: 1px solid #ccc;
  205. border-radius: 5px;
  206. }
  207. .cwedcw{
  208. width: 90%;
  209. }
  210. .sdcscs{
  211. display: flex;
  212. align-content: center;
  213. }
  214. </style>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/875342
推荐阅读
相关标签
  

闽ICP备14008679号