diff --git a/src/assets/images/V-2504/RestaurantOil-logo-1.png b/src/assets/images/V-2504/RestaurantOil-logo-1.png new file mode 100644 index 0000000000000000000000000000000000000000..7e0022c1b4b0d2734ae568bd63f193a68fa18c9b Binary files /dev/null and b/src/assets/images/V-2504/RestaurantOil-logo-1.png differ diff --git a/src/assets/images/V-2504/RestaurantOil-logo-2.png b/src/assets/images/V-2504/RestaurantOil-logo-2.png new file mode 100644 index 0000000000000000000000000000000000000000..bee912a7d41d863bcdfe566704286728ce1c5fbe Binary files /dev/null and b/src/assets/images/V-2504/RestaurantOil-logo-2.png differ diff --git a/src/pages/Home_v_2504/components/SubPages/RestaurantOil/components/LeftContent/components/DualBackgroundCard/index.less b/src/pages/Home_v_2504/components/SubPages/RestaurantOil/components/LeftContent/components/DualBackgroundCard/index.less new file mode 100644 index 0000000000000000000000000000000000000000..6ed88cec12560300e4ff33e6b0a6089999b936af --- /dev/null +++ b/src/pages/Home_v_2504/components/SubPages/RestaurantOil/components/LeftContent/components/DualBackgroundCard/index.less @@ -0,0 +1,70 @@ +.container { + display: flex; + width: 242px; + height: 140px; + background: linear-gradient(180.00deg, rgba(77, 107, 178, 0.3), rgba(8, 153, 255, 0.01) 100%); + border-radius: 15px; + box-shadow: inset 0px 0px 23px 0px rgba(31, 87, 222, 0.5); + position: relative; +} + +.iconWrapper { + width: 100px; + height: 142px; + background: linear-gradient(180.00deg, rgba(73, 118, 255, 0.06), rgba(0, 255, 246, 0.2) 100%); + border-radius: 15px; + display: flex; + align-items: center; + justify-content: center; + position: relative; + top: -1px; + left: -2px; +} + +.icon { + width: 100px; + height: 142px; + object-fit: contain; +} + +.content { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + align-items: flex-start; + padding: 16px; +} + +.label { + color: rgb(188, 206, 233); + font-family: 微软雅黑; + font-size: 16px; + font-weight: 400; + line-height: 21px; + margin-bottom: 8px; +} + +.valueWrapper { + display: flex; + align-items: flex-end; +} + +.value { + font-family: 'D-DIN'; + font-size: 28px; + font-weight: 700; + line-height: 1.2; + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +} + +.unit { + color: rgb(188, 206, 233); + font-family: 微软雅黑; + font-size: 16px; + font-weight: 400; + line-height: 21px; + margin-left: 4px; +} \ No newline at end of file diff --git a/src/pages/Home_v_2504/components/SubPages/RestaurantOil/components/LeftContent/components/DualBackgroundCard/index.tsx b/src/pages/Home_v_2504/components/SubPages/RestaurantOil/components/LeftContent/components/DualBackgroundCard/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..d9fdd91303c0f548c4dfe08d5f9a32af9512f6ec --- /dev/null +++ b/src/pages/Home_v_2504/components/SubPages/RestaurantOil/components/LeftContent/components/DualBackgroundCard/index.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import styles from './index.less'; + +interface DualBackgroundCardProps { + icon: string; + label: string; + value: number; + unit: string; + valueColor: string; +} + +const DualBackgroundCard: React.FC = ({ + icon, + label, + value, + unit, + valueColor +}) => { + return ( +
+
+ {label} +
+
+
{label}
+
+ + {value} + + {unit} +
+
+
+ ); +}; + +export default DualBackgroundCard; \ No newline at end of file diff --git a/src/pages/Home_v_2504/components/SubPages/RestaurantOil/components/LeftContent/index.less b/src/pages/Home_v_2504/components/SubPages/RestaurantOil/components/LeftContent/index.less new file mode 100644 index 0000000000000000000000000000000000000000..b164531ddec3264a9a4684da408ac48c54a5ab89 --- /dev/null +++ b/src/pages/Home_v_2504/components/SubPages/RestaurantOil/components/LeftContent/index.less @@ -0,0 +1,101 @@ +.container { + width: 1105px; + height: 928px; + // width: 100%; + // height: 100%; + display: flex; + flex-direction: column; + // background: url('@/assets/images/V-2504/subpage-bg.png') no-repeat center center; + // background-size: 100% 100%; + + background-image: url('~@/assets/images/V-2504/subpage-bg.png'); + background-size: cover; + background-position: center; + border-radius: 20px; +} + +.header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 15px; +} + +.contentWrapper { + display: flex; + gap: 20px; + width: 100%; + height: calc(100% - 50px); + padding: 0 16px 0 15px; +} + +.leftSection { + display: flex; + flex-direction: column; + gap: 20px; + width: 530px; +} + +.rightSection { + flex: 1; +} + +/* 整体情况样式 */ +.overallSection { + width: 530px; + height: 227px; + background: linear-gradient(180.00deg, rgba(77, 107, 178, 0.3), rgba(8, 153, 255, 0.01) 100%); + border-radius: 15px; + box-shadow: inset 0px 0px 23px 0px rgba(31, 87, 222, 0.5); + padding: 16px; +} + +.overallContent { + display: flex; + justify-content: space-between; + margin-top: 16px; + height: calc(100% - 52px); +} + +/* 告警趋势样式 */ +.alertTrendSection { + width: 530px; + height: 200px; + background: linear-gradient(180.00deg, rgba(77, 107, 178, 0.3), rgba(8, 153, 255, 0.01) 100%); + border-radius: 15px; + box-shadow: inset 0px 0px 23px 0px rgba(31, 87, 222, 0.5); + padding: 16px; +} + +.alertTrendContent { + height: calc(100% - 52px); +} + +/* 告警区域样式 */ +.alertAreaSection { + width: 530px; + height: 380px; + background: linear-gradient(180.00deg, rgba(77, 107, 178, 0.3), rgba(8, 153, 255, 0.01) 100%); + border-radius: 15px; + box-shadow: inset 0px 0px 23px 0px rgba(31, 87, 222, 0.5); + padding: 16px; +} + +.alertAreaContent { + height: calc(100% - 52px); +} + +/* 告警排行样式 */ +.alertRankingSection { + width: 530px; + height: 844px; + background: linear-gradient(180.00deg, rgba(77, 107, 178, 0.3), rgba(8, 153, 255, 0.01) 100%); + border-radius: 15px; + box-shadow: inset 0px 0px 23px 0px rgba(31, 87, 222, 0.5); + padding: 16px; +} + +.alertRankingContent { + height: calc(100% - 52px); + overflow-y: auto; +} \ No newline at end of file diff --git a/src/pages/Home_v_2504/components/SubPages/RestaurantOil/components/LeftContent/index.tsx b/src/pages/Home_v_2504/components/SubPages/RestaurantOil/components/LeftContent/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..77360f4c9238e7de03ee884608a55ee6b1f19585 --- /dev/null +++ b/src/pages/Home_v_2504/components/SubPages/RestaurantOil/components/LeftContent/index.tsx @@ -0,0 +1,182 @@ +import React, { useCallback, useState } from 'react'; +import PanelTitle from '@/pages/Home_v_2504/components/common/PanelTitle'; +import DateSelector from '@/components/V2504/DateSelector'; +import ModuleTitleWithTabs from '@/pages/Home_v_2504/components/common/ModuleTitleWithTabs'; +import SmoothLineChart from '@/components/V2504/SmoothLineChart'; +import AreaBarList from '@/components/V2504/AreaBarList'; +import DualBackgroundCard from './components/DualBackgroundCard'; +import styles from './index.less'; + +// 导入图标 +import logo1 from '@/assets/images/V-2504/RestaurantOil-logo-1.png'; +import logo2 from '@/assets/images/V-2504/RestaurantOil-logo-2.png'; + +// 类型定义 +type AreaType = 'all' | 'urban' | 'central' | 'county'; + +interface AreaData { + name: string; + percentage: number; + count: number; +} + +const LeftContent: React.FC = () => { + // 状态 + const [dateType, setDateType] = useState('day'); + const [dateRange, setDateRange] = useState<{ startTime: string; endTime: string }>({ + startTime: '', + endTime: '', + }); + const [alertTrendData, setAlertTrendData] = useState<{ time: string; value: number }[]>([]); + const [activeAreaType, setActiveAreaType] = useState('all'); + const [activeRankingType, setActiveRankingType] = useState('all'); + const [alertAreaData, setAlertAreaData] = useState([ + { name: '锦江区', percentage: 37.2, count: 456 }, + { name: '金牛区', percentage: 33.5, count: 400 }, + { name: '成华区', percentage: 20.8, count: 322 }, + { name: '青羊区', percentage: 15.6, count: 186 }, + { name: '双流区', percentage: 12.9, count: 152 }, + ]); + const [alertRankingData, setAlertRankingData] = useState([ + { name: '成都麻辣传奇火锅店', percentage: 87.2, count: 7582 }, + { name: '宽窄巷子老灶火锅', percentage: 83.5, count: 7277 }, + { name: '锦鲤古街风情火锅', percentage: 70.8, count: 7004 }, + { name: '辣斗拉火锅春熙路店', percentage: 65.6, count: 6985 }, + { name: '川西坝子火锅', percentage: 62.9, count: 6932 }, + { name: '蜀九香火锅', percentage: 60.6, count: 6820 }, + { name: '巴蜀大将火锅', percentage: 58.5, count: 6755 }, + { name: '龙抄手火锅', percentage: 55.4, count: 6666 }, + { name: '老妈蹄花火锅', percentage: 50.3, count: 6338 }, + { name: '钢管厂老火锅', percentage: 48.2, count: 6000 }, + { name: '洞子口张老二凉粉', percentage: 45.1, count: 5882 }, + { name: '川西印象火锅', percentage: 42.0, count: 5661 }, + ]); + + // 处理日期变化 + const handleDateChange = useCallback((params: { type: string; startTime: string; endTime: string }) => { + setDateType(params.type); + setDateRange({ + startTime: params.startTime, + endTime: params.endTime, + }); + }, []); + + // 生成趋势数据 + React.useEffect(() => { + const now = new Date(); + const getMonthDays = () => { + return new Date(now.getFullYear(), now.getMonth() + 1, 0).getDate(); + }; + + const mockData = Array.from({ length: getMonthDays() }, (_, i) => ({ + time: `${now.getMonth() + 1}月${i + 1}日`, + value: Math.floor(Math.random() * 50) + 10 + })); + setAlertTrendData(mockData); + }, []); + + return ( +
+ {/* 标题 */} +
+ + +
+ +
+ {/* 左侧内容区域 */} +
+ {/* 整体情况 */} +
+ +
+ + +
+
+ + {/* 告警趋势 */} +
+ +
+ +
+
+ + {/* 告警区域 */} +
+ setActiveAreaType(key as AreaType)} + /> +
+ +
+
+
+ + {/* 右侧内容区域 */} +
+ {/* 告警排行 */} +
+ setActiveRankingType(key as AreaType)} + /> +
+ +
+
+
+
+
+ ); +}; + +export default LeftContent; \ No newline at end of file diff --git a/src/pages/Home_v_2504/components/SubPages/RestaurantOil/index.less b/src/pages/Home_v_2504/components/SubPages/RestaurantOil/index.less index 2dbe940051c6ebd94d59c980b461cad9dd9ebee2..0a903f1a56f3b29210bb2a349069eaeb81d4af02 100644 --- a/src/pages/Home_v_2504/components/SubPages/RestaurantOil/index.less +++ b/src/pages/Home_v_2504/components/SubPages/RestaurantOil/index.less @@ -8,6 +8,7 @@ .leftSidebar { width: 1105px; + margin-left: 40px; // height: 100%; // height: 928px; pointer-events: auto; // Make the sidebar respond to events diff --git a/src/pages/Home_v_2504/components/SubPages/RestaurantOil/index.tsx b/src/pages/Home_v_2504/components/SubPages/RestaurantOil/index.tsx index e7a77511d92744fb38ddf6120d36248aa22158e4..e6c4168a03f065244b5785e49aa4526a91ed88be 100644 --- a/src/pages/Home_v_2504/components/SubPages/RestaurantOil/index.tsx +++ b/src/pages/Home_v_2504/components/SubPages/RestaurantOil/index.tsx @@ -1,6 +1,7 @@ import React, { useEffect } from 'react'; import { useDashboard } from '../../context'; import RightContent from './components/RightContent'; +import LeftContent from './components/LeftContent'; import styles from './index.less'; interface RestaurantOilProps { @@ -24,7 +25,7 @@ const RestaurantOil: React.FC = ({ visible }) => {
{/* 左侧内容区域 - 通过CSS设置pointer-events为auto,仅在有内容的区域启用事件 */}
- {/* 左侧内容将在后续实现 */} +
{/* 中间区域 - 保持pointer-events: none让地图可交互 */}