From 5c08304b6d9f6340d1220a469c7dc83e15edfdec Mon Sep 17 00:00:00 2001 From: mtvpls Date: Wed, 21 Jan 2026 00:16:42 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BD=91=E7=BB=9C=E7=9B=B4=E6=92=AD=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=BC=80=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/admin/page.tsx | 110 ++++++++++++++++++++++++++ src/app/api/admin/web-live/route.ts | 6 ++ src/app/api/web-live/sources/route.ts | 2 + src/app/layout.tsx | 4 + src/app/web-live/page.tsx | 42 +++++++++- src/components/MobileBottomNav.tsx | 10 ++- src/components/Sidebar.tsx | 10 ++- src/lib/admin.types.ts | 1 + 8 files changed, 177 insertions(+), 8 deletions(-) diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index 8f0625f..9d09b16 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -10734,6 +10734,9 @@ const WebLiveConfig = ({ platform: 'huya', roomId: '', }); + const [showDisclaimerModal, setShowDisclaimerModal] = useState(false); + const [countdown, setCountdown] = useState(10); + const [isEnabling, setIsEnabling] = useState(false); useEffect(() => { if (config?.WebLiveConfig) { @@ -10741,6 +10744,14 @@ const WebLiveConfig = ({ } }, [config]); + useEffect(() => { + let timer: NodeJS.Timeout; + if (showDisclaimerModal && countdown > 0) { + timer = setTimeout(() => setCountdown(countdown - 1), 1000); + } + return () => clearTimeout(timer); + }, [showDisclaimerModal, countdown]); + const callApi = async (body: Record) => { try { const resp = await fetch('/api/admin/web-live', { @@ -10798,12 +10809,111 @@ const WebLiveConfig = ({ withLoading(`deleteWebLive_${key}`, () => callApi({ action: 'delete', key })).catch(() => {}); }; + const handleToggleWebLiveEnabled = async () => { + const currentEnabled = config?.WebLiveEnabled ?? false; + + if (!currentEnabled) { + setShowDisclaimerModal(true); + setCountdown(10); + } else { + await withLoading('toggleWebLiveEnabled', async () => { + await callApi({ action: 'toggleEnabled', enabled: false }); + }).catch(() => {}); + } + }; + + const handleConfirmEnable = async () => { + setIsEnabling(true); + try { + await callApi({ action: 'toggleEnabled', enabled: true }); + setShowDisclaimerModal(false); + setCountdown(10); + } catch (err) { + // Error already handled by callApi + } finally { + setIsEnabling(false); + } + }; + if (!config) { return
加载中...
; } return (
+ {/* 功能总开关 */} +
+
+
+

+ 网络直播功能总开关 +

+

+ 关闭后,侧边栏和底部导航栏的网络直播入口将被隐藏,用户无法访问网络直播页面 +

+
+ +
+
+ + {/* 免责声明弹窗 */} + {showDisclaimerModal && createPortal( +
+
+
+
+ +
+ +

+ 免责声明 +

+ +
+

+ 本功能仅供个人学习和技术研究使用,请勿将其部署在公网环境中,更不得用于任何违法违规行为。 + 使用本功能所产生的一切法律责任由使用者自行承担,与开发者无关。 + 启用此功能即表示您已充分理解并同意承担相应风险。 +

+
+ +
+ + +
+
+
+
, + document.body + )} +

网络直播列表