事件中心不提示通知修复,增加开启/关闭通知按钮。修复edge或者opera浏览器登录扫码无跳转的问题

This commit is contained in:
2025-11-10 10:36:29 +08:00
parent fbf6813615
commit 25163789ca
3 changed files with 172 additions and 22 deletions

View File

@@ -508,19 +508,19 @@ export default function WechatRegister() {
title="微信扫码登录" title="微信扫码登录"
width="300" width="300"
height="350" height="350"
scrolling="no" // ✅ 新增:禁止滚动 scrolling="no"
// sandbox="allow-scripts allow-same-origin allow-forms" // ✅ 阻止iframe跳转父页面 sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-top-navigation"
allow="clipboard-write"
style={{ style={{
border: 'none', border: 'none',
transform: 'scale(0.77) translateY(-35px)', // ✅ 裁剪顶部logo transform: 'scale(0.77) translateY(-35px)',
transformOrigin: 'top left', transformOrigin: 'top left',
marginLeft: '-5px', marginLeft: '-5px',
pointerEvents: 'auto', // 允许点击 │ │ pointerEvents: 'auto',
overflow: 'hidden', // 尝试隐藏滚动条(可能不起作用) overflow: 'hidden',
}} }}
// 使用 onWheel 事件阻止滚动 │ │ onWheel={(e) => e.preventDefault()}
onWheel={(e) => e.preventDefault()} // ✅ 在父容器上阻止滚动 onTouchMove={(e) => e.preventDefault()}
onTouchMove={(e) => e.preventDefault()} // ✅ 移动端也阻止
/> />
) : ( ) : (
/* 未获取:显示占位符 */ /* 未获取:显示占位符 */

View File

@@ -25,8 +25,12 @@ import {
useColorModeValue, useColorModeValue,
useToast, useToast,
useDisclosure, useDisclosure,
Switch,
Tooltip,
Icon,
} from '@chakra-ui/react'; } 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 EventScrollList from './DynamicNewsCard/EventScrollList';
import ModeToggleButtons from './DynamicNewsCard/ModeToggleButtons'; import ModeToggleButtons from './DynamicNewsCard/ModeToggleButtons';
import PaginationControl from './DynamicNewsCard/PaginationControl'; import PaginationControl from './DynamicNewsCard/PaginationControl';
@@ -73,6 +77,9 @@ const DynamicNewsCard = forwardRef(({
const cardBg = useColorModeValue('white', 'gray.800'); const cardBg = useColorModeValue('white', 'gray.800');
const borderColor = useColorModeValue('gray.200', 'gray.700'); const borderColor = useColorModeValue('gray.200', 'gray.700');
// 通知权限相关
const { browserPermission, requestBrowserPermission } = useNotification();
// 固定模式状态 // 固定模式状态
const [isFixedMode, setIsFixedMode] = useState(false); const [isFixedMode, setIsFixedMode] = useState(false);
const [headerHeight, setHeaderHeight] = useState(0); const [headerHeight, setHeaderHeight] = useState(0);
@@ -146,6 +153,23 @@ const [currentMode, setCurrentMode] = useState('vertical');
dispatch(toggleEventFollow(eventId)); dispatch(toggleEventFollow(eventId));
}, [dispatch]); }, [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); const [selectedEvent, setSelectedEvent] = useState(null);
@@ -511,9 +535,66 @@ const [currentMode, setCurrentMode] = useState('vertical');
<Badge colorScheme="blue">快讯</Badge> <Badge colorScheme="blue">快讯</Badge>
</HStack> </HStack>
</VStack> </VStack>
<VStack align="end" spacing={2}>
{/* 通知开关 */}
<Tooltip
label={browserPermission === 'granted'
? '浏览器通知已开启,新事件将实时推送'
: '开启后可接收实时事件推送通知'}
placement="left"
hasArrow
>
<HStack
spacing={2}
px={3}
py={2}
borderRadius="md"
bg={browserPermission === 'granted'
? useColorModeValue('green.50', 'green.900')
: useColorModeValue('gray.50', 'gray.700')}
borderWidth="1px"
borderColor={browserPermission === 'granted'
? useColorModeValue('green.200', 'green.700')
: useColorModeValue('gray.200', 'gray.600')}
cursor="pointer"
_hover={{
borderColor: browserPermission === 'granted'
? useColorModeValue('green.300', 'green.600')
: useColorModeValue('blue.300', 'blue.600'),
}}
transition="all 0.2s"
onClick={handleNotificationToggle}
>
<Icon
as={BellIcon}
boxSize={4}
color={browserPermission === 'granted'
? useColorModeValue('green.600', 'green.300')
: useColorModeValue('gray.500', 'gray.400')}
/>
<Text
fontSize="sm"
fontWeight="medium"
color={browserPermission === 'granted'
? useColorModeValue('green.700', 'green.200')
: useColorModeValue('gray.600', 'gray.300')}
>
{browserPermission === 'granted' ? '通知已开启' : '开启通知'}
</Text>
<Switch
size="sm"
isChecked={browserPermission === 'granted'}
pointerEvents="none"
colorScheme="green"
/>
</HStack>
</Tooltip>
<Text fontSize="xs" color="gray.500"> <Text fontSize="xs" color="gray.500">
最后更新: {lastUpdateTime?.toLocaleTimeString() || '未知'} 最后更新: {lastUpdateTime?.toLocaleTimeString() || '未知'}
</Text> </Text>
</VStack>
</Flex> </Flex>
{/* 搜索和筛选组件 */} {/* 搜索和筛选组件 */}

View File

@@ -1,5 +1,5 @@
// src/views/Community/index.js // 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 { useNavigate } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux'; import { useSelector, useDispatch } from 'react-redux';
import { import {
@@ -10,6 +10,15 @@ import {
Box, Box,
Container, Container,
useColorModeValue, useColorModeValue,
Alert,
AlertIcon,
AlertTitle,
AlertDescription,
Button,
CloseButton,
HStack,
VStack,
Text,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
// 导入组件 // 导入组件
@@ -40,7 +49,10 @@ const Community = () => {
const containerRef = useRef(null); const containerRef = useRef(null);
// ⚡ 通知权限引导 // ⚡ 通知权限引导
const { showCommunityGuide } = useNotification(); const { browserPermission, requestBrowserPermission } = useNotification();
// 通知横幅显示状态
const [showNotificationBanner, setShowNotificationBanner] = useState(false);
// 🎯 初始化Community埋点Hook // 🎯 初始化Community埋点Hook
const communityEvents = useCommunityEvents({ navigate }); const communityEvents = useCommunityEvents({ navigate });
@@ -71,17 +83,38 @@ const Community = () => {
} }
}, [events, loading, pagination, filters]); }, [events, loading, pagination, filters]);
// ⚡ 首次访问社区时,延迟显示权限引导 // ⚡ 检查通知权限状态,显示横幅提示
useEffect(() => { useEffect(() => {
if (showCommunityGuide) { // 延迟3秒显示让用户先浏览页面
const timer = setTimeout(() => { const timer = setTimeout(() => {
logger.info('Community', '显示社区权限引导'); // 如果未授权或未请求过权限,显示横幅
showCommunityGuide(); if (browserPermission !== 'granted') {
}, 5000); // 延迟 5 秒,让用户先浏览页面 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(() => { useEffect(() => {
@@ -104,6 +137,42 @@ const Community = () => {
<Box minH="100vh" bg={bgColor}> <Box minH="100vh" bg={bgColor}>
{/* 主内容区域 */} {/* 主内容区域 */}
<Container ref={containerRef} maxW="1600px" pt={6} pb={8}> <Container ref={containerRef} maxW="1600px" pt={6} pb={8}>
{/* 通知权限提示横幅 */}
{showNotificationBanner && (
<Alert
status="info"
variant="subtle"
borderRadius="lg"
mb={4}
boxShadow="md"
bg={useColorModeValue('blue.50', 'blue.900')}
borderWidth="1px"
borderColor={useColorModeValue('blue.200', 'blue.700')}
>
<AlertIcon />
<Box flex="1">
<AlertTitle fontSize="md" mb={1}>
开启桌面通知不错过重要事件
</AlertTitle>
<AlertDescription fontSize="sm">
即使浏览器最小化也能第一时间接收新事件推送通知
</AlertDescription>
</Box>
<HStack spacing={2} ml={4}>
<Button
size="sm"
colorScheme="blue"
onClick={handleEnableNotifications}
>
立即开启
</Button>
<CloseButton
onClick={handleCloseBanner}
position="relative"
/>
</HStack>
</Alert>
)}
{/* 热点事件区域 */} {/* 热点事件区域 */}
<HotEventsSection <HotEventsSection
events={hotEvents} events={hotEvents}