Browse Source

一对一聊天

master
ZhaoYang 1 month ago
parent
commit
5398320a9a
  1. 213
      pagesA/pages/expertChat/expertChat.js
  2. 64
      pagesA/pages/expertChat/expertChat.wxml
  3. 2
      pagesA/pages/expertChat/expertChat.wxss

213
pagesA/pages/expertChat/expertChat.js

@ -84,7 +84,10 @@ Page({
// 显示发送中提示 // 显示发送中提示
showSendingTip: false, showSendingTip: false,
// 发送中的消息数量 // 发送中的消息数量
sendingCount: 0
sendingCount: 0,
// 上传状态
isUploading: false
}, },
onLoad: function(options) { onLoad: function(options) {
@ -1064,82 +1067,184 @@ Page({
// 上传图片后发送 // 上传图片后发送
uploadImages: function(tempFilePaths) { uploadImages: function(tempFilePaths) {
tempFilePaths.forEach((tempFilePath, index) => {
const fileName = `image_${Date.now()}_${index}.jpg`;
this.uploadFile(tempFilePath, fileName, 0, 'image');
// 改为依次上传,避免并发问题
this.uploadNextImage(tempFilePaths, 0);
},
// 递归上传下一张图片
uploadNextImage: function(tempFilePaths, index) {
if (index >= tempFilePaths.length) return;
const tempFilePath = tempFilePaths[index];
const fileName = `image_${Date.now()}_${index}.jpg`;
this.uploadImage(tempFilePath, fileName, () => {
// 上传完成后,继续上传下一张
this.uploadNextImage(tempFilePaths, index + 1);
}); });
}, },
// 上传视频后发送
uploadVideo: function(tempFilePath, thumbPath) {
const fileName = `video_${Date.now()}.mp4`;
this.uploadFile(tempFilePath, fileName, 0, 'video', thumbPath);
},
// 上传单张图片 - 修复版
uploadImage: function(tempPath, fileName, callback) {
if (this.data.isUploading) {
wx.showToast({
title: '已有上传任务,请稍后',
icon: 'none'
});
return;
}
// 通用文件上传
uploadFile: function(tempFilePath, fileName, fileSize = 0, contentType = 'file', thumbPath = '') {
const messageId = 'file_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
this.setData({ isUploading: true });
// 显示上传中提示
wx.showLoading({
title: '上传中...',
mask: true
});
const messageId = 'img_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
// 将消息ID添加到发送中集合 // 将消息ID添加到发送中集合
const sendingMessages = new Set(this.data.sendingMessages); const sendingMessages = new Set(this.data.sendingMessages);
sendingMessages.add(messageId); sendingMessages.add(messageId);
const message = {
// 先显示本地图片(临时路径)
const tempMessage = {
id: messageId, id: messageId,
isMe: true, isMe: true,
sender: 'user', sender: 'user',
contentType: contentType,
content: tempFilePath,
thumb: thumbPath,
fileName: fileName,
fileSize: fileSize,
extension: fileName.split('.').pop().toLowerCase(),
senderId: this.getCurrentUserId(),
contentType: 'image',
content: tempPath, // 先用临时路径显示
timestamp: Date.now(), timestamp: Date.now(),
status: 'uploading', status: 'uploading',
progress: 0
progress: 0,
fileName: fileName
}; };
this.addMessageToList(message);
this.addMessageToList(tempMessage);
this.setData({ this.setData({
sendingMessages: sendingMessages, sendingMessages: sendingMessages,
sendingCount: sendingMessages.size, sendingCount: sendingMessages.size,
showSendingTip: sendingMessages.size > 0 showSendingTip: sendingMessages.size > 0
}); });
this.simulateUpload(messageId, contentType, tempFilePath);
},
// 模拟上传
simulateUpload: function(messageId, contentType, tempFilePath) {
let progress = 0;
const uploadInterval = setInterval(() => {
progress += Math.random() * 20 + 10;
if (progress >= 100) {
progress = 100;
clearInterval(uploadInterval);
setTimeout(() => {
this.updateMessageStatus(messageId, 'success');
// 开始上传
wx.uploadFile({
url: baseUrl + '/common/upload',
header: {
'Authorization': 'Bearer ' + wx.getStorageSync('token')
},
filePath: tempPath,
name: 'file',
success: (uploadRes) => {
try {
console.log('上传响应:', uploadRes);
const result = JSON.parse(uploadRes.data);
const { messageList } = this.data;
const index = messageList.findIndex(msg => msg.id === messageId);
if (index !== -1) {
delete messageList[index].progress;
this.setData({ messageList });
if (result.code === 200 || result.fileName) {
// 获取服务器返回的文件路径
const serverPath = result.fileName || result.url;
console.log('服务器返回路径:', serverPath);
// 更新消息内容为服务器路径
this.updateMessageContent(messageId, serverPath);
// 通过WebSocket发送消息
this.sendMessageToServer(serverPath, 'image', messageId);
const fileUrl = tempFilePath;
this.sendMessageToServer(fileUrl, contentType, messageId);
wx.hideLoading();
wx.showToast({
title: '上传成功',
icon: 'success'
});
} else {
throw new Error(result.msg || '上传失败');
} }
}, 200);
} catch (error) {
console.error('上传失败:', error);
wx.hideLoading();
// 更新消息状态为失败
this.updateMessageStatus(messageId, 'failed');
// 从发送中集合移除
const sendingMessages = new Set(this.data.sendingMessages);
sendingMessages.delete(messageId);
this.setData({
sendingMessages: sendingMessages,
sendingCount: sendingMessages.size,
showSendingTip: sendingMessages.size > 0
});
wx.showToast({
title: error.message || '上传失败',
icon: 'none'
});
}
},
fail: (error) => {
console.error('网络请求失败:', error);
wx.hideLoading();
// 更新消息状态为失败
this.updateMessageStatus(messageId, 'failed');
// 从发送中集合移除
const sendingMessages = new Set(this.data.sendingMessages);
sendingMessages.delete(messageId);
this.setData({
sendingMessages: sendingMessages,
sendingCount: sendingMessages.size,
showSendingTip: sendingMessages.size > 0
});
wx.showToast({
title: '网络请求失败',
icon: 'none'
});
},
complete: () => {
this.setData({ isUploading: false });
if (callback) callback();
} }
const { messageList } = this.data;
const index = messageList.findIndex(msg => msg.id === messageId);
if (index !== -1) {
messageList[index].progress = Math.min(Math.floor(progress), 100);
this.setData({ messageList });
});
// 模拟上传进度(因为wx.uploadFile不支持进度回调)
let progress = 0;
const progressInterval = setInterval(() => {
progress += Math.random() * 20 + 5;
if (progress >= 95) {
progress = 95;
clearInterval(progressInterval);
} }
}, 100);
this.updateMessageProgress(messageId, Math.min(Math.floor(progress), 95));
}, 200);
},
// 更新消息内容
updateMessageContent: function(messageId, serverPath) {
const { messageList } = this.data;
const index = messageList.findIndex(msg => msg.id === messageId);
if (index !== -1) {
messageList[index].content = serverPath;
messageList[index].status = 'success';
messageList[index].progress = 100;
this.setData({ messageList });
}
},
// 更新消息进度
updateMessageProgress: function(messageId, progress) {
const { messageList } = this.data;
const index = messageList.findIndex(msg => msg.id === messageId);
if (index !== -1) {
messageList[index].progress = progress;
this.setData({ messageList });
}
}, },
// 添加消息到列表 // 添加消息到列表
@ -1303,11 +1408,13 @@ Page({
wx.chooseImage({ wx.chooseImage({
count: 9, count: 9,
sizeType: ['compressed'], sizeType: ['compressed'],
sourceType: ['album'],
sourceType: ['album', 'camera'],
success: (res) => { success: (res) => {
console.log('选择的图片:', res.tempFilePaths);
this.uploadImages(res.tempFilePaths); this.uploadImages(res.tempFilePaths);
}, },
fail: () => {
fail: (err) => {
console.error('选择图片失败:', err);
wx.showToast({ wx.showToast({
title: '选择图片失败', title: '选择图片失败',
icon: 'none' icon: 'none'
@ -1316,8 +1423,6 @@ Page({
}); });
}, },
// 预览图片 // 预览图片
previewImage: function(e) { previewImage: function(e) {
const url = e.currentTarget.dataset.url; const url = e.currentTarget.dataset.url;

64
pagesA/pages/expertChat/expertChat.wxml

@ -1,3 +1,4 @@
<!-- 咨询页面 -->
<view class="consult-page"> <view class="consult-page">
<!-- 头部专家信息 --> <!-- 头部专家信息 -->
<view class="consult-header"> <view class="consult-header">
@ -30,7 +31,6 @@
<text class="date-text">{{todayDate}}</text> <text class="date-text">{{todayDate}}</text>
</view> </view>
<!-- 消息列表 --> <!-- 消息列表 -->
<block wx:for="{{messageList}}" wx:key="index"> <block wx:for="{{messageList}}" wx:key="index">
<!-- 对方消息 --> <!-- 对方消息 -->
@ -50,36 +50,14 @@
<!-- 图片消息 --> <!-- 图片消息 -->
<view class="media-bubble" wx:elif="{{item.contentType === 'image'}}"> <view class="media-bubble" wx:elif="{{item.contentType === 'image'}}">
<image <image
src="{{item.content}}"
src="{{baseUrl+item.content}}"
class="message-image" class="message-image"
mode="aspectFill" mode="aspectFill"
bindtap="previewImage" bindtap="previewImage"
data-url="{{item.content}}" data-url="{{item.content}}"
></image> ></image>
</view> </view>
<!-- 视频消息 -->
<view class="media-bubble" wx:elif="{{item.contentType === 'video'}}">
<video
src="{{item.content}}"
class="message-video"
controls
show-center-play-btn
poster="{{item.thumb}}"
object-fit="contain"
></video>
</view>
<!-- 文件消息 -->
<view class="message-bubble bubble-left message-file" wx:elif="{{item.contentType === 'file'}}">
<view class="file-icon-box">
<image src="/images/icons/file_icon.png" class="file-icon"></image>
</view>
<view class="file-info">
<text class="file-name">{{item.fileName}}</text>
<text class="file-size">{{formatFileSize(item.fileSize)}}</text>
</view>
</view>
<!-- 消息状态 - 仅对方消息显示已读状态 --> <!-- 消息状态 - 仅对方消息显示已读状态 -->
<view class="message-status" wx:if="{{item.status === 'read'}}"> <view class="message-status" wx:if="{{item.status === 'read'}}">
@ -101,7 +79,7 @@
<!-- 图片消息 --> <!-- 图片消息 -->
<view class="media-bubble" wx:elif="{{item.contentType === 'image'}}"> <view class="media-bubble" wx:elif="{{item.contentType === 'image'}}">
<image <image
src="{{item.content}}"
src="{{baseUrl+item.content}}"
class="message-image" class="message-image"
mode="aspectFill" mode="aspectFill"
bindtap="previewImage" bindtap="previewImage"
@ -114,39 +92,6 @@
</view> </view>
</view> </view>
</view> </view>
<!-- 视频消息 -->
<view class="media-bubble" wx:elif="{{item.contentType === 'video'}}">
<video
src="{{item.content}}"
class="message-video"
controls
show-center-play-btn
poster="{{item.thumb}}"
object-fit="contain"
></video>
<view class="upload-progress" wx:if="{{item.status === 'uploading'}}">
<view class="progress-circle">
<text class="progress-text">{{item.progress}}%</text>
</view>
</view>
</view>
<!-- 文件消息 -->
<view class="message-bubble bubble-right message-file" wx:elif="{{item.contentType === 'file'}}">
<view class="file-icon-box">
<image src="/images/icons/file_icon.png" class="file-icon"></image>
</view>
<view class="file-info">
<text class="file-name">{{item.fileName}}</text>
<text class="file-size">{{formatFileSize(item.fileSize)}}</text>
</view>
<view class="upload-progress" wx:if="{{item.status === 'uploading'}}">
<view class="progress-circle">
<text class="progress-text">{{item.progress}}%</text>
</view>
</view>
</view>
</view> </view>
<view class="message-avatar"> <view class="message-avatar">
@ -232,7 +177,6 @@
</view> </view>
<text class="option-text">照片</text> <text class="option-text">照片</text>
</view> </view>
</view> </view>
<view class="sheet-bottom"> <view class="sheet-bottom">

2
pagesA/pages/expertChat/expertChat.wxss

@ -105,8 +105,6 @@
background-color: #d8d8d8; background-color: #d8d8d8;
} }
/* ========== 消息项 ========== */ /* ========== 消息项 ========== */
.message-item { .message-item {
display: flex; display: flex;

Loading…
Cancel
Save