This commit is contained in:
haomingming
2026-05-20 18:21:39 +08:00
commit 815aa04fe8
564 changed files with 82601 additions and 0 deletions
@@ -0,0 +1,116 @@
<template>
<PageContainer title="站内通知中心">
<template #header>
<div class="header-row">
<el-space>
<el-tag type="info">总数 {{ rows.length }}</el-tag>
<el-tag type="danger">未读 {{ unreadCount }}</el-tag>
<el-switch
v-if="canRead"
v-model="onlyUnread"
inline-prompt
active-text="仅看未读"
inactive-text="全部"
/>
<el-button
v-if="canRead && canMarkRead"
type="primary"
plain
:disabled="unreadCount <= 0"
@click="handleMarkAllRead"
>
全部标记已读
</el-button>
<el-button v-if="canRead" @click="load">刷新</el-button>
</el-space>
</div>
</template>
<el-alert
v-if="!canRead"
title="当前账号无查看站内通知权限"
type="warning"
show-icon
:closable="false"
class="mb-md"
/>
<el-table v-else :data="displayRows" class="mt-md" empty-text="暂无站内通知">
<el-table-column prop="title" label="标题" min-width="220" />
<el-table-column prop="content" label="内容" min-width="360" show-overflow-tooltip />
<el-table-column prop="status" label="状态" width="100" :formatter="statusFormatter" />
<el-table-column prop="createdAt" label="创建时间" width="180" />
<el-table-column prop="readAt" label="已读时间" width="180" />
<el-table-column label="操作" width="120">
<template #default="{ row }">
<el-button
v-if="canMarkRead && row.status !== 'READ'"
type="primary"
size="small"
@click="handleMarkRead(row.id)"
>
标记已读
</el-button>
<span v-else>-</span>
</template>
</el-table-column>
</el-table>
</PageContainer>
</template>
<script setup lang="ts">
import { computed, onMounted, ref } from "vue";
import { storeToRefs } from "pinia";
import PageContainer from "../../components/PageContainer.vue";
import { ElMessage } from "element-plus";
import { PERMS } from "../../constants/permissions";
import { useAuthStore } from "../../stores/auth";
import { useNotificationStore } from "../../stores/notification";
import { toZhStatus } from "../../utils/status";
const authStore = useAuthStore();
const notificationStore = useNotificationStore();
const { notifRows: rows } = storeToRefs(notificationStore);
const canRead = computed(() => authStore.scope === "TENANT" && authStore.hasPermission(PERMS.notification.inAppRead));
const canMarkRead = computed(
() => authStore.scope === "TENANT" && authStore.hasPermission(PERMS.notification.inAppMarkRead),
);
const onlyUnread = ref(false);
const unreadCount = computed(() => rows.value.filter((item) => String(item?.status || "") === "UNREAD").length);
const displayRows = computed(() =>
onlyUnread.value ? rows.value.filter((item) => String(item?.status || "") === "UNREAD") : rows.value,
);
const statusFormatter = (_row: unknown, _column: unknown, value: unknown) => toZhStatus(value);
const load = async () => {
if (!canRead.value) {
notificationStore.reset();
return;
}
await notificationStore.loadRows();
};
const handleMarkRead = async (id: number) => {
await notificationStore.markRead(id);
ElMessage.success("已标记为已读");
};
const handleMarkAllRead = async () => {
const affected = await notificationStore.markAllRead();
ElMessage.success(affected > 0 ? `已标记 ${affected} 条通知为已读` : "没有未读通知");
};
onMounted(async () => {
await load();
});
</script>
<style scoped>
.header-row {
display: flex;
align-items: center;
justify-content: space-between;
}
</style>