Ai_GirlFriend/xuniYou/pages/chat/simple.vue

290 lines
5.6 KiB
Vue
Raw 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-page">
<!-- 顶部 Tab -->
<main-tabs :current="1"></main-tabs>
<!-- 聊天内容区域 -->
<scroll-view
class="message-container"
scroll-y="true"
:scroll-top="scrollTop"
scroll-with-animation="true">
<view class="message-list">
<view
v-for="(msg, index) in messages"
:key="index"
class="message-item"
:class="msg.role === 'user' ? 'message-right' : 'message-left'">
<image
class="avatar"
:src="msg.role === 'user' ? userAvatar : loverAvatar"
mode="aspectFill">
</image>
<view class="message-bubble">
<text class="message-text">{{ msg.content }}</text>
</view>
</view>
</view>
</scroll-view>
<!-- 底部输入框 -->
<view class="input-bar">
<input
class="message-input"
v-model="inputText"
placeholder="输入消息..."
confirm-type="send"
@confirm="sendMessage"
/>
<view class="send-btn" @click="sendMessage">
<text>发送</text>
</view>
</view>
</view>
</template>
<script>
import MainTabs from '@/components/main-tabs.vue';
import { SessionInit, SessionSend } from '@/utils/api.js';
export default {
components: {
MainTabs
},
data() {
return {
messages: [],
inputText: '',
scrollTop: 0,
sessionId: null,
userAvatar: '',
loverAvatar: '',
sending: false
}
},
onLoad() {
// 获取用户头像
const userInfo = uni.getStorageSync('userinfo');
this.userAvatar = userInfo?.avatar || '/static/images/avatar.png';
// 获取恋人头像
const loverInfo = uni.getStorageSync('loverBasicList');
this.loverAvatar = loverInfo?.image_url || '/static/images/avatar.png';
// 初始化会话
this.initSession();
},
methods: {
// 初始化会话
initSession() {
uni.showLoading({ title: '加载中...' });
SessionInit().then(res => {
uni.hideLoading();
if (res.code === 1) {
this.sessionId = res.data.session_id;
// 加载历史消息只显示最近10条
const allMessages = res.data.messages || [];
this.messages = allMessages.slice(-10).map(msg => ({
role: msg.role === 'lover' ? 'ai' : 'user',
content: msg.content
}));
// 滚动到底部
this.$nextTick(() => {
this.scrollToBottom();
});
} else {
uni.showToast({ title: res.msg || '加载失败', icon: 'none' });
}
}).catch(err => {
uni.hideLoading();
console.error('初始化会话失败:', err);
uni.showToast({ title: '网络错误', icon: 'none' });
});
},
// 发送消息
sendMessage() {
if (!this.inputText.trim()) {
return;
}
if (this.sending) {
return;
}
if (!this.sessionId) {
uni.showToast({ title: '会话未初始化', icon: 'none' });
return;
}
const userMessage = this.inputText.trim();
this.inputText = '';
// 添加用户消息到列表
this.messages.push({
role: 'user',
content: userMessage
});
// 滚动到底部
this.$nextTick(() => {
this.scrollToBottom();
});
// 添加"思考中"提示
const thinkingIndex = this.messages.length;
this.messages.push({
role: 'ai',
content: '思考中...'
});
this.sending = true;
// 发送到后端
SessionSend({
session_id: this.sessionId,
message: userMessage
}).then(res => {
this.sending = false;
if (res.code === 1) {
// 移除"思考中"
this.messages.splice(thinkingIndex, 1);
// 添加 AI 回复
this.messages.push({
role: 'ai',
content: res.data.reply || '...'
});
// 滚动到底部
this.$nextTick(() => {
this.scrollToBottom();
});
} else {
// 移除"思考中"
this.messages.splice(thinkingIndex, 1);
uni.showToast({ title: res.msg || '发送失败', icon: 'none' });
}
}).catch(err => {
this.sending = false;
// 移除"思考中"
this.messages.splice(thinkingIndex, 1);
console.error('发送消息失败:', err);
uni.showToast({ title: '发送失败', icon: 'none' });
});
},
// 滚动到底部
scrollToBottom() {
this.scrollTop = 999999;
}
}
}
</script>
<style scoped>
.chat-page {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
background: #f5f5f5;
}
.message-container {
flex: 1;
margin-top: calc(80rpx + var(--status-bar-height));
margin-bottom: 120rpx;
padding: 20rpx;
}
.message-list {
width: 100%;
}
.message-item {
display: flex;
margin-bottom: 30rpx;
align-items: flex-start;
}
.message-left {
flex-direction: row;
}
.message-right {
flex-direction: row-reverse;
}
.avatar {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
flex-shrink: 0;
}
.message-bubble {
max-width: 500rpx;
padding: 20rpx 25rpx;
border-radius: 20rpx;
margin: 0 20rpx;
}
.message-left .message-bubble {
background: #fff;
border-top-left-radius: 5rpx;
}
.message-right .message-bubble {
background: linear-gradient(135deg, #9F47FF 0%, #0053FA 100%);
}
.message-text {
font-size: 28rpx;
line-height: 1.6;
word-wrap: break-word;
}
.message-left .message-text {
color: #333;
}
.message-right .message-text {
color: #fff;
}
.input-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
display: flex;
align-items: center;
padding: 20rpx;
background: #fff;
border-top: 1rpx solid #e5e5e5;
z-index: 100;
}
.message-input {
flex: 1;
height: 80rpx;
padding: 0 25rpx;
background: #f5f5f5;
border-radius: 40rpx;
font-size: 28rpx;
}
.send-btn {
margin-left: 20rpx;
padding: 20rpx 40rpx;
background: linear-gradient(135deg, #9F47FF 0%, #0053FA 100%);
color: #fff;
border-radius: 40rpx;
font-size: 28rpx;
}
</style>