通知系统-1
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
<script setup lang="ts">
|
||||
import type { AdminNotificationTestResult } from '@/types/admin'
|
||||
import type { EditableNotificationRecipient } from '@/composables/admin/platform-shops/types'
|
||||
|
||||
type Props = {
|
||||
notificationFilePath: string
|
||||
notificationForm: {
|
||||
enabled: boolean
|
||||
barkEnabled: boolean
|
||||
barkServerUrl: string
|
||||
testTitle: string
|
||||
testBody: string
|
||||
testUrl: string
|
||||
}
|
||||
notificationRecipients: EditableNotificationRecipient[]
|
||||
notificationSaving: boolean
|
||||
notificationTesting: boolean
|
||||
notificationResultError: string
|
||||
notificationTestResult: AdminNotificationTestResult | null
|
||||
notificationStats: {
|
||||
configuredRecipientCount: number
|
||||
enabledRecipientCount: number
|
||||
barkReady: boolean
|
||||
lastSuccessCount: number
|
||||
lastFailedCount: number
|
||||
}
|
||||
addNotificationRecipient: () => void
|
||||
removeNotificationRecipient: (id: string) => void
|
||||
handleNotificationSaveConfig: () => void | Promise<void>
|
||||
handleNotificationTest: () => void | Promise<void>
|
||||
}
|
||||
|
||||
defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="meta-card">
|
||||
<div class="meta-line">
|
||||
<span class="meta-label">职责</span>
|
||||
<span>内部运营通知,仅发送给后台管理员、客服或值班人员。</span>
|
||||
</div>
|
||||
<div class="meta-line">
|
||||
<span class="meta-label">配置文件</span>
|
||||
<span>{{ notificationFilePath || '-' }}</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="table-card">
|
||||
<div class="section-title-row">
|
||||
<div>
|
||||
<h3>Bark 通知</h3>
|
||||
<p>已配置 {{ notificationStats.configuredRecipientCount }} 人,启用 {{ notificationStats.enabledRecipientCount }} 人。</p>
|
||||
</div>
|
||||
<div class="section-actions">
|
||||
<el-button round @click="addNotificationRecipient">新增接收人</el-button>
|
||||
<el-button :loading="notificationSaving" round type="primary" @click="handleNotificationSaveConfig">保存配置</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p v-if="notificationResultError" class="error-copy">{{ notificationResultError }}</p>
|
||||
|
||||
<div class="form-grid">
|
||||
<label class="checkbox-line">
|
||||
<input v-model="notificationForm.enabled" class="checkbox-box" type="checkbox" />
|
||||
<span>启用内部通知</span>
|
||||
</label>
|
||||
<label class="checkbox-line">
|
||||
<input v-model="notificationForm.barkEnabled" class="checkbox-box" type="checkbox" />
|
||||
<span>启用 Bark 通道</span>
|
||||
</label>
|
||||
<label class="field-block field-wide">
|
||||
<span>Bark 服务地址</span>
|
||||
<input v-model="notificationForm.barkServerUrl" class="text-input" placeholder="https://api.day.app" />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>接收人</th>
|
||||
<th>Device Key</th>
|
||||
<th>状态</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="item in notificationRecipients" :key="item.id">
|
||||
<td>
|
||||
<input v-model="item.name" class="text-input" placeholder="例如:客服A" />
|
||||
</td>
|
||||
<td>
|
||||
<input v-model="item.deviceKey" class="text-input" placeholder="Bark device key" />
|
||||
</td>
|
||||
<td>
|
||||
<label class="checkbox-line">
|
||||
<input v-model="item.enabled" class="checkbox-box" type="checkbox" />
|
||||
<span>{{ item.enabled ? '启用' : '停用' }}</span>
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<el-button link type="danger" @click="removeNotificationRecipient(item.id)">删除</el-button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="notificationRecipients.length === 0">
|
||||
<td colspan="4" class="empty-inline">还没有 Bark 接收人。</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<section class="table-card">
|
||||
<div class="section-title-row">
|
||||
<div>
|
||||
<h3>测试发送</h3>
|
||||
<p>测试会发送给所有已启用且填写了 Device Key 的接收人。</p>
|
||||
</div>
|
||||
<div class="section-actions">
|
||||
<el-button :disabled="!notificationStats.barkReady" :loading="notificationTesting" round type="primary" @click="handleNotificationTest">发送测试</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-grid">
|
||||
<label class="field-block">
|
||||
<span>标题</span>
|
||||
<input v-model="notificationForm.testTitle" class="text-input" />
|
||||
</label>
|
||||
<label class="field-block field-wide">
|
||||
<span>内容</span>
|
||||
<input v-model="notificationForm.testBody" class="text-input" />
|
||||
</label>
|
||||
<label class="field-block field-wide">
|
||||
<span>跳转链接</span>
|
||||
<input v-model="notificationForm.testUrl" class="text-input" placeholder="可选" />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div v-if="notificationTestResult" class="result-grid">
|
||||
<div class="result-card">
|
||||
<span class="result-label">成功</span>
|
||||
<strong>{{ notificationTestResult.successCount }}</strong>
|
||||
</div>
|
||||
<div class="result-card">
|
||||
<span class="result-label">失败</span>
|
||||
<strong>{{ notificationTestResult.failedCount }}</strong>
|
||||
</div>
|
||||
<div class="result-card">
|
||||
<span class="result-label">通道</span>
|
||||
<strong>{{ notificationTestResult.channel || '-' }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table v-if="notificationTestResult" class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>接收人</th>
|
||||
<th>结果</th>
|
||||
<th>状态码</th>
|
||||
<th>说明</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="item in notificationTestResult.results" :key="item.recipientId || item.recipientKeyMasked">
|
||||
<td>{{ item.recipientName || item.recipientKeyMasked || '-' }}</td>
|
||||
<td>{{ item.ok ? '成功' : '失败' }}</td>
|
||||
<td>{{ item.status || '-' }}</td>
|
||||
<td>{{ item.errorMessage || '-' }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
</template>
|
||||
Reference in New Issue
Block a user