From 39e59a40774a2a793e87f214203539cb79e43245 Mon Sep 17 00:00:00 2001 From: aits2026 Date: Fri, 6 Mar 2026 14:41:02 +0800 Subject: [PATCH] feat(export): split default media options --- .../Export/ExportDefaultsSettingsForm.scss | 29 +++++++ .../Export/ExportDefaultsSettingsForm.tsx | 83 +++++++++++++++---- src/pages/ExportPage.tsx | 60 ++++++++++++-- src/services/config.ts | 43 +++++++++- 4 files changed, 185 insertions(+), 30 deletions(-) diff --git a/src/components/Export/ExportDefaultsSettingsForm.scss b/src/components/Export/ExportDefaultsSettingsForm.scss index f570820..3ba86b6 100644 --- a/src/components/Export/ExportDefaultsSettingsForm.scss +++ b/src/components/Export/ExportDefaultsSettingsForm.scss @@ -220,6 +220,29 @@ background: var(--bg-primary); } + .media-default-grid { + width: 100%; + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 8px 12px; + margin-bottom: 10px; + + label { + display: inline-flex; + align-items: center; + gap: 6px; + margin-bottom: 0; + font-size: 13px; + font-weight: 500; + color: var(--text-primary); + cursor: pointer; + } + + input { + margin: 0; + } + } + .log-status { font-size: 13px; color: var(--text-secondary); @@ -354,6 +377,11 @@ margin-bottom: 0; } + .media-default-grid { + max-width: 360px; + margin-bottom: 0; + } + .concurrency-inline-options { max-width: 360px; margin-bottom: 0; @@ -391,6 +419,7 @@ .select-field, .settings-time-range-field, .log-toggle-line, + .media-default-grid, .concurrency-inline-options, .format-grid { max-width: none; diff --git a/src/components/Export/ExportDefaultsSettingsForm.tsx b/src/components/Export/ExportDefaultsSettingsForm.tsx index 974aa19..115f705 100644 --- a/src/components/Export/ExportDefaultsSettingsForm.tsx +++ b/src/components/Export/ExportDefaultsSettingsForm.tsx @@ -15,7 +15,7 @@ export interface ExportDefaultsSettingsPatch { format?: string avatars?: boolean dateRange?: ExportDateRangeSelection - media?: boolean + media?: configService.ExportDefaultMediaConfig voiceAsText?: boolean excelCompactColumns?: boolean concurrency?: number @@ -62,7 +62,12 @@ export function ExportDefaultsSettingsForm({ const [exportDefaultFormat, setExportDefaultFormat] = useState('excel') const [exportDefaultAvatars, setExportDefaultAvatars] = useState(true) const [exportDefaultDateRange, setExportDefaultDateRange] = useState(() => createDefaultExportDateRangeSelection()) - const [exportDefaultMedia, setExportDefaultMedia] = useState(false) + const [exportDefaultMedia, setExportDefaultMedia] = useState({ + images: true, + videos: true, + voices: true, + emojis: true + }) const [exportDefaultVoiceAsText, setExportDefaultVoiceAsText] = useState(false) const [exportDefaultExcelCompactColumns, setExportDefaultExcelCompactColumns] = useState(true) const [exportDefaultConcurrency, setExportDefaultConcurrency] = useState(2) @@ -85,7 +90,12 @@ export function ExportDefaultsSettingsForm({ setExportDefaultFormat(savedFormat || 'excel') setExportDefaultAvatars(savedAvatars ?? true) setExportDefaultDateRange(resolveExportDateRangeConfig(savedDateRange)) - setExportDefaultMedia(savedMedia ?? false) + setExportDefaultMedia(savedMedia ?? { + images: true, + videos: true, + voices: true, + emojis: true + }) setExportDefaultVoiceAsText(savedVoiceAsText ?? false) setExportDefaultExcelCompactColumns(savedExcelCompactColumns ?? true) setExportDefaultConcurrency(savedConcurrency ?? 2) @@ -237,27 +247,66 @@ export function ExportDefaultsSettingsForm({
- - 控制图片/语音/表情的默认导出开关 + + 控制图片、视频、语音、表情包的默认导出开关
-
- {exportDefaultMedia ? '已开启' : '已关闭'} -
diff --git a/src/pages/ExportPage.tsx b/src/pages/ExportPage.tsx index 89449ea..bcdb977 100644 --- a/src/pages/ExportPage.tsx +++ b/src/pages/ExportPage.tsx @@ -1288,7 +1288,12 @@ function ExportPage() { const [exportDefaultFormat, setExportDefaultFormat] = useState('excel') const [exportDefaultAvatars, setExportDefaultAvatars] = useState(true) const [exportDefaultDateRangeSelection, setExportDefaultDateRangeSelection] = useState(() => createDefaultExportDateRangeSelection()) - const [exportDefaultMedia, setExportDefaultMedia] = useState(false) + const [exportDefaultMedia, setExportDefaultMedia] = useState({ + images: true, + videos: true, + voices: true, + emojis: true + }) const [exportDefaultVoiceAsText, setExportDefaultVoiceAsText] = useState(false) const [exportDefaultExcelCompactColumns, setExportDefaultExcelCompactColumns] = useState(true) const [exportDefaultConcurrency, setExportDefaultConcurrency] = useState(2) @@ -1301,11 +1306,11 @@ function ExportPage() { }, useAllTime: false, exportAvatars: true, - exportMedia: false, + exportMedia: true, exportImages: true, exportVoices: true, exportVideos: true, - exportEmojis: true, + exportEmojis: true, exportVoiceAsText: false, excelCompactColumns: true, txtColumns: defaultTxtColumns, @@ -1831,7 +1836,12 @@ function ExportPage() { setLastSnsExportPostCount(savedSnsPostCount) setExportDefaultFormat((savedFormat as TextExportFormat) || 'excel') setExportDefaultAvatars(savedAvatars ?? true) - setExportDefaultMedia(savedMedia ?? false) + setExportDefaultMedia(savedMedia ?? { + images: true, + videos: true, + voices: true, + emojis: true + }) setExportDefaultVoiceAsText(savedVoiceAsText ?? false) setExportDefaultExcelCompactColumns(savedExcelCompactColumns ?? true) setExportDefaultConcurrency(savedConcurrency ?? 2) @@ -1854,7 +1864,16 @@ function ExportPage() { ...prev, format: ((savedFormat as TextExportFormat) || 'excel'), exportAvatars: savedAvatars ?? true, - exportMedia: savedMedia ?? prev.exportMedia, + exportMedia: Boolean( + (savedMedia?.images ?? prev.exportImages) || + (savedMedia?.voices ?? prev.exportVoices) || + (savedMedia?.videos ?? prev.exportVideos) || + (savedMedia?.emojis ?? prev.exportEmojis) + ), + exportImages: savedMedia?.images ?? prev.exportImages, + exportVoices: savedMedia?.voices ?? prev.exportVoices, + exportVideos: savedMedia?.videos ?? prev.exportVideos, + exportEmojis: savedMedia?.emojis ?? prev.exportEmojis, exportVoiceAsText: savedVoiceAsText ?? prev.exportVoiceAsText, excelCompactColumns: savedExcelCompactColumns ?? prev.excelCompactColumns, txtColumns, @@ -3214,7 +3233,16 @@ function ExportPage() { exportAvatars: exportDefaultAvatars, useAllTime: exportDefaultDateRangeSelection.useAllTime, dateRange: nextDateRange, - exportMedia: exportDefaultMedia, + exportMedia: Boolean( + exportDefaultMedia.images || + exportDefaultMedia.voices || + exportDefaultMedia.videos || + exportDefaultMedia.emojis + ), + exportImages: exportDefaultMedia.images, + exportVoices: exportDefaultMedia.voices, + exportVideos: exportDefaultMedia.videos, + exportEmojis: exportDefaultMedia.emojis, exportVoiceAsText: exportDefaultVoiceAsText, excelCompactColumns: exportDefaultExcelCompactColumns, exportConcurrency: exportDefaultConcurrency @@ -3772,7 +3800,12 @@ function ExportPage() { await configService.setExportDefaultFormat(options.format) await configService.setExportDefaultAvatars(options.exportAvatars) - await configService.setExportDefaultMedia(Boolean(options.exportImages || options.exportVoices || options.exportVideos || options.exportEmojis)) + await configService.setExportDefaultMedia({ + images: options.exportImages, + voices: options.exportVoices, + videos: options.exportVideos, + emojis: options.exportEmojis + }) await configService.setExportDefaultVoiceAsText(options.exportVoiceAsText) await configService.setExportDefaultExcelCompactColumns(options.excelCompactColumns) await configService.setExportDefaultTxtColumns(options.txtColumns) @@ -5215,8 +5248,17 @@ function ExportPage() { if (patch.dateRange) { setExportDefaultDateRangeSelection(patch.dateRange) } - if (typeof patch.media === 'boolean') { - setExportDefaultMedia(patch.media) + if (patch.media) { + const mediaPatch = patch.media + setExportDefaultMedia(mediaPatch) + setOptions(prev => ({ + ...prev, + exportMedia: Boolean(mediaPatch.images || mediaPatch.voices || mediaPatch.videos || mediaPatch.emojis), + exportImages: mediaPatch.images, + exportVoices: mediaPatch.voices, + exportVideos: mediaPatch.videos, + exportEmojis: mediaPatch.emojis + })) } if (typeof patch.voiceAsText === 'boolean') { setExportDefaultVoiceAsText(patch.voiceAsText) diff --git a/src/services/config.ts b/src/services/config.ts index 0ac5008..2cd8787 100644 --- a/src/services/config.ts +++ b/src/services/config.ts @@ -78,6 +78,20 @@ export interface WxidConfig { updatedAt?: number } +export interface ExportDefaultMediaConfig { + images: boolean + videos: boolean + voices: boolean + emojis: boolean +} + +const DEFAULT_EXPORT_MEDIA_CONFIG: ExportDefaultMediaConfig = { + images: true, + videos: true, + voices: true, + emojis: true +} + // 获取解密密钥 export async function getDecryptKey(): Promise { const value = await config.get(CONFIG_KEYS.DECRYPT_KEY) @@ -364,15 +378,36 @@ export async function setExportDefaultDateRange(range: ExportDefaultDateRangeCon } // 获取导出默认媒体设置 -export async function getExportDefaultMedia(): Promise { +export async function getExportDefaultMedia(): Promise { const value = await config.get(CONFIG_KEYS.EXPORT_DEFAULT_MEDIA) - if (typeof value === 'boolean') return value + if (typeof value === 'boolean') { + return { + images: value, + videos: value, + voices: value, + emojis: value + } + } + if (value && typeof value === 'object') { + const raw = value as Partial> + return { + images: typeof raw.images === 'boolean' ? raw.images : DEFAULT_EXPORT_MEDIA_CONFIG.images, + videos: typeof raw.videos === 'boolean' ? raw.videos : DEFAULT_EXPORT_MEDIA_CONFIG.videos, + voices: typeof raw.voices === 'boolean' ? raw.voices : DEFAULT_EXPORT_MEDIA_CONFIG.voices, + emojis: typeof raw.emojis === 'boolean' ? raw.emojis : DEFAULT_EXPORT_MEDIA_CONFIG.emojis + } + } return null } // 设置导出默认媒体设置 -export async function setExportDefaultMedia(enabled: boolean): Promise { - await config.set(CONFIG_KEYS.EXPORT_DEFAULT_MEDIA, enabled) +export async function setExportDefaultMedia(media: ExportDefaultMediaConfig): Promise { + await config.set(CONFIG_KEYS.EXPORT_DEFAULT_MEDIA, { + images: media.images, + videos: media.videos, + voices: media.voices, + emojis: media.emojis + }) } // 获取导出默认语音转文字