update: 右上角
This commit is contained in:
parent
9e84a7bb8c
commit
fab790bbe6
|
@ -70,6 +70,10 @@ const iconKeys = [
|
|||
'CaretDownOutlined',
|
||||
'MinusOutlined',
|
||||
'AudioOutlined',
|
||||
'BellOutlined',
|
||||
'UserOutlined',
|
||||
'LogoutOutlined',
|
||||
'ReadIconOutlined'
|
||||
]
|
||||
|
||||
const Icon = (props: {type: string}) => {
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-dropdown :trigger="['click']">
|
||||
<div style="height: 48px; display: flex; display: flex">
|
||||
<AIcon type="BellOutlined" @click.prevent />
|
||||
<div class="notice-container">
|
||||
<a-dropdown :trigger="['click']" @visible-change="visibleChange">
|
||||
<div class="icon-content">
|
||||
<AIcon
|
||||
type="BellOutlined"
|
||||
@click.prevent
|
||||
style="font-size: 16px"
|
||||
/>
|
||||
<span class="unread" v-show="total > 0">{{ total }}</span>
|
||||
</div>
|
||||
<template #overlay>
|
||||
<div>
|
||||
|
@ -17,6 +22,11 @@
|
|||
import { getList_api } from '@/api/account/notificationRecord';
|
||||
import NoticeInfo from './NoticeInfo.vue';
|
||||
import { getWebSocket } from '@/utils/websocket';
|
||||
import { notification } from 'ant-design-vue';
|
||||
import { changeStatus_api } from '@/api/account/notificationRecord';
|
||||
import { useUserInfo } from '@/store/userInfo';
|
||||
|
||||
const updateCount = computed(()=>useUserInfo().$state.alarmUpdateCount);
|
||||
|
||||
const total = ref(0);
|
||||
const list = ref<any[]>([]);
|
||||
|
@ -26,7 +36,15 @@ const subscribeNotice = () => {
|
|||
getWebSocket('notification', '/notifications', {})
|
||||
?.pipe()
|
||||
.subscribe((resp: any) => {
|
||||
total.value += 1
|
||||
total.value += 1;
|
||||
notification.open({
|
||||
message: 'Notification Title',
|
||||
description:
|
||||
'This is the content of the notification. This is the content of the notification. This is the content of the notification.',
|
||||
onClick: () => {
|
||||
changeStatus_api('_read', [resp.id]);
|
||||
},
|
||||
});
|
||||
});
|
||||
};
|
||||
const getList = () => {
|
||||
|
@ -44,8 +62,38 @@ const getList = () => {
|
|||
})
|
||||
.finally(() => (loading.value = false));
|
||||
};
|
||||
|
||||
subscribeNotice();
|
||||
getList();
|
||||
watch(updateCount, () => getList());
|
||||
const visibleChange = (bool: boolean) => {
|
||||
bool && getList();
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
<style lang="less" scoped>
|
||||
.notice-container {
|
||||
.icon-content {
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.unread {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -12px;
|
||||
min-width: 20px;
|
||||
height: 20px;
|
||||
padding: 0 6px;
|
||||
color: #fff;
|
||||
font-weight: normal;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
background: #ff4d4f;
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,18 +1,29 @@
|
|||
<template>
|
||||
<div class="notice-info-container">
|
||||
<img v-if="props.data.length" :src="NoData" alt="" />
|
||||
<a-tabs v-else :activeKey="'default'">
|
||||
<a-tab-pane key="default" tab="未读消息">
|
||||
<ul class="list">
|
||||
<li class="list-item" v-for="item in props.data" @click="read(item.id)">
|
||||
<h5>{{ item.topicName }}</h5>
|
||||
<p>{{ item.message }}</p>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="btns">
|
||||
<span @click="read()">当前标记为已读</span>
|
||||
<span @click="jumpPage('account/NotificationRecord')">查看更多</span>
|
||||
</div>
|
||||
<a-tabs :activeKey="'default'">
|
||||
<a-tab-pane key="default" tab="未读消息">
|
||||
<div class="no-data" v-if="props.data.length === 0">
|
||||
<img src="https://gw.alipayobjects.com/zos/rmsportal/sAuJeJzSKbUmHfBQRzmZ.svg" alt="" />
|
||||
</div>
|
||||
|
||||
<div v-else class="content">
|
||||
<ul class="list">
|
||||
<li
|
||||
class="list-item"
|
||||
v-for="item in props.data"
|
||||
@click="read(item.id)"
|
||||
>
|
||||
<h5>{{ item.topicName }}</h5>
|
||||
<p>{{ item.message }}</p>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="btns">
|
||||
<span @click="read()">当前标记为已读</span>
|
||||
<span @click="jumpPage('account/NotificationRecord')"
|
||||
>查看更多</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
|
@ -21,22 +32,19 @@
|
|||
<script setup lang="ts">
|
||||
import { changeStatus_api } from '@/api/account/notificationRecord';
|
||||
import { useMenuStore } from '@/store/menu';
|
||||
import NoData from './nodata.svg';
|
||||
|
||||
const emits = defineEmits(['onAction'])
|
||||
const emits = defineEmits(['onAction']);
|
||||
const props = defineProps<{
|
||||
data: any[];
|
||||
}>();
|
||||
const { jumpPage } = useMenuStore();
|
||||
|
||||
const read = (id?:string)=>{
|
||||
const ids = id ? [id]: props.data.map(item=>item.id)
|
||||
changeStatus_api('_read',ids).then(resp=>{
|
||||
if(resp.status === 200) emits('onAction')
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const read = (id?: string) => {
|
||||
const ids = id ? [id] : props.data.map((item) => item.id);
|
||||
changeStatus_api('_read', ids).then((resp:any) => {
|
||||
if (resp.status === 200) emits('onAction');
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
@ -52,22 +60,61 @@ const read = (id?:string)=>{
|
|||
justify-content: center;
|
||||
}
|
||||
|
||||
.list {
|
||||
.list-item {
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
padding: 24px;
|
||||
.no-data {
|
||||
width: 100%;
|
||||
padding: 73px 0 88px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
text-align: center;
|
||||
|
||||
img {
|
||||
height: 76px;
|
||||
}
|
||||
}
|
||||
.btns {
|
||||
display: flex;
|
||||
span {
|
||||
display: block;
|
||||
width: 50%;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
|
||||
&:first-child{
|
||||
border-right: 1px solid #f0f0f0;
|
||||
.content {
|
||||
.list {
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
&::-webkit-scrollbar {
|
||||
//隐藏或取消滚动条
|
||||
display: none;
|
||||
}
|
||||
|
||||
.list-item {
|
||||
padding: 12px 24px;
|
||||
list-style: none;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
cursor: pointer;
|
||||
h5 {
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
p {
|
||||
font-size: 12px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
|
||||
&:hover{
|
||||
background: #f0f5ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.btns {
|
||||
display: flex;
|
||||
height: 46px;
|
||||
line-height: 46px;
|
||||
span {
|
||||
display: block;
|
||||
width: 50%;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
|
||||
&:first-child {
|
||||
border-right: 1px solid #f0f0f0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,12 +11,12 @@
|
|||
</div>
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item @click="jumpPage('account/center')" style="width: 160px;">
|
||||
<AIcon type="UserOutlined" />
|
||||
<a-menu-item @click="push('/account/center')" style="width: 160px;">
|
||||
<AIcon type="UserOutlined" style="margin-right: 8px;" />
|
||||
<span>个人中心</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item @click="logOut">
|
||||
<AIcon type="LogoutOutlined" />
|
||||
<AIcon type="LogoutOutlined" style="margin-right: 8px;" />
|
||||
<span>退出登录</span>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
|
@ -27,17 +27,17 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { loginout_api } from '@/api/login';
|
||||
import { useMenuStore } from '@/store/menu';
|
||||
import { useUserInfo } from '@/store/userInfo';
|
||||
|
||||
const {push} = useRouter();
|
||||
|
||||
const userInfo = useUserInfo().$state.userInfos as any;
|
||||
|
||||
const { jumpPage } = useMenuStore();
|
||||
|
||||
const logOut = () => {
|
||||
loginout_api().then(() => {
|
||||
localStorage.clear();
|
||||
jumpPage('user/login');
|
||||
push('/user/login');
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -20,7 +20,9 @@ export const useUserInfo = defineStore('userInfo', {
|
|||
token: '',
|
||||
user: {},
|
||||
},
|
||||
alarmUpdateCount: 0
|
||||
}),
|
||||
|
||||
actions: {
|
||||
login(userInfo: any) {
|
||||
const username = userInfo.userName.trim();
|
||||
|
@ -49,6 +51,9 @@ export const useUserInfo = defineStore('userInfo', {
|
|||
}
|
||||
}).catch(() => rej())
|
||||
})
|
||||
},
|
||||
updateAlarm(){
|
||||
this.alarmUpdateCount += 1
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -54,18 +54,6 @@
|
|||
}"
|
||||
>
|
||||
<AIcon type="ReadIconOutlined" />
|
||||
<!-- <svg
|
||||
width="1em"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M12 18H6L2 22V2C2 2 2.9 2 4 2H20C21.1 2 22 2 22 2V11H20V4H4V16H12V18ZM23 14.34L21.59 12.93L17.35 17.17L15.23 15.05L13.82 16.46L17.34 20L23 14.34Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg> -->
|
||||
</PermissionButton>
|
||||
<PermissionButton
|
||||
type="link"
|
||||
|
@ -80,7 +68,11 @@
|
|||
</template>
|
||||
</j-pro-table>
|
||||
|
||||
<ViewDialog v-if="viewVisible" v-model:visible="viewVisible" :data="viewItem" />
|
||||
<ViewDialog
|
||||
v-if="viewVisible"
|
||||
v-model:visible="viewVisible"
|
||||
:data="viewItem"
|
||||
/>
|
||||
</div>
|
||||
</page-container>
|
||||
</template>
|
||||
|
@ -97,7 +89,10 @@ import { optionItem } from '@/views/rule-engine/Scene/typings';
|
|||
import { dictItemType } from '@/views/system/DataSource/typing';
|
||||
import moment from 'moment';
|
||||
import { message } from 'ant-design-vue';
|
||||
import NoticeCp from '@/components/Layout/components/Notice.vue';
|
||||
import { useUserInfo } from '@/store/userInfo';
|
||||
|
||||
const { updateAlarm } = useUserInfo();
|
||||
const columns = [
|
||||
{
|
||||
title: '类型',
|
||||
|
@ -181,6 +176,7 @@ const table = {
|
|||
if (resp.status === 200) {
|
||||
message.success('操作成功!');
|
||||
table.refresh();
|
||||
updateAlarm();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
43
yarn.lock
43
yarn.lock
|
@ -2146,7 +2146,7 @@ cli-width@^3.0.0:
|
|||
resolved "https://registry.npmmirror.com/cli-width/-/cli-width-3.0.0.tgz"
|
||||
integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==
|
||||
|
||||
clipboard@^2.0.4:
|
||||
clipboard@^2.0.10, clipboard@^2.0.4:
|
||||
version "2.0.11"
|
||||
resolved "https://registry.jetlinks.cn/clipboard/-/clipboard-2.0.11.tgz"
|
||||
integrity sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==
|
||||
|
@ -3416,6 +3416,11 @@ highlight.js@^11.3.1:
|
|||
resolved "https://registry.npmmirror.com/highlight.js/-/highlight.js-11.7.0.tgz"
|
||||
integrity sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==
|
||||
|
||||
hls.js@^1.0.10:
|
||||
version "1.3.4"
|
||||
resolved "https://registry.jetlinks.cn/hls.js/-/hls.js-1.3.4.tgz#8212a3f95c3321f64a586f20e67876f3a9d09488"
|
||||
integrity sha512-iFEwVqtEDk6sKotcTwtJ5OMo/nuDTk9PrpB8FI2J2WYf8EriTVfR4FaK0aNyYtwbYeRSWCXJKlz23xeREdlNYg==
|
||||
|
||||
homedir-polyfill@^1.0.0:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmmirror.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz"
|
||||
|
@ -3896,10 +3901,10 @@ jetlinks-store@^0.0.3:
|
|||
resolved "https://registry.npmjs.org/jetlinks-store/-/jetlinks-store-0.0.3.tgz"
|
||||
integrity sha512-AZf/soh1hmmwjBZ00fr1emuMEydeReaI6IBTGByQYhTmK1Zd5pQAxC7WLek2snRAn/HHDgJfVz2hjditKThl6Q==
|
||||
|
||||
jetlinks-ui-components@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.jetlinks.cn/jetlinks-ui-components/-/jetlinks-ui-components-1.0.2.tgz#753507e4a84dee966c65d4ae33943507bd60cc9d"
|
||||
integrity sha512-LXKetf75/uqzWP4XOobm+iUWTVEeMJNnwEk+GrNftQdcDzGvUxBaoFCoS+HBH06FnE2VBbh6rEwrpDhkLSNEow==
|
||||
jetlinks-ui-components@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.jetlinks.cn/jetlinks-ui-components/-/jetlinks-ui-components-1.0.3.tgz#08a35ebfa016574affcfd11204359cdccf8e139f"
|
||||
integrity sha512-kA/AxzdfNy+Sl8En8raMwIh3stofgElkUuJ+oRJMpQVTGbrOk29DifRsHJJFNvtEvclmLdKZkOkthOuEdG2mnw==
|
||||
dependencies:
|
||||
"@vueuse/core" "^9.12.0"
|
||||
ant-design-vue "^3.2.15"
|
||||
|
@ -6554,6 +6559,11 @@ three@0.143.0:
|
|||
resolved "https://registry.npmjs.org/three/-/three-0.143.0.tgz"
|
||||
integrity sha512-oKcAGYHhJ46TGEuHjodo2n6TY2R6lbvrkp+feKZxqsUL/WkH7GKKaeu6RHeyb2Xjfk2dPLRKLsOP0KM2VgT8Zg==
|
||||
|
||||
throttle-debounce@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.jetlinks.cn/throttle-debounce/-/throttle-debounce-3.0.1.tgz#32f94d84dfa894f786c9a1f290e7a645b6a19abb"
|
||||
integrity sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==
|
||||
|
||||
through2@^4.0.0:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.npmmirror.com/through2/-/through2-4.0.2.tgz"
|
||||
|
@ -6940,6 +6950,11 @@ uuid@^3.3.2:
|
|||
resolved "https://registry.jetlinks.cn/uuid/-/uuid-3.4.0.tgz"
|
||||
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
|
||||
|
||||
v-clipboard3@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.jetlinks.cn/v-clipboard3/-/v-clipboard3-0.1.4.tgz#13bdd12ce9728190d70f6ebf8b71de59d88b550e"
|
||||
integrity sha512-iGIXgluf2WLbT+/Z1de9kKzoK9c9aPpy+zcPlY8/fneO+NHK95QEmFx2Q9LoxeUPRemD+nOfEv1J20Ki7W0v7Q==
|
||||
|
||||
v8-compile-cache-lib@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz"
|
||||
|
@ -7072,6 +7087,13 @@ vue-types@^3.0.0:
|
|||
dependencies:
|
||||
is-plain-object "3.0.1"
|
||||
|
||||
vue3-json-viewer@^2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.jetlinks.cn/vue3-json-viewer/-/vue3-json-viewer-2.2.2.tgz#43a512f378c602bb6b7f2a72adeaf7d15b443885"
|
||||
integrity sha512-56l3XDGggnpwEqZieXsSMhNT4NhtO6d7zuSAxHo4i0UVxymyY2jRb7UMQOU1ztChKALZCAzX7DlgrsnEhxu77A==
|
||||
dependencies:
|
||||
clipboard "^2.0.10"
|
||||
|
||||
vue3-markdown-it@^1.0.10:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.npmmirror.com/vue3-markdown-it/-/vue3-markdown-it-1.0.10.tgz"
|
||||
|
@ -7099,7 +7121,16 @@ vue3-ts-jsoneditor@^2.7.1:
|
|||
vanilla-jsoneditor "^0.7.9"
|
||||
vue "^3.2.37"
|
||||
|
||||
vue@^3.2.25:
|
||||
vue3-video-play@^1.3.1-beta.6:
|
||||
version "1.3.1-beta.6"
|
||||
resolved "https://registry.jetlinks.cn/vue3-video-play/-/vue3-video-play-1.3.1-beta.6.tgz#bca3f55a11053eaa37053835e4610c04d9cc509e"
|
||||
integrity sha512-Olrx2/LNAds7fuor/yX9ZKT9sOcwcfTt2g2YbbCrEaAmZ5Tb0hwBr5z+/CoLwELzzRzXCHPmWWoT0Wm5W/Nwpw==
|
||||
dependencies:
|
||||
hls.js "^1.0.10"
|
||||
throttle-debounce "^3.0.1"
|
||||
vue "^3.2.2"
|
||||
|
||||
vue@^3.2.2, vue@^3.2.25:
|
||||
version "3.2.47"
|
||||
resolved "https://registry.jetlinks.cn/vue/-/vue-3.2.47.tgz#3eb736cbc606fc87038dbba6a154707c8a34cff0"
|
||||
integrity sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==
|
||||
|
|
Loading…
Reference in New Issue