优化页面头部的消息气泡卡片

This commit is contained in:
zhoumingfa 2024-08-04 11:38:16 +08:00
parent bf64f525fb
commit ecd671682e
5 changed files with 85 additions and 40 deletions

View File

@ -0,0 +1,44 @@
<template>
<a-modal v-model:open="showFlag" :width="800" title="消息内容" :destroyOnClose="true" @ok="showFlag = false">
<a-descriptions bordered :column="2" size="small">
<a-descriptions-item :labelStyle="{ width: '80px' }" :span="1" label="类型"
>{{ $smartEnumPlugin.getDescByValue('MESSAGE_TYPE_ENUM', messageDetail.messageType) }}
</a-descriptions-item>
<a-descriptions-item :labelStyle="{ width: '120px' }" :span="1" label="发送时间">{{ messageDetail.createTime }}</a-descriptions-item>
<a-descriptions-item :labelStyle="{ width: '80px' }" :span="2" label="标题">{{ messageDetail.title }}</a-descriptions-item>
<a-descriptions-item :labelStyle="{ width: '80px' }" :span="2" label="内容">
<pre>{{ messageDetail.content }}</pre>
</a-descriptions-item>
</a-descriptions>
</a-modal>
</template>
<script setup>
import { reactive, ref } from 'vue';
import { messageApi } from '/@/api/support/message-api.js';
const emit = defineEmits(['refresh']);
const messageDetail = reactive({
messageType: '',
title: '',
content: '',
createTime: '',
});
const showFlag = ref(false);
function show(data) {
Object.assign(messageDetail, data);
showFlag.value = true;
read(data);
}
async function read(message) {
if (!message.readFlag) {
await messageApi.updateReadFlag(message.messageId);
emit('refresh');
}
}
defineExpose({ show });
</script>

View File

@ -9,15 +9,19 @@
--> -->
<template> <template>
<a-dropdown trigger="click" v-model:open="show"> <div>
<a-popover v-model:open="show" trigger="contextmenu" placement="bottomLeft" @openChange="() => (show = true)">
<a-button type="text" @click="showMessage" style="padding: 4px 5px">
<a-badge :count="unreadMessageCount + toBeDoneCount"> <a-badge :count="unreadMessageCount + toBeDoneCount">
<div style="width: 26px; height: 26px"> <div style="width: 26px; height: 26px">
<BellOutlined :style="{ fontSize: '16px' }" /> <BellOutlined :style="{ fontSize: '16px' }" />
</div> </div>
</a-badge> </a-badge>
</a-button>
<template #overlay> <template #content>
<a-card class="message-container" :bodyStyle="{ padding: 0 }"> <!-- 为了能在点击查看消息详情弹窗的同时防止消息气泡卡片关闭 所以加了一个手动关闭按钮 -->
<a-button type="text" @click="closeMessage" style="padding: 4px 5px"> 关闭 </a-button>
<a-spin :spinning="loading"> <a-spin :spinning="loading">
<a-tabs class="dropdown-tabs" centered :tabBarStyle="{ textAlign: 'center' }" style="width: 300px"> <a-tabs class="dropdown-tabs" centered :tabBarStyle="{ textAlign: 'center' }" style="width: 300px">
<a-tab-pane key="message"> <a-tab-pane key="message">
@ -30,7 +34,8 @@
<a-list-item-meta> <a-list-item-meta>
<template #title> <template #title>
<div class="title"> <div class="title">
<a @click="gotoMessage">{{ item.title }}</a> <a-badge status="error" />
<a @click="showMessageDetail(item)">{{ item.title }}</a>
</div> </div>
</template> </template>
<template #description> <template #description>
@ -38,12 +43,12 @@
</template> </template>
</a-list-item-meta> </a-list-item-meta>
</a-list-item> </a-list-item>
<a-list-item v-if="unreadMessageCount !== 0"> <a-list-item v-if="unreadMessageCount > 3">
<a-button type="text" @click="gotoMessage" style="padding: 4px 5px"> ... 查看更多 </a-button> <a-button type="text" @click="gotoMessage" style="padding: 4px 5px"> ... 查看更多 </a-button>
</a-list-item> </a-list-item>
</a-list> </a-list>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="TO_BE_DONE"> <a-tab-pane key="to_be_done">
<template #tab> <template #tab>
待办工作 待办工作
<a-badge :count="toBeDoneCount" showZero :offset="[0, -20]" /> <a-badge :count="toBeDoneCount" showZero :offset="[0, -20]" />
@ -62,10 +67,10 @@
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
</a-spin> </a-spin>
</a-card>
</template> </template>
</a-dropdown> </a-popover>
<MessageDetail ref="messageDetailRef" @refresh="queryMessage" /> <MessageDetailModal ref="messageDetailModalRef" @refresh="queryMessage" />
</div>
</template> </template>
<script setup> <script setup>
@ -77,24 +82,27 @@
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { theme } from 'ant-design-vue'; import { theme } from 'ant-design-vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import MessageDetail from '/@/views/system/account/components/message/components/message-detail.vue'; import MessageDetailModal from './header-message-detail-modal.vue';
import localKey from '/@/constants/local-storage-key-const'; import localKey from '/@/constants/local-storage-key-const';
import { localRead } from '/@/utils/local-util'; import { localRead } from '/@/utils/local-util';
const { useToken } = theme; const { useToken } = theme;
const { token } = useToken(); const { token } = useToken();
defineExpose({ showMessage });
function showMessage() {
queryMessage();
loadToBeDoneList();
show.value = true;
}
const loading = ref(false); const loading = ref(false);
const show = ref(false); const show = ref(false);
//
function showMessage() {
show.value = true;
queryMessage();
loadToBeDoneList();
}
function closeMessage() {
show.value = false;
}
// ------------------------- ------------------------- // ------------------------- -------------------------
// //
@ -124,6 +132,11 @@
} }
} }
const messageDetailModalRef = ref();
function showMessageDetail(data) {
messageDetailModalRef.value.show(data);
}
const router = useRouter(); const router = useRouter();
function gotoMessage() { function gotoMessage() {
show.value = false; show.value = false;
@ -232,10 +245,6 @@
cursor: pointer; cursor: pointer;
} }
.message-container {
border: #eeeeee solid 1px;
}
.dropdown-tabs { .dropdown-tabs {
background-color: @base-bg-color; background-color: @base-bg-color;
border-radius: 4px; border-radius: 4px;

View File

@ -18,7 +18,7 @@
</a-form-item> </a-form-item>
<a-form-item :label="$t('setting.color')"> <a-form-item :label="$t('setting.color')">
<div class="color-container"> <div class="color-container">
<template v-for="(item, index) in themeColors"> <template v-for="(item, index) in themeColors" :key="index">
<div v-if="index === formState.colorIndex" class="color"> <div v-if="index === formState.colorIndex" class="color">
<CheckSquareFilled :style="{ color: item.primaryColor, fontSize: '22px' }" /> <CheckSquareFilled :style="{ color: item.primaryColor, fontSize: '22px' }" />
</div> </div>
@ -34,7 +34,7 @@
> >
<path <path
d="M128 160.01219c0-17.67619 14.336-32.01219 32.01219-32.01219h704c17.65181 0 31.98781 14.336 31.98781 32.01219v704c0 17.65181-14.336 31.98781-32.01219 31.98781H160.036571a31.98781 31.98781 0 0 1-32.01219-32.01219V160.036571z" d="M128 160.01219c0-17.67619 14.336-32.01219 32.01219-32.01219h704c17.65181 0 31.98781 14.336 31.98781 32.01219v704c0 17.65181-14.336 31.98781-32.01219 31.98781H160.036571a31.98781 31.98781 0 0 1-32.01219-32.01219V160.036571z"
></path> />
</svg> </svg>
</div> </div>
</template> </template>

View File

@ -18,9 +18,7 @@
size="small" size="small"
/> />
<!---消息通知---> <!---消息通知--->
<a-button type="text" @click="showMessage" style="padding: 4px 5px">
<HeaderMessage ref="headerMessage" /> <HeaderMessage ref="headerMessage" />
</a-button>
<!---国际化---> <!---国际化--->
<!-- <a-button type="text" @click="showSetting" class="operate-icon"> <!-- <a-button type="text" @click="showSetting" class="operate-icon">
<template #icon><switcher-outlined /></template> <template #icon><switcher-outlined /></template>
@ -59,12 +57,6 @@
headerSetting.value.show(); headerSetting.value.show();
} }
//
const headerMessage = ref();
function showMessage() {
headerMessage.value.showMessage();
}
// //
function showHelpDoc() { function showHelpDoc() {
useAppConfigStore().showHelpDoc(); useAppConfigStore().showHelpDoc();

View File

@ -26,7 +26,7 @@ const smartAxios = axios.create({
// 退出系统 // 退出系统
function logout() { function logout() {
useUserStore.logout(); useUserStore().logout();
location.href = '/'; location.href = '/';
} }