YingXingAI/pages/chat/chat-detail.vue

380 lines
7.9 KiB
Vue

<template>
<view class="chat-detail-page">
<!-- 顶部导航 -->
<view class="chat-header">
<view class="header-left" @click="goBack">
<u-icon name="arrow-left" color="#333" size="20"></u-icon>
</view>
<view class="header-title">{{ userName }}</view>
<view class="header-right" @click="showUserInfo">
<u-icon name="more-dot-fill" color="#333" size="20"></u-icon>
</view>
</view>
<!-- 消息列表 -->
<scroll-view
class="message-list"
scroll-y
:scroll-into-view="scrollIntoView"
scroll-with-animation
>
<view
v-for="(msg, index) in messageList"
:key="msg.id"
:id="'msg-' + msg.id"
class="message-item"
>
<!-- 我发送的消息 -->
<view v-if="msg.isSelf" class="message-self">
<view class="message-content-wrapper">
<view class="message-content">{{ msg.content }}</view>
</view>
<image class="message-avatar" :src="myAvatar"></image>
</view>
<!-- 对方发送的消息 -->
<view v-else class="message-other">
<image class="message-avatar" :src="otherAvatar"></image>
<view class="message-content-wrapper">
<view class="message-content">{{ msg.content }}</view>
</view>
</view>
</view>
<!-- 空状态 -->
<view v-if="messageList.length === 0" class="empty-message">
<text>暂无消息</text>
</view>
</scroll-view>
<!-- 输入栏 -->
<view class="input-bar">
<view class="input-wrapper">
<input
class="input-field"
v-model="inputValue"
placeholder="请输入消息..."
confirm-type="send"
@confirm="sendMessage"
/>
</view>
<view class="send-button" @click="sendMessage">
<text>发送</text>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'ChatDetail',
data() {
return {
// 用户信息
userId: '',
userName: '',
// 头像
myAvatar: '/static/avatar/default-avatar.png',
otherAvatar: '/static/avatar/default-avatar.png',
// 消息列表
messageList: [
{
id: 1,
content: '你好,请问学校的招生政策是怎样的?',
isSelf: false,
timestamp: '2024-01-15 09:45'
},
{
id: 2,
content: '你好!我们学校今年的招生政策主要包括...',
isSelf: true,
timestamp: '2024-01-15 09:46'
},
{
id: 3,
content: '好的,谢谢老师!那请问学费是多少呢?',
isSelf: false,
timestamp: '2024-01-15 09:47'
},
],
// 输入框
inputValue: '',
// 滚动位置
scrollIntoView: '',
}
},
onLoad(options) {
// 获取传入的用户信息
this.userId = options.userId || ''
this.userName = options.name || '用户'
console.log('[聊天详情] 用户ID:', this.userId)
console.log('[聊天详情] 用户名:', this.userName)
// 加载历史消息
this.loadHistoryMessages()
// 滚动到底部
this.$nextTick(() => {
this.scrollToBottom()
})
},
methods: {
// 返回
goBack() {
uni.navigateBack()
},
// 显示用户信息
showUserInfo() {
uni.showToast({
title: '用户信息',
icon: 'none'
})
},
// 发送消息
sendMessage() {
if (!this.inputValue.trim()) {
uni.showToast({
title: '请输入消息内容',
icon: 'none'
})
return
}
// 构建消息对象
const message = {
id: Date.now(),
content: this.inputValue,
isSelf: true,
timestamp: this.formatTime(new Date())
}
// 添加到消息列表
this.messageList.push(message)
// 清空输入框
this.inputValue = ''
// 滚动到底部
this.$nextTick(() => {
this.scrollToBottom()
})
// TODO: 通过 WebSocket 发送消息
// wsManager.send({
// type: 'message',
// toUserId: this.userId,
// content: message.content
// })
console.log('[聊天详情] 发送消息:', message)
// 模拟对方回复
setTimeout(() => {
this.receiveMessage('收到,我马上处理')
}, 1000)
},
// 接收消息
receiveMessage(content) {
const message = {
id: Date.now(),
content: content,
isSelf: false,
timestamp: this.formatTime(new Date())
}
this.messageList.push(message)
this.$nextTick(() => {
this.scrollToBottom()
})
},
// 加载历史消息
loadHistoryMessages() {
// TODO: 从服务器加载历史消息
// this.$u.api.getChatHistory({
// userId: this.userId
// }).then(res => {
// this.messageList = res.data
// })
console.log('[聊天详情] 加载历史消息')
},
// 滚动到底部
scrollToBottom() {
if (this.messageList.length > 0) {
const lastMsg = this.messageList[this.messageList.length - 1]
this.scrollIntoView = 'msg-' + lastMsg.id
}
},
// 格式化时间
formatTime(date) {
const hours = date.getHours().toString().padStart(2, '0')
const minutes = date.getMinutes().toString().padStart(2, '0')
return `${hours}:${minutes}`
}
}
}
</script>
<style scoped>
.chat-detail-page {
height: 100vh;
display: flex;
flex-direction: column;
background-color: #f5f6fa;
}
/* ===== 顶部导航 ===== */
.chat-header {
display: flex;
align-items: center;
justify-content: space-between;
height: 44px;
padding: 0 15px;
background: #fff;
border-bottom: 1rpx solid #e5e5e5;
}
.header-left,
.header-right {
width: 44px;
height: 44px;
display: flex;
align-items: center;
justify-content: center;
}
.header-title {
flex: 1;
text-align: center;
font-size: 17px;
font-weight: 500;
color: #333;
}
/* ===== 消息列表 ===== */
.message-list {
flex: 1;
padding: 15px;
overflow-y: auto;
}
.message-item {
margin-bottom: 20px;
}
/* 我发送的消息 */
.message-self {
display: flex;
justify-content: flex-end;
align-items: flex-start;
}
.message-self .message-content-wrapper {
max-width: 70%;
margin-right: 10px;
}
.message-self .message-content {
background: #4a6cf7;
color: #fff;
padding: 12px 15px;
border-radius: 8px;
font-size: 15px;
line-height: 1.5;
word-wrap: break-word;
}
/* 对方发送的消息 */
.message-other {
display: flex;
justify-content: flex-start;
align-items: flex-start;
}
.message-other .message-content-wrapper {
max-width: 70%;
margin-left: 10px;
}
.message-other .message-content {
background: #fff;
color: #333;
padding: 12px 15px;
border-radius: 8px;
font-size: 15px;
line-height: 1.5;
word-wrap: break-word;
}
/* 头像 */
.message-avatar {
width: 40px;
height: 40px;
border-radius: 8px;
background-color: #e8e8e8;
flex-shrink: 0;
}
/* 空状态 */
.empty-message {
text-align: center;
padding: 100px 20px;
color: #999;
font-size: 14px;
}
/* ===== 输入栏 ===== */
.input-bar {
display: flex;
align-items: center;
padding: 10px 15px;
background: #fff;
border-top: 1rpx solid #e5e5e5;
padding-bottom: calc(10px + env(safe-area-inset-bottom));
}
.input-wrapper {
flex: 1;
margin-right: 10px;
}
.input-field {
height: 36px;
padding: 0 15px;
background: #f5f5f5;
border-radius: 18px;
font-size: 15px;
}
.send-button {
width: 60px;
height: 36px;
background: #4a6cf7;
border-radius: 18px;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 15px;
}
.send-button:active {
opacity: 0.8;
}
</style>