index.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <template>
  2. <view class="container">
  3. <scroll-view class="chat-messages" scroll-y="true" :scroll-with-animation="true"
  4. :scroll-into-view="scrollToView"
  5. :style="{ width: $scrollViewWidth + 'px', padding: $viewPadding + 'px',maxHeight: $viewMaxHeight + 'px'}">
  6. <!-- 循环渲染消息 -->
  7. <view v-for="(message, index) in messages" :key="index" :id="'msg' + index" style="clear: both;">
  8. <view :class="['message', message.sender === 'user' ? 'user-message' : 'ai-message']">
  9. <text>{{ message.content }}</text>
  10. </view>
  11. </view>
  12. </scroll-view>
  13. <view class="chat-input">
  14. <textarea @linechange="chatMsgMaxHeightChange" auto-height v-model="inputMessage" placeholder="输入消息..."
  15. class="input-field" />
  16. <button class="send-button" @click="sendMessage">发送</button>
  17. </view>
  18. </view>
  19. </template>
  20. <script setup>
  21. import {
  22. ref,
  23. nextTick,
  24. onMounted
  25. } from 'vue';
  26. import $modal from '@/plugins/modal.js'
  27. const inputMessage = ref('');
  28. const messages = ref([{
  29. sender: 'ai',
  30. content: '您好,我是ai助手'
  31. },
  32. ]);
  33. const scrollToView = ref('');// 滚动到特定消息的标识
  34. // 发送消息函数
  35. function sendMessage() {
  36. if (inputMessage.value.trim() === '') {
  37. return;
  38. }
  39. messages.value.push({
  40. sender: 'user',
  41. content: inputMessage.value
  42. });
  43. inputMessage.value = ''; // 清空输入框
  44. scrollToBottom(); // 滚动到底部
  45. getAIResponse(); // 获取AI的回复
  46. };
  47. // 获取AI回复的函数
  48. function getAIResponse() {
  49. // 这里调用AI客服接口,获取回复
  50. uni.request({
  51. url: 'http://api.qingyunke.com/api.php?key=free&appid=0&msg=' + messages.value[messages.value.length -
  52. 1].content,
  53. success: (res) => {
  54. messages.value.push({
  55. sender: 'ai',
  56. content: res.data.content
  57. });
  58. },
  59. fail: (err) => {
  60. console.log('err', err);
  61. $modal.alert('err'+ JSON.stringify(err))
  62. // $modal.msg(err)
  63. messages.value.push({
  64. sender: 'ai',
  65. content: '小客服不在线'
  66. });
  67. },
  68. complete: () => {
  69. scrollToBottom();
  70. }
  71. })
  72. };
  73. // 滚动到底部的函数
  74. function scrollToBottom() {
  75. nextTick(() => {
  76. scrollToView.value = 'msg' + (messages.value.length - 1); // 更新滚动到的消息
  77. });
  78. };
  79. const $scrollViewWidth = ref(0); // 滚动视图宽度
  80. const $viewMaxHeight = ref(0); // 滚动视图最大高度
  81. const $viewPadding = ref(10); // 滚动视图内边距
  82. const $windowHeight = ref(0); // 窗口高度
  83. // 使用 onMounted 钩子在组件挂载后获取窗口高度
  84. onMounted(() => {
  85. const res = uni.getWindowInfo();
  86. // 计算滚动视图宽度
  87. $scrollViewWidth.value = res.windowWidth - $viewPadding.value * 2;
  88. $windowHeight.value = res.windowHeight;
  89. $viewMaxHeight.value = res.windowHeight - 100;
  90. });
  91. // 输入框行数变化时更新最大高度
  92. function chatMsgMaxHeightChange(e) {
  93. console.log($windowHeight,e.detail.height);
  94. $viewMaxHeight.value = $windowHeight.value - e.detail.height - 70;
  95. }
  96. </script>
  97. <style scoped>
  98. .container {
  99. display: flex;
  100. flex-direction: column;
  101. height: 100vh;
  102. position: relative;
  103. }
  104. .chat-messages {
  105. flex: 1;
  106. background-color: #f3f3f3;
  107. overflow-y: auto;
  108. }
  109. .message {
  110. max-width: 70%;
  111. margin: 5px 0;
  112. padding: 8px;
  113. border-radius: 10px;
  114. display: inline-block;
  115. word-wrap: break-word;
  116. }
  117. .user-message {
  118. background-color: #DCF8C6;
  119. align-self: flex-end;
  120. float: right;
  121. }
  122. .ai-message {
  123. background-color: #ECECEC;
  124. align-self: flex-start;
  125. }
  126. .chat-input {
  127. display: flex;
  128. padding: 10px;
  129. background-color: #FFFFFF;
  130. border-top: 1px solid #E0E0E0;
  131. position: absolute;
  132. bottom: 0;
  133. left: 0;
  134. right: 0;
  135. }
  136. .input-field {
  137. flex: 1;
  138. border: 1px solid #E0E0E0;
  139. border-radius: 20px;
  140. padding: 12px;
  141. margin-right: 10px;
  142. }
  143. .send-button {
  144. border: none;
  145. border-radius: 20px;
  146. padding: 0 20px;
  147. background-color: #007AFF;
  148. color: white;
  149. height: 46px;
  150. }
  151. </style>