middleground_code_v2/src/views/newVersionView/message/index.vue

614 lines
16 KiB
Vue

<template>
<div class="messageContainer">
<div class="messageLeft">
<div class="leftMessageTitle">消息</div>
<div class="leftMessageBox">
<div
v-for="(item, index) in leftMessgaeData"
:key="index"
class="leftMessageItem"
:class="currentIndex == index ? 'activeLeftMessage' : ''"
@click="leftMessageClickEvent(item, index)"
>
<img
class="messageLeftIcon"
:src="item.appIcon"
v-if="item.appIcon"
/>
<img class="messageLeftIcon" src="../logo1.png" v-else />
<div class="messageLeftItemBox">
<div class="messageLeftContent">{{ item.name }}</div>
<div class="messageLeftCount" v-if="item.newMessageCount > 0">
{{ item.newMessageCount > 100 ? "99+" : item.newMessageCount }}
</div>
</div>
</div>
</div>
</div>
<div class="messageRight">
<div class="rightMessageTitle">审批消息</div>
<div v-if="isShowScroll" @click="scrollToFirstCard" class="scrollTopTip">
<i class="el-icon-d-arrow-left scrollTopIcon"></i>
{{ rightMessgaeData.newData.length }}条最新消息
</div>
<div
class="rigthMessageBox"
id="container"
ref="container"
@scroll="handleScroll"
>
<div
v-if="
rightMessgaeData.newData.length == 0 &&
rightMessgaeData.oldData.length == 0
"
class="rightEmpty"
>
<el-empty :image-size="200"></el-empty>
</div>
<div v-else>
<div
v-if="rightMessgaeData.oldData.length == oldTotal && oldTotal > 0"
style="padding: 10px 0"
ref="dividerNew"
>
<el-divider>没有更多了</el-divider>
</div>
<div
v-for="(oldItem, oldIndex) in rightMessgaeData.oldData"
:key="`oldIndex${oldIndex}`"
class="item"
ref="oldMessage"
>
<div class="itemAvatar">
<img
:src="currntAppImg"
v-if="currntAppImg"
/>
<img src="../logo1.png" v-else />
</div>
<div class="itemBox">
<div class="itemBoxTitle">
{{ oldItem.appName }}
</div>
<div class="box">
<div class="item-title">
<div v-html="oldItem.messageTitle" style="display: flex"></div>
<div>推送时间:{{ oldItem.sendDatetime }}</div>
</div>
<div class="item-content">
<div v-html="oldItem.sendCount"></div>
</div>
</div>
</div>
</div>
<div
v-if="rightMessgaeData.newData.length > 0"
style="padding: 10px 0"
ref="dividerNew"
>
<el-divider>以下是最新消息</el-divider>
</div>
<div
v-for="(newItem, newIndex) in rightMessgaeData.newData"
:key="newIndex"
class="item"
ref="lastNewData"
>
<div class="itemAvatar">
<img
:src="currntAppImg"
v-if="currntAppImg"
/>
<img src="../logo1.png" v-else />
</div>
<div class="itemBox">
<div class="itemBoxTitle">{{ newItem.appName }}</div>
<div class="box">
<div class="item-title">
<div v-html="newItem.messageTitle" style="display: flex"></div>
<div>推送时间:{{ newItem.sendDatetime }}</div>
</div>
<div class="item-content">
<div v-html="newItem.sendCount"></div>
</div>
<div class="item-btns">
<!-- <div v-for="(btnList,btnIndex) in JSON.parse(newItem.btns)">
{{111}}
</div> -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { getApiModuleApi } from "@/api/apiChunks/index.js";
import request from '@/utils/request'
export default {
data() {
return {
leftMessgaeData: [],
currentIndex: null,
rightMessgaeData: {
newData: [],
oldData: [],
},
pageModel: {
pageNum: 1,
pageSize: 10,
},
oldTotal: 0,
firstCardOffsetTop: null,
cardContainerScrollTop: null,
isShowScroll: false,
currentBottomScrollTo: null,
firstLoad: true,
currntAppImg:null
};
},
filters: {
timeDate(row) {
if (!row) {
return;
}
return row.replace("T", " ").slice(0, 19);
},
},
mounted() {
// 初始滚动到最底部
this.scrollToBottom();
this.GetMessageCount();
},
methods: {
// 最新消息被点击
scrollToFirstCard() {
this.$nextTick(() => {
this.isShowScroll = false;
const firstCard = this.$refs["lastNewData"][0];
const cardContainer = this.$refs.container;
const dividerNew = this.$refs.dividerNew;
if (firstCard && cardContainer) {
this.$refs.container.scrollTo(
0,
firstCard.offsetTop -
cardContainer.offsetTop -
dividerNew.offsetHeight -
100
); // 滚动到当前位置
}
});
},
scrollToBottom() {
this.$nextTick(() => {
this.$refs.container.scrollTop = this.$refs.container.scrollHeight;
this.currentBottomScrollTo = this.$refs.container.scrollTop;
});
},
handleScroll() {
const container = this.$refs.container;
// 检查是否滚动到顶部
if (container.scrollTop === 0 && !this.firstLoad) {
if (this.pageModel.pageNum * this.pageModel.pageSize <= this.oldTotal) {
this.pageModel.pageNum++;
this.GetOldMessageList("page");
}
} else {
if (this.rightMessgaeData.newData.length > 5) {
let height = 0;
for (let i = 0; i < 5; i++) {
height += this.$refs["lastNewData"][i].offsetHeight;
}
if (container.scrollTop <= container.clientHeight) {
this.isShowScroll = false;
}
if (container.scrollTop <= this.currentBottomScrollTo - height) {
this.isShowScroll = false;
}
}
}
this.firstLoad = false;
},
async GetMessageCount() {
let that = this
const res = await getApiModuleApi(
{
tl: "sysWarningInterfaceService",
as: "",
dj: "queryWarningAppList",
},
{}
);
if (res.status == "200") {
this.leftMessgaeData = res.attribute ? res.attribute : [];
let count = 0;
res.attribute.forEach((item) => {
count += item.newMessageCount * 1;
that.$set(item, "appIcon", null);
if (item.appLogo) {
that.getLogoUrl(item.appLogo).then((res) => {
let imageUrl =
"data:image/png/jpg;base64," +
btoa(
new Uint8Array(res).reduce(
(data, byte) => data + String.fromCharCode(byte),
""
)
);
that.$set(item, "appIcon", imageUrl);
});
}
});
this.$store.commit("SET_MESSAGE_COUNT", count);
}
},
getLogoUrl(id) {
return request({
url:
"/kangarooDataCenterV3/entranceController/fileDownloadNew?id=" + id,
method: "get",
responseType: "arraybuffer",
}).then((res) => {
return res;
});
},
leftMessageClickEvent(item, index) {
this.currentIndex = index;
this.currentBillKindID = item.id;
this.currntAppImg = item.appIcon
this.rightMessgaeData.newData = [];
this.rightMessgaeData.oldData = [];
this.isShowScroll = false;
this.pageModel.pageNum = 1;
this.firstLoad = true;
this.scrollToBottom();
this.GetOldMessageList("", item);
},
async GetNewMessageList(item) {
let params = {
state: "0", //未读
appId: this.currentBillKindID,
};
const res = await getApiModuleApi(
{
tl: "sysSendMessageLogService",
as: "",
dj: "queryEntity",
},
{
...params
}
);
if (res.status == "200") {
this.ReadMessage(item);
let data = res.attribute ? res.attribute : [];
// 按时间升序排序
data.sort(function (a, b) {
return new Date(a.sendDatetime) - new Date(b.sendDatetime);
});
if (data.length > 5) {
this.isShowScroll = true;
}
this.rightMessgaeData.newData = data;
this.scrollToBottom();
}
},
async ReadMessage(item) {
const res = await getApiModuleApi(
{
tl: "sysSendMessageLogService",
as: "",
dj: "markRead",
},
{
appId: this.currentBillKindID, //应用id
state: "0", //未读
}
);
if (res.status == "200") {
this.$set(item, "newMessageCount", 0);
let count = 0;
this.leftMessgaeData.forEach((item) => {
count += item.newMessageCount * 1;
});
this.$store.commit("SET_MESSAGE_COUNT", count);
}
},
async GetOldMessageList(type, item) {
let params = {
...this.pageModel,
billKindID: this.currentBillKindID,
};
const res = await getApiModuleApi(
{
tl: "sysSendMessageLogService",
as: "",
dj: "queryEntityPage",
},
{
...this.pageModel,
appId: this.currentBillKindID, //应用id
state: "1", //未读
}
);
if (res.status == "200") {
this.oldTotal = res.attribute.total;
let allData = JSON.parse(JSON.stringify(this.rightMessgaeData.oldData));
if (type == "page") {
// 先删除原有标记位置
allData.forEach((item) => {
delete item.MarkPosition;
});
// 给第一条数据打标记
if (allData.length > 1) {
allData[0].MarkPosition = true;
}
}
let data = res.attribute.list ? res.attribute.list : [];
allData.push(...data);
// 按时间升序排序
allData.sort(function (a, b) {
return new Date(a.sendDatetime) - new Date(b.sendDatetime);
});
this.rightMessgaeData.oldData = allData;
this.$nextTick(() => {
if (type == "page") {
let index = this.rightMessgaeData.oldData.findIndex(
(item) => item.MarkPosition
);
if (index >= 0) {
this.$refs.container.scrollTo(
0,
this.$refs["oldMessage"][index].offsetTop
); // 滚动到当前位置
}
} else {
this.$nextTick(() => {
this.scrollToBottom();
this.GetNewMessageList(item);
});
}
});
}
},
},
};
</script>
<style lang="scss" scoped>
::v-deep .el-divider__text {
color: #909399;
font-size: 12px;
}
.messageContainer {
height: 100vh !important;
display: flex;
}
/* 左侧应用消息样式 */
.messageLeft {
width: 278px;
height: 100%;
overflow-y: auto;
background: #fafafa;
padding: 15px;
.leftMessageTitle {
font-size: 18px;
font-weight: 500;
color: #333333;
text-align: left;
margin: 10px 0;
}
.leftMessageBox {
margin-top: 20px;
height: calc(100% - 75px);
.leftMessageItem {
display: flex;
align-items: center;
padding: 12px 10px;
border-radius: 4px;
cursor: pointer;
&:hover {
background-color: #ebeced;
}
.messageLeftIcon {
width: 42px;
height: 42px;
border-radius: 10px;
}
.messageLeftItemBox {
width: calc(100% - 42px);
display: flex;
align-items: center;
justify-content: space-between;
.messageLeftContent {
margin-left: 8px;
font-size: 14px;
color: #333333;
font-weight: 400;
overflow: hidden;
/* 确保超出容器的内容被裁剪 */
white-space: nowrap;
/* 确保文本在一行内显示 */
text-overflow: ellipsis;
/* 超出部分显示省略号 */
}
.messageLeftCount {
background: #ff3b30;
border-radius: 40px;
font-size: 12px;
line-height: 16px;
color: #ffffff;
text-align: center;
border: 1px solid #ffffff;
width: 35px;
}
}
}
.activeLeftMessage {
background-color: #ebeced;
}
}
}
// 右侧消息
.messageRight {
width: calc(100% - 278px);
height: 100%;
overflow: hidden;
background: #ffffff;
position: relative;
.rightMessageTitle {
font-size: 18px;
font-weight: 500;
color: #333333;
text-align: left;
padding: 25px 15px 15px 15px;
border-bottom: 1px solid #f6f6f6;
position: fixed;
background: #ffffff;
width: 100%;
z-index: 1;
}
.rigthMessageBox {
padding: 0 15px;
margin-top: 70px;
height: calc(100% - 70px);
overflow: scroll;
.rightEmpty {
display: flex;
align-items: center;
justify-content: center;
height: 80%;
}
.item {
display: flex;
margin: 20px 0;
.itemAvatar {
width: 30px;
height: 30px;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
img {
height: 100%;
width: 100%;
border-radius: 6px;
}
}
.itemBox {
margin-left: 15px;
.itemBoxTitle {
font-weight: 600;
font-size: 12px;
color: #333333;
line-height: 17px;
text-align: left;
font-style: normal;
margin-bottom: 10px;
}
.box {
width: 546px;
background: #f8f8f8;
border-radius: 12px;
padding: 10px;
margin-bottom: 10px;
.item-title {
font-weight: 600;
font-size: 12px;
font-style: normal;
display: flex;
justify-content: space-between;
padding: 10px 6px;
border-bottom: 1px solid #e8e8e8;
}
.item-title div:first-child {
width: calc(100% - 190px);
color: #333333;
text-align: left;
overflow: hidden;
/* 确保超出容器的内容被裁剪 */
white-space: nowrap;
/* 确保文本在一行内显示 */
text-overflow: ellipsis;
/* 超出部分显示省略号 */
::v-deep p {
overflow: hidden;
/* 确保超出容器的内容被裁剪 */
white-space: nowrap;
/* 确保文本在一行内显示 */
text-overflow: ellipsis;
/* 超出部分显示省略号 */
}
}
.item-title div:last-child {
width: 180px;
color: #1478f6;
text-align: right;
white-space: nowrap;
}
.item-content {
font-weight: 400;
font-size: 12px;
color: #333333;
line-height: 28px;
text-align: left;
font-style: normal;
padding: 10px 6px;
}
}
}
}
}
}
.scrollTopTip {
position: absolute;
top: 30%;
right: 5%;
cursor: pointer;
background: #fbfbfb;
border-radius: 19px;
padding: 3px 15px;
.scrollTopIcon {
transform: rotate(90deg);
}
}
</style>