index.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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"></span>
  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 settingsStore = useSettingsStore()
  52. const { theme } = storeToRefs(settingsStore)
  53. const activeName = ref<string>('notice')
  54. const notices = ref<Array<any>>([])
  55. const badge = ref<any>(undefined)
  56. const fetchData = async () => {
  57. const { data } = await getList()
  58. notices.value = data.list
  59. badge.value = data.total === 0 ? undefined : data.total
  60. }
  61. const handleClick = () => {
  62. fetchData()
  63. }
  64. const handleClearNotice = () => {
  65. badge.value = ''
  66. notices.value = []
  67. $baseMessage('清空消息成功', 'success', 'hey')
  68. }
  69. onBeforeMount(() => {
  70. if (theme.value.showNotice) fetchData()
  71. })
  72. </script>
  73. <style lang="scss" scoped>
  74. :deep() {
  75. .el-tabs__active-bar {
  76. min-width: 28px;
  77. }
  78. }
  79. .notice-list {
  80. height: 315px;
  81. ul {
  82. padding: 0 15px 0 0;
  83. margin: 0;
  84. li {
  85. display: flex;
  86. align-items: center;
  87. padding: 10px 0 15px 0;
  88. &:hover {
  89. background-color: var(--el-color-primary-light-9);
  90. border-radius: var(--el-border-radius-base);
  91. }
  92. :deep() {
  93. .el-avatar {
  94. flex-shrink: 0;
  95. width: 50px;
  96. height: 50px;
  97. border-radius: 50%;
  98. }
  99. }
  100. span {
  101. margin-left: 10px;
  102. }
  103. }
  104. }
  105. }
  106. .notice-clear {
  107. display: flex;
  108. align-items: center;
  109. justify-content: center;
  110. padding: 10px 0 0 0;
  111. font-size: var(--el-font-size-base);
  112. text-align: center;
  113. cursor: pointer;
  114. border-top: 1px solid var(--el-border-color);
  115. }
  116. </style>