From 25163789ca3873766c8bae5a434862893a02c7ad Mon Sep 17 00:00:00 2001 From: zzlgreat Date: Mon, 10 Nov 2025 10:36:29 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E4=B8=AD=E5=BF=83=E4=B8=8D?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E9=80=9A=E7=9F=A5=E4=BF=AE=E5=A4=8D=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BC=80=E5=90=AF/=E5=85=B3=E9=97=AD?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E6=8C=89=E9=92=AE=E3=80=82=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?edge=E6=88=96=E8=80=85opera=E6=B5=8F=E8=A7=88=E5=99=A8=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=89=AB=E7=A0=81=E6=97=A0=E8=B7=B3=E8=BD=AC=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Auth/WechatRegister.js | 16 ++-- .../Community/components/DynamicNewsCard.js | 89 ++++++++++++++++++- src/views/Community/index.js | 89 ++++++++++++++++--- 3 files changed, 172 insertions(+), 22 deletions(-) diff --git a/src/components/Auth/WechatRegister.js b/src/components/Auth/WechatRegister.js index b5d221e1..d878afaf 100644 --- a/src/components/Auth/WechatRegister.js +++ b/src/components/Auth/WechatRegister.js @@ -508,19 +508,19 @@ export default function WechatRegister() { title="微信扫码登录" width="300" height="350" - scrolling="no" // ✅ 新增:禁止滚动 - // sandbox="allow-scripts allow-same-origin allow-forms" // ✅ 阻止iframe跳转父页面 + scrolling="no" + sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-top-navigation" + allow="clipboard-write" style={{ border: 'none', - transform: 'scale(0.77) translateY(-35px)', // ✅ 裁剪顶部logo + transform: 'scale(0.77) translateY(-35px)', transformOrigin: 'top left', marginLeft: '-5px', - pointerEvents: 'auto', // 允许点击 │ │ - overflow: 'hidden', // 尝试隐藏滚动条(可能不起作用) + pointerEvents: 'auto', + overflow: 'hidden', }} - // 使用 onWheel 事件阻止滚动 │ │ - onWheel={(e) => e.preventDefault()} // ✅ 在父容器上阻止滚动 - onTouchMove={(e) => e.preventDefault()} // ✅ 移动端也阻止 + onWheel={(e) => e.preventDefault()} + onTouchMove={(e) => e.preventDefault()} /> ) : ( /* 未获取:显示占位符 */ diff --git a/src/views/Community/components/DynamicNewsCard.js b/src/views/Community/components/DynamicNewsCard.js index b355e42f..f8d5cbdc 100644 --- a/src/views/Community/components/DynamicNewsCard.js +++ b/src/views/Community/components/DynamicNewsCard.js @@ -25,8 +25,12 @@ import { useColorModeValue, useToast, useDisclosure, + Switch, + Tooltip, + Icon, } from '@chakra-ui/react'; -import { TimeIcon } from '@chakra-ui/icons'; +import { TimeIcon, BellIcon } from '@chakra-ui/icons'; +import { useNotification } from '../../../contexts/NotificationContext'; import EventScrollList from './DynamicNewsCard/EventScrollList'; import ModeToggleButtons from './DynamicNewsCard/ModeToggleButtons'; import PaginationControl from './DynamicNewsCard/PaginationControl'; @@ -73,6 +77,9 @@ const DynamicNewsCard = forwardRef(({ const cardBg = useColorModeValue('white', 'gray.800'); const borderColor = useColorModeValue('gray.200', 'gray.700'); + // 通知权限相关 + const { browserPermission, requestBrowserPermission } = useNotification(); + // 固定模式状态 const [isFixedMode, setIsFixedMode] = useState(false); const [headerHeight, setHeaderHeight] = useState(0); @@ -146,6 +153,23 @@ const [currentMode, setCurrentMode] = useState('vertical'); dispatch(toggleEventFollow(eventId)); }, [dispatch]); + // 通知开关处理 + const handleNotificationToggle = useCallback(async () => { + if (browserPermission === 'granted') { + // 已授权,提示用户去浏览器设置中关闭 + toast({ + title: '已开启通知', + description: '要关闭通知,请在浏览器地址栏左侧点击锁图标,找到"通知"选项进行设置', + status: 'info', + duration: 5000, + isClosable: true, + }); + } else { + // 未授权,请求权限 + await requestBrowserPermission(); + } + }, [browserPermission, requestBrowserPermission, toast]); + // 本地状态 const [selectedEvent, setSelectedEvent] = useState(null); @@ -511,9 +535,66 @@ const [currentMode, setCurrentMode] = useState('vertical'); 快讯 - - 最后更新: {lastUpdateTime?.toLocaleTimeString() || '未知'} - + + + {/* 通知开关 */} + + + + + {browserPermission === 'granted' ? '通知已开启' : '开启通知'} + + + + + + + 最后更新: {lastUpdateTime?.toLocaleTimeString() || '未知'} + + {/* 搜索和筛选组件 */} diff --git a/src/views/Community/index.js b/src/views/Community/index.js index 8f522468..531d93aa 100644 --- a/src/views/Community/index.js +++ b/src/views/Community/index.js @@ -1,5 +1,5 @@ // src/views/Community/index.js -import React, { useEffect, useRef } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { useSelector, useDispatch } from 'react-redux'; import { @@ -10,6 +10,15 @@ import { Box, Container, useColorModeValue, + Alert, + AlertIcon, + AlertTitle, + AlertDescription, + Button, + CloseButton, + HStack, + VStack, + Text, } from '@chakra-ui/react'; // 导入组件 @@ -40,7 +49,10 @@ const Community = () => { const containerRef = useRef(null); // ⚡ 通知权限引导 - const { showCommunityGuide } = useNotification(); + const { browserPermission, requestBrowserPermission } = useNotification(); + + // 通知横幅显示状态 + const [showNotificationBanner, setShowNotificationBanner] = useState(false); // 🎯 初始化Community埋点Hook const communityEvents = useCommunityEvents({ navigate }); @@ -71,17 +83,38 @@ const Community = () => { } }, [events, loading, pagination, filters]); - // ⚡ 首次访问社区时,延迟显示权限引导 + // ⚡ 检查通知权限状态,显示横幅提示 useEffect(() => { - if (showCommunityGuide) { - const timer = setTimeout(() => { - logger.info('Community', '显示社区权限引导'); - showCommunityGuide(); - }, 5000); // 延迟 5 秒,让用户先浏览页面 + // 延迟3秒显示,让用户先浏览页面 + const timer = setTimeout(() => { + // 如果未授权或未请求过权限,显示横幅 + if (browserPermission !== 'granted') { + const hasClosedBanner = localStorage.getItem('notification_banner_closed'); + if (!hasClosedBanner) { + setShowNotificationBanner(true); + logger.info('Community', '显示通知权限横幅'); + } + } + }, 3000); - return () => clearTimeout(timer); + return () => clearTimeout(timer); + }, [browserPermission]); + + // 处理开启通知 + const handleEnableNotifications = async () => { + const permission = await requestBrowserPermission(); + if (permission === 'granted') { + setShowNotificationBanner(false); + logger.info('Community', '通知权限已授予'); } - }, [showCommunityGuide]); // 只在组件挂载时执行一次 + }; + + // 处理关闭横幅 + const handleCloseBanner = () => { + setShowNotificationBanner(false); + localStorage.setItem('notification_banner_closed', 'true'); + logger.info('Community', '通知横幅已关闭'); + }; // ⚡ 首次进入页面时滚动到内容区域(考虑导航栏高度) useEffect(() => { @@ -104,6 +137,42 @@ const Community = () => { {/* 主内容区域 */} + {/* 通知权限提示横幅 */} + {showNotificationBanner && ( + + + + + 开启桌面通知,不错过重要事件 + + + 即使浏览器最小化,也能第一时间接收新事件推送通知 + + + + + + + + )} {/* 热点事件区域 */}