NotificationView.vue 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. <template>
  2. <div class="notification-page">
  3. <el-card>
  4. <template #header>
  5. <div class="card-header">
  6. <span>消息通知</span>
  7. <el-button text type="primary" @click="markAllRead">全部已读</el-button>
  8. </div>
  9. </template>
  10. <el-table :data="notifications" stripe v-loading="loading">
  11. <el-table-column label="状态" width="70">
  12. <template #default="{ row }">
  13. <el-tag size="small" :type="row.isRead === 0 ? 'danger' : 'info'">
  14. {{ row.isRead === 0 ? '未读' : '已读' }}
  15. </el-tag>
  16. </template>
  17. </el-table-column>
  18. <el-table-column prop="title" label="标题" min-width="180" />
  19. <el-table-column prop="content" label="内容" min-width="240" show-overflow-tooltip />
  20. <el-table-column label="类型" width="120">
  21. <template #default="{ row }">{{ typeLabel(row.type) }}</template>
  22. </el-table-column>
  23. <el-table-column prop="createdAtFriendly" label="时间" width="100" />
  24. </el-table>
  25. <div style="margin-top:16px; text-align:center">
  26. <el-pagination
  27. v-model:current-page="page"
  28. :total="total"
  29. :page-size="20"
  30. layout="prev, pager, next"
  31. @current-change="loadData"
  32. />
  33. </div>
  34. </el-card>
  35. </div>
  36. </template>
  37. <script setup>
  38. import { ref, onMounted } from 'vue'
  39. import { notificationApi } from '../../api'
  40. const notifications = ref([])
  41. const loading = ref(false)
  42. const page = ref(1)
  43. const total = ref(0)
  44. function typeLabel(type) {
  45. const map = {
  46. OKR_REVIEW: 'OKR审核', OKR_REVIEWED: '审核结果',
  47. SCORE_CONFIRM: '评分确认', SCORE_CONFIRMED: '确认通知',
  48. PERIOD_DEADLINE: '截止提醒',
  49. PERIOD_OKR_ALIGN: '周期发布', PERIOD_EXECUTING: '开始执行',
  50. PERIOD_ASSESSING: '考评开始', PERIOD_ARCHIVED: '周期归档',
  51. FEEDBACK_NOTIFY: '面谈通知'
  52. }
  53. return map[type] || type
  54. }
  55. async function loadData() {
  56. loading.value = true
  57. try {
  58. const data = await notificationApi.getPage({ page: page.value, size: 20 })
  59. notifications.value = data.records
  60. total.value = data.total
  61. } finally {
  62. loading.value = false
  63. }
  64. }
  65. async function markAllRead() {
  66. await notificationApi.markAllRead()
  67. await loadData()
  68. }
  69. onMounted(loadData)
  70. </script>
  71. <style scoped>
  72. .notification-page { max-width: 960px; margin: 0 auto; }
  73. .card-header { display: flex; justify-content: space-between; align-items: center; }
  74. </style>