This commit is contained in:
2026-08-12 19:30:17 +08:00
parent 71b3361361
commit 9999f3f26b
4 changed files with 7 additions and 2 deletions
@@ -16,6 +16,8 @@ test('does not accept browser-selected customer or user scope in the API boundar
assert.doesNotMatch(source, /tenantId|customerId|merchantId|userId/)
assert.match(source, /merchant\/v1\/notifications/)
assert.match(source, /unread-count/)
assert.match(source, /notifications\/\$\{encodeURIComponent\(id\)\}/)
assert.match(source, /notifications\/\$\{encodeURIComponent\(id\)\}\/read/)
assert.match(source, /read-all/)
assert.match(source, /category: query\.type/)
assert.match(source, /method: 'PUT'/)
@@ -31,4 +33,6 @@ test('keeps customer message actions first and covers the requested local states
assert.match(source, /标为已读/)
assert.match(source, /state-panel--error/)
assert.match(source, /暂无消息/)
assert.doesNotMatch(source, /清空已读|删除消息/)
assert.match(source, /Promise\.all\(\[load\(\), notifications\.refreshUnreadCount\(\)\]\)/)
})
@@ -10,5 +10,5 @@ const route = useRoute(); const router = useRouter(); const notifications = useN
async function load(){loading.value=true;errorMessage.value='';try{detail.value=await getMyNotification(String(route.params.notificationId));if(detail.value.status==='UNREAD'){await markMyNotificationRead(detail.value.id);detail.value={...detail.value,status:'READ'};await notifications.refreshUnreadCount()}}catch(error){errorMessage.value=error instanceof ApiError?error.message:'消息加载失败,请稍后重试'}finally{loading.value=false}}
onMounted(()=>{void load()})
</script>
<template><div class="notification-detail"><el-button link @click="router.push({ name: 'notifications-list' })"><ArrowLeft :size="16" />返回我的消息</el-button><header class="page-heading"><div><p class="eyebrow">消息详情</p><h1>{{ detail?.title || '消息详情' }}</h1></div><Bell :size="30" /></header><div v-if="errorMessage" class="state-panel state-panel--error" role="alert"><p>{{ errorMessage }}</p><el-button @click="load"><RefreshCcw :size="15" />重试</el-button></div><article v-else v-loading="loading" class="content-card"><p class="meta">{{ detail?.sentAt }} · {{ detail?.type }}</p><p class="content">{{ detail?.content || '暂无消息内容' }}</p></article></div></template>
<template><div class="notification-detail"><el-button link @click="router.push({ name: 'notifications-list' })"><ArrowLeft :size="16" />返回我的消息</el-button><header class="page-heading"><div><p class="eyebrow">消息详情</p><h1>{{ detail?.title || '消息详情' }}</h1></div><Bell :size="30" /></header><div v-if="errorMessage" class="state-panel state-panel--error" role="alert"><p>{{ errorMessage }}</p><el-button @click="load()"><RefreshCcw :size="15" />重试</el-button></div><article v-else v-loading="loading" class="content-card"><p class="meta">{{ detail?.sentAt }} · {{ detail?.type }}</p><p class="content">{{ detail?.content || '暂无消息内容' }}</p></article></div></template>
<style scoped>.notification-detail{display:flex;flex-direction:column;gap:16px}.page-heading{display:flex;justify-content:space-between;color:var(--navy)}.page-heading h1{margin:2px 0 5px;font-size:24px}.eyebrow{margin:0;color:var(--primary);font-size:11px;font-weight:700}.content-card{min-height:240px;padding:24px;border:1px solid var(--border);border-radius:8px;background:var(--surface,#fff)}.meta{color:var(--muted);font-size:12px}.content{white-space:pre-wrap;line-height:1.8;color:var(--navy)}.state-panel{display:flex;min-height:180px;align-items:center;justify-content:center;flex-direction:column;gap:12px}.state-panel--error{color:#b42318;background:#fff8f7;border:1px solid #f5c2bd;border-radius:6px}@media(max-width:720px){.content-card{padding:16px}.page-heading h1{font-size:21px}}</style>
@@ -22,7 +22,7 @@ async function load(nextPage = page.value.page) {
async function markRead(row: NotificationSummary) { try { await markMyNotificationRead(row.id); await Promise.all([load(), notifications.refreshUnreadCount()]) } catch (error) { errorMessage.value = messageOf(error) } }
async function markAllRead() { try { await markAllMyNotificationsRead(); await Promise.all([load(), notifications.refreshUnreadCount()]) } catch (error) { errorMessage.value = messageOf(error) } }
function openDetail(row: NotificationSummary) { void router.push({ name: 'notification-detail', params: { notificationId: row.id } }) }
onMounted(() => { void load() })
onMounted(() => { void Promise.all([load(), notifications.refreshUnreadCount()]) })
</script>
<template>