Files

236 lines
6.5 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="chat-wrap">
<!-- 顶部导航 -->
<uititle title="AI 智能客服"></uititle>
<!-- 消息列表 -->
<scroll-view scroll-y class="msg-list" :scroll-into-view="scrollId" scroll-with-animation
:style="{ height: msgListHeight + 'px' }">
<!-- 欢迎消息 -->
<view v-if="messages.length === 0" class="msg-item left" id="msg-welcome">
<view class="avatar">🤖</view>
<view class="bubble">
您好!我是金久信AI智能客服,可以帮您解答平台注册、相关认证、平台操作、企业推广等问题。请问有什么可以帮您?
<view class="quick-btns">
<view class="quick-btn" @click="quickSend('使用说明书')">使用说明书</view>
<view class="quick-btn" @click="quickSend('开通金久信公证')">开通金久信公证</view>
<view class="quick-btn" @click="quickSend('如何下询价单')">如何下询价单</view>
<view class="quick-btn" @click="quickSend('如何报价')">如何报价</view>
</view>
</view>
</view>
<!-- 对话消息 -->
<view v-for="(msg, i) in messages" :key="i" :id="'msg' + i"
:class="['msg-item', msg.role === 'user' ? 'right' : 'left']">
<view v-if="msg.role !== 'user'" class="avatar">🤖</view>
<view class="bubble" v-html="formatContent(msg.content)"></view>
</view>
<!-- 加载中 -->
<view v-if="loading" class="msg-item left" id="msg-loading">
<view class="avatar">🤖</view>
<view class="bubble loading">思考中...</view>
</view>
</scroll-view>
<!-- 底部输入栏 -->
<view class="input-bar">
<input v-model="inputText" @confirm="send" placeholder="输入您的问题..."
:adjust-position="true" confirm-type="send" />
<view class="send-btn" @click="send">发送</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
inputText: '',
messages: [],
loading: false,
conversationId: null,
scrollId: '',
msgListHeight: 500
};
},
onReady() {
// 计算消息列表高度(屏幕高度 - 导航栏 - 输入栏)
const sys = uni.getSystemInfoSync();
this.msgListHeight = sys.windowHeight - 88 - 56;
},
methods: {
formatContent(text) {
if (!text) return '';
let html = text.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
html = html.replace(/^[\-\•]\s+(.+)$/gm, '<div style="padding-left:12px;">• $1</div>');
html = html.replace(/^(\d+)\.\s+(.+)$/gm, '<div style="padding-left:12px;">$1. $2</div>');
html = html.replace(/\n/g, '<br>');
return html;
},
quickSend(text) {
this.inputText = text;
this.send();
},
async send() {
const msg = this.inputText.trim();
if (!msg || this.loading) return;
this.inputText = '';
this.messages.push({ role: 'user', content: msg });
this.loading = true;
this.scrollToBottom();
try {
const res = await this.vk.callFunction({
url: 'client/ai/pub/chat',
data: { message: msg, bot_id: '7680345813062680618' }
});
if (res.data.conversation_id) this.conversationId = res.data.conversation_id;
this.messages.push({ role: 'assistant', content: res.data.answer });
} catch (e) {
this.messages.push({ role: 'assistant', content: '网络异常,请稍后重试' });
}
this.loading = false;
this.scrollToBottom();
},
scrollToBottom() {
this.$nextTick(() => {
setTimeout(() => {
if (this.messages.length === 0) {
this.scrollId = 'msg-welcome';
} else if (this.loading) {
this.scrollId = 'msg-loading';
} else {
this.scrollId = 'msg' + (this.messages.length - 1);
}
}, 50);
});
}
}
};
</script>
<style lang="scss" scoped>
.chat-wrap {
height: 93vh;
display: flex;
flex-direction: column;
background: #f5f5f5;
}
uni-scroll-view{
width: auto !important;
}
.msg-list {
flex: 1;
padding-left: 24rpx;
padding-right: 24rpx;
padding-top :24rpx;
}
.msg-item {
display: flex;
margin-bottom: 24rpx;
align-items: flex-start;
}
.msg-item.right {
flex-direction: row-reverse;
}
.avatar {
width: 64rpx;
height: 64rpx;
border-radius: 50%;
background: linear-gradient(135deg, #a92924, #d4574e);
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
flex-shrink: 0;
}
.bubble {
max-width: 70%;
padding: 20rpx 24rpx;
border-radius: 24rpx;
font-size: 28rpx;
line-height: 1.6;
word-break: break-word;
}
.msg-item.left .bubble {
background: #fff;
color: #333;
margin-left: 16rpx;
border-top-left-radius: 8rpx;
}
.msg-item.right .bubble {
background: #a92924;
color: #fff;
margin-right: 16rpx;
border-top-right-radius: 8rpx;
}
.bubble.loading {
color: #999;
}
.quick-btns {
display: flex;
flex-wrap: wrap;
gap: 12rpx;
margin-top: 16rpx;
}
.quick-btn {
padding: 8rpx 24rpx;
border-radius: 28rpx;
font-size: 24rpx;
border: 1px solid #a92924;
color: #a92924;
background: #fff;
}
.quick-btn:active {
background: #a92924;
color: #fff;
}
.input-bar {
display: flex;
align-items: center;
padding: 16rpx 24rpx;
background: #fff;
border-top: 1px solid #eee;
gap: 16rpx;
}
.input-bar input {
flex: 1;
height: 72rpx;
background: #f5f5f5;
border-radius: 36rpx;
padding: 0 24rpx;
font-size: 28rpx;
}
.send-btn {
width: 120rpx;
height: 72rpx;
line-height: 72rpx;
text-align: center;
background: #a92924;
color: #fff;
border-radius: 36rpx;
font-size: 28rpx;
flex-shrink: 0;
}
.send-btn:active {
background: #982520;
}
</style>