361 lines
11 KiB
Vue
361 lines
11 KiB
Vue
<template>
|
|
<!-- 消息页面 -->
|
|
<div style="display: flex; flex-direction: column; height: 100vh">
|
|
<div style="width: 100%; background-color: #f5f5f5">
|
|
<Header class="wapper" />
|
|
</div>
|
|
<div class="container">
|
|
<div class="message-left">
|
|
<el-card style="width: 100%; height: 100%">
|
|
<h2>聊天列表</h2>
|
|
|
|
<div
|
|
class="user-list"
|
|
v-for="item in messageList"
|
|
:key="item.uuid"
|
|
@click="onClickMessage(item)"
|
|
>
|
|
<div>
|
|
<el-avatar :size="40" @error="errorHandler">
|
|
<img
|
|
src="https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg"
|
|
/>
|
|
</el-avatar>
|
|
</div>
|
|
|
|
<div class="message-info">
|
|
<div>
|
|
{{
|
|
myCompanyId == item.toCompany
|
|
? item.fromCompanyName || '系统通知'
|
|
: item.toCompanyName
|
|
}}
|
|
</div>
|
|
<div>
|
|
<span>
|
|
{{ item.messageContent }}
|
|
</span>
|
|
<div>
|
|
<el-badge is-dot class="item" v-if="item.isRead != 1" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
</div>
|
|
|
|
<div class="message-box">
|
|
<h2>{{ rightCompanyName }}</h2>
|
|
|
|
<div class="message-info-list">
|
|
<div class="message-content" v-for="item in messageDetails" :key="item.uuid">
|
|
<div
|
|
class="message-info-right"
|
|
:key="item"
|
|
v-if="myCompanyId == item.fromCompany"
|
|
>
|
|
<div class="message-items">{{ item.messageContent }}</div>
|
|
<div>
|
|
<el-avatar :size="40" @error="errorHandler">
|
|
<img
|
|
src="https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg"
|
|
/>
|
|
</el-avatar>
|
|
</div>
|
|
</div>
|
|
<div class="message-info" v-else>
|
|
<div>
|
|
<el-avatar :size="40" @error="errorHandler">
|
|
<img
|
|
src="https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg"
|
|
/>
|
|
</el-avatar>
|
|
</div>
|
|
<div class="message-items">{{ item.messageContent }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="message-send">
|
|
<el-input
|
|
v-model="sendParams.messageContent"
|
|
style="width: 88%; margin-right: 16px"
|
|
:autosize="{ minRows: 2, maxRows: 30 }"
|
|
type="textarea"
|
|
/>
|
|
<el-icon
|
|
size="36"
|
|
color="#00a288"
|
|
style="cursor: pointer"
|
|
@click="onSendMessage"
|
|
>
|
|
<Promotion />
|
|
</el-icon>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<FooterInfo />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import Header from 'components/header/index.vue'
|
|
import FooterInfo from 'components/FooterInfo/index.vue'
|
|
import {
|
|
getMessageListApi,
|
|
getMessageInfoApi,
|
|
sendMessageApi,
|
|
messageIsReadApi,
|
|
messageHistoryApi,
|
|
getMessageListAllApi,
|
|
isReadMessageAPI,
|
|
} from 'http/api/message/index'
|
|
import { mainStore } from 'store/main'
|
|
import { debounce } from 'lodash-es'
|
|
import { useRoute } from 'vue-router'
|
|
import { ElMessage } from 'element-plus'
|
|
const myCompanyId = ref('')
|
|
const queryDetailsCompanyId = ref('')
|
|
const rightCompanyName = ref('')
|
|
const store: any = mainStore()
|
|
const route = useRoute()
|
|
const messageList = ref<any>([])
|
|
const messageListAll = ref<any>([])
|
|
const messageDetails = ref<any>([])
|
|
const messageInterval = ref<any>(null)
|
|
const messageListInterval = ref<any>(null)
|
|
const sendParams = ref<any>({
|
|
toUser: '',
|
|
toCompany: '',
|
|
messageContent: '',
|
|
toCompanyName: '',
|
|
fromCompanyName: '',
|
|
})
|
|
|
|
// 消息列表
|
|
const getMessageListData = async () => {
|
|
const { data: res }: any = await getMessageListApi()
|
|
// messageList.value = [...new Set([...messageListAll.value, ...res])]
|
|
const uniqueMessages = [
|
|
...new Map([...res, ...messageListAll.value].map((item) => [item.uuid, item])).values(),
|
|
]
|
|
|
|
messageList.value = uniqueMessages
|
|
}
|
|
|
|
const getMessageListAllData = async () => {
|
|
const { data: res }: any = await getMessageListAllApi()
|
|
messageListAll.value = res
|
|
// console.log(res, '历史记录')
|
|
}
|
|
|
|
// 消息详情
|
|
const getMessageInfoData = async (toCompany: any) => {
|
|
const { data: res }: any = await getMessageInfoApi({ toCompany })
|
|
messageDetails.value = res
|
|
}
|
|
|
|
// 历史消息
|
|
const getMessageHistoryData = async (fromCompany: any) => {
|
|
const { data: res }: any = await messageHistoryApi({ fromCompany })
|
|
console.log(res, '历史记录---')
|
|
// messageDetails.value = res
|
|
}
|
|
|
|
// 消息已读
|
|
const isReadMessageData = async (toCompany: any, fromCompany: any) => {
|
|
const isReadParams = {
|
|
toCompany,
|
|
fromCompany,
|
|
}
|
|
const res = await isReadMessageAPI(isReadParams)
|
|
}
|
|
|
|
// 消息点击
|
|
const onClickMessage = async (item: any) => {
|
|
const { toCompany, fromCompany, toCompanyName, fromCompanyName, toUser, fromUser } = item
|
|
const isForm = myCompanyId.value == fromCompany
|
|
rightCompanyName.value = isForm ? toCompanyName : fromCompanyName
|
|
sendParams.value.toUser = isForm ? toUser : fromUser
|
|
sendParams.value.toCompany = isForm ? toCompany : fromCompany
|
|
sendParams.value.toCompanyName = isForm ? toCompanyName : fromCompanyName
|
|
queryDetailsCompanyId.value = isForm ? toCompany : fromCompany
|
|
|
|
const res: any = await messageIsReadApi({
|
|
toCompany: myCompanyId.value,
|
|
fromCompany: queryDetailsCompanyId.value,
|
|
})
|
|
|
|
// console.log(res, '已读结果--')
|
|
|
|
getMessageInfoData(queryDetailsCompanyId.value)
|
|
|
|
// console.log(res, '消息已读')
|
|
if (!messageInterval.value) {
|
|
messageInterval.value = setInterval(() => {
|
|
getMessageInfoData(queryDetailsCompanyId.value)
|
|
// getMessageHistoryData(queryDetailsCompanyId.value)
|
|
}, 5000)
|
|
}
|
|
}
|
|
// 点击发送
|
|
const onSendMessage = debounce(async () => {
|
|
sendParams.value.fromCompanyName = localStorage.getItem('currentCompanyName')
|
|
const res: any = await sendMessageApi(sendParams.value)
|
|
if (res.code == 200) {
|
|
sendParams.value.messageContent = ''
|
|
|
|
const result: any = await messageIsReadApi({
|
|
toCompany: myCompanyId.value,
|
|
fromCompany: queryDetailsCompanyId.value,
|
|
})
|
|
}
|
|
}, 500)
|
|
const errorHandler = () => true
|
|
onMounted(() => {
|
|
Promise.all([getMessageListAllData()]).then(() => {
|
|
getMessageListData()
|
|
})
|
|
|
|
if (route.query && route.query.companyId) {
|
|
const { companyId, companyName, ownId }: any = route.query
|
|
rightCompanyName.value = companyName
|
|
sendParams.value.toUser = ownId
|
|
sendParams.value.toCompany = companyId
|
|
sendParams.value.toCompanyName = companyName
|
|
queryDetailsCompanyId.value = companyId
|
|
getMessageInfoData(queryDetailsCompanyId.value)
|
|
|
|
setTimeout(() => {
|
|
messageInterval.value = setInterval(() => {
|
|
getMessageInfoData(queryDetailsCompanyId.value)
|
|
}, 5000)
|
|
}, 3000)
|
|
}
|
|
myCompanyId.value = store.userInfo.companyId
|
|
|
|
setTimeout(() => {
|
|
messageListInterval.value = setInterval(() => {
|
|
getMessageListAllData()
|
|
getMessageListData()
|
|
}, 5000)
|
|
}, 3000)
|
|
})
|
|
|
|
onBeforeMount(() => {
|
|
if (messageInterval.value) {
|
|
clearInterval(messageInterval.value)
|
|
messageInterval.value = null
|
|
}
|
|
if (messageListInterval.value) {
|
|
clearInterval(messageListInterval.value)
|
|
messageListInterval.value = null
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.container {
|
|
width: 1552px;
|
|
margin: 15px auto;
|
|
flex: 1;
|
|
display: flex;
|
|
background: #eeeff6;
|
|
font-size: 16px;
|
|
padding: 20px 10px;
|
|
background-color: #fff;
|
|
border-radius: 15px;
|
|
h2 {
|
|
margin-bottom: 16px;
|
|
font-size: 18px;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.message-left {
|
|
width: 30%;
|
|
|
|
.user-list {
|
|
padding: 10px;
|
|
display: flex;
|
|
align-items: center;
|
|
border-bottom: 1px solid #ccc;
|
|
cursor: pointer;
|
|
|
|
.message-info {
|
|
padding-left: 10px;
|
|
width: 100%;
|
|
div {
|
|
padding: 8px 0;
|
|
}
|
|
& div:first-child {
|
|
font-size: 16px;
|
|
font-weight: bold;
|
|
}
|
|
& div:last-child {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.message-box {
|
|
flex: 1;
|
|
height: 100%;
|
|
padding-left: 50px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
|
|
h2 {
|
|
padding: 18px 0;
|
|
border-bottom: 1px solid #cccc;
|
|
}
|
|
|
|
.message-info-list {
|
|
flex: 1;
|
|
// max-height: 500px;
|
|
overflow-y: auto !important;
|
|
}
|
|
|
|
// .message-content {
|
|
// }
|
|
|
|
.message-send {
|
|
min-height: 100px;
|
|
padding: 10px 30px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-top: 1px solid #ccc;
|
|
}
|
|
|
|
.message-info,
|
|
.message-info-right {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-top: 10px;
|
|
padding: 0 15px;
|
|
|
|
.message-items {
|
|
display: inline-block;
|
|
width: auto;
|
|
margin-left: 12px;
|
|
padding: 10px 12px;
|
|
background-color: #fff;
|
|
box-shadow: 0 1px 2px 1px rgba(0, 0, 0, 0.1);
|
|
}
|
|
}
|
|
|
|
.message-info-right {
|
|
justify-content: flex-end;
|
|
|
|
.message-items {
|
|
margin-right: 12px !important;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|