Browse Source

add:消息中心UI基本样式与逻辑

zhangrenyuan/feature-20251104133449-现金管理二期
lihui 3 weeks ago
parent
commit
7e9aa14dde
  1. 0
      src/assets/SvgIcons/activity-management.svg
  2. 10
      src/assets/SvgIcons/bell.svg
  3. 0
      src/assets/SvgIcons/cash-management.svg
  4. 0
      src/assets/SvgIcons/channel-management.svg
  5. 0
      src/assets/SvgIcons/gold-management.svg
  6. 0
      src/assets/SvgIcons/permission-management.svg
  7. 92
      src/components/dialogs/MessageDialog.vue
  8. 202
      src/views/home.vue
  9. 2
      src/views/moneyManage/executor/executor.vue

0
src/assets/SvgIcons/activityManagement.svg → src/assets/SvgIcons/activity-management.svg

10
src/assets/SvgIcons/bell.svg

@ -0,0 +1,10 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36" class="design-iconfont">
<path d="M20.2471 26.999C20.2471 28.6559 18.9039 29.999 17.2471 29.999C15.5904 29.9988 14.2471 28.6557 14.2471 26.999H20.2471ZM17.5244 7.5C22.0806 7.5 25.7742 11.1938 25.7744 15.75V21.6045C25.7745 22.1781 26.0027 22.7281 26.4082 23.1338L26.8154 23.541C27.1003 23.8261 27.2149 24.2398 27.1172 24.6309C26.9895 25.1417 26.5304 25.4998 26.0039 25.5H9.0459C8.5192 25.5 8.06038 25.1418 7.93262 24.6309C7.83483 24.2397 7.9493 23.8261 8.23438 23.541L8.64062 23.1338C9.04631 22.7281 9.27432 22.1782 9.27441 21.6045V15.75C9.27461 11.1939 12.9683 7.50015 17.5244 7.5Z" fill="url(#hstdcnta0__paint0_linear_1114_40363)"/>
<path d="M22.7617 16.501C22.3475 16.501 22.0117 16.1652 22.0117 15.751C22.0117 13.2657 19.997 11.251 17.5117 11.251C17.0975 11.251 16.7617 10.9152 16.7617 10.501C16.7617 10.0868 17.0975 9.75098 17.5117 9.75098C20.8254 9.75098 23.5117 12.4373 23.5117 15.751C23.5117 16.1652 23.1759 16.501 22.7617 16.501Z" fill="#fff"/>
<defs>
<linearGradient id="hstdcnta0__paint0_linear_1114_40363" x1="36.7782" y1="17.9995" x2="15.8579" y2="-1.1813" gradientUnits="userSpaceOnUse">
<stop stop-color="#2741DE"/>
<stop offset="1" stop-color="#3A68F9"/>
</linearGradient>
</defs>
</svg>

0
src/assets/SvgIcons/cashManagement.svg → src/assets/SvgIcons/cash-management.svg

0
src/assets/SvgIcons/channelManagement.svg → src/assets/SvgIcons/channel-management.svg

0
src/assets/SvgIcons/goldManagement.svg → src/assets/SvgIcons/gold-management.svg

0
src/assets/SvgIcons/permissionManagement.svg → src/assets/SvgIcons/permission-management.svg

92
src/components/dialogs/MessageDialog.vue

@ -1,92 +0,0 @@
<script setup>
import { ref, onMounted } from 'vue'
import API from '@/util/http.js' //
const emit = defineEmits(['close', 'update-dot'])
const dialogRef = ref(null)
//
const messages = ref([])
//
async function getMessages() {
try {
const res = await API({ url: '/getMessages', method: 'GET' })
if (res.code === 200) {
messages.value = res.data
//
const hasUnread = messages.value.some(msg => !msg.read)
// emit('update-dot', false)
}else {
// emit('update-dot', false)
}
} catch (e) {
emit('update-dot', false)
console.error('获取消息失败:', e)
}
}
onMounted(() => {
getMessages()
})
function closeDialog() {
emit('close')
}
</script>
<template>
<dialog class="message-dialog" open>
<div class="dialog-content">
<h3>消息中心</h3>
<div v-if="messages.length > 0">
<!-- <div
v-for="msg in messages"
:key="msg.id"
class="msg-item"
:class="{ unread: !msg.read }"
>
{{ msg.title }}
</div>-->
<div>
测试测试
</div>
</div>
<div v-else>测试测试</div>
<div class="dialog-footer">
<el-button type="primary" @click="closeDialog">关闭</el-button>
</div>
</div>
</dialog>
</template>
<style scoped>
.message-dialog {
border: none;
border-radius: 10px;
background: rgba(255, 255, 255, 0.96);
box-shadow: 0 0 20px rgba(0, 0, 0, 0.25);
width: 380px;
z-index: 99999;
}
.dialog-content {
padding: 20px;
}
.msg-item {
padding: 6px 0;
}
.msg-item.unread {
font-weight: bold;
color: #409eff;
}
.dialog-footer {
text-align: right;
margin-top: 20px;
}
::backdrop {
background-color: rgba(0, 0, 0, 0.4);
}
</style>

202
src/views/home.vue

@ -24,11 +24,11 @@ const icons = import.meta.glob('@/assets/SvgIcons/*.svg', {eager: true})
const menuNameMap = {
'工作台': 'workbench',
'金币管理': 'goldManagement',
'现金管理': 'cashManagement',
'活动管理': 'activityManagement',
'频道管理': 'channelManagement',
'权限管理': 'permissionManagement',
'金币管理': 'gold-management',
'现金管理': 'cash-management',
'活动管理': 'activity-management',
'频道管理': 'channel-management',
'权限管理': 'permission-management',
}
//
@ -52,12 +52,8 @@ const getIconPath = (menuName) => {
}
}
// -----------------------------------
//
import API from '@/util/http.js'
import MessageDialog from "@/components/dialogs/MessageDialog.vue"; // HTTP
//
const refreshData = async () => {
@ -85,8 +81,6 @@ const refreshData = async () => {
}
}
// ---------------------------------------
//
const menuList = ref([])
@ -132,7 +126,6 @@ const router = useRouter()
const imgrule1 = dmmn
const messageVisible = ref(false)
//
const openMessage = function () {
messageVisible.value = true
@ -179,14 +172,47 @@ const toggleFlag = () => {
//
// MessageDialog
import bell from '@/assets/SvgIcons/bell.svg'
import noMessage from '@/assets/images/no-message.svg'
const messageNum = ref(0)
const showMessageDialog = ref(false)
//
const messageDot = ref(true)
//
const openMessageDialog = () => {
showMessageDialog.value = true
messageDot.value = false
}
//
const messageDot = ref(true)
//
const closeMessageDialog = () => {
showMessageDialog.value = false
}
//
const messageList = ref([
{ id: 1, title: '现金管理—收款明细', desc: 'XXX(用户)的收款单被驳回', time: '2分钟前', group: '今天' },
{ id: 2, title: '现金管理—收款明细', desc: 'XXX(用户)的收款单被驳回', time: '1小时前', group: '今天' },
{ id: 3, title: '现金管理—收款明细', desc: 'XXX(用户)的收款单被驳回', time: '昨天 09:30', group: '昨天' },
{ id: 4, title: '现金管理—收款明细', desc: 'XXX(用户)的收款单被驳回', time: '昨天 08:30', group: '昨天' },
{ id: 5, title: '现金管理—收款明细', desc: 'XXX(用户)的收款单被驳回', time: '2025-11-05 10:05:20', group: '更早' },
{ id: 6, title: '现金管理—收款明细', desc: 'XXX(用户)的收款单被驳回', time: '2025-11-05 10:05:20', group: '更早' },
]);
//
const groupedMessages = ref({});
messageList.value.forEach(item => {
if (!groupedMessages.value[item.group]) {
groupedMessages.value[item.group] = [];
}
groupedMessages.value[item.group].push(item);
});
</script>
<template>
@ -285,13 +311,12 @@ const messageDot = ref(true)
</template>
</el-dropdown>
</div>
<!-- 消息提示 -->
<!-- 消息提示 这里的 小红点不用el-badge 他在切换状态会抽一下 应该是dom问题 -->
<div class="message-container">
<el-badge :is-dot="messageDot" class="item">
<el-icon @click="openMessageDialog" style="cursor: pointer;">
<Bell/>
</el-icon>
</el-badge>
<div class="relative">
<el-image :src="bell" style="width: 28px; height: 28px;" @click="openMessageDialog"></el-image>
<span v-show="messageDot" class="dot"></span>
</div>
</div>
</div>
@ -343,12 +368,43 @@ const messageDot = ref(true)
<ChangePassword ref="pwdRef" @confirm="showPasswordDialog = false"/>
</el-dialog>
<MessageDialog
v-if="showMessageDialog"
@close="showMessageDialog = false"
@update-dot="messageDot = $event"
/>
<el-dialog style="background: #F3FAFE" v-model="showMessageDialog" title="" width="500px">
<div v-if="messageNum !== 0">
| 消息 ({{ messageNum }})
<el-divider
style="height: 2px; align-self: stretch; background: #CEE5FE; border: none;"
></el-divider>
<div class="no-message">
<el-image :src="noMessage"></el-image>
<p class="no-message-text">暂无未办消息快去处理工作吧</p>
</div>
</div>
<div v-else>
| 消息 ({{ messageNum }})
<!-- 按时间分组的消息列表 -->
<div v-for="(group, time) in groupedMessages" :key="time" class="message-group">
<div class="time-header" style="display: flex; align-items: center; gap: 8px;">
{{ time }} <span class="little-dot"></span>
<el-divider
style="height: 2px; align-self: stretch; flex: 1;background: #CEE5FE; border: none;"
></el-divider>
</div>
<div v-for="item in group" :key="item.id" class="message-item">
<div class="message-content">
<span class="message-title">{{ item.title }}</span>
<p class="message-desc">{{ item.desc }}</p>
</div>
<el-button type="primary" size="small" class="view-btn">前往查看</el-button>
<div class="message-time">{{ item.time }}</div>
</div>
</div>
<el-button type="text" class="view-all">查看全部</el-button>
</div>
</el-dialog>
</div>
@ -532,4 +588,100 @@ const messageDot = ref(true)
scrollbar-color: rgba(0, 0, 0, 0.3) rgba(255, 255, 255, 0.2);
/* Firefox滑块和轨道颜色 */
}
/* 添加相对定位,用于添加消息点 */
.relative {
position: relative;
}
.dot {
position: absolute;
top: -2px;
right: -2px;
width: 8px;
height: 8px;
background: #F23C39;
border-radius: 50%;
}
/* 整体样式 */
.message {
background: #0d84ff;
}
/* 无消息的样式 */
.no-message {
text-align: center;
position: relative;
}
.no-message-text {
position: absolute;
top: 60%;
left: 50%;
/* 水平垂直居中 */
transform: translate(-50%, -50%);
/* 文字样式 */
font-weight: bold;
margin: 0;
/* 可添加更多样式(如字体大小、阴影等) */
font-size: 14px;
}
/* 有消息的样式 */
.message-group {
margin-bottom: 16px;
}
.time-header {
font-size: 14px;
color: #666;
margin-bottom: 8px;
}
.message-item {
display: flex;
align-items: center;
margin-bottom: 12px;
padding-bottom: 12px;
border-bottom: 1px solid #eee;
}
.message-content {
flex: 1;
}
.message-tag {
color: red;
margin-right: 4px;
}
.message-title {
font-weight: bold;
margin-right: 4px;
}
.message-desc {
font-size: 13px;
color: #666;
margin: 4px 0 0 0;
}
.view-btn {
margin-right: 16px;
}
.message-time {
font-size: 13px;
color: #999;
}
.view-all {
display: block;
margin: 0 auto 16px;
}
.little-dot {
display: inline-block;
width: 8px; /* 圆点直径 */
height: 8px;
border-radius: 50%; /* 圆形 */
background-color: #CEE5FE;;
}
</style>

2
src/views/moneyManage/executor/executor.vue

@ -122,7 +122,7 @@
</template>
</el-table-column>
</el-table>
<el-pagination :current-page="pagination.pageNum" :page-size="pagination.pageSize"
<el-pagination v-model:current-page="pagination.pageNum" v-model:page-size="pagination.pageSize"
layout="total, sizes, prev, pager, next, jumper" :total="pagination.total" style="margin-top: 1vh;"/>
</el-card>

Loading…
Cancel
Save