feat: 建立发送网关与动作审计

This commit is contained in:
Wxw-Gu
2026-09-02 18:00:39 +08:00
parent 76e9e683c4
commit e1f4ec79dd
10 changed files with 1411 additions and 88 deletions
@@ -80,6 +80,38 @@ const sendCapabilityLabel = (capability: PersonalWechatSendCapability | null): s
const sendCapabilityTone = (capability: PersonalWechatSendCapability | null): string =>
capability?.ready && capability.capabilities.text ? 'ready' : 'unready'
function EventNotificationStatus({
event
}: {
event: GroupExitMonitorState['events'][number]
}): React.ReactElement {
const status = event.notificationStatus || event.notification?.status || 'not_requested'
const details =
status === 'sent'
? { label: '已通知当前群聊', tone: 'sent', description: '' }
: status === 'pending'
? { label: '正在通知当前群聊', tone: 'pending', description: '' }
: status === 'blocked'
? { label: '通知已拦截', tone: 'blocked', description: '该操作未通过发送策略检查。' }
: status === 'failed'
? {
label: '通知未发送',
tone: 'failed',
description:
event.notification?.errorCode === 'SEND_CAPABILITY_UNAVAILABLE' ||
event.notification?.errorCode === 'SEND_NOT_READY'
? '当前微信发送能力不可用,退群事件已正常记录。'
: '退群事件已正常记录,但通知发送失败。'
}
: { label: '仅记录', tone: 'recorded', description: '' }
return (
<div className={`exit-monitor-event-notification ${details.tone}`}>
<span>{details.label}</span>
{details.description ? <small>{details.description}</small> : null}
</div>
)
}
function SendCapabilityStatus({
capability,
className = ''
@@ -783,6 +815,7 @@ export function GroupExitMonitorWorkspace({
群人数 {event.previousCount} 人 → {event.currentCount} 人
</p>
) : null}
<EventNotificationStatus event={event} />
<dl className="exit-monitor-event-details">
<div>
<dt>微信名</dt>
@@ -350,6 +350,40 @@
color: var(--wxex-danger);
}
.exit-monitor-event-notification {
display: flex;
flex-wrap: wrap;
align-items: baseline;
gap: 6px;
margin-top: 7px;
color: var(--wxex-text-secondary);
font-size: 12px;
line-height: 18px;
}
.exit-monitor-event-notification span {
font-weight: 600;
}
.exit-monitor-event-notification small {
color: var(--wxex-text-muted);
font-size: 11px;
line-height: 18px;
}
.exit-monitor-event-notification.sent {
color: var(--wxex-success);
}
.exit-monitor-event-notification.blocked,
.exit-monitor-event-notification.failed {
color: var(--wxex-danger);
}
.exit-monitor-event-notification.pending {
color: var(--wxex-brand);
}
.exit-monitor-event-details {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));