Files
tk-mini-program/pages/index/chat/chat.vue

1263 lines
35 KiB
Vue
Raw Permalink Normal View History

2025-07-18 13:06:06 +08:00
<template>
<view class="chat">
<view class="bg" @click="onMore(false)">
<image
class="bgImg"
src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/HomeBackground.png"
mode="scaleToFill"
/>
</view>
<view class="Return" @click="onBack">
<image
class="ReturnImg"
src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/Return.png"
mode="scaleToFill"
/>
</view>
<view class="title" @click="onMore(false)">{{ nickname }}</view>
<!-- 聊天内容 -->
<view
class="content"
@click="onMore(false)"
:style="{
bottom:
2025-07-25 16:39:52 +08:00
MoreStatus || KeyboardHeight != 0
2025-07-18 13:06:06 +08:00
? MoreStatus
? 650 + Elementheight + 'rpx'
: KeyboardHeight != 0
? KeyboardHeight + Elementheight + 'rpx'
2025-07-25 16:39:52 +08:00
:'10vh'
: '10vh',
2025-07-18 13:06:06 +08:00
}"
>
<scroll-view
show-scrollbar="false"
scroll-y="true"
class="scroll"
2025-07-21 22:10:59 +08:00
upper-threshold="100"
@scrolltoupper="onScrollToUpper"
2025-07-18 13:06:06 +08:00
:scroll-into-view="ElementPositioning"
@scroll="onScroll"
>
<view
class="chat-card"
v-for="(item, index) in chatList"
:key="item.id"
:id="item.id"
>
2025-07-21 22:10:59 +08:00
<view class="chat-time" v-if="item.timestampStatus">{{
2025-07-18 13:06:06 +08:00
TimeFormatting(item.timestamp)
}}</view>
<view class="chat-avatar">
2025-07-21 22:10:59 +08:00
<!-- 对方消息 -->
<view class="oppositeChatNews" v-if="item.senderId == userId">
<image class="chat-avatarImg" :src="avatar" mode="scaleToFill" />
<view class="oppositesharpCorner">
2025-07-25 16:39:52 +08:00
<view
class="oppositeSharpCornercion"
v-if="item.type == 'text' || item.type == 'audio'"
></view>
2025-07-21 22:10:59 +08:00
</view>
2025-07-25 16:39:52 +08:00
<view
class="oppositeChatNewsContent"
:style="{
backgroundColor:
item.type == 'text' || item.type == 'audio' ? '#7bbd0093' : '#ffffff',
}"
>
2025-07-21 22:10:59 +08:00
<!-- 消息类型 -->
2025-07-25 16:39:52 +08:00
<!-- 文字消息 -->
2025-07-21 22:10:59 +08:00
<textmessage
v-if="item.type == 'text'"
:messagetext="item.payload.text"
></textmessage>
2025-07-25 16:39:52 +08:00
<!-- 自定义PK消息 -->
2025-07-21 22:10:59 +08:00
<customPKMessage
v-if="item.type == 'pk'"
:message="item.payload"
></customPKMessage>
2025-07-25 16:39:52 +08:00
<!-- 图片消息 -->
<imageMessage
v-if="item.type == 'image'"
:message="item.payload"
></imageMessage>
<!-- 视频消息 -->
<videoMessage
v-if="item.type == 'video'"
:message="item.payload"
></videoMessage>
<!-- 语音消息 -->
<voiceMessage
v-if="item.type == 'audio'"
:message="item.payload"
:senderId="item.senderId"
:userId="userinfo.id"
>
</voiceMessage>
2025-07-21 22:10:59 +08:00
</view>
</view>
<!-- 自己消息 -->
<view class="myChatNews" v-if="item.senderId == userinfo.id">
<image
class="chat-avatarImg"
:src="userinfo.headerIcon"
mode="scaleToFill"
/>
<view class="mysharpCorner">
2025-07-25 16:39:52 +08:00
<view
class="mySharpCornercion"
v-if="item.type == 'text' || item.type == 'audio'"
></view>
2025-07-21 22:10:59 +08:00
</view>
2025-07-25 16:39:52 +08:00
<view
class="myChatNewsContent"
:style="{
backgroundColor:
item.type == 'text' || item.type == 'audio' ? '#7bbd0093' : '#ffffff',
}"
>
2025-07-21 22:10:59 +08:00
<!-- 消息类型 -->
2025-07-25 16:39:52 +08:00
<!-- 文字消息 -->
2025-07-21 22:10:59 +08:00
<textmessage
v-if="item.type == 'text'"
:messagetext="item.payload.text"
></textmessage>
2025-07-25 16:39:52 +08:00
<!-- 自定义PK消息 -->
2025-07-21 22:10:59 +08:00
<customPKMessage
v-if="item.type == 'pk'"
:message="item.payload"
></customPKMessage>
2025-07-25 16:39:52 +08:00
<!-- 图片消息 -->
<imageMessage
v-if="item.type == 'image'"
:message="item.payload"
></imageMessage>
<!-- 视频消息 -->
<videoMessage
v-if="item.type == 'video'"
:message="item.payload"
></videoMessage>
<!-- 语音消息 -->
<voiceMessage
v-if="item.type == 'audio'"
:message="item.payload"
:senderId="item.senderId"
:userId="userinfo.id"
:playbackStatus="playbackStatus"
@notplayVoice="notplayVoice"
>
</voiceMessage>
2025-07-21 22:10:59 +08:00
</view>
</view>
2025-07-18 13:06:06 +08:00
</view>
</view>
</scroll-view>
</view>
<!-- 输入框组 -->
<view
class="inputComponent"
id:inputComponent
:style="{
bottom:
2025-07-21 22:10:59 +08:00
MoreStatus || KeyboardHeight > 300
2025-07-18 13:06:06 +08:00
? MoreStatus
? '650rpx'
2025-07-21 22:10:59 +08:00
: KeyboardHeight > 300
2025-07-18 13:06:06 +08:00
? KeyboardHeight + 'rpx'
: '0'
: '0',
}"
>
2025-07-25 16:39:52 +08:00
<view class="Voice">
<view class="MicrophoneImg" v-if="!voiceStatus" @click="onVoice(!voiceStatus)">
<image
class="Microphonepng"
src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/Microphone.png"
mode="scaleToFill"
/>
</view>
<view class="KeyboardImg" v-if="voiceStatus" @click="onVoice(!voiceStatus)">
<image
class="Keyboardpng"
src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/Keyboard.png"
mode="scaleToFill"
/>
</view>
</view>
<view class="textareacomponent" v-if="voiceStatus">
<view
class="VoiceInput"
@touchstart="voiceTouchstart"
@touchend="voiceTouchend"
@touchmove="voiceTouchmove"
@touchcancel="voiceTouchcancel"
>按住&nbsp;说话</view
>
</view>
<view class="textareacomponent" v-if="!voiceStatus">
2025-07-18 13:06:06 +08:00
<textarea
v-model="content"
@input="SendInput"
auto-height
class="input"
:maxlength="500"
cursor-spacing="20"
@focus="onFocus"
2025-07-25 16:39:52 +08:00
:focus="inputfocus"
2025-07-18 13:06:06 +08:00
@blur="onBlur"
:adjust-position="false"
></textarea>
</view>
<view class="sendComponent">
<image
v-if="!ButtonStatus"
class="MoreImg"
src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/chat_add.png"
mode="scaleToFill"
@click="onMore(!MoreStatus)"
/>
<button v-if="ButtonStatus" class="send" @click="onSend">发送</button>
</view>
</view>
<!-- 更多消息类型弹窗 -->
<view
class="MoreComponent"
:style="{
bottom:
2025-07-21 22:10:59 +08:00
MoreStatus || KeyboardHeight > 300
2025-07-18 13:06:06 +08:00
? MoreStatus
? '0'
2025-07-21 22:10:59 +08:00
: KeyboardHeight > 300
2025-07-18 13:06:06 +08:00
? '0'
: KeyboardHeight + 'rpx'
: '-650rpx',
}"
>
<view class="Morecontent">
<view class="MoreList" v-for="(item, index) in popUpList" :key="index">
<view class="MoreItem" @click="onMoreItem(item.type)">
<image class="Moreicon" :src="item.icon" mode="scaleToFill" />
<text class="MoreName">{{ item.name }}</text>
</view>
</view>
</view>
</view>
<!-- 相关消息事件弹窗 -->
<view
class="popUpInvitation"
@click="onMoreItem(null)"
:style="{ top: MoreItemStatus == null ? '100vh' : '0' }"
>
<view
class="popUpInvitationContent"
@click.stop
:style="{ bottom: MoreItemStatus == null ? '-1000rpx' : '0' }"
>
2025-07-21 22:10:59 +08:00
<!-- 自定义消息组件 -->
2025-07-18 13:06:06 +08:00
<InvitationComponents
v-if="MoreItemStatus == 'Invitation'"
2025-07-21 22:10:59 +08:00
:oppositeId="userId"
:myId="userinfo.id"
:avatar="avatar"
:nickname="nickname"
@refreshMessage="refreshMessage"
2025-07-18 13:06:06 +08:00
></InvitationComponents>
</view>
</view>
2025-07-25 16:39:52 +08:00
<!-- 语音组件 -->
<view class="popUpVoice" :style="{ top: voicepopUpstart == false ? '100vh' : '0' }">
<view
class="popUpvoiceContent"
:style="{ bottom: voicepopUpstart == false ? '-1000rpx' : '0' }"
>
<view class="voiceCenter">
<view class="gifModule">
<video
class="video-player"
src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/Recording.mp4"
:autoplay="true"
:loop="true"
:controls="false"
></video>
</view>
<view
class="CancelModule"
:style="{ backgroundColor: voiceCancelOrSend ? '#ebebeb' : '#000000a9' }"
>
取消
</view>
<view
class="btnModule"
:style="{ backgroundColor: !voiceCancelOrSend ? '#ebebeb' : '#000000a9' }"
>
{{ voiceCancelOrSend ? "取消" : "松手发送" }}
</view>
</view>
</view>
</view>
2025-07-18 13:06:06 +08:00
</view>
</template>
<script>
import textmessage from "./messageComponent/textmessage";
2025-07-21 22:10:59 +08:00
import customPKMessage from "./messageComponent/customPKMessage";
2025-07-25 16:39:52 +08:00
import imageMessage from "./messageComponent/imageMessage";
import videoMessage from "./messageComponent/videoMessage";
import voiceMessage from "./messageComponent/voiceMessage";
2025-07-18 13:06:06 +08:00
import InvitationComponents from "./moreMessageComponents/InvitationComponents";
import { generateId } from "../../../components/ChatId.js";
import TimeFormatting from "../../../components/TimeFormatting.js";
2025-07-21 22:10:59 +08:00
import request from "../../../components/request.js";
2025-07-18 13:06:06 +08:00
import {
getConversationMessages,
sendMessage,
messageRead,
2025-07-21 22:10:59 +08:00
sendCustomMessage,
2025-07-25 16:39:52 +08:00
sendGroupMessage,
2025-07-18 13:06:06 +08:00
} from "../../../components/goEasyTool/tool.js";
import GoEasy from "goeasy";
export default {
data() {
return {
userId: "", // 对方用户id
nickname: "", // 对方用户昵称
avatar: "", // 对方用户头像
chatList: [], // 聊天记录
userinfo: {}, // 自己用户信息
ButtonStatus: false, // 发送按钮状态
MoreStatus: false, // 更多消息类型弹窗状态
KeyboardHeight: 0, // 键盘高度
content: "", // 输入框内容
MoreItemStatus: null, // 更多消息类型弹窗点击属性
ioshide: 0, // 隐藏ios键盘
ElementPositioning: null, // 元素定位
scrollviewheight: 0, // 滚动视图高度
Elementheight: 0, // 元素高度
Scrolling: false, // 滚动状态
scrollTop: 0, // 滚动高度
judgescrollTop: false, // 判断滚动高度
onPage: false, // 是否在页面
timer: null, // 定时器
lastTimestamp: null, // 上一次刷新时间戳
2025-07-21 22:10:59 +08:00
LastTime: null, // 最后聊天记录的时间戳
MoreMessageList: [],
Record: null, // 定位记录
myitem: null, //直接发送自定义消息的我的选中主播
youritem: null, //直接发送自定义消息的对方选中主播
type: null, //直接发送自定义消息的消息类型
2025-07-25 16:39:52 +08:00
voiceStatus: false, // 语音状态
inputfocus: false, // 输入框焦点状态
voicepopUpstart: false, // 语音长按状态/false关闭/true开启
voiceCancelOrSend: false, // 语音取消/发送/false发送/true取消
recorderManager: uni.getRecorderManager(),
playbackStatus: true, // 语音播放状态
2025-07-18 13:06:06 +08:00
popUpList: [
2025-07-21 22:10:59 +08:00
{
2025-07-25 16:39:52 +08:00
name: "图片",
2025-07-21 22:10:59 +08:00
icon: "https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/Album.png",
type: "Album",
},
2025-08-05 22:05:56 +08:00
// {
// name: "视频",
// icon: "https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/Video.png",
// type: "Video",
// },
2025-07-18 13:06:06 +08:00
{
name: "邀请",
icon: "https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/chat_invite.png",
type: "Invitation",
},
], /// 更多消息类型弹窗列表
};
},
onShow() {
this.onPage = true;
2025-07-21 22:10:59 +08:00
uni.onKeyboardHeightChange((res) => {
this.KeyboardHeight = res.height * 2 - this.ioshide;
});
2025-07-18 13:06:06 +08:00
},
onHide() {
this.onPage = false;
},
2025-07-29 14:23:27 +08:00
onUnload() {
this.onPage = false;
},
2025-07-18 13:06:06 +08:00
onLoad(options) {
2025-07-25 16:39:52 +08:00
this.recorderManager.onStop((res) => {
console.log("录音结束", res);
if(this.ioshide != 0){
if(res.fileSize<20*1024){
uni.showToast({
title:"您说话太短",
icon: "none",
duration: 2000,
});
}else{
if (this.voiceCancelOrSend) {
this.voiceCancelOrSend = false;
}else{
this.sendVoice(res)
this.voiceCancelOrSend = false;
}
}
}else{
if(res.fileSize<2*1024){
uni.showToast({
title:"您说话太短",
icon: "none",
duration: 2000,
});
}else{
if (this.voiceCancelOrSend) {
this.voiceCancelOrSend = false;
}else{
this.sendVoice(res)
this.voiceCancelOrSend = false;
}
}
}
});
2025-07-18 13:06:06 +08:00
uni.getStorage({
key: "userinfo",
success: (res) => {
2025-07-21 22:10:59 +08:00
this.userinfo = res.data;
2025-07-18 13:06:06 +08:00
},
});
this.userId = options.userId;
this.nickname = options.nickname;
this.avatar = options.avatar;
2025-07-21 22:10:59 +08:00
this.type = options.type;
try {
this.myitem = JSON.parse(options.myitem);
this.youritem = JSON.parse(options.youritem);
} catch (e) {}
if (this.type == "pk") {
setTimeout(() => {
this.sendCustomMessage();
}, 500);
}
2025-07-18 13:06:06 +08:00
// 获取和对方用户的聊天记录
getConversationMessages(this.$goeasy, this.userId, null).then((res) => {
this.chatList = res.map((item) => {
item.id = generateId();
2025-07-21 22:10:59 +08:00
item.timestampStatus = this.checkInterval(item.timestamp);
2025-07-18 13:06:06 +08:00
return item;
});
setTimeout(() => {
2025-07-21 22:10:59 +08:00
if (this.chatList.length > 0) {
this.ElementPositioning = this.chatList[this.chatList.length - 1].id;
this.LastTime = this.chatList[0].timestamp;
} else {
uni.showToast({
title: "您和对方暂无聊天记录,快去聊天吧",
icon: "none",
duration: 2000,
});
}
2025-07-18 13:06:06 +08:00
}, 300);
const query = uni.createSelectorQuery().in(this);
query
.select(".inputComponent")
.boundingClientRect((res) => {
this.Elementheight = res.height * 2;
})
.exec();
});
//已读对方的消息
messageRead(this.$goeasy, this.userId).then((res) => {
console.log("已读对方的消息");
});
this.getIOSDeviceType();
var im = this.$goeasy.im;
im.on(GoEasy.IM_EVENT.PRIVATE_MESSAGE_RECEIVED, this.onPrivateMessageReceived); //监听接受消息
im.on(GoEasy.IM_EVENT.MESSAGE_READ, this.onMessageRead); //监听已读消息
this.getscrollviewheight();
2025-09-29 20:48:31 +08:00
this.checkRecordPermission();
2025-07-18 13:06:06 +08:00
},
methods: {
2025-07-25 16:39:52 +08:00
//暂停所有播放
notplayVoice(type) {
this.playbackStatus = type;
},
//发送录音
sendVoice(res) {
const im = this.$goeasy.im;
var message = im.createAudioMessage({
file: res,
to: {
type: GoEasy.IM_SCENE.PRIVATE,
id: this.userId, //对方用户id
data: { avatar: this.avatar, nickname: this.nickname },
},
onProgress: function (event) {
console.log("file uploading:", event);
}, //获取上传进度
});
sendGroupMessage(this.$goeasy, message).then((ress) => {
this.ElementPositioning = ress.id = generateId();
ress.timestampStatus = this.checkInterval(ress.timestamp);
this.chatList.push(ress);
this.judgescrollTop = false;
});
},
//长按语音
voiceTouchstart() {
console.log("长按语音");
this.voicepopUpstart = true;
this.recorderManager.start();
this.notplayVoice(false);
},
//松开语音
voiceTouchend() {
setTimeout(() => {
this.recorderManager.stop();
}, 100);
console.log("松开语音");
this.voicepopUpstart = false;
},
//移动语音
voiceTouchmove(event) {
const threshold = uni.getSystemInfoSync().windowHeight * 0.86;
try {
if (event.touches[0].clientY > threshold) {
this.voiceCancelOrSend = false;
} else {
this.voiceCancelOrSend = true;
}
} catch (e) {}
},
//中断语音
voiceTouchcancel() {
console.log("中断语音");
this.voicepopUpstart = false;
this.voiceCancelOrSend = false;
},
//语音切换
onVoice(status) {
if (status) {
this.inputfocus = false;
this.MoreStatus = false;
} else {
this.inputfocus = true;
}
this.voiceStatus = status;
},
//录音权限
checkRecordPermission() {
// 检查当前录音权限状态
uni.getSetting({
success: (res) => {
const hasPermission = res.authSetting["scope.record"];
if (hasPermission === undefined) {
this.requestPermission();
} else if (!hasPermission) {
this.voiceStatus = false;
uni.showModal({
title: "权限提示",
content: "需要录音权限才能正常使用功能,请在设置中开启",
confirmText: "去开启",
success: (modalRes) => {
if (modalRes.confirm) {
uni.openSetting({
success: (settingRes) => {
if (settingRes.authSetting["scope.record"] === true) {
this.checkRecordPermission();
}
},
});
}
},
});
}
},
});
},
//请求录音权限
requestPermission() {
uni.authorize({
scope: "scope.record",
fail: (err) => {
this.voiceStatus = false;
uni.showToast({
title: "请授予麦克风权限,否则可能导致语音功能异常",
icon: "none",
});
},
});
},
2025-07-21 22:10:59 +08:00
//直接发送自定义消息
sendCustomMessage() {
request({
url: "pk/createPkRecord",
method: "POST",
data: {
pkIdA: this.youritem.id,
pkIdB: this.myitem.id,
userIdA: this.userId,
userIdB: this.userinfo.id,
pkTime: this.youritem.pkTime,
pkNumber: this.youritem.pkNumber,
anchorIdA: this.youritem.anchorId,
anchorIdB: this.myitem.anchorId,
anchorIconA: this.youritem.anchorIcon,
anchorIconB: this.myitem.anchorIcon,
piIdA: this.youritem.id,
piIdB: this.myitem.id,
},
userInfo: true,
}).then((res) => {
if (res.code == 200) {
const customData = {
id: res.data.id,
pkIdA: this.youritem.id,
pkIdB: this.myitem.id,
};
let order = {
customData: customData,
link: "https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/pk.png",
text: "PK邀请消息",
};
sendCustomMessage(
this.$goeasy,
this.type,
this.userId,
order,
this.avatar,
this.nickname
).then((res) => {
this.ElementPositioning = res.id = generateId();
res.timestampStatus = this.checkInterval(res.timestamp);
this.chatList.push(res);
uni.showToast({
title: "发送成功",
icon: "none",
});
});
} else {
uni.showToast({
title: res.msg,
icon: "none",
});
}
});
},
2025-07-18 13:06:06 +08:00
//时间显示
checkInterval(timestamp) {
if (!this.lastTimestamp) {
this.lastTimestamp = timestamp;
return true;
}
const timeDiff = timestamp - this.lastTimestamp;
if (timeDiff >= 300000) {
// 5 分钟=300000 毫秒
this.lastTimestamp = timestamp;
return true;
}
return false;
},
//时间格式化
TimeFormatting: TimeFormatting,
//获取容器高度
getscrollviewheight() {
const queryheight = uni.createSelectorQuery().in(this);
queryheight
.select(".scroll")
.boundingClientRect((res) => {
this.scrollviewheight = res.height;
})
.exec();
},
//滚动事件
onScroll(event) {
if (!this.judgescrollTop) {
this.scrollTop = event.detail.scrollTop;
this.judgescrollTop = true;
} else if (this.scrollTop - event.detail.scrollTop > this.scrollviewheight) {
this.Scrolling = true;
} else if (this.scrollTop - event.detail.scrollTop < this.scrollviewheight) {
this.Scrolling = false;
}
},
2025-07-21 22:10:59 +08:00
//获取更多聊天记录
onScrollToUpper() {
this.lastTimestamp = null;
getConversationMessages(this.$goeasy, this.userId, this.LastTime).then((res) => {
this.Record = this.chatList[0].id;
this.MoreMessageList = res.map((item) => {
item.id = generateId();
item.timestampStatus = this.checkInterval(item.timestamp);
return item;
});
});
setTimeout(() => {
this.chatList = [...this.MoreMessageList, ...this.chatList];
console.log("获取更多聊天记录", this.chatList);
this.LastTime = this.chatList[0].timestamp;
this.ElementPositioning = this.Record;
}, 300);
},
2025-07-18 13:06:06 +08:00
//监听已读消息
onMessageRead(message) {
2025-07-21 22:10:59 +08:00
console.log("1已读消息", message);
2025-07-18 13:06:06 +08:00
},
//监听接受消息
onPrivateMessageReceived(message) {
if (!this.Scrolling) {
this.ElementPositioning = message.id = generateId();
2025-07-21 22:10:59 +08:00
message.timestampStatus = this.checkInterval(message.timestamp);
2025-07-18 13:06:06 +08:00
this.judgescrollTop = false;
} else {
message.id = generateId();
2025-07-21 22:10:59 +08:00
message.timestampStatus = this.checkInterval(message.timestamp);
2025-07-18 13:06:06 +08:00
}
this.chatList.push(message);
if (this.onPage) {
messageRead(this.$goeasy, this.userId).then((res) => {
console.log("已读对方的消息");
});
}
},
//发送消息
onSend() {
if (this.content != "") {
sendMessage(
this.$goeasy,
this.userId,
this.content,
this.avatar,
this.nickname
).then((res) => {
console.log("发送成功", res);
this.ElementPositioning = res.id = generateId();
2025-07-21 22:10:59 +08:00
res.timestampStatus = this.checkInterval(res.timestamp);
2025-07-18 13:06:06 +08:00
this.chatList.push(res);
this.judgescrollTop = false;
});
this.content = "";
this.ButtonStatus = false;
}
},
2025-07-21 22:10:59 +08:00
//自定义消息发送返回处理
refreshMessage(message) {
this.MoreItemStatus = null;
this.ElementPositioning = message.message.id = generateId();
message.timestampStatus = this.checkInterval(message.message.timestamp);
this.chatList.push(message.message);
this.judgescrollTop = false;
this.MoreStatus = false;
},
2025-07-18 13:06:06 +08:00
//ios兼容
getIOSDeviceType() {
const systemInfo = uni.getSystemInfoSync();
const model = systemInfo.model;
2025-09-29 20:48:31 +08:00
if (/iPhone X|iPhone11|iPhone12|iPhone13|iPhone14|iPhone15|iPhone16|iPhone15 Pro|iPhone15 Pro Max|iPhone14 Pro|iPhone14 Pro Max|iPhone13 Pro|iPhone13 Pro Max|iPhone12 Pro|iPhone12 Pro Max|iPhone11 Pro|iPhone11 Pro Max|iPhone13 mini|iPhone12 mini|iPhoneXS|iPhoneXS Max/i.test(model)) {
if (/iPhone X|iPhone XS|iPhone 11 Pro|iPhone 11 Pro Max|iPhone 12 Pro|iPhone 12 Pro Max|iPhone 13 Pro|iPhone 13 Pro Max|iPhone 14 Pro|iPhone 14 Pro Max|iPhone 15 Pro|iPhone 15 Pro Max|iPhone 16/i.test(model)) {
2025-07-18 13:06:06 +08:00
this.ioshide = 88;
} else if (/iPhone 12|iPhone 13|iPhone 14/i.test(model)) {
this.ioshide = 94;
}
}
},
//更多消息类型弹窗事件
onMore(Status) {
if (!this.Scrolling) {
this.ElementPositioning = null;
setTimeout(() => {
this.ElementPositioning = this.chatList[this.chatList.length - 1].id;
}, 100);
this.judgescrollTop = false;
}
this.getscrollviewheight();
2025-07-25 16:39:52 +08:00
if (Status) {
this.MoreStatus = Status;
this.voiceStatus = false;
} else {
this.MoreStatus = Status;
}
2025-07-18 13:06:06 +08:00
const query = uni.createSelectorQuery().in(this);
query
.select(".inputComponent")
.boundingClientRect((res) => {
this.Elementheight = res.height * 2;
})
.exec();
},
//更多消息类型弹窗点击事件
onMoreItem(type) {
2025-07-21 22:10:59 +08:00
if (type == "Album") {
2025-07-25 16:39:52 +08:00
this.onSendMedia(); //发送图片
} else if (type == "Video") {
this.onSendVideo(); //发送视频
2025-07-21 22:10:59 +08:00
} else {
this.MoreItemStatus = type;
}
},
2025-07-25 16:39:52 +08:00
//发送视频
onSendVideo() {
var im = this.$goeasy.im;
uni.chooseVideo({
2025-07-21 22:10:59 +08:00
sourceType: ["album", "camera"],
2025-07-25 16:39:52 +08:00
success: (res) => {
var message = im.createVideoMessage({
file: res, //H5获得的视频file对象 Uniapp和小程序调用chooseVideosuccess时得到的res对象
to: {
type: GoEasy.IM_SCENE.PRIVATE,
id: this.userId, //对方用户id
data: { avatar: this.avatar, nickname: this.nickname },
},
onProgress: function (event) {
console.log("file uploading:", event);
}, //获取上传进度
});
sendGroupMessage(this.$goeasy, message).then((res) => {
this.ElementPositioning = res.id = generateId();
res.timestampStatus = this.checkInterval(res.timestamp);
this.chatList.push(res);
this.judgescrollTop = false;
});
2025-07-21 22:10:59 +08:00
},
});
},
2025-07-25 16:39:52 +08:00
//发送图片
onSendMedia() {
var im = this.$goeasy.im;
uni.chooseImage({
count: 9, //默认9
sizeType: ["original", "compressed"], //可以指定是原图还是压缩图,默认二者都有
sourceType: ["album", "camera"], //从相册选择
success: (res) => {
const tempFiles = res.tempFiles;
tempFiles.forEach((item, index) => {
var message = im.createImageMessage({
file: item,
to: {
type: GoEasy.IM_SCENE.PRIVATE,
id: this.userId,
data: { avatar: this.avatar, nickname: this.nickname },
},
onProgress: function (event) {
console.log("上传进度", event);
}, //获取上传进度
});
sendGroupMessage(this.$goeasy, message).then((res) => {
this.ElementPositioning = res.id = generateId();
res.timestampStatus = this.checkInterval(res.timestamp);
this.chatList.push(res);
this.judgescrollTop = false;
});
});
},
});
2025-07-18 13:06:06 +08:00
},
// 获取键盘高度
onFocus(event) {
if (!this.Scrolling) {
this.ElementPositioning = null;
setTimeout(() => {
this.ElementPositioning = this.chatList[this.chatList.length - 1].id;
}, 100);
this.judgescrollTop = false;
}
this.getscrollviewheight();
const query = uni.createSelectorQuery().in(this);
query
.select(".inputComponent")
.boundingClientRect((res) => {
this.Elementheight = res.height * 2;
})
.exec();
},
//键盘消失
onBlur(event) {
const query = uni.createSelectorQuery().in(this);
query
.select(".inputComponent")
.boundingClientRect((res) => {
this.Elementheight = res.height * 2;
})
.exec();
this.getscrollviewheight();
},
//按钮切换
SendInput(event) {
const query = uni.createSelectorQuery().in(this);
query
.select(".inputComponent")
.boundingClientRect((res) => {
this.Elementheight = res.height * 2;
})
.exec();
if (event.target.value != "") {
this.ButtonStatus = true;
} else {
this.ButtonStatus = false;
}
},
// 返回上一页
onBack() {
this.onPage = false;
wx.navigateBack({
delta: 1,
});
},
},
components: {
textmessage,
InvitationComponents,
2025-07-21 22:10:59 +08:00
customPKMessage,
2025-07-25 16:39:52 +08:00
imageMessage,
videoMessage,
voiceMessage,
2025-07-18 13:06:06 +08:00
},
};
</script>
<style scoped>
.bg {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
z-index: -1;
}
.bgImg {
width: 100%;
height: 100%;
}
.Return {
position: fixed;
left: 35rpx;
top: 120rpx;
width: 46rpx;
height: 46rpx;
2025-07-29 14:23:27 +08:00
z-index: 2;
2025-07-18 13:06:06 +08:00
}
.title {
position: fixed;
top: 120rpx;
2025-07-29 14:23:27 +08:00
left:0;
right: 0;
text-align: center;
2025-07-18 13:06:06 +08:00
font-size: 34rpx;
color: #100e0f;
font-weight: bold;
z-index: 1;
}
.ReturnImg {
width: 100%;
height: 100%;
}
.content {
position: absolute;
top: 200rpx;
left: 0rpx;
right: 0rpx;
}
.scroll {
width: 96%;
height: 100%;
padding: 0% 2% 0% 2%;
}
2025-07-21 22:10:59 +08:00
.scroll ::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
display: none;
}
2025-07-18 13:06:06 +08:00
.inputComponent {
position: absolute;
left: 0;
right: 0;
height: auto;
background-color: #f0f0f0;
padding: 15rpx 15rpx 37.5rpx 15rpx;
display: flex;
align-items: flex-end;
2025-07-21 22:10:59 +08:00
transition: bottom 0.25s ease;
2025-07-18 13:06:06 +08:00
}
.chat-card {
width: 100%;
height: auto;
2025-07-21 22:10:59 +08:00
margin-bottom: 10rpx;
margin-top: 10rpx;
2025-07-18 13:06:06 +08:00
padding: 10rpx;
2025-07-21 22:10:59 +08:00
/* background-color: #ffffff; */
2025-07-18 13:06:06 +08:00
}
.chat-time {
width: 100%;
height: 50rpx;
text-align: center;
font-size: 24rpx;
color: #999999;
line-height: 50rpx;
margin-top: 20rpx;
margin-bottom: 20rpx;
background-color: #00000000;
}
.chat-avatar {
width: 100%;
height: auto;
2025-07-21 22:10:59 +08:00
display: flex;
align-items: flex-start;
}
.oppositeChatNews {
width: 100%;
display: flex;
align-items: flex-start;
}
.oppositesharpCorner {
width: 20rpx;
height: 80rpx;
display: flex;
flex-direction: row-reverse;
align-items: center;
}
.oppositeSharpCornercion {
width: 0;
height: 0;
border-top: 13rpx solid transparent;
border-right: 13rpx solid #ffffff;
border-bottom: 13rpx solid transparent;
}
.oppositeChatNewsContent {
width: auto;
height: auto;
background-color: #ffffff;
border-radius: 10rpx;
max-width: 450rpx;
}
.myChatNews {
width: 100%;
display: flex;
flex-direction: row-reverse;
align-items: flex-start;
margin-right: 15rpx;
}
.mysharpCorner {
width: 20rpx;
height: 80rpx;
display: flex;
align-items: center;
}
.mySharpCornercion {
width: 0;
height: 0;
border-top: 13rpx solid transparent;
border-left: 13rpx solid #7bbd0093;
border-bottom: 13rpx solid transparent;
}
.myChatNewsContent {
width: auto;
height: auto;
border-radius: 20rpx;
max-width: 450rpx;
}
.chat-avatarImg {
width: 80rpx;
height: 80rpx;
border-radius: 10rpx;
2025-07-18 13:06:06 +08:00
}
2025-07-25 16:39:52 +08:00
.Voice {
width: 80rpx;
height: 80rpx;
border-radius: 50rpx;
margin-left: 10rpx;
display: flex;
justify-content: center;
align-items: center;
}
.KeyboardImg {
width: 70rpx;
height: 70rpx;
border-radius: 50rpx;
display: flex;
justify-content: center;
align-items: center;
}
.Keyboardpng {
width: 100%;
height: 100%;
border-radius: 50rpx;
}
.MicrophoneImg {
margin-top: 5rpx;
width: 53rpx;
height: 53rpx;
border: 4rpx solid #424242;
border-radius: 50rpx;
display: flex;
justify-content: center;
align-items: center;
}
.Microphonepng {
width: 80%;
height: 80%;
border-radius: 50rpx;
}
2025-07-18 13:06:06 +08:00
.textareacomponent {
width: 570rpx;
height: auto;
}
.input {
width: 95%;
background-color: #ffffff;
min-height: 60rpx;
max-height: 200rpx;
border-radius: 10rpx;
padding: 10rpx;
overflow-wrap: break-word;
margin-left: 30rpx;
}
2025-07-25 16:39:52 +08:00
.VoiceInput {
width: 95%;
background-color: #ffffff;
height: 60rpx;
border-radius: 10rpx;
padding: 10rpx;
overflow-wrap: break-word;
margin-left: 30rpx;
line-height: 60rpx;
text-align: center;
color: #000;
}
2025-07-18 13:06:06 +08:00
.sendComponent {
margin-left: 40rpx;
}
.send {
width: 100rpx;
height: 75rpx;
background-color: #539c00;
border-radius: 10rpx;
color: #ffffff;
font-size: 20rpx;
text-align: center;
line-height: 75rpx;
}
.MoreImg {
margin-left: 20rpx;
height: 80rpx;
width: 80rpx;
margin-bottom: -10rpx;
border-radius: 50rpx;
}
.MoreComponent {
position: fixed;
left: 0;
right: 0;
height: 650rpx;
2025-07-21 22:10:59 +08:00
transition: bottom 0.25s ease;
2025-07-18 13:06:06 +08:00
background-color: #ffffff;
}
.Morecontent {
width: 100%;
height: 100%;
display: flex;
align-content: baseline;
flex-wrap: wrap;
}
.MoreList {
width: 150rpx;
height: 150rpx;
background-color: #f1f1f1;
border-radius: 20rpx;
margin: 18.75rpx;
}
.MoreItem {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.Moreicon {
width: 80rpx;
height: 80rpx;
}
.popUpInvitation {
position: fixed;
left: 0;
right: 0;
bottom: 0;
2025-07-21 22:10:59 +08:00
transition: top 0.25s ease;
z-index: 1000;
2025-07-18 13:06:06 +08:00
}
2025-07-25 16:39:52 +08:00
.popUpVoice {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
background-color: #8b8b8bd7;
}
2025-07-18 13:06:06 +08:00
.popUpInvitationContent {
position: absolute;
left: 0;
right: 0;
height: 1000rpx;
2025-07-21 22:10:59 +08:00
transition: bottom 0.25s ease;
2025-07-18 13:06:06 +08:00
background-color: #ffffff;
border-top-left-radius: 40rpx;
border-top-right-radius: 40rpx;
}
2025-07-25 16:39:52 +08:00
.popUpvoiceContent {
position: absolute;
left: 0;
right: 0;
height: 1000rpx;
/* transition: bottom 0.1s ease; */
/* background-color: #ebebeb; */
}
.gifModule {
padding: 20rpx;
border-radius: 20rpx;
overflow: hidden;
height: 120rpx;
background-color: #232123;
}
.voiceCenter {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
.video-player {
width: 300rpx;
height: 300rpx;
border-radius: 20rpx;
margin-top: -94rpx;
}
.CancelModule {
width: 95%;
height: 100rpx;
text-align: center;
line-height: 100rpx;
background-color: #000000a9;
font-size: 30rpx;
color: #999999;
border-radius: 50rpx;
margin-top: 500rpx;
}
.btnModule {
width: 100%;
height: 200rpx;
background-color: #000000;
color: #999999;
font-size: 30rpx;
text-align: center;
line-height: 200rpx;
border-top-left-radius: 50%;
border-top-right-radius: 50%;
}
2025-07-18 13:06:06 +08:00
</style>