380 lines
7.9 KiB
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>
|
|
|