diff --git a/soul-admin/src/pages/content/ContentPage.tsx b/soul-admin/src/pages/content/ContentPage.tsx index 1a817d96..c1afbc55 100644 --- a/soul-admin/src/pages/content/ContentPage.tsx +++ b/soul-admin/src/pages/content/ContentPage.tsx @@ -352,6 +352,60 @@ export function ContentPage() { } } + const loadPinnedSections = useCallback(async () => { + setPinnedLoading(true) + try { + const data = await get<{ success?: boolean; data?: string[] }>( + '/api/db/config/full?key=pinned_section_ids', + { cache: 'no-store' as RequestCache }, + ) + const d = data && (data as { data?: string[] }).data + if (Array.isArray(d)) setPinnedSectionIds(d) + } catch { /* keep default */ } finally { setPinnedLoading(false) } + }, []) + + const handleTogglePin = async (sectionId: string) => { + const next = pinnedSectionIds.includes(sectionId) + ? pinnedSectionIds.filter((id) => id !== sectionId) + : [...pinnedSectionIds, sectionId] + setPinnedSectionIds(next) + try { + await post<{ success?: boolean }>('/api/db/config', { + key: 'pinned_section_ids', + value: next, + description: '强制置顶章节ID列表(精选推荐/首页最新更新)', + }) + } catch { setPinnedSectionIds(pinnedSectionIds) } + } + + const loadPreviewPercent = useCallback(async () => { + setPreviewPercentLoading(true) + try { + const data = await get<{ success?: boolean; data?: number }>( + '/api/db/config/full?key=unpaid_preview_percent', + { cache: 'no-store' as RequestCache }, + ) + const d = data && (data as { data?: number }).data + if (typeof d === 'number' && d > 0 && d <= 100) setPreviewPercent(d) + } catch { /* keep default */ } finally { setPreviewPercentLoading(false) } + }, []) + + const handleSavePreviewPercent = async () => { + if (previewPercent < 1 || previewPercent > 100) { alert('预览比例需在 1~100 之间'); return } + setPreviewPercentSaving(true) + try { + const res = await post<{ success?: boolean; error?: string }>('/api/db/config', { + key: 'unpaid_preview_percent', + value: previewPercent, + description: '小程序未付费内容默认预览比例(%)', + }) + if (res && (res as { success?: boolean }).success !== false) alert('已保存') + else alert('保存失败: ' + ((res as { error?: string }).error || '')) + } catch { alert('保存失败') } finally { setPreviewPercentSaving(false) } + } + + useEffect(() => { loadPinnedSections(); loadPreviewPercent() }, [loadPinnedSections, loadPreviewPercent]) + const handleShowSectionOrders = async (section: Section & { filePath?: string }) => { setSectionOrdersModal({ section, orders: [] }) setSectionOrdersLoading(true)