166 lines
4.3 KiB
Vue
166 lines
4.3 KiB
Vue
<template>
|
|
<view class="page">
|
|
<BackBar title="沟通" />
|
|
<view v-if="list.length" class="card">
|
|
<view v-for="item of list" :key="item.id" class="item" @click="toDetails(item)">
|
|
<view class="left">
|
|
<wd-badge :modelValue="item.unreadCount" :max="99" :right="8" :top="4" :hidden="false">
|
|
<wd-img
|
|
width="90rpx"
|
|
height="90rpx"
|
|
round
|
|
:src="item.avatarUrl || defaultAvatar"
|
|
></wd-img>
|
|
</wd-badge>
|
|
</view>
|
|
<view class="right">
|
|
<view class="right-top">
|
|
<view class="name">{{ item.nickName }}</view>
|
|
<view class="date">{{ formatDate(item.createTime) }}</view>
|
|
</view>
|
|
<view class="info">
|
|
{{ item.messageContent }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<wd-loadmore custom-class="loadmore" :state="state" @reload="loadmore" />
|
|
</view>
|
|
<Empty v-else content="暂无消息哦~" />
|
|
</view>
|
|
</template>
|
|
<script setup lang="ts">
|
|
import { onShow } from '@dcloudio/uni-app'
|
|
import { ref, onMounted, watch } from 'vue'
|
|
import dayjs from 'dayjs'
|
|
import { getTalkList } from '@/api/modules/inspector'
|
|
import Empty from '@/components/Empty/index.vue'
|
|
import { formatDate, getCache } from '@/utils'
|
|
const OSS_URL = import.meta.env.VITE_OSS_HOST
|
|
const defaultAvatar = `${OSS_URL}/urm/default_avatar.png`
|
|
const list = ref<any[]>([])
|
|
const state = ref<string>('loading')
|
|
import { useSocket } from '@/hooks/useSocket'
|
|
import db from '@/utils/db'
|
|
const current = ref(1)
|
|
const userInfo = ref<anyObj>({})
|
|
const { init: socketInit, inspectorMessage } = useSocket()
|
|
async function getTalkData() {
|
|
try {
|
|
uni.showLoading({
|
|
title: '加载中...',
|
|
})
|
|
const { code, data } = await getTalkList({ current: current.value })
|
|
uni.hideLoading()
|
|
if (code === 200) {
|
|
list.value = data.rows
|
|
if (data.rows.length < 10) {
|
|
state.value = 'finished'
|
|
}
|
|
}
|
|
} catch (error) {}
|
|
}
|
|
// 详情
|
|
function toDetails(row: anyObj) {
|
|
uni.setStorageSync('stu', row)
|
|
uni.navigateTo({
|
|
url: '/pages/inspector/chat/chatDetails',
|
|
})
|
|
}
|
|
function loadmore() {
|
|
current.value++
|
|
getTalkData()
|
|
}
|
|
watch(
|
|
inspectorMessage,
|
|
msg => {
|
|
if (!msg) return
|
|
const index = list.value.findIndex(e => e.senderId === msg.senderId)
|
|
if (index !== -1) {
|
|
list.value[index].messageContent = msg.messageContent
|
|
list.value[index].createTime = msg.createTime
|
|
? msg.createTime
|
|
: dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss')
|
|
list.value[index].unreadCount++
|
|
} else {
|
|
const newMsg = {
|
|
messageContent: msg.messageContent,
|
|
createTime: msg.createTime,
|
|
unreadCount: 1,
|
|
avatarUrl: msg.avatarUrl || defaultAvatar,
|
|
}
|
|
list.value.unshift(newMsg)
|
|
}
|
|
if (msg.senderId === userInfo.value.userId) {
|
|
//
|
|
}
|
|
},
|
|
{
|
|
immediate: true,
|
|
deep: true,
|
|
},
|
|
)
|
|
onShow(() => {
|
|
getTalkData()
|
|
})
|
|
onMounted(() => {
|
|
// userInfo.value = uni.getStorageSync('QY_USERINFO');
|
|
userInfo.value = db.get('dxs_userInfo')
|
|
socketInit()
|
|
})
|
|
</script>
|
|
<style lang="scss" scoped>
|
|
.page {
|
|
padding: 0 30rpx 30rpx 30rpx;
|
|
box-sizing: border-box;
|
|
.card {
|
|
margin-top: 30rpx;
|
|
width: 690rpx;
|
|
padding: 30rpx;
|
|
box-sizing: border-box;
|
|
border-radius: 20rpx;
|
|
background-color: #fff;
|
|
.item {
|
|
box-sizing: border-box;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
.right {
|
|
width: 520rpx;
|
|
.right-top {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
.name {
|
|
color: #0a1f13;
|
|
font-size: 32rpx;
|
|
line-height: 48rpx;
|
|
font-weight: 600;
|
|
}
|
|
.date {
|
|
color: #a9aab5;
|
|
font-size: 24rpx;
|
|
line-height: 36rpx;
|
|
}
|
|
}
|
|
.info {
|
|
margin-top: 6rpx;
|
|
text-overflow: ellipsis;
|
|
overflow: hidden;
|
|
white-space: nowrap;
|
|
font-size: 26rpx;
|
|
color: #a9aab5;
|
|
line-height: 36rpx;
|
|
}
|
|
}
|
|
}
|
|
.item:not(:last-child) {
|
|
padding-bottom: 30rpx;
|
|
border-bottom: 1rpx solid #f6f6f6;
|
|
}
|
|
.item:not(:first-child) {
|
|
padding-top: 30rpx;
|
|
}
|
|
}
|
|
}
|
|
</style>
|