talk_appAmin/pages/Friend/messagechat.vue

1095 lines
24 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!-- 消息聊天 -->
<template>
<view class="content">
<!-- -->
<view class="header_are" >
<uni-nav-bar statusBar="false" left-icon="left" @clickLeft="ReturnPage" :fixed="true" :border="false"
background-color="#ffffff" :title="title" />
</view>
<!-- -->
<view class="middle_area" @click="hideFuncBox()" :style="`padding-bottom:${KeyboardHeight}px`">
<scroll-view class="scroll-container" :class="{ show: IsShwo }" scroll-y="true"
:scroll-with-animation="true" :scroll-into-view="lastMessageId" @touchstart="checkmsg" style="padding-top: 20rpx;">
<view class="bigbox" @touchmove="watchjilu">
<view v-for="item in arrlist" :id="'ms' + item.id" :key="item.id" @longpress="showFuncBox(item.id)">
<view v-if="item.senderId != myuserid" @longpress="funcBoxShow(item.id)">
<view>
<view class="contentmessagetimes" v-if="IsSendTime(item.sendTime)">
<text class="contentmessagetimetext">{{ ReturnTime(item.sendTime) }}</text>
</view>
</view>
<view class="contentmessage">
<view @click="toPerson">
<!-- <image class="contentmessageimage" :src="bindIcon(youavatar)"></image> -->
<image v-if="youavatar" class="contentmessageimage" :src="bindIcon(youavatar)"></image>
<image v-else class="contentmessageimage" src="../../static/images/icon/tu4-1.jpg" mode=""></image>
</view>
<view style="margin-left: 16rpx;">
<view class="message" v-if="item.messageType == 51">
<text class="messagetext">{{ item.messageText }}</text>
</view>
<view v-else class="mymessageImage" @longpress="saveImage(item.messageText)">
<up-image :show-loading="true" :src="bindIcon(item.messageText)" radius="12rpx"
width="240rpx" height="300rpx"
@tap="previewImage(item.messageText)"></up-image>
</view>
</view>
</view>
<view class="funcBox" v-if="visibleFuncBoxId === item.id" @click.stop="handleFuncBoxClick">
<view class="moveFunc" @click="delOne(item.id,item.senderId,item.receiverId)">
删除
</view>
<!-- <view class="moveFunc">
|
</view>
<view class="delectFunc" @click="withdrawOne(item.id)">
撤回
</view> -->
<view class="moveFunc">
|
</view>
<view class="cancel" @click="cancelBox(item.id)">
取消
</view>
</view>
</view>
<view v-else>
<!-- v-if="IsSendTime(item.sendTime)" -->
<view>
<!-- <p>{{ReturnTime(item.sendTime)}}</p> -->
<view class="contentmessagetimes" v-if="IsSendTime(item.sendTime)">
<text class="contentmessagetimetext">{{ ReturnTime(item.sendTime) }}</text>
</view>
</view>
<view class="mycontentmessage">
<view>
<view v-if="item.messageType == 51" class="mymessage">
<text class="mymessagetext">{{ item.messageText }}</text>
</view>
<view v-else class="mymessageImage" @longpress="saveImage(item.messageText)">
<up-image :show-loading="true" :src="bindIcon(item.messageText)" radius="12rpx"
width="240rpx" height="300rpx"
@tap="previewImage(item.messageText)"></up-image>
</view>
</view>
<view @click="toPersonz">
<image class="mycontentmessageimage" :src="avatar"></image>
</view>
</view>
<view class="funcBox funcBoxT" v-if="visibleFuncBoxId === item.id" @click.stop="handleFuncBoxClick">
<view class="moveFunc" @click="delOne(item.id,item.senderId,item.receiverId)">
删除
</view>
<view class="moveFunc">
|
</view>
<view class="delectFunc" @click="withdrawOne(item.id)">
撤回
</view>
<view class="moveFunc">
|
</view>
<view class="cancel" @click="cancelBox(item.id)">
取消
</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<!-- 下 -->
<view class="bottom_area" :class="{ show: IsShwo }" :style="IsShwo!=true?`transform: translateY(${-KeyboardHeight}px);`:`transform: translateY(${-210}rpx);`">
<!-- 输入区域 -->
<view class="bottm" >
<view class="botomview">
<view class="viewtextarea">
<textarea class="classtextarea" v-model="messageinput" :adjust-position="false"
:disabled="ifdisab" auto-height placeholder="请输入内容" @focus="onFocus"
@linechange="input_text" :focus="false" cursor-spacing="15" @keyboardheightchange="hightchange" />
<view class="right_shuru">
<view class="bottombutton" @click="ButtonSend()">
<text>发送</text>
</view>
</view>
</view>
</view>
<view class="imageview" @click="ShowBottom()">
<image class="messageaddimage" src="../../static/images/sign/messageadd.png"></image>
</view>
</view>
<!-- 发送照片区域 -->
<view class="popup" >
<view style="display: flex;margin-left: 32rpx;margin-top: 24rpx;">
<view >
<fileUpload v-model="messageinput" @dropDownValueChange="fruitValueChange" :limit="1">
</fileUpload>
<view @click="UpPorops()">
<text class="textpopup" style="margin-top: 4rpx;">相册</text>
</view>
</view>
<view style="margin-left: 48rpx;" @click="UpReport()">
<image class="imagepopup" src="../../static/images/sign/report.png"></image>
<view>
<text class="textpopup">举报</text>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import fileUpload from '@/pages/common/file/fileUpload/sendImage.vue'
import navbar_neadVue from "@/pages/common/navbar/navbar_nead.vue";
import {
onMounted,
ref,
getCurrentInstance,
reactive,
nextTick,
watch
} from "vue"
import {
onReachBottom,
onLoad,
onShow,
onPageScroll
} from "@dcloudio/uni-app";
import {
GetListid
} from "@/api/signln/SignTa/SignTa";
import {
addNotificationHistorical,
listNotificationHistoricalUser
} from "@/api/signln/NotificationHistorical/NotificationHistorical";
import {
delMeMessage,
withdrawMessage
}from "@/api/signln/FriendShip/FriendShip";
const {
proxy
} = getCurrentInstance();
const messageinput = ref(null);
const myuserid = ref(0);
// const funcBoxVisibility = reactive({}); // 用于存储每个消息的funcBox显示状态
const visibleFuncBoxId = ref(null); // 当前可见的弹窗ID
const co = ref(null);
// 图片
const fileList1 = ref();
const socket = ref(null);
const message = ref('');
const IsShwo = ref(false)
const funcBoxIsShow = ref(false)
import {
useRouter,
useRoute
} from 'vue-router';
const route = useRoute();
const title = ref("");
const uid = ref(0);
const myavatar = ref();
const youavatar = ref();
var att = ref('hh')
// 底部输入部分的整体高度
var bottombox = ref('100');
var scrollto = ref()
var ifdisab = ref(false)
onShow(() => {
//获取$("#")
const getuser = GetListid().then(res => {
myuserid.value = res;
console.log("党情登录用户" + myuserid.value)
if (myuserid.value != 0) {
WebSockOpen(myuserid.value)
setTimeout(() => {
GetList();
}, 100)
}
})
uni.getStorage({
key: 'userInfo',
success: function(res) {
const storedUserInfo = res.data;
uid.value = storedUserInfo.friendid;
title.value = storedUserInfo.title;
myavatar.value = storedUserInfo.myavatar;
youavatar.value = storedUserInfo.youavatar;
console.log('User info retrieved successfully:', storedUserInfo.myavatar);
},
fail: function(err) {
console.error('Failed to retrieve user info:', err);
}
});
})
// 点击头像跳转个人主页
const toPerson = () => {
uni.navigateTo({
url: "/pages/Friend/addfruebd?id=" + uid.value
})
};
const toPersonz = () => {
uni.navigateTo({
url: "/pages/Friend/addfruebd?id=" + myuserid.value
})
};
// 实现图片预览
const previewImage = (url) => {
console.log("图片预览111", url);
uni.previewImage({
current: QNDomain + url, // 当前显示图片的http链接
urls: [QNDomain + url] // 需要预览的图片http链接列表这里只放了一个URL
});
};
// let mesfunc = false; // 使用 let 或 var 声明,以便在函数内部修改
// // 下载图片
// const saveImage = (imageUrl) => {
// console.log("长按保存哦哦哦哦哦哦哦哦哦哦")
// mesfunc = true
// const saveImage = (imageUrl) => {
// console.log("长按保存图片...");
// const fullImageUrl = QNDomain + imageUrl;
// uni.downloadFile({
// url: fullImageUrl, // 完整的网络图片URL
// success: (res) => {
// if (res.statusCode === 200) {
// // 临时文件路径
// const tempFilePath = res.tempFilePath;
// // 保存文件到本地相册
// uni.saveImageToPhotosAlbum({
// filePath: tempFilePath,
// success: () => {
// uni.showToast({
// title: '保存成功',
// icon: 'success'
// });
// },
// fail: (err) => {
// uni.showToast({
// title: '保存失败: ' + err.errMsg,
// icon: 'none'
// });
// }
// });
// }
// },
// fail: (err) => {
// uni.showToast({
// title: '下载失败: ' + err.errMsg,
// icon: 'none'
// });
// }
// });
// };
// };
const lastMessageId = ref(null);
import config from "@/config";
function WebSockOpen(id) {
socket.value = proxy.$store.state.chat.socket;
console.log("socketInfo:", proxy.$store.state.chat.socket);
}
const usermessInfo = ref(proxy.$store.state.chat.userMessageinfo)
// 使用 watch 监听 count 的变化
watch(
() => proxy.$store.state.chat.userMessageinfo,
(newVal, oldVal) => {
IsSendTime();
arrlist.value.push(newVal)
console.log("新数据chat", arrlist.value);
setTimeout(() => {
lastMessageId.value = 'test';
}, 40);
setTimeout(() => {
lastMessageId.value = 'ms' + arrlist.value[arrlist.value.length - 1].id;
// console.log(lastMessageId.value)
// lastMessageId.value = 'boxlastsss';
}, 50);
}
);
onShow(() => {
proxy.$store.dispatch('webSockerInfo')
})
const webInfo = () => {
console.log("操作web1");
webInfo2()
}
const webInfo2 = () => {
proxy.$store.dispatch('webSockerInfo')
proxy.$store.dispatch('getQNDomainInfo')
console.log("操作web2");
}
onLoad(() => {
proxy.$store.dispatch('webSockerInfo')
GetList();
})
// 显示功能弹窗
const showFuncBox = (messageId) => {
visibleFuncBoxId.value = messageId; // 更新为当前消息的ID
};
// 隐藏功能弹窗
const hideFuncBox = (event) => {
if (!event.target.closest('.funcBox')) {
visibleFuncBoxId.value = null;
}
};
const cancelBox = (messageId) => {
visibleFuncBoxId.value = null;
}
// 删除自己单条信息(对方仍然可见)
const delOne = (messageId,senId,recId) => {
var data = {
senderId: senId,
receiverId: recId,
id:messageId
}
delMeMessage(data).then(response => {
console.log('接口返回response', response)
MyList();
});
visibleFuncBoxId.value = null;
}
// 删除自己单条信息(对方也不可见)
const withdrawOne = (messageId) => {
var data = {
senderId: myuserid.value,
receiverId: uid.value,
id:messageId
}
withdrawMessage(data).then(response => {
console.log('撤回接口返回response', response)
MyList();
});
visibleFuncBoxId.value = null;
}
// 处理功能弹窗的点击事件,阻止冒泡
const handleFuncBoxClick = (event) => {
event.stopPropagation();
};
// 判断键盘是否升起
function onFocus() {
// console.log("键盘升起")
IsShwo.value=false
setTimeout(() => {
lastMessageId.value = 'test';
}, 40);
setTimeout(() => {
lastMessageId.value = 'ms' + arrlist.value[arrlist.value.length - 1].id;
// console.log(lastMessageId.value)
// lastMessageId.value = 'boxlastsss';
}, 50);
};
const arrlist = ref();
// 获取历史记录
function GetList() {
MyList();
}
function MyList() {
var data = {
// pageNum: 1,
// pageSize: 10,
senderId: null,
receiverId: null,
messageType: null,
sendTime: null,
readTime: null,
status: null,
messageText: null,
send: null
}
data.senderId = myuserid.value;
data.receiverId = uid.value;
// console.log(data);
listNotificationHistoricalUser(data).then(response => {
// console.log(response.rows.length)
const filteredRows = response.rows.filter(row => row.withdraw === 0);
arrlist.value = filteredRows;
console.log(arrlist.value,"arrlist.value1111111");
IsSendTime();
if (arrlist.value != null) {
setTimeout(() => {
lastMessageId.value = 'ms' + arrlist.value[arrlist.value.length - 1].id;
// console.log(lastMessageId.value)
// lastMessageId.value = 'boxlastsss';
}, 30);
}
});
}
// 发送消息
function ButtonSend() {
if (messageinput.value == null) {
proxy.$modal.msg("空消息,请输入内容!");
return;
}
const form = {
senderId: null,
receiverId: null,
messageType: null,
sendTime: null,
readTime: null,
status: null,
messageText: null,
send: null
}
form.messageText = messageinput.value;
form.receiverId = uid.value;
form.senderId = myuserid.value;
form.status = 0;
form.messageType = 51; //文字
// form.sendTime = new Date();
form.send = myuserid.value;
toWSMessage(form);
addNotificationHistorical(form).then(response => {
// console.log(response)
GetList();
});
messageinput.value = null;
}
// 弹起底部
function ShowBottom() {
IsShwo.value = !IsShwo.value;
movebottom()
}
//相册
function UpPorops() {
}
var KeyboardHeight = ref(0)
function hightchange(e){
console.log('键盘变化',e.detail.height);
KeyboardHeight.value=e.detail.height
setTimeout(() => {
lastMessageId.value = 'test';
}, 40);
setTimeout(() => {
lastMessageId.value = 'ms' + arrlist.value[arrlist.value.length - 1].id;
// console.log(lastMessageId.value)
// lastMessageId.value = 'boxlastsss';
}, 50);
}
//举报
function UpReport() {
var data = {
userid: myuserid.value,
reportId: uid.value
}
// console.log(data);
uni.setStorage({
data: data,
key: "data",
success() {
proxy.$tab.navigateTo("/pages/Friend/violationreporting")
}
})
}
import {
useStore
} from 'vuex';
const store = useStore();
const avatar = ref(proxy.$store.state.user.avatar)
// 默认头像 URL
const avatarUrl = ref("/static/images/icon/tu4-1.jpg");
const useDefaultAvatar = ref(true); // 默认使用默认头像
function bindIcon(icon) {
return store.state.user.QNDomain + icon;;
}
useDefaultAvatar.value = false;
function closeWebSocket() {
if (socket.value) {
// socket.value.close();
}
}
// 返回后更新上一页数据
function ReturnPage() {
// 关闭 WebSocket
closeWebSocket();
uni.navigateBack()
}
//存放照片的地方
const picList = ref();
function fruitValueChange(e) {
console.log(e)
picList.value = e;
// console.log("发送")
console.log(messageinput.value)
const form = {
senderId: null,
receiverId: null,
messageType: null,
sendTime: null,
readTime: null,
status: null,
messageText: null,
send: null
}
form.messageText = picList.value;
form.receiverId = uid.value;
form.senderId = myuserid.value;
form.status = 0;
form.messageType = 52;
form.send = myuserid.value;
addNotificationHistorical(form).then(response => {
// console.log(response)
GetList();
});
messageinput.value = null;
}
const toWSMessage = (e) => {
// console.log(e)
const info = {
fromid: null,
toid: null,
content: null
}
info.fromid = e.senderId;
info.toid = e.receiverId;
info.content = e.messageText;
// console.log(info)
if (socket.value) {
try {
socket.value.send({
data: JSON.stringify(info),
async success() {
console.log("消息发送成功");
},
});
} catch (e) {
console.log("eee:", e);
}
}
}
var scrollhight = ref(0)
var boxheight = ref(0)
var scroll_to_id = ref('')
//输入框变高低
function movebottom() {
// 获取下部输入区域高度
setTimeout(() => {
lastMessageId.value = '';
}, 40);
setTimeout(() => {
lastMessageId.value = 'ms' + arrlist.value[arrlist.value.length - 1].id;
}, 50);
}
// 输入文字的事件
function input_text() {
setTimeout(() => {
movebottom()
}, 50)
}
//滑动查看消息
function checkmsg() {
console.log('查看');
IsShwo.value = false
}
// 监听WebSocket连接
function onSocketOpen() {
// console.log('WebSocket连接已打开');
}
// 监听WebSocket错误
function onSocketError() {
// console.log('WebSocket连接打开失败请检查');
}
// 时间函数
function ReturnTime(res) {
// console.log(res);
var time = new Date(res);
// console.log(time);
var now = new Date();
// console.log(now);
// console.log("当前时间"+time.getDate() + "闲杂世家"+now.getDate());
var year = time.getFullYear();
var month = time.getMonth() + 1;
var date = time.getDate();
var hours = time.getHours();
var minutes = time.getMinutes();
var months = month.toString().padStart(2, '0');
var hours = hours.toString().padStart(2, '0');
var min = minutes.toString().padStart(2, '0');
if (time.getDate() == now.getDate()) {
return `${hours}:${min}`;
} else {
return `${year}.${months}.${date} ${hours}:${min}`;
}
}
// 判断在5分钟内发的消息不显示时间
function IsSendTime(time) {
var time = new Date(time).getDate();
if(arrlist.value.length>2){
var lasttime = new Date(arrlist.value[arrlist.value.length - 2].sendTime).getDate();
var result = time - lasttime;
if (result == 0) {
return false;
// console.log(result)
} else {
return true;
}
}
}
// 输入情况下查看记录
// function watchjilu(){
// console.log('翻看记录');
// }
</script>
<style lang="scss" scoped>
@import '@/pages/common/navbar/navbar.css';
page {
background-color: #F4F5F6;
height: 100%;
}
.bottm {
width: 750rpx;
background: #ffffff;
display: flex;
padding-bottom: 10rpx;
transition: all 0.357s;
border-bottom: 4rpx solid #ffffff;
}
.botomview {
margin-left: 32rpx;
}
.scroll-container {
height: 100%;
transition: all 0.357s;
}
.viewtextarea {
display: flex;
width: 606rpx;
min-height: 80rpx;
border-radius: 40rpx 40rpx 40rpx 40rpx;
background: #f7f8fa;
margin-top: 12rpx;
}
.right_shuru {
display: flex;
align-items: flex-end;
box-sizing: border-box;
margin-bottom: 16rpx;
}
.imageview {
margin-left: 20rpx;
margin-top: 20rpx;
margin-right: 32rpx;
}
.messageaddimage {
width: 60rpx;
height: 60rpx;
}
.classtextarea {
width: 480rpx;
min-height: 32rpx;
display: block;
margin: auto 0;
line-height: 40rpx;
padding-left: 32rpx;
resize: none;
padding-top: 25rpx;
margin-bottom: 25rpx;
transition: all;
}
.bottombutton {
width: 104rpx;
height: 56rpx;
border-radius: 28rpx 28rpx 28rpx 28rpx;
background: #3477fc;
margin-right: 12rpx;
margin-left: 1rpx;
}
.bottombutton>text {
font-weight: 400;
width: 57rpx;
height: 28rpx;
font-size: 28rpx;
text-align: left;
color: #FFFFFF;
display: block;
margin: auto;
line-height: 56rpx;
}
.scroll-container {
flex: 1;
overflow: hidden;
width: 100%;
box-sizing: border-box;
}
.bigbox {
padding-bottom: 50rpx;
transition: transform 0.3s ease-in-out;
}
.container {
/* top: 10rpx; */
/* position: relative; */
/* bottom: 100rpx; */
display: flex;
flex-direction: column;
transition: all 0.25s;
height: 100%;
flex: 1;
box-sizing: border-box;
/* 让内容元素占据可用空间 */
/* 让内容元素距离底部100rpx */
}
.bottom_liaotian_box {
// height:62.10416793823242+82px;
}
.ShowBottom {
width: 750rpx;
height: 210rpx;
background: #3477fc;
bottom: -100rpx;
left: 0;
right: 0;
position: fixed;
transform: translateY(0);
transition: transform 0.3s ease-in-out;
}
.show {
transform: translateY(-210rpx);
/* 显示视图 */
}
.page {
position: relative;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.content {
flex: 1;
overflow: auto;
}
.popup {
position: fixed;
left: 0;
right: 0;
bottom: -210rpx;
/* 初始位置隐藏在视图外 */
height: 210rpx;
background-color: #fff;
transform: translateY(0);
transition: all 0.35s;
border-top: 4rpx solid #fff;
}
.popup.show {
transform: translateY(-210rpx);
}
.imagepopup {
width: 120rpx;
height: 120rpx;
}
.textpopup {
font-weight: 400;
width: 57rpx;
height: 28rpx;
font-size: 28rpx;
text-align: left;
color: #999999;
display: block;
margin: auto;
}
.contentmessage {
display: flex;
margin-top: 24rpx;
margin-left: 32rpx;
}
.mycontentmessage {
display: flex;
justify-content: flex-end;
margin-right: 32rpx;
margin-top: 24rpx;
}
.contentmessagetime {
/* width: 300rpx; */
height: 28rpx;
border-radius: 14rpx 14rpx 14rpx 14rpx;
opacity: 0.1;
background: #000000;
margin: auto;
margin-top: 48rpx;
}
.contentmessagetime>p {
/* display: inline-block; */
font-weight: 400;
height: 17rpx;
font-size: 20rpx;
text-align: center;
color: #FFFFFF;
display: block;
margin: auto;
line-height: 28rpx;
}
.contentmessagetimes {
display: block;
margin: auto;
margin-top: 48rpx;
text-align: center;
}
.contentmessagetimetext {
border-radius: 14rpx 14rpx 14rpx 14rpx;
background: #000000;
opacity: 0.1;
display: inline-block;
font-weight: 400;
height: 28rpx;
font-size: 20rpx;
text-align: center;
color: #FFFFFF;
line-height: 28rpx;
padding-left: 13rpx;
padding-right: 13rpx;
/* padding-top: 1rpx; */
}
.contentmessageimage {
width: 82rpx;
height: 82rpx;
border-radius: 82rpx;
}
.mycontentmessageimage {
width: 82rpx;
height: 82rpx;
border-radius: 82rpx;
margin-left: 18rpx;
margin-top: -1rpx;
}
.message {
/* max-width: 500rpx; */
/* width: 288rpx; */
/* height: 82rpx; */
/* max-height: 10000rpx; */
border-radius: 12rpx 12rpx 12rpx 12rpx;
background: #ffffff;
}
.mymessge {
border-radius: 12rpx 12rpx 12rpx 12rpx;
background: #3477fc;
}
.messagetext {
font-weight: 400;
max-width: 500rpx;
padding-right: 24rpx;
padding-top: 24rpx;
padding-bottom: 24rpx;
font-size: 30rpx;
text-align: left;
color: #000000;
display: inline-block;
margin: auto;
/* line-height: 82rpx; */
margin-left: 24rpx;
word-break: break-all;
}
.mymessage {
max-width: 500rpx;
/* width: 168rpx; */
/* height: 82rpx; */
border-radius: 12rpx 12rpx 12rpx 12rpx;
background: #3477fc;
}
.mymessagetext {
font-weight: 400;
max-width: 500rpx;
padding-right: 24rpx;
padding-top: 24rpx;
padding-bottom: 24rpx;
font-size: 30rpx;
text-align: left;
color: #FFFFFF;
/* float: right; */
display: inline-block;
margin: auto;
/* line-height: 82rpx; */
margin-left: 24rpx;
}
.content {
height: 100%;
width: 100%;
display: flex;
align-items: center;
flex-direction: column;
}
.header_are {
min-height: 50rpx;
width: 100%;
background-color: #999999;
z-index: 100;
}
.middle_area {
width: 100%;
height: 200rpx;
flex-grow: 1;
}
.bottom_area {
width: 100%;
min-height: 100rpx;
background-color: #fff;
}
.funcBox {
width: 200rpx;
padding: 24rpx;
background-color: rgba(0, 0, 0, .6);
color: #fff;
border-radius: 14rpx;
display: flex;
justify-content: space-between;
margin-left: 116rpx;
}
.funcBoxT{
width: 300rpx;
margin-left: 334rpx;
}
</style>