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

tsj: 实现餐饮油烟设施弹窗的静态

parent facc66e5
Branches
Tags
No related merge requests found
......@@ -5,42 +5,7 @@ import SmoothLineChart from '@/components/V2504/SmoothLineChart';
import DescriptionItem from '@/components/DescriptionItem';
import BlueTable from '@/components/BlueTable';
import { ColumnsType } from 'antd/es/table';
// 模块标题组件
const ModuleTitle: React.FC<{
title: string;
showDateSelector?: boolean;
dateType?: string;
onDateTypeChange?: (type: string) => void;
}> = ({ title, showDateSelector = false, dateType = 'day', onDateTypeChange }) => {
return (
<div className={styles.moduleTitle}>
<div className={styles.title}>{title}</div>
{showDateSelector && (
<div className={styles.dateSelector}>
<div
className={`${styles.dateItem} ${dateType === 'day' ? styles.active : ''}`}
onClick={() => onDateTypeChange && onDateTypeChange('day')}
>
</div>
<div
className={`${styles.dateItem} ${dateType === 'month' ? styles.active : ''}`}
onClick={() => onDateTypeChange && onDateTypeChange('month')}
>
</div>
<div
className={`${styles.dateItem} ${dateType === 'year' ? styles.active : ''}`}
onClick={() => onDateTypeChange && onDateTypeChange('year')}
>
</div>
</div>
)}
</div>
);
};
import ModuleTitle from '@/pages/Home_v_2504/components/common/ModuleTitle';
// 告警详情弹窗组件
const RestaurantOilAlarm: React.FC = () => {
......@@ -64,8 +29,6 @@ const RestaurantOilAlarm: React.FC = () => {
{ name: '油烟浓度', value: 0.222, unit: 'mg/m³' },
{ name: '颗粒物浓度', value: 0.222, unit: 'mg/m³' },
{ name: '非甲烷总烃', value: 0.222, unit: 'mg/m³' },
// { name: '风机状态', unit: '' },
// { name: '净化器状态', unit: '' },
{ name: '风机状态', value: '', unit: '' },
{ name: '净化器状态', value: '', unit: '' },
];
......
.container {
width: 100%;
height: 100%;
box-sizing: border-box;
}
.topRow {
margin-bottom: 24px;
}
.enterpriseInfo {
width: 550px;
height: 246px;
background: rgba(57, 122, 183, 0.2);
border-radius: 20px;
position: relative;
.infoContent {
height: 148px;
overflow-y: auto;
padding: 0 28px;
/* 隐藏滚动条 */
&::-webkit-scrollbar {
display: none;
}
scrollbar-width: none;
-ms-overflow-style: none;
}
.scrollArea {
width: 100%;
}
.infoItem {
display: flex;
align-items: flex-start;
.label {
color: rgb(203, 237, 255);
font-family: 思源黑体;
font-size: 16px;
font-weight: 400;
line-height: 23px;
white-space: nowrap;
}
.value {
color: rgb(255, 255, 255);
font-family: 思源黑体;
font-size: 16px;
font-weight: 400;
line-height: 23px;
flex: 1;
}
}
}
.realTimeStatus {
width: 810px;
height: 250px;
background: rgba(57, 122, 183, 0.2);
border-radius: 20px;
position: relative;
.statusCards {
padding: 0 0 0 20px;
}
.statusCard {
width: 242px;
height: 70px;
background: rgba(57, 122, 183, 0.2);
border-radius: 20px;
display: flex;
align-items: center;
justify-content: flex-start;
padding: 11px 0 0 25px;
position: relative;
}
}
.monitoringDetails {
width: 1387px;
height: 430px;
background: rgba(57, 122, 183, 0.2);
border-radius: 20px;
position: relative;
.tableContainer {
padding: 0 20px;
height: calc(100% - 52px);
overflow: hidden;
/* 自定义表格样式 */
:global {
// 表格行样式
.ant-table-row {
background: rgba(57, 122, 183, 0.2);
border-radius: 16px;
margin-bottom: 13px;
height: 50px;
}
// 表格单元格样式
.ant-table-cell {
border-bottom: none !important;
color: rgb(255, 255, 255);
font-family: 思源黑体;
font-size: 18px;
font-weight: 500;
line-height: 26px;
padding: 8px 16px;
}
// 表头单元格样式
.ant-table-thead .ant-table-cell {
color: rgb(188, 206, 233);
font-family: 微软雅黑;
font-size: 16px;
font-weight: 400;
line-height: 21px;
background: transparent;
border-bottom: none;
padding: 8px 26px;
}
/* 隐藏表格滚动条样式 */
.ant-table-body {
scrollbar-width: none;
-ms-overflow-style: none;
}
.ant-table-body::-webkit-scrollbar {
display: none;
}
.ant-table-scroll .ant-table-body-wrapper {
scrollbar-width: none;
-ms-overflow-style: none;
}
.ant-table-scroll .ant-table-body-wrapper::-webkit-scrollbar {
display: none;
}
}
}
}
.statusTag {
width: 50px;
height: 22px;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
font-family: 思源黑体;
font-size: 12px;
font-weight: 400;
line-height: 17px;
}
.normalStatus {
background: rgba(71, 223, 155, 0.2);
color: rgb(33, 188, 92);
}
.timeoutStatus {
background: rgba(255, 130, 130, 0.2);
color: rgb(255, 119, 119);
}
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import { Flex, Space } from 'antd';
import styles from './index.less';
import DescriptionItem from '@/components/DescriptionItem';
import BlueTable from '@/components/BlueTable';
import { ColumnsType } from 'antd/es/table';
import ModuleTitle from '@/pages/Home_v_2504/components/common/ModuleTitle';
// 餐饮油烟设施弹窗组件
const RestaurantOilFacility: React.FC = () => {
// 日期选择器状态
const [dateType, setDateType] = useState<string>('day');
// 企业详情数据
const enterpriseInfo = {
enterpriseName: '辣斗拉火锅春熙路店',
deviceNum: '102305333220',
contactPerson: '李经理',
contactPhone: '13802232223',
address: '锦江区牛市口街道办事处双桂路99号',
};
// 实时运行状态数据
const statusData = [
{ name: '油烟浓度', value: 0.222, unit: 'mg/m³' },
{ name: '颗粒物浓度', value: 0.222, unit: 'mg/m³' },
{ name: '非甲烷总烃', value: 0.222, unit: 'mg/m³' },
{ name: '风机状态', value: '', unit: '' },
{ name: '净化器状态', value: '', unit: '' },
];
// 监测详情数据
interface MonitoringData {
id: string;
monitoringTime: string;
oilConcentration: string;
particleConcentration: string;
nmhc: string;
fanStatus: string;
purifierStatus: string;
status: string;
}
const [monitoringData, setMonitoringData] = useState<MonitoringData[]>([]);
// 监测详情表格列定义
const columns: ColumnsType<MonitoringData> = [
{
title: '序号',
dataIndex: 'id',
key: 'id',
width: 80,
},
{
title: '监测时间',
dataIndex: 'monitoringTime',
key: 'monitoringTime',
width: 180,
},
{
title: '油烟浓度 (mg/m³)',
dataIndex: 'oilConcentration',
key: 'oilConcentration',
width: 160,
},
{
title: '颗粒物浓度 (mg/m³)',
dataIndex: 'particleConcentration',
key: 'particleConcentration',
width: 160,
},
{
title: '非甲烷总烃 (mg/m³)',
dataIndex: 'nmhc',
key: 'nmhc',
width: 160,
},
{
title: '风机状态',
dataIndex: 'fanStatus',
key: 'fanStatus',
width: 120,
},
{
title: '净化器状态',
dataIndex: 'purifierStatus',
key: 'purifierStatus',
width: 120,
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 100,
render: (text) => (
<div className={`${styles.statusTag} ${text === '超时' ? styles.timeoutStatus : styles.normalStatus}`}>
{text}
</div>
),
},
];
// 加载数据
useEffect(() => {
// 生成监测详情数据
const generateMonitoringData = () => {
const data: MonitoringData[] = [];
const now = new Date();
const statusOptions = ['正常', '超时'];
const deviceStatusOptions = ['', ''];
for (let i = 0; i < 20; i++) {
const monitoringTime = new Date(now.getTime() - i * 60 * 60 * 1000);
const formattedTime = monitoringTime.toLocaleString('zh-CN', {
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
});
data.push({
id: (i + 1).toString(),
monitoringTime: formattedTime,
oilConcentration: (Math.random() * 0.3 + 0.2).toFixed(3),
particleConcentration: (Math.random() * 0.3 + 0.2).toFixed(3),
nmhc: (Math.random() * 0.3 + 0.2).toFixed(3),
fanStatus: deviceStatusOptions[Math.floor(Math.random() * deviceStatusOptions.length)],
purifierStatus: deviceStatusOptions[Math.floor(Math.random() * deviceStatusOptions.length)],
status: statusOptions[Math.floor(Math.random() * statusOptions.length)],
});
}
setMonitoringData(data);
};
generateMonitoringData();
}, [dateType]);
const valueStyle = {
color: 'rgb(89, 238, 255)',
fontFamily: 'D-DIN',
fontSize: '24px',
fontWeight: 700,
}
const textValueStyle = {
...valueStyle,
fontSize: '20px',
}
return (
<div className={styles.container}>
<Flex gap={27} className={styles.topRow}>
{/* 企业详情 */}
<div className={styles.enterpriseInfo}>
<ModuleTitle title="企业详情" />
<div className={styles.infoContent}>
<Space direction="vertical" size={9} className={styles.scrollArea}>
<div className={styles.infoItem}>
<span className={styles.label}>企业名称:</span>
<span className={styles.value}>{enterpriseInfo.enterpriseName}</span>
</div>
<div className={styles.infoItem}>
<span className={styles.label}>设备编号:</span>
<span className={styles.value}>{enterpriseInfo.deviceNum}</span>
</div>
<div className={styles.infoItem}>
<span className={styles.label}>联系人:</span>
<span className={styles.value}>{enterpriseInfo.contactPerson}</span>
</div>
<div className={styles.infoItem}>
<span className={styles.label}>联系电话:</span>
<span className={styles.value}>{enterpriseInfo.contactPhone}</span>
</div>
<div className={styles.infoItem}>
<span className={styles.label}>企业地址:</span>
<span className={styles.value}>{enterpriseInfo.address}</span>
</div>
</Space>
</div>
</div>
{/* 实时运行状态 */}
<div className={styles.realTimeStatus}>
<ModuleTitle title="实时运行状态" />
<Flex wrap="wrap" gap={20} className={styles.statusCards}>
{statusData.map((item, index) => (
<div className={styles.statusCard} key={index}>
<DescriptionItem
value={item.value}
name={item.name}
unit={item.unit}
valueStyle={typeof item.value === 'number' ? valueStyle : textValueStyle}
labelStyle={{
color: 'rgb(203, 237, 255)',
fontFamily: 'DingTalk JinBuTi',
fontSize: '18px',
fontWeight: 400,
lineHeight: '22px',
}}
unitStyle={{
color: 'rgb(188, 206, 233)',
fontFamily: '微软雅黑',
fontSize: '16px',
fontWeight: 400,
lineHeight: '21px',
}}
reverseName={true}
decimals={3}
showTextToValue={typeof item.value !== 'number'}
/>
</div>
))}
</Flex>
</div>
</Flex>
{/* 监测详情 */}
<div className={styles.monitoringDetails}>
<ModuleTitle
title="监测详情"
showDateSelector
dateType={dateType}
onDateTypeChange={setDateType}
/>
<div className={styles.tableContainer}>
<BlueTable
columns={columns}
dataSource={monitoringData}
pagination={false}
scroll={{ y: 305 }}
size='small'
/>
</div>
</div>
</div>
);
};
export default RestaurantOilFacility;
\ No newline at end of file
......@@ -50,6 +50,7 @@ import PipelineMonitor from './modals/PipelineMonitor';
import PipelineMonitorDetail from './modals/PipelineMonitorDetail';
import PipelinePassage from './modals/PipelinePassage';
import RestaurantOilAlarm from './modals/RestaurantOilAlarm';
import RestaurantOilFacility from './modals/RestaurantOilFacility';
import SanitationDisp from './modals/SanitationDisp';
import SanitationEvent from './modals/SanitationEvent';
import SanitationResource from './modals/SanitationResource';
......@@ -794,6 +795,19 @@ export default class Registry {
defaultProps: {},
modal: RestaurantOilAlarm,
},
/**
* 餐饮油烟设施详情
* @module RestaurantOilFacility
*/
RestaurantOilFacility: {
defaultConfig: {
w: 1452,
h: 848,
title: '餐饮油烟设施详情',
},
defaultProps: {},
modal: RestaurantOilFacility,
},
};
static get(modalKey: ModalKey) {
......
......@@ -92,6 +92,12 @@ const AreaSelector: React.FC = () => {
return;
}
if (key === 'restaurant') {
// 点击餐饮企业按钮,显示弹窗
dispatch.push('RestaurantOilFacility');
return;
}
if (activeLevel1 === key) {
// 如果点击当前已激活的按钮,则取消选中
setActiveLevel1(null);
......
.moduleTitle {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 21px;
.title {
color: rgb(179, 214, 247);
font-family: 微软雅黑;
font-size: 20px;
font-weight: 700;
line-height: 26px;
margin: 26px 0 0 28px;
}
.dateSelector {
display: flex;
gap: 8px;
margin-right: 33px;
margin-top: 18px;
.dateItem {
width: 60px;
height: 30px;
background: rgb(18, 61, 102);
border-radius: 25px;
display: flex;
justify-content: center;
align-items: center;
color: rgb(97, 148, 199);
font-family: 'DingTalk JinBuTi';
font-size: 16px;
font-weight: 400;
line-height: 19px;
cursor: pointer;
&.active {
background: linear-gradient(180.00deg, rgb(28, 192, 255), rgb(82, 148, 255) 100%);
color: rgb(255, 255, 255);
}
}
}
}
\ No newline at end of file
import React from 'react';
import styles from './index.less';
// 模块标题组件
const ModuleTitle: React.FC<{
title: string;
showDateSelector?: boolean;
dateType?: string;
onDateTypeChange?: (type: string) => void;
}> = ({ title, showDateSelector = false, dateType = 'day', onDateTypeChange }) => {
return (
<div className={styles.moduleTitle}>
<div className={styles.title}>{title}</div>
{showDateSelector && (
<div className={styles.dateSelector}>
<div
className={`${styles.dateItem} ${dateType === 'day' ? styles.active : ''}`}
onClick={() => onDateTypeChange && onDateTypeChange('day')}
>
</div>
<div
className={`${styles.dateItem} ${dateType === 'month' ? styles.active : ''}`}
onClick={() => onDateTypeChange && onDateTypeChange('month')}
>
</div>
<div
className={`${styles.dateItem} ${dateType === 'year' ? styles.active : ''}`}
onClick={() => onDateTypeChange && onDateTypeChange('year')}
>
</div>
</div>
)}
</div>
);
};
export default ModuleTitle;
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment