CaiYuanYiTiHua/src/layouts/default/header/components/notify/index.vue

428 lines
11 KiB
Vue

<template>
<div :class="prefixCls">
<Popover
v-model:visible="visible"
title=""
trigger="click"
:overlayClassName="`${prefixCls}__overlay`"
>
<Badge :count="count" dot :numberStyle="numberStyle">
<BellOutlined />
</Badge>
<template #content>
<Tabs>
<template v-for="item in listData" :key="item.key">
<Tabs.TabPane>
<template #tab>
{{ item.name }}
<span v-if="item.list.length !== 0">({{ item.list.length }})</span>
</template>
<!-- 绑定title-click事件的通知列表中标题是“可点击”的-->
<NoticeList :list="item.list" v-if="item.key === '1'" @title-click="onNoticeClick" />
<NoticeList :list="item.list" v-else />
</Tabs.TabPane>
</template>
</Tabs>
</template>
</Popover>
<!-- 云查询内容提示 -->
<div class="cloudquery-notice" v-if="cloudQueryVisible">
<div class="cloudquery-title">
<div class="cloudquery-left">
<img src="/message.png" alt="" />
<span class="title-box">您有一条云查询结果,请查收</span>
</div>
<div class="cloudquery-right">
<a-button type="primary" @click="handCloudQuery">查看</a-button>
<div class="line"></div>
<CloseOutlined @click="closeCloudQuery" style="color: #fff" title="关闭" />
</div>
</div>
</div>
<!-- 流程任务详情 -->
<a-modal
width="100%"
wrap-class-name="full-modal"
v-model:open="auditOpen"
title="详情"
:destroyOnClose="true"
>
<template #footer> </template>
<Look ref="posRef" :processId="processId" />
</a-modal>
<!-- 消息详情 -->
<DetailModal @register="registerModal" />
<!-- 云查询结果 -->
<a-modal
v-model:open="open"
:footer="false"
@cancel="open = false"
:width="compare ? '1020px' : '510px'"
style="top: 20px"
>
<div class="modal-content-div">
<div class="title-text">
{{ compare ? '国家云查询结果(对比模式)' : '国家云查询结果' }}
<Icon
class="split-button"
style="font-size: 20px"
icon="bi:layout-split"
@click="changeCompare"
/>
</div>
<div style="display: flex; width: 100%">
<div :style="`display: block; width: ${compare ? '50%' : '100%'};`">
<CloudQueryModal />
</div>
<div style="display: block; width: 50%; margin-left: 20px" v-if="compare">
<CloudQueryModal />
</div>
</div>
</div>
</a-modal>
</div>
</template>
<script lang="ts" setup>
import { computed, onMounted, ref, h } from 'vue';
import { Popover, Tabs, Badge, Button } from 'ant-design-vue';
import {
BellOutlined,
CloseOutlined,
FileSearchOutlined,
StarFilled,
} from '@ant-design/icons-vue';
import { tabListData } from './data';
import { useDesign } from '@/hooks/web/useDesign';
import { useMessage } from '@/hooks/web/useMessage';
import { getLastList, readMsg, getInfoByContentId } from '@/api/demo/message';
import { useUserStore } from '@/store/modules/user';
import { Look } from '@/views/demo/workflow/task/process/page';
import { useModal } from '@/components/Modal';
import NoticeList from './NoticeList.vue';
import { signal } from '@/utils/signalR';
import { getDetail } from '@/api/sys/WFSchemeInfo';
import { flowStore } from '@/store/modules/flow';
import DetailModal from '@/views/demo/message/msg/DetailModal.vue';
import CloudQueryModal from '@/views/dashboard/test/SearchMenu/CloudQueryModal/index.vue';
import Icon from '@/components/Icon/Icon.vue';
import { useCloudQueryStore } from '@/store/modules/cloudquery';
const flowWfDataStore = flowStore();
const useCloudQuery = useCloudQueryStore();
const [registerModal, { openModal: openLookModal }] = useModal();
const userStore = useUserStore();
const userInfo: any = userStore.getUserInfo;
const visible = ref(false);
const { prefixCls } = useDesign('header-notify');
const { createMessage, notification } = useMessage();
const listData = ref(tabListData);
const numberStyle = {};
const auditOpen = ref(false);
const processId = ref('');
const taskId = ref('');
const isRead: any = ref(0);
const type = ref('');
const cloudQueryVisible = ref(false);
const compare = ref(false);
const open = ref(false);
const count = computed(() => {
let count = 0;
for (let i = 0; i < listData.value.length; i++) {
count += listData.value[i].list.length;
}
return count;
});
async function onNoticeClick(record) {
console.log(record);
visible.value = false;
const index = listData.value[0].list.findIndex((item: any) => item.id === record.id);
if (index !== -1) {
listData.value[0].list.splice(index, 1);
}
if (record.contentId) {
const info = await getInfoByContentId({
id: record.contentId,
});
if (info) {
let data = await getDetail({ code: info.ProcessCode });
let scheme = JSON.parse(data.scheme.content);
let wfData = scheme.wfData;
flowWfDataStore.setWfDataAll(wfData);
auditOpen.value = true;
processId.value = info.ProcessId;
taskId.value = info.Id;
type.value = info.Type;
} else {
openLookModal(true, {
record: {
content: record.title,
createDate: record.datetime,
isRead: 0,
},
});
}
} else {
openLookModal(true, {
record: {
content: record.title,
createDate: record.datetime,
isRead: 0,
},
});
}
const data = await readMsg({
id: record.id,
});
}
async function getList() {
const data = await getLastList({
userId: userInfo.id,
});
let arr: any = [];
if (data && data.length > 0) {
data.forEach((item: any) => {
arr.push({
id: item.msgId,
title: item.content,
datetime: item.createDate,
contentId: item.contentId,
});
});
listData.value[0].list = arr;
}
}
// 连接
async function start() {
try {
await signal.start().then(() => {
signal
.invoke('SendInfo', userInfo.id.toString())
.catch((err) => console.error(err.toString()));
});
console.log('userInfo.id', userInfo.id);
console.log('SignalR Connected.连接成功');
} catch (err) {
console.log(err);
// setTimeout(start, 5000);
}
}
signal.onclose(async () => {
await start();
});
//接口推送
signal.on('RevMsg', (user, message, time, id, issystem) => {
console.log('报警', user, message, time, id, issystem); //拿到后台推送的数据
// ChaoShi 超时报警
// CloudQuery 云查询
if (user == 'CloudQuery') {
showCloudQuery({
id,
});
} else {
notification.info({
message: '您有一条新消息',
description: () => {
const res = message + '\n' + time;
return h('pre', {}, res);
},
duration: 3,
});
getList();
}
});
onMounted(() => {
getList();
start();
});
function closeMolder() {
auditOpen.value = false;
}
function showCloudQuery(info) {
cloudQueryVisible.value = true;
useCloudQuery.setIdentification(false);
useCloudQuery.setCloudQueryInfo(info);
}
// 查看云查询结果
function handCloudQuery() {
open.value = true;
closeCloudQuery();
}
function closeCloudQuery() {
cloudQueryVisible.value = false;
}
const changeCompare = () => {
compare.value = !compare.value;
console.log('compare.value', compare.value);
};
</script>
<style lang="less">
@prefix-cls: ~'@{namespace}-header-notify';
.@{prefix-cls} {
padding-bottom: 1px;
&__overlay {
max-width: 360px;
}
.ant-tabs-content {
width: 300px;
}
.ant-badge {
display: flex;
align-items: center;
font-size: 18px;
.ant-badge-multiple-words {
padding: 0 4px;
}
svg {
width: 0.9em;
}
}
}
.full-modal {
.ant-modal {
max-width: 100%;
top: 0;
}
.ant-modal-content {
height: calc(100vh);
}
.ant-modal-body {
height: 85%;
}
}
.cloudquery-notice {
background: rgba(0, 0, 0, 0.53);
padding: 0px 14px;
border-radius: 6px;
position: fixed;
top: 30px;
right: 1vw;
width: 700px;
color: #fff;
z-index: 10;
.cloudquery-title {
height: 40px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 16px;
}
.cloudquery-left {
display: flex;
align-items: center;
}
.cloudquery-right {
display: flex;
align-items: center;
justify-content: space-around;
width: 130px;
}
img {
width: 34px;
height: 29px;
}
.cloudquery-btn {
display: flex;
justify-content: flex-end;
}
.line {
background: #ededed;
width: 1px;
height: 20px;
}
.anticon.anticon-close {
height: 30px;
}
button {
width: 70px;
height: 26px;
background: linear-gradient(-74deg, #086dec, #0b4bdd);
box-shadow: 3px 4px 5px 1px rgba(13, 13, 13, 0.05);
border-radius: 16px;
display: flex;
align-items: center;
justify-content: center;
}
.title-box {
margin-left: 10px;
font-size: 14px;
}
}
</style>
<style lang="scss" scoped>
.modal-content-div {
padding: 53px 20px 10px 20px;
width: 100%;
.title-text {
display: flex;
justify-content: center;
font-size: 18px;
color: #2f83d9;
text-decoration: underline;
font-weight: 600;
position: relative;
}
.split-button {
font-size: 20px;
display: inline-flex;
position: absolute;
right: 8px;
top: 2px;
color: #000000a3;
cursor: pointer;
}
}
.search-menu {
width: 50px;
height: 355px;
background-color: #fff;
position: absolute;
top: 30px;
left: 20px;
border-radius: 25px;
padding-top: 19px;
}
.active {
background: repeating-linear-gradient(to left, rgb(38, 51, 231), rgb(20, 118, 230));
color: #fff;
}
.menu-item {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 7px;
cursor: pointer;
.item-icon {
font-size: 20px;
margin-bottom: 2px;
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
transition: 0.2s;
}
.item-text {
user-select: none;
}
}
.menu-content {
padding: 10px;
background: #fff;
position: absolute;
top: 0px;
left: 70px;
width: 420px;
}
</style>