2025-09-29

聊天记录上拉获取记录
This commit is contained in:
2025-10-09 15:13:48 +08:00
parent 22c4b5d4d5
commit 039111ed27
14 changed files with 445 additions and 122 deletions

View File

@@ -1,9 +1,9 @@
<template>
<view class="chat-container">
<u-navbar title="聊天" id="navBarId" :background="{background: 'transparent' }" :border-bottom="false"
<u-navbar :title="chatTitle" id="navBarId" :background="{background: 'transparent' }" :border-bottom="false"
back-icon-color="#000" title-color="#000">
<template v-slot:right>
<image class="collection" src="/static/icon/Bookmark.png" mode=""></image>
<image class="collection" src="/static/icon/More horizontal.png" mode=""></image>
</template>
</u-navbar>
@@ -37,11 +37,16 @@
<view v-for="(item, index) in dataList">
<view v-if="item.createId==userId" class="my-message">
<view class="msg-main">
<!-- 消息内容 -->
<view class="msg-content" v-if="item.type=='text'">
<view class="text">
{{item.content}}
</view>
<view>
{{handleFormatDate(item.createTime)}}
</view>
</view>
<!-- 录音内容 -->
<view class="mp3-content" v-if="item.type=='mp3'">
<view class="mp3" @click="handlePlayMp3(item.content)">
<view class="mp3-icon">
@@ -51,9 +56,13 @@
点击播放
</view>
</view>
<!-- 图片内容 -->
<view class="img-content" v-if="item.type=='img'">
<u-image @click="handlePreView(item.content)" height="100%" :src="item.content"
:lazy-load="true" mode="heightFix"></u-image>
<view>
{{handleFormatDate(item.createTime)}}
</view>
</view>
<!-- 头像 -->
<view class="msg-avatar">
@@ -65,15 +74,38 @@
</view>
<view v-else class="other-message">
<view class="msg-main">
<!-- 对方头像 -->
<view class="msg-avatar">
<image style="width: 100%;height: 100%;" :src="getImageUrl(item.userInfo.avatar)"
mode="">
</image>
</view>
<view class="msg-content">
<!-- 对方文本 -->
<view class="msg-content" v-if="item.type=='text'">
<view class="text">
{{item.content}}
</view>
<view>
{{handleFormatDate(item.createTime)}}
</view>
</view>
<!-- 对方录音-->
<view class="mp3-content" v-if="item.type=='mp3'">
<view class="mp3" @click="handlePlayMp3(item.content)">
<view class="mp3-icon">
<image style="width: 100%;height: 100%;" src="/static/icon/listen.png" mode="">
</image>
</view>
点击播放
</view>
</view>
<!-- 图片内容 -->
<view class="img-content" v-if="item.type=='img'">
<u-image @click="handlePreView(item.content)" height="100%" :src="item.content"
:lazy-load="true" mode="heightFix"></u-image>
<view>
{{handleFormatDate(item.createTime)}}
</view>
</view>
</view>
</view>
@@ -119,11 +151,13 @@
<script setup lang="ts">
import { onMounted, ref, getCurrentInstance, onBeforeMount, nextTick } from 'vue';
import {
onLoad, onLaunch
onLoad, onLaunch, onReady, onUnload, onPullDownRefresh
} from "@dcloudio/uni-app";
import io from '@hyoga/uni-socket.io';
import { getImageUrl } from '../../util/common';
import { permissionUtil } from '@/uni_modules/colorful-uni-perm';
import { messageAPI } from '../../api/message';
import { groupAPI } from '../../api/group';
const navBarRef = ref()
const instance = getCurrentInstance();
@@ -141,16 +175,55 @@
}
})
}
const handleFormatDate = (date) => {
const inputDate = new Date(date.replace(/-/g, '/'));
const now = new Date();
// 计算日期差(天)
const diffDays = Math.floor((now - inputDate) / (1000 * 60 * 60 * 24));
// 格式化时间
const hours = inputDate.getHours().toString().padStart(2, '0');
const minutes = inputDate.getMinutes().toString().padStart(2, '0');
const year = inputDate.getFullYear();
const month = (inputDate.getMonth() + 1).toString().padStart(2, '0');
const day = inputDate.getDate().toString().padStart(2, '0');
if (diffDays === 0) {
return `今天 ${hours}:${minutes}`;
} else if (diffDays === 1) {
return '昨天';
} else {
return `${year}-${month}-${day}`;
}
}
const dataList = ref([])
// 模拟聊天数据
const mockData = () => {
for (var i = 0; i < 5; i++) {
if (i % 2 == 0) {
dataList.value.push({
"createId": 3641,
"groupId": "1",
"content": "即使在没有空格的地方也 ",
"content": "即使在没有空格的地方也即使在没有空格的地方也即使在没有空格的地方也即使在没有空格的地方也即使在没有空格的地方也即使在没有空格的地方也即使在没有空格的地方也即使在没有空格的地方",
"type": "text",
"messageId": 44,
"createTime": "2025-09-27T18:32:42.000Z",
"userInfo": {
"id": 9958,
"username": "15867461647",
"userType": "user",
"isSystemAccount": 0,
"avatar": "/uploads/documents/1753833656669_524106424.jpg"
}
})
dataList.value.push({
"createId": 3641,
"groupId": "1",
"content": "即使在没有空格的地方也即使在没",
"type": "text",
"messageId": 44,
"createTime": "2025-09-27T18:32:42.000Z",
@@ -179,41 +252,42 @@
}
})
}
dataList.value.push(
{
"createId": 3641,
"groupId": "5",
"content": "http://114.55.111.44:9000/jurongquan/app_records/1759049412254.mp3",
"type": "mp3",
"messageId": 56,
"createTime": "2025-09-28T00:50:16.000Z",
"userInfo": {
"id": 3641,
"username": "15867461617",
"userType": "agent",
"isSystemAccount": 0,
"avatar": "/uploads/documents/1753833656669_524106424.jpg"
}
})
dataList.value.push(
{
"createId": 3641,
"groupId": "5",
"content": "http://114.55.111.44:9000/jurongquan/app_records/1759110192420_Screenshot_20250929_084636_com.bilibili.star.bili.jpg",
"type": "img",
"messageId": 62,
"createTime": "2025-09-28T17:43:13.000Z",
"userInfo": {
"id": 3641,
"username": "15867461617",
"userType": "agent",
"isSystemAccount": 0,
"avatar": "/uploads/documents/1753833656669_524106424.jpg"
}
})
}
dataList.value.push(
{
"createId": 3641,
"groupId": "5",
"content": "http://114.55.111.44:9000/jurongquan/app_records/1759049412254.mp3",
"type": "mp3",
"messageId": 56,
"createTime": "2025-09-28T00:50:16.000Z",
"userInfo": {
"id": 3641,
"username": "15867461617",
"userType": "agent",
"isSystemAccount": 0,
"avatar": "/uploads/documents/1753833656669_524106424.jpg"
}
})
dataList.value.push(
{
"createId": 3641,
"groupId": "5",
"content": "http://114.55.111.44:9000/jurongquan/app_records/1759110192420_Screenshot_20250929_084636_com.bilibili.star.bili.jpg",
"type": "img",
"messageId": 62,
"createTime": "2025-09-28T17:43:13.000Z",
"userInfo": {
"id": 3641,
"username": "15867461617",
"userType": "agent",
"isSystemAccount": 0,
"avatar": "/uploads/documents/1753833656669_524106424.jpg"
}
})
}
// 发送消息
@@ -433,38 +507,47 @@
});
}
// 初始化
const groupId = ref()
const userId = ref()
const chatTitle = ref()
onLoad((val) => {
groupId.value = val.groupId
});
const scrollTop = ref(0)
const socket = ref()
// 通信连接
const connection = () => {
socket.value = io('http://192.168.0.15:3007', {
const socket = ref()
const connection = async () => {
console.log("连接服务器");
socket.value = io(`http://192.168.0.15:3007?userId=${userId.value}`, {
query: {},
transports: ['websocket', 'polling'],
timeout: 5000,
});
socket.value.on('connect', async () => {
socket.value.on('connect', () => {
console.log("连接成功");
})
socket.value.emit('addGroup', {
groupId: groupId.value,
})
socket.value.on('serverMsg', async (message:any) => {
dataList.value.push(message)
// console.log(dataList.value);
setTimeout(()=>{
scrollToBottom()
}, 500)
// socket.value.emit('cleanup')
socket.value.emit('addGroup', {
groupId: groupId.value
})
socket.value.on('serverMsg', async (message : any) => {
dataList.value.push(message)
// console.log(dataList.value);
setTimeout(() => {
scrollToBottom()
}, 500)
})
})
}
const scrollTop = ref(0)
const disConnection = () => {
console.log("disConnection");
socket.value.emit('leaveGroup', {
groupId: groupId.value
})
}
const scrollToBottom = () => {
uni.createSelectorQuery().in(this).select("#scroll-main").boundingClientRect((res : any) => {
@@ -475,17 +558,69 @@
}).exec()
}
const loadData = () => {
const loadUnReadData = () => {
// 获取用户ID
userId.value = uni.getStorageSync("user").id
// 获取标题
groupAPI.getById(groupId.value).then(res => {
chatTitle.value = res.data.program.linkman.username + "(" + res.data.program.name + ")"
})
// 未读变已读
let data = { groupId: groupId.value, userId: userId.value }
messageAPI.unread(data).then(res => {
if (res.code == 200) {
dataList.value = dataList.value.concat(res.data)
}
})
messageAPI.read({ groupId: groupId.value, userId: userId.value })
}
onMounted(() => {
// mockData()
loadData()
const params = ref({
page: 1,
size: 10,
groupId: null
})
const loadFix = ref(true)
// 历史记录
const loadHistoryData = () => {
params.value.groupId = groupId.value
messageAPI.list(params.value).then(res => {
console.log(res);
if (res.data.list.length != 0) {
res.data.list.forEach(item => {
dataList.value.unshift(item)
})
params.value.page++
}
})
}
onPullDownRefresh(() => {
loadHistoryData()
uni.stopPullDownRefresh()
})
onLoad((val) => {
groupId.value = val.groupId
});
onReady(() => {
})
onMounted(() => {
loadHeight()
// mockData()
loadUnReadData()
connection()
})
onUnload(() => {
disConnection()
})
</script>
<style scoped lang="scss">
@@ -553,6 +688,14 @@
.text {
overflow-wrap: break-word;
text-align: right;
background-color: #4873FF;
display: block;
padding: 10rpx;
color: #fff;
box-shadow: 0rpx 4rpx 8rpx 0rpx #00000040;
}
}
@@ -568,11 +711,11 @@
// border: 1rpx solid #000;
padding: 15rpx 10rpx;
background-color: #55ff7f;
justify-content: flex-end;
align-items: center;
justify-content: flex-start;
// align-items: center;
.mp3-icon {
margin: 0 10rpx;
// margin: 0 10rpx;
width: 25rpx;
height: 25rpx;
}
@@ -582,6 +725,7 @@
.img-content {
margin-right: 10rpx;
height: 200rpx;
margin-bottom: 30rpx;
}
.msg-avatar {
@@ -599,24 +743,58 @@
justify-content: flex-start;
padding: 0 10rpx;
.msg-avatar {
width: 80rpx;
height: 80rpx;
}
.msg-content {
// background-color: #00ffff;
padding: 2rpx;
width: 70%;
margin-left: 10rpx;
// border: 1rpx solid #c7c7c7;
box-sizing: content-box;
.text {
overflow-wrap: break-word;
text-align: left;
background-color: #F0F3FF;
display: block;
padding: 10rpx;
box-shadow: 0rpx 4rpx 8rpx 0rpx #00000040;
}
}
.msg-avatar {
width: 80rpx;
height: 80rpx;
margin-right: 10rpx;
.mp3-content {
padding: 2rpx;
// width: 70%;
margin-left: 10rpx;
box-sizing: content-box;
.mp3 {
display: flex;
// border: 1rpx solid #000;
padding: 15rpx 10rpx;
background-color: #55ff7f;
justify-content: flex-start;
align-items: center;
.mp3-icon {
margin: 0 10rpx;
width: 25rpx;
height: 25rpx;
}
}
}
.img-content {
margin-left: 10rpx;
height: 200rpx;
}
}
}
}