| New file |
| | |
| | | <template> |
| | | <div v-if="totalCount > 0" class="notification-badge"> |
| | | <div class="badge-wrapper" @click="handleClick"> |
| | | <a-badge :count="totalCount" :number-style="{ backgroundColor: '#ff4d4f' }"> |
| | | <a-icon type="bell" :style="{ fontSize: '24px', color: '#1890ff', cursor: 'pointer' }" /> |
| | | </a-badge> |
| | | </div> |
| | | <div class="notification-popover" v-if="showPopover" @click.stop> |
| | | <div class="notification-item" @click="goToRecharge"> |
| | | <span>充值待处理</span> |
| | | <a-badge :count="rechargeCount" :number-style="{ backgroundColor: '#ff4d4f' }" /> |
| | | </div> |
| | | <div class="notification-item" @click="goToWithdraw"> |
| | | <span>提现待处理</span> |
| | | <a-badge :count="withdrawCount" :number-style="{ backgroundColor: '#ff4d4f' }" /> |
| | | </div> |
| | | <div class="notification-item" @click="goToAuth"> |
| | | <span>实名认证待处理</span> |
| | | <a-badge :count="authCount" :number-style="{ backgroundColor: '#ff4d4f' }" /> |
| | | </div> |
| | | </div> |
| | | <div v-if="showPopover" class="popover-mask" @click="closePopover"></div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getPendingCount } from '@/api/home' |
| | | |
| | | export default { |
| | | name: 'NotificationBadge', |
| | | data() { |
| | | return { |
| | | rechargeCount: 0, |
| | | withdrawCount: 0, |
| | | authCount: 0, |
| | | totalCount: 0, |
| | | showPopover: false, |
| | | timer: null |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.fetchPendingCount() |
| | | this.startPolling() |
| | | document.addEventListener('click', this.handleDocumentClick) |
| | | }, |
| | | beforeDestroy() { |
| | | this.stopPolling() |
| | | document.removeEventListener('click', this.handleDocumentClick) |
| | | }, |
| | | methods: { |
| | | fetchPendingCount() { |
| | | getPendingCount() |
| | | .then((res) => { |
| | | if (res.status === 0 && res.data) { |
| | | this.rechargeCount = res.data.rechargeCount || 0 |
| | | this.withdrawCount = res.data.withdrawCount || 0 |
| | | this.authCount = res.data.authCount || 0 |
| | | this.totalCount = res.data.totalCount || 0 |
| | | } |
| | | }) |
| | | .catch((error) => { |
| | | console.error('获取待处理数量失败', error) |
| | | }) |
| | | }, |
| | | startPolling() { |
| | | this.timer = setInterval(() => { |
| | | this.fetchPendingCount() |
| | | }, 30000) // 每30秒轮询一次 |
| | | }, |
| | | stopPolling() { |
| | | if (this.timer) { |
| | | clearInterval(this.timer) |
| | | this.timer = null |
| | | } |
| | | }, |
| | | handleClick(e) { |
| | | e.stopPropagation() |
| | | this.showPopover = !this.showPopover |
| | | }, |
| | | closePopover() { |
| | | this.showPopover = false |
| | | }, |
| | | handleDocumentClick(e) { |
| | | if (this.showPopover && !this.$el.contains(e.target)) { |
| | | this.showPopover = false |
| | | } |
| | | }, |
| | | goToRecharge() { |
| | | this.$router.push('/capital/rechargelist') |
| | | this.showPopover = false |
| | | }, |
| | | goToWithdraw() { |
| | | this.$router.push('/capital/withdrawallist') |
| | | this.showPopover = false |
| | | }, |
| | | goToAuth() { |
| | | this.$router.push('/userlist') |
| | | this.showPopover = false |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | .notification-badge { |
| | | position: fixed; |
| | | right: 30px; |
| | | bottom: 30px; |
| | | z-index: 1000; |
| | | } |
| | | |
| | | .badge-wrapper { |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .popover-mask { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | z-index: 999; |
| | | } |
| | | |
| | | .notification-popover { |
| | | position: absolute; |
| | | bottom: 50px; |
| | | right: 0; |
| | | background: #fff; |
| | | border-radius: 4px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); |
| | | padding: 12px 0; |
| | | min-width: 200px; |
| | | } |
| | | |
| | | .notification-item { |
| | | padding: 12px 16px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | cursor: pointer; |
| | | transition: background-color 0.3s; |
| | | |
| | | &:hover { |
| | | background-color: #f5f5f5; |
| | | } |
| | | |
| | | span { |
| | | font-size: 14px; |
| | | color: #333; |
| | | } |
| | | } |
| | | </style> |
| | | |