| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- <template>
- <view class="container">
- <scroll-view class="chat-messages" scroll-y="true" :scroll-with-animation="true"
- :scroll-into-view="scrollToView"
- :style="{ width: $scrollViewWidth + 'px', padding: $viewPadding + 'px',maxHeight: $viewMaxHeight + 'px'}">
- <!-- 循环渲染消息 -->
- <view v-for="(message, index) in messages" :key="index" :id="'msg' + index" style="clear: both;">
- <view :class="['message', message.sender === 'user' ? 'user-message' : 'ai-message']">
- <text>{{ message.content }}</text>
- </view>
- </view>
- </scroll-view>
- <view class="chat-input">
- <textarea @linechange="chatMsgMaxHeightChange" auto-height v-model="inputMessage" placeholder="输入消息..."
- class="input-field" />
- <button class="send-button" @click="sendMessage">发送</button>
- </view>
- </view>
- </template>
- <script setup>
- import {
- ref,
- nextTick,
- onMounted
- } from 'vue';
- import $modal from '@/plugins/modal.js'
- const inputMessage = ref('');
- const messages = ref([{
- sender: 'ai',
- content: '您好,我是ai助手'
- },
- ]);
- const scrollToView = ref('');// 滚动到特定消息的标识
- // 发送消息函数
- function sendMessage() {
- if (inputMessage.value.trim() === '') {
- return;
- }
- messages.value.push({
- sender: 'user',
- content: inputMessage.value
- });
- inputMessage.value = ''; // 清空输入框
- scrollToBottom(); // 滚动到底部
- getAIResponse(); // 获取AI的回复
- };
- // 获取AI回复的函数
- function getAIResponse() {
- // 这里调用AI客服接口,获取回复
- uni.request({
- url: 'http://api.qingyunke.com/api.php?key=free&appid=0&msg=' + messages.value[messages.value.length -
- 1].content,
- success: (res) => {
- messages.value.push({
- sender: 'ai',
- content: res.data.content
- });
- },
- fail: (err) => {
- console.log('err', err);
- $modal.alert('err'+ JSON.stringify(err))
- // $modal.msg(err)
- messages.value.push({
- sender: 'ai',
- content: '小客服不在线'
- });
- },
- complete: () => {
- scrollToBottom();
- }
- })
- };
- // 滚动到底部的函数
- function scrollToBottom() {
- nextTick(() => {
- scrollToView.value = 'msg' + (messages.value.length - 1); // 更新滚动到的消息
- });
- };
- const $scrollViewWidth = ref(0); // 滚动视图宽度
- const $viewMaxHeight = ref(0); // 滚动视图最大高度
- const $viewPadding = ref(10); // 滚动视图内边距
- const $windowHeight = ref(0); // 窗口高度
- // 使用 onMounted 钩子在组件挂载后获取窗口高度
- onMounted(() => {
- const res = uni.getWindowInfo();
- // 计算滚动视图宽度
- $scrollViewWidth.value = res.windowWidth - $viewPadding.value * 2;
- $windowHeight.value = res.windowHeight;
- $viewMaxHeight.value = res.windowHeight - 100;
- });
- // 输入框行数变化时更新最大高度
- function chatMsgMaxHeightChange(e) {
- console.log($windowHeight,e.detail.height);
- $viewMaxHeight.value = $windowHeight.value - e.detail.height - 70;
- }
- </script>
- <style scoped>
- .container {
- display: flex;
- flex-direction: column;
- height: 100vh;
- position: relative;
- }
- .chat-messages {
- flex: 1;
- background-color: #f3f3f3;
- overflow-y: auto;
-
- }
- .message {
- max-width: 70%;
- margin: 5px 0;
- padding: 8px;
- border-radius: 10px;
- display: inline-block;
- word-wrap: break-word;
- }
- .user-message {
- background-color: #DCF8C6;
- align-self: flex-end;
- float: right;
- }
- .ai-message {
- background-color: #ECECEC;
- align-self: flex-start;
- }
- .chat-input {
- display: flex;
- padding: 10px;
- background-color: #FFFFFF;
- border-top: 1px solid #E0E0E0;
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- }
- .input-field {
- flex: 1;
- border: 1px solid #E0E0E0;
- border-radius: 20px;
- padding: 12px;
- margin-right: 10px;
- }
- .send-button {
- border: none;
- border-radius: 20px;
- padding: 0 20px;
- background-color: #007AFF;
- color: white;
- height: 46px;
- }
- </style>
|