Skip to content
Snippets Groups Projects
Commit 9481239f authored by 汤绍坚's avatar 汤绍坚
Browse files

tsj: AreaSelector 的行政区划的按钮,增加hover(层级导航),与点击的行为区分开

parent 49ec9af6
No related branches found
No related tags found
No related merge requests found
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import styles from './index.less'; import styles from './index.less';
import { useGlobalModalServices } from '@/pages/GlobalModalServices/provider'; import { useGlobalModalServices } from '@/pages/GlobalModalServices/provider';
...@@ -46,9 +46,17 @@ const AreaSelector: React.FC<AreaSelectorProps> = ({ mapInstance }) => { ...@@ -46,9 +46,17 @@ const AreaSelector: React.FC<AreaSelectorProps> = ({ mapInstance }) => {
const [activeLevel2, setActiveLevel2] = useState<string | null>(null); const [activeLevel2, setActiveLevel2] = useState<string | null>(null);
const [activeLevel3, setActiveLevel3] = useState<string | null>(null); const [activeLevel3, setActiveLevel3] = useState<string | null>(null);
// 悬停状态管理
const [hoverLevel1, setHoverLevel1] = useState<string | null>(null);
const [hoverLevel2, setHoverLevel2] = useState<string | null>(null);
// 悬停计时器
const hoverTimerRef = useRef<any>(null);
// 控制第二层、第三层按钮组的显示 // 控制第二层、第三层按钮组的显示
const showLevel2 = activeLevel1 && buttonGroupData.level2[activeLevel1]; // 使用 hover 或 active 状态来控制显示
const showLevel3 = activeLevel2 && buttonGroupData.level3[activeLevel2]; const showLevel2 = (hoverLevel1 || activeLevel1) && buttonGroupData.level2[hoverLevel1 || activeLevel1 || ''];
const showLevel3 = (hoverLevel2 || activeLevel2) && buttonGroupData.level3[hoverLevel2 || activeLevel2 || ''];
// 初始化时从 JSON 加载区域树数据 // 初始化时从 JSON 加载区域树数据
useEffect(() => { useEffect(() => {
...@@ -140,26 +148,86 @@ const AreaSelector: React.FC<AreaSelectorProps> = ({ mapInstance }) => { ...@@ -140,26 +148,86 @@ const AreaSelector: React.FC<AreaSelectorProps> = ({ mapInstance }) => {
} }
}; };
// 处理第一层行政区划按钮悬停
const handleLevel1Hover = (key: string, hasChildren?: boolean) => {
// 只处理行政区划按钮的悬停(成都市)
if (key === 'chengdu' && hasChildren) {
clearTimeout(hoverTimerRef.current);
hoverTimerRef.current = setTimeout(() => {
setHoverLevel1(key);
}, 300); // 300ms 延迟,防止鼠标快速划过时触发
}
};
// 处理第二层行政区划按钮悬停
const handleLevel2Hover = (key: string, hasChildren?: boolean) => {
if (hasChildren) {
clearTimeout(hoverTimerRef.current);
hoverTimerRef.current = setTimeout(() => {
setHoverLevel2(key);
}, 300);
}
};
// 处理鼠标离开
const handleMouseLeave = (level: number) => {
clearTimeout(hoverTimerRef.current);
// 延迟清除悬停状态,给用户一些时间移动到子菜单
hoverTimerRef.current = setTimeout(() => {
if (level === 1) {
setHoverLevel1(null);
} else if (level === 2) {
setHoverLevel2(null);
}
}, 300);
};
// 处理子菜单鼠标进入,取消清除悬停状态的计时器
const handleSubMenuMouseEnter = () => {
clearTimeout(hoverTimerRef.current);
};
// 处理第一层按钮点击 // 处理第一层按钮点击
const handleLevel1Click = (key: string, hasChildren?: boolean, regionCode?: string, dataCode?: string) => { const handleLevel1Click = (key: string, hasChildren?: boolean, regionCode?: string, dataCode?: string) => {
// 处理特殊功能按钮
if (key === 'oilSmokeAlert') { if (key === 'oilSmokeAlert') {
// 点击油烟告警按钮,显示弹窗 // 点击油烟告警按钮,显示弹窗
dispatch.push('RestaurantOilAlarm'); dispatch.push('RestaurantOilAlarm');
// 发送数据类型变化事件
const dataTypeChangeEvent = new CustomEvent('mapDataTypeChange', {
detail: { dataCode: '20102' }
});
window.dispatchEvent(dataTypeChangeEvent);
return; return;
} }
if (key === 'restaurant') { if (key === 'restaurant') {
// 点击餐饮企业按钮,显示弹窗 // 点击餐饮企业按钮,显示弹窗
dispatch.push('RestaurantOilFacility'); dispatch.push('RestaurantOilFacility');
// 发送数据类型变化事件
const dataTypeChangeEvent = new CustomEvent('mapDataTypeChange', {
detail: { dataCode: '20103' }
});
window.dispatchEvent(dataTypeChangeEvent);
return; return;
} }
if (key === 'oilSmoke') {
// 发送数据类型变化事件
const dataTypeChangeEvent = new CustomEvent('mapDataTypeChange', {
detail: { dataCode: '20101' }
});
window.dispatchEvent(dataTypeChangeEvent);
}
// 处理行政区划按钮点击 - 激活状态切换
if (activeLevel1 === key) { if (activeLevel1 === key) {
// 如果点击当前已激活的按钮,则取消选中
setActiveLevel1(null); setActiveLevel1(null);
setActiveLevel2(null); setActiveLevel2(null);
} else { } else {
// 否则激活该按钮
setActiveLevel1(key); setActiveLevel1(key);
setActiveLevel2(null); setActiveLevel2(null);
} }
...@@ -173,10 +241,8 @@ const AreaSelector: React.FC<AreaSelectorProps> = ({ mapInstance }) => { ...@@ -173,10 +241,8 @@ const AreaSelector: React.FC<AreaSelectorProps> = ({ mapInstance }) => {
// 处理第二层按钮点击 // 处理第二层按钮点击
const handleLevel2Click = (key: string, hasChildren?: boolean, regionCode?: string) => { const handleLevel2Click = (key: string, hasChildren?: boolean, regionCode?: string) => {
if (activeLevel2 === key) { if (activeLevel2 === key) {
// 如果点击当前已激活的按钮,则取消选中
setActiveLevel2(null); setActiveLevel2(null);
} else { } else {
// 否则激活该按钮
setActiveLevel2(key); setActiveLevel2(key);
} }
...@@ -204,40 +270,59 @@ const AreaSelector: React.FC<AreaSelectorProps> = ({ mapInstance }) => { ...@@ -204,40 +270,59 @@ const AreaSelector: React.FC<AreaSelectorProps> = ({ mapInstance }) => {
} }
}, [mapInstance]); }, [mapInstance]);
// 清除定时器
useEffect(() => {
return () => {
clearTimeout(hoverTimerRef.current);
};
}, []);
return ( return (
<div className={styles.areaSelector}> <div className={styles.areaSelector}>
{/* 第一层按钮组 */} {/* 第一层按钮组 */}
<div className={styles.level1ButtonGroup}> <div className={styles.level1ButtonGroup}>
{buttonGroupData.level1.map((button) => ( {buttonGroupData.level1.map((button) => {
<div // 判断是否为行政区划按钮
key={button.key} const isAdminButton = button.key === 'chengdu';
className={classNames(styles.button, {
[styles.buttonActive]: activeLevel1 === button.key return (
})} <div
onClick={() => handleLevel1Click(button.key, button.hasChildren, button.regionCode, button.dataCode)} key={button.key}
> className={classNames(styles.button, {
{button.label} [styles.buttonActive]: activeLevel1 === button.key
{activeLevel1 === button.key && button.hasChildren && ( })}
<img onClick={() => handleLevel1Click(button.key, button.hasChildren, button.regionCode, button.dataCode)}
src={require('@/assets/images/V-2504/map-district-arrow.png')} onMouseEnter={isAdminButton ? () => handleLevel1Hover(button.key, button.hasChildren) : undefined}
className={styles.arrow} onMouseLeave={isAdminButton ? () => handleMouseLeave(1) : undefined}
alt="" >
/> {button.label}
)} {(activeLevel1 === button.key || hoverLevel1 === button.key) && button.hasChildren && (
</div> <img
))} src={require('@/assets/images/V-2504/map-district-arrow.png')}
className={styles.arrow}
alt=""
/>
)}
</div>
);
})}
</div> </div>
{/* 第二层按钮组 */} {/* 第二层按钮组 */}
{showLevel2 && ( {showLevel2 && (
<div className={styles.level2ButtonGroup}> <div
{buttonGroupData.level2[activeLevel1!].map((button) => ( className={styles.level2ButtonGroup}
onMouseEnter={handleSubMenuMouseEnter}
onMouseLeave={() => handleMouseLeave(2)}
>
{buttonGroupData.level2[hoverLevel1 || activeLevel1 || ''].map((button) => (
<div <div
key={button.key} key={button.key}
className={classNames(styles.button, { className={classNames(styles.button, {
[styles.buttonActive]: activeLevel2 === button.key [styles.buttonActive]: activeLevel2 === button.key
})} })}
onClick={() => handleLevel2Click(button.key, button.hasChildren, button.regionCode)} onClick={() => handleLevel2Click(button.key, button.hasChildren, button.regionCode)}
onMouseEnter={button.hasChildren ? () => handleLevel2Hover(button.key, button.hasChildren) : undefined}
> >
{button.label} {button.label}
</div> </div>
...@@ -247,8 +332,11 @@ const AreaSelector: React.FC<AreaSelectorProps> = ({ mapInstance }) => { ...@@ -247,8 +332,11 @@ const AreaSelector: React.FC<AreaSelectorProps> = ({ mapInstance }) => {
{/* 第三层按钮组 */} {/* 第三层按钮组 */}
{showLevel3 && ( {showLevel3 && (
<div className={styles.level3ButtonGroup}> <div
{buttonGroupData.level3[activeLevel2!].map((button) => ( className={styles.level3ButtonGroup}
onMouseEnter={handleSubMenuMouseEnter}
>
{buttonGroupData.level3[hoverLevel2 || activeLevel2 || ''].map((button) => (
<div <div
key={button.key} key={button.key}
className={classNames(styles.button, { className={classNames(styles.button, {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment