mirror of
https://wget.la/https://github.com/Wxw-Gu/WechatExplorer
synced 2026-10-05 12:34:35 +08:00
feat: 退群监控增加重新发送功能
This commit is contained in:
@@ -1175,6 +1175,9 @@ app.whenReady().then(async () => {
|
||||
)
|
||||
ipcMain.handle('group-exit-monitor:checkNow', () => groupExitMonitorService.checkNow())
|
||||
ipcMain.handle('group-exit-monitor:clearEvents', () => groupExitMonitorService.clearEvents())
|
||||
ipcMain.handle('group-exit-monitor:resendEvent', (_, eventId: string) =>
|
||||
groupExitMonitorService.resendEvent(eventId)
|
||||
)
|
||||
ipcMain.handle('group-exit-monitor:markRead', (_, readAt?: number) =>
|
||||
groupExitMonitorService.markRead(readAt)
|
||||
)
|
||||
|
||||
@@ -602,7 +602,8 @@ class GroupExitMonitorService {
|
||||
|
||||
private async notifyGroup(
|
||||
group: GroupSnapshotRecord,
|
||||
event: GroupExitMonitorEvent
|
||||
event: GroupExitMonitorEvent,
|
||||
idempotencyKey = `member_left_notification:${event.id}`
|
||||
): Promise<void> {
|
||||
event.notificationStatus = 'pending'
|
||||
event.notification = { status: 'pending' }
|
||||
@@ -610,7 +611,7 @@ class GroupExitMonitorService {
|
||||
this.broadcast()
|
||||
try {
|
||||
const result = await this.actionGateway.execute({
|
||||
idempotencyKey: `member_left_notification:${event.id}`,
|
||||
idempotencyKey,
|
||||
origin: 'member_monitor',
|
||||
purpose: 'member_left_notification',
|
||||
triggerType: 'automation',
|
||||
@@ -665,6 +666,17 @@ class GroupExitMonitorService {
|
||||
}
|
||||
}
|
||||
|
||||
async resendEvent(eventId: string): Promise<GroupExitMonitorState> {
|
||||
const event = this.events.find((item) => item.id === eventId)
|
||||
if (!event) throw new Error('退群动态不存在')
|
||||
await this.notifyGroup(
|
||||
{ roomId: event.roomId, groupName: event.groupName } as GroupSnapshotRecord,
|
||||
event,
|
||||
`member_left_notification:${event.id}:retry:${Date.now()}`
|
||||
)
|
||||
return this.getState()
|
||||
}
|
||||
|
||||
private filePath(): string {
|
||||
return path.join(app.getPath('userData'), 'group-exit-monitor.json')
|
||||
}
|
||||
|
||||
Vendored
+1
@@ -275,6 +275,7 @@ declare global {
|
||||
setGroupExitMonitorNotificationTemplate: (template: string) => Promise<GroupExitMonitorState>
|
||||
checkGroupExitMonitorNow: () => Promise<GroupExitMonitorState>
|
||||
clearGroupExitMonitorEvents: () => Promise<GroupExitMonitorState>
|
||||
resendGroupExitMonitorEvent: (eventId: string) => Promise<GroupExitMonitorState>
|
||||
markGroupExitMonitorRead: (readAt?: number) => Promise<GroupExitMonitorState>
|
||||
listWechatActionLogs: () => Promise<ActionLogEntry[]>
|
||||
onGroupExitMonitorState: (callback: (state: GroupExitMonitorState) => void) => () => void
|
||||
|
||||
@@ -155,6 +155,8 @@ const api = {
|
||||
ipcRenderer.invoke('group-exit-monitor:checkNow'),
|
||||
clearGroupExitMonitorEvents: (): Promise<GroupExitMonitorState> =>
|
||||
ipcRenderer.invoke('group-exit-monitor:clearEvents'),
|
||||
resendGroupExitMonitorEvent: (eventId: string): Promise<GroupExitMonitorState> =>
|
||||
ipcRenderer.invoke('group-exit-monitor:resendEvent', eventId),
|
||||
markGroupExitMonitorRead: (readAt?: number): Promise<GroupExitMonitorState> =>
|
||||
ipcRenderer.invoke('group-exit-monitor:markRead', readAt),
|
||||
listWechatActionLogs: (): Promise<ActionLogEntry[]> =>
|
||||
|
||||
@@ -85,10 +85,14 @@ const sendCapabilityTone = (capability: PersonalWechatSendCapability | null): st
|
||||
|
||||
function EventNotificationStatus({
|
||||
event,
|
||||
onOpenSendSettings
|
||||
onOpenSendSettings,
|
||||
onResend,
|
||||
resending
|
||||
}: {
|
||||
event: GroupExitMonitorState['events'][number]
|
||||
onOpenSendSettings?: () => void
|
||||
onResend?: () => void
|
||||
resending?: boolean
|
||||
}): React.ReactElement {
|
||||
const status = event.notificationStatus || event.notification?.status || 'not_requested'
|
||||
const details =
|
||||
@@ -120,6 +124,11 @@ function EventNotificationStatus({
|
||||
去设置
|
||||
</Button>
|
||||
) : null}
|
||||
{status !== 'sent' && status !== 'pending' && onResend ? (
|
||||
<Button variant="link" size="sm" onClick={onResend} disabled={resending}>
|
||||
{resending ? '发送中...' : '重新发送'}
|
||||
</Button>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -455,6 +464,7 @@ export function GroupExitMonitorWorkspace({
|
||||
const [templateError, setTemplateError] = React.useState('')
|
||||
const [selectedRoomId, setSelectedRoomId] = React.useState('all')
|
||||
const [view, setView] = React.useState<'events' | 'manage'>('events')
|
||||
const [resendingEventId, setResendingEventId] = React.useState<string | null>(null)
|
||||
const [manageKeyword, setManageKeyword] = React.useState('')
|
||||
const [manageFilter, setManageFilter] = React.useState<GroupSelectionFilter>('all')
|
||||
const [selectedManageRoomIds, setSelectedManageRoomIds] = React.useState<Set<string>>(
|
||||
@@ -594,6 +604,19 @@ export function GroupExitMonitorWorkspace({
|
||||
}
|
||||
}
|
||||
|
||||
const resendEvent = async (eventId: string): Promise<void> => {
|
||||
if (resendingEventId || typeof window.api.resendGroupExitMonitorEvent !== 'function') return
|
||||
setResendingEventId(eventId)
|
||||
setError('')
|
||||
try {
|
||||
setState(await window.api.resendGroupExitMonitorEvent(eventId))
|
||||
} catch (reason) {
|
||||
setError(reason instanceof Error ? reason.message : String(reason))
|
||||
} finally {
|
||||
setResendingEventId(null)
|
||||
}
|
||||
}
|
||||
|
||||
const saveGroups = async (): Promise<void> => {
|
||||
const api = window.api
|
||||
if (saving || !dbReady || typeof api.setGroupExitMonitorGroups !== 'function') return
|
||||
@@ -857,6 +880,8 @@ export function GroupExitMonitorWorkspace({
|
||||
<EventNotificationStatus
|
||||
event={event}
|
||||
onOpenSendSettings={onOpenSendSettings}
|
||||
onResend={() => void resendEvent(event.id)}
|
||||
resending={resendingEventId === event.id}
|
||||
/>
|
||||
<dl className="exit-monitor-event-details">
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user