index.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <template>
  2. <el-badge type="danger" :value="badge">
  3. <el-popover placement="bottom" trigger="hover" :width="305">
  4. <template #reference>
  5. <vab-icon icon="notification-2-line" />
  6. </template>
  7. <el-tabs v-model="activeName" @tab-click="handleClick">
  8. <el-tab-pane :label="translate('通知')" name="notice">
  9. <div class="notice-list">
  10. <el-scrollbar>
  11. <ul v-if="badge">
  12. <li v-for="(item, index) in notices" :key="index">
  13. <el-avatar :size="45" :src="item.image" />
  14. <span v-html="item.notice" />
  15. </li>
  16. </ul>
  17. <el-empty v-else description="暂无数据" />
  18. </el-scrollbar>
  19. </div>
  20. </el-tab-pane>
  21. <el-tab-pane :label="translate('邮件')" name="email">
  22. <div class="notice-list">
  23. <el-scrollbar>
  24. <ul v-if="badge">
  25. <li v-for="(item, index) in notices" :key="index">
  26. <el-avatar :size="45" :src="item.image" />
  27. <span>{{ item.email }}</span>
  28. </li>
  29. </ul>
  30. <el-empty v-else description="暂无数据" />
  31. </el-scrollbar>
  32. </div>
  33. </el-tab-pane>
  34. </el-tabs>
  35. <div class="notice-clear" @click="handleClearNotice">
  36. <el-button text>
  37. <vab-icon icon="close-circle-line" />
  38. <span>{{ translate('清空消息') }}</span>
  39. </el-button>
  40. </div>
  41. </el-popover>
  42. </el-badge>
  43. </template>
  44. <script lang="ts" setup>
  45. import { getList } from '/@/api/notice'
  46. import { translate } from '/@/i18n'
  47. import { useSettingsStore } from '/@/store/modules/settings'
  48. defineOptions({
  49. name: 'VabNotice',
  50. })
  51. const $baseMessage = inject<any>('$baseMessage')
  52. const settingsStore = useSettingsStore()
  53. const { theme } = storeToRefs(settingsStore)
  54. const activeName = ref<string>('notice')
  55. const notices = ref<Array<any>>([])
  56. const badge = ref<any>(undefined)
  57. const fetchData = async () => {
  58. const { data } = await getList()
  59. notices.value = data.list
  60. badge.value = data.total === 0 ? undefined : data.total
  61. }
  62. const handleClick = () => {
  63. fetchData()
  64. }
  65. const handleClearNotice = () => {
  66. badge.value = ''
  67. notices.value = []
  68. $baseMessage('清空消息成功', 'success', 'hey')
  69. }
  70. onBeforeMount(() => {
  71. if (theme.value.showNotice) fetchData()
  72. })
  73. </script>
  74. <style lang="scss" scoped>
  75. :deep() {
  76. .el-tabs__active-bar {
  77. min-width: 28px;
  78. }
  79. }
  80. .notice-list {
  81. height: 315px;
  82. ul {
  83. padding: 0 15px 0 0;
  84. margin: 0;
  85. li {
  86. display: flex;
  87. align-items: center;
  88. padding: 10px 0 15px 0;
  89. &:hover {
  90. background-color: var(--el-color-primary-light-9);
  91. border-radius: var(--el-border-radius-base);
  92. }
  93. :deep() {
  94. .el-avatar {
  95. flex-shrink: 0;
  96. width: 50px;
  97. height: 50px;
  98. border-radius: 50%;
  99. }
  100. }
  101. span {
  102. margin-left: 10px;
  103. }
  104. }
  105. }
  106. }
  107. .notice-clear {
  108. display: flex;
  109. align-items: center;
  110. justify-content: center;
  111. padding: 10px 0 0 0;
  112. font-size: var(--el-font-size-default);
  113. text-align: center;
  114. cursor: pointer;
  115. border-top: 1px solid var(--el-border-color);
  116. }
  117. </style>