fix: 增加手动复制退群信息 以及设置页面文案

This commit is contained in:
Wxw-Gu
2026-09-15 10:36:09 +08:00
parent 389a853560
commit ff212d594c
5 changed files with 160 additions and 3 deletions
@@ -22,7 +22,9 @@ import type { Contact } from '../../../../shared/types'
import {
GROUP_EXIT_NOTIFICATION_TEMPLATE,
GROUP_EXIT_NOTIFICATION_TEMPLATE_MAX_LENGTH,
renderGroupExitMonitorNotification,
validateGroupExitNotificationTemplate,
type GroupExitMonitorEvent,
type GroupExitMonitorState
} from '../../../../shared/group-exit-monitor'
import type { PersonalWechatSendCapability } from '../../../../shared/personal-wechat'
@@ -465,6 +467,8 @@ export function GroupExitMonitorWorkspace({
const [selectedRoomId, setSelectedRoomId] = React.useState('all')
const [view, setView] = React.useState<'events' | 'manage'>('events')
const [resendingEventId, setResendingEventId] = React.useState<string | null>(null)
const [copiedEventId, setCopiedEventId] = React.useState('')
const copyResetTimer = React.useRef<number | null>(null)
const [manageKeyword, setManageKeyword] = React.useState('')
const [manageFilter, setManageFilter] = React.useState<GroupSelectionFilter>('all')
const [selectedManageRoomIds, setSelectedManageRoomIds] = React.useState<Set<string>>(
@@ -522,6 +526,13 @@ export function GroupExitMonitorWorkspace({
}
}, [])
React.useEffect(
() => () => {
if (copyResetTimer.current !== null) window.clearTimeout(copyResetTimer.current)
},
[]
)
const groupOptions = React.useMemo(() => {
const optionMap = new Map<string, { roomId: string; groupName: string; count: number }>()
for (const event of state.events) {
@@ -617,6 +628,28 @@ export function GroupExitMonitorWorkspace({
}
}
/**
* 手动复制退群信息:按“管理群聊”里保存的模板拼接当前事件,只写系统剪贴板,
* 不触发任何微信发送,用户自行决定粘贴到哪里。
*/
const copyEventNotification = async (event: GroupExitMonitorEvent): Promise<void> => {
const api = typeof window !== 'undefined' ? window.api : undefined
const text = renderGroupExitMonitorNotification(event, notificationTemplate)
setError('')
try {
const result = api && typeof api.copyText === 'function' ? await api.copyText(text) : null
if (!result?.success) throw new Error(result?.error || '复制失败,请重试')
setCopiedEventId(event.id)
if (copyResetTimer.current !== null) window.clearTimeout(copyResetTimer.current)
copyResetTimer.current = window.setTimeout(() => {
copyResetTimer.current = null
setCopiedEventId('')
}, 2_000)
} catch (reason) {
setError(reason instanceof Error ? reason.message : String(reason))
}
}
const saveGroups = async (): Promise<void> => {
const api = window.api
if (saving || !dbReady || typeof api.setGroupExitMonitorGroups !== 'function') return
@@ -868,9 +901,20 @@ export function GroupExitMonitorWorkspace({
<div className="exit-monitor-event-body">
<div className="exit-monitor-event-heading">
<strong>{event.message}</strong>
<time dateTime={new Date(event.detectedAt).toISOString()}>
{formatDetectedAt(event.detectedAt)}
</time>
<div className="exit-monitor-event-side">
<time dateTime={new Date(event.detectedAt).toISOString()}>
{formatDetectedAt(event.detectedAt)}
</time>
<Button
variant="link"
size="sm"
className="exit-monitor-event-copy"
onClick={() => void copyEventNotification(event)}
aria-label={`复制退群信息:${event.message}`}
>
{copiedEventId === event.id ? '已复制' : '复制退群信息'}
</Button>
</div>
</div>
{event.previousCount > event.currentCount ? (
<p className="exit-monitor-event-count">
@@ -36,6 +36,10 @@ function formatBytes(value: number): string {
return `${(value / 1024 / 1024).toFixed(1)} MB`
}
const REPOSITORY_URL = 'https://github.com/Wxw-Gu/TraceMemo'
// README 就是仓库首页,跳转后需要的正是「交流与反馈」这一节(含群二维码)。
const GROUP_README_URL = `${REPOSITORY_URL}#-交流与反馈`
const capabilityLabel: Record<PersonalWechatSendCapability['status'], string> = {
unsupported: '暂不支持',
unconfigured: '尚未配置',
@@ -507,6 +511,23 @@ export function PersonalWechatSendPage({
</Button>
</div>
</section>
<h2 className="settings-section-heading">发送能力授权</h2>
<section className="settings-card grid gap-2">
<p>发送能力属授权制,需要联系群主。请先加入交流群,然后在群内添加群主申请授权。</p>
<p className="settings-footnote">
进群请点击{' '}
<a
className="text-primary hover:underline"
href={GROUP_README_URL}
target="_blank"
rel="noreferrer"
>
这里
</a>{' '}
跳转。
</p>
</section>
</>
) : isMac ? (
<>
@@ -337,6 +337,19 @@
white-space: nowrap;
}
.exit-monitor-event-side {
display: flex;
flex: 0 0 auto;
flex-direction: column;
align-items: flex-end;
gap: 2px;
}
.exit-monitor-event-side .exit-monitor-event-copy {
font-size: 11px;
line-height: 18px;
}
.exit-monitor-event-count {
display: block;
margin: 5px 0 0;
@@ -707,6 +720,13 @@
margin-top: 3px;
}
.exit-monitor-event-side {
flex-direction: row;
align-items: baseline;
justify-content: flex-start;
gap: 10px;
}
.exit-monitor-event-details {
grid-template-columns: 1fr;
}