123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501 |
- import { getPendingList } from '@/services/message';
- import { queryConditionSnapshot } from '@/services/SmartOps';
- import { getToken, UnityAction } from '@/utils/utils';
- import { LoadingOutlined } from '@ant-design/icons';
- import { connect, useParams, useRequest } from '@umijs/max';
- import { Popover } from 'antd';
- import dayjs from 'dayjs';
- import { useEffect, useMemo, useState } from 'react';
- import { getScadaPage } from '../../services/OperationManagement';
- import styles from './index.less';
- const HomePage = (props) => {
- const { projectId } = useParams();
- const { data } = useRequest(queryConditionSnapshot, {
- defaultParams: [{ project_id: projectId }],
- pollingInterval: 10 * 1000,
- });
- const getPositionPst = (e) => {
- const width = document.body.clientWidth;
- const height = document.body.clientHeight;
- const xPst = (e.clientX / width).toFixed(2);
- const yPst = (e.clientY / height).toFixed(2);
- return xPst + '-' + yPst;
- };
- const webMouseEvent = {
- onMouseUp: (e) => {
- UnityAction.sendMsg('PointerOut', getPositionPst(e));
- },
- onMouseDown: (e) => {
- UnityAction.sendMsg('PointerIn', getPositionPst(e));
- },
- };
- useEffect(() => {
- localStorage.width = document.documentElement.getBoundingClientRect().width;
- window.refreshRem();
- document.body.style.backgroundColor = 'transparent';
- }, []);
- return (
- <div className={styles.content} {...webMouseEvent}>
- <CenterContent data={data} />
- <LeftContent data={data} />
- <RightContent data={data} />
- </div>
- );
- };
- const LeftContent = (props) => {
- const { data } = props;
- return (
- <div className={styles.left}>
- {/* <SmartWork data={data} /> */}
- <WaterAmt data={data} />
- <WaterQuality data={data} />
- <Backlog />
- {/* <Backlog /> */}
- </div>
- );
- };
- const CenterContent = (props) => {
- const { data } = props;
- return (
- <div className={styles.centerBox}>
- <SmartWork data={data} />
- <SelfInspection />
- {/* <Backlog />
- <Scada /> */}
- </div>
- );
- };
- const RightContent = (props) => {
- const { data } = props;
- return (
- <div className={styles.right}>
- {/* <SelfInspection /> */}
- <Electric data={data} />
- <Medicine data={data} />
- <Scada />
- {/* <Scada /> */}
- </div>
- );
- };
- export const getValue = (str) => {
- const result = str?.match(/.*?(\d+(?:\.\d+)?)\D*$/);
- if (result && result[1]) return result[1];
- return 0;
- };
- // 水厂工况
- const SmartWork = (props) => {
- const { data } = props;
- return (
- <div
- className={styles.smartWork}
- onClick={() => UnityAction.sendMsg('menuItem', '工况管理')}
- >
- <Title title="水厂工况" />
- <div className={styles.scoreBox}>
- <div className={styles.circle}>
- <div className={styles.score}>{data?.score}</div>
- <div className={styles.grade}>{data?.grade}</div>
- </div>
- <div className={styles.scoreTitle}>
- 当前运行{data?.grade},可继续优化
- </div>
- </div>
- <div className={styles.time}>
- {dayjs(data?.clac_time).format('YYYY-MM-DD HH:mm')}
- </div>
- </div>
- );
- };
- // 水量监测
- const WaterAmt = (props) => {
- const { data } = props;
- const status = useMemo(() => {
- switch (data?.dwa_status) {
- case 1:
- return '当前处于外供水高峰期';
- case 2:
- return '当前处于外供水平时期';
- case 3:
- return '当前处于外供水低峰期';
- }
- }, [data?.dwa_status]);
- return (
- <div
- className={styles.waterAmt}
- onClick={() => UnityAction.sendMsg('menuItem', '水量监测')}
- >
- <Title title="水量监测" />
- <div className={styles.boxTip}>{status}</div>
- <ul>
- <li>
- <div className={styles.value}>{getValue(data?.fwa)}</div>
- <div className={styles.btn1}>进水量(m³/h)</div>
- </li>
- <li>
- <div className={styles.value}>{getValue(data?.dwa)}</div>
- <div className={styles.btn2}>产水量(m³/h)</div>
- </li>
- </ul>
- </div>
- );
- };
- // 水质监测
- const WaterQuality = (props) => {
- const { data } = props;
- const status = useMemo(() => {
- switch (data?.water_quality_status) {
- case 1:
- return '当前水质良好';
- case 2:
- return '当前水质较好';
- }
- }, [data?.water_quality_status]);
- return (
- <div
- className={styles.waterQuality}
- onClick={() => UnityAction.sendMsg('menuItem', '水质监测')}
- >
- <Title title="水质监测" />
- <div className={styles.boxTip}>{status}</div>
- <ul>
- <li style={{ width: '60%' }}>
- <div className={styles.valueLong}>{getValue(data?.dtds)}</div>
- <div className={styles.btn1}>外供水电导率(µs/cm)</div>
- </li>
- <li style={{ width: '40%' }}>
- <div className={styles.valueLong}>{data?.dph || 0}</div>
- <div className={styles.btn2}>外供水(PH)</div>
- </li>
- </ul>
- </div>
- );
- };
- // 系统自检
- const SelfInspection = connect(({ eqSelfInspection, loading }) => ({
- autoReport: eqSelfInspection.autoReport,
- loading: loading.models['eqSelfInspection'],
- }))((props) => {
- const { autoReport, dispatch, loading } = props;
- const { projectId } = useParams();
- const renderStatus = () => {
- if (loading) return <LoadingOutlined />;
- if (autoReport.Status > 0) {
- return (
- <span className={styles.text} style={{ color: '#FE5850' }}>
- 异常
- </span>
- );
- }
- return (
- <span className={styles.text} style={{ color: '' }}>
- 正常
- </span>
- );
- };
- useEffect(() => {
- dispatch({
- type: 'eqSelfInspection/getAutoPatrol',
- payload: {
- projectId,
- },
- });
- }, []);
- return (
- <div
- className={styles.selfInspection}
- onClick={() => UnityAction.sendMsg('menuItem', '系统自检')}
- >
- <Title title="系统自检" />
- <div className={styles.selfCon}>
- <div className={styles.circle}>{renderStatus()}</div>
- <div className={styles.texting}>自检中</div>
- </div>
- <div className={styles.time}>
- {dayjs(autoReport.CreatedTime).format('YYYY-MM-DD HH:mm')}
- </div>
- {/* <div className={styles.insTag}>自检中</div> */}
- {/* <div className={styles.insStatus}>{renderStatus()}</div>
- <div className={styles.time} style={{ marginBottom: 30 }}>
- {dayjs(autoReport.CreatedTime).format('YYYY-MM-DD HH:mm')}
- </div> */}
- </div>
- );
- });
- // 能耗监测
- const Electric = (props) => {
- const { data } = props;
- const [open, setOpen] = useState(false);
- const elec = useMemo(() => {
- return getValue(data?.elec_unit);
- }, [data?.elec_unit]);
- const status = useMemo(() => {
- if (!data) return '';
- if (elec > data.elec_unit_theory) {
- return '当前电耗高于理论值';
- }
- if (elec == data.elec_unit_theory) {
- return '当前电耗持平理论值';
- }
- if (elec < data.elec_unit_theory) {
- return '当前电耗低于理论值';
- }
- }, [data]);
- const content = (
- <div className={styles.popoverContent}>
- <p>理论值规则:</p>
- <p>分为高/中/低温3档。则高温为≥25℃,低温为<20℃,中温为≥20且<25℃;</p>
- <p>
- 吨水电耗理论值:高温阶段理论值暂定为0.77Kwh/m3;高温阶段理论值暂定为0.83Kwh/m3;低温阶段理论值暂定为0.89Kwh/m3。
- </p>
- </div>
- );
- return (
- <div
- className={styles.electric}
- onClick={() => UnityAction.sendMsg('menuItem', '能耗监测')}
- >
- <Title title={'能耗监测'} />
- <div className={styles.boxTip}>{status}</div>
- <div
- className={`password-eye ${styles.eye} ${open ? 'open' : ''}`}
- onClick={(e) => {
- e.stopPropagation();
- setOpen(!open);
- }}
- ></div>
- <ul>
- <li>
- <div className={styles.value}>{open ? elec : '*****'}</div>
- <div className={styles.btn1}>吨水电耗(KWh/m³)</div>
- </li>
- <li>
- <div className={styles.value}>
- {/* {open ? getValue(data?.elec) : '*****'} */}
- {open ? data?.elec_unit_theory || '-' : '*****'}
- </div>
- <Popover title={content}>
- <div className={styles.btn1} onClick={(e) => e.stopPropagation()}>
- 理论值(KWh/m³)
- <i className={styles.iconAlert}></i>
- </div>
- </Popover>
- </li>
- </ul>
- </div>
- );
- };
- // 药耗监测
- const Medicine = (props) => {
- const { data } = props;
- const [open, setOpen] = useState(false);
- const otc_cost = useMemo(() => {
- return getValue(data?.otc_cost_unit);
- }, [data?.otc_cost_unit]);
- const status = useMemo(() => {
- if (!data) return '';
- if (otc_cost > data.otc_unit_theory) {
- return '当前药耗高于理论值';
- }
- if (otc_cost == data.otc_unit_theory) {
- return '当前药耗持平理论值';
- }
- if (otc_cost < data.otc_unit_theory) {
- return '当前药耗低于理论值';
- }
- }, [data]);
- const content = (
- <div className={styles.popoverContent}>
- <p>理论值规则:</p>
- <p>分为高/中/低温3档。则高温为≥25℃,低温为<20℃,中温为≥20且<25℃;</p>
- <p>
- 吨水药耗理论值:高温阶段理论值暂定为0.165元/m3;中温阶段理论值暂定为0.177元/m3;低温阶段理论值暂定为0.189元/m3。
- </p>
- </div>
- );
- return (
- <div
- className={styles.medicine}
- onClick={() => UnityAction.sendMsg('menuItem', '药耗监测')}
- >
- <Title title={'药耗监测'} />
- <div className={styles.boxTip}>{status}</div>
- <div
- className={`password-eye ${styles.eye} ${open ? 'open' : ''}`}
- onClick={(e) => {
- e.stopPropagation();
- setOpen(!open);
- }}
- ></div>
- <ul>
- <li>
- <div className={styles.valueLong}>{open ? otc_cost : '*****'}</div>
- <div className={styles.btn1}>吨水药成本(元/m³)</div>
- </li>
- <li>
- <div className={styles.valueLong}>
- {open ? data?.otc_unit_theory || '-' : '*****'}
- </div>
- <Popover title={content}>
- <div className={styles.btn1} onClick={(e) => e.stopPropagation()}>
- 理论值(元/m³)
- <i className={styles.iconAlert}></i>
- </div>
- </Popover>
- </li>
- </ul>
- </div>
- );
- };
- // 工艺监控
- const Scada = () => {
- const { projectId } = useParams();
- const { data } = useRequest(getScadaPage, {
- defaultParams: [{ project_id: projectId }],
- formatResult: (res) => {
- let domain = location.host.includes('pad.greentech.com.cn')
- ? 'https://metawant.greentech.com.cn/'
- : 'http://47.96.12.136:8788/';
- const token = getToken();
- const pageList = res?.filter((item) => item.hide);
- const urls = pageList.map(
- (item) =>
- `${domain}smart-water/scada/index.html#/3dview/${projectId}/${item.id}?JWT-TOKEN=${token}&hideTitle=true&pauseLoadRealTimeData=true`,
- );
- return urls.splice(0, 1);
- },
- });
- return (
- <div
- className={styles.scadaMain}
- onClick={() => UnityAction.sendMsg('menuItem', '工艺监控')}
- >
- <Title title="工艺监控" />
- <div style={{ width: '707px', height: '279px' }}>
- {data?.map((url) => (
- <iframe
- key={url}
- style={{
- width: '707px',
- height: '279px',
- borderRadius: '0 0 44px 0',
- }}
- frameBorder="0"
- src={url}
- />
- ))}
- <div className={styles.mask}></div>
- </div>
- </div>
- );
- };
- // 待办事项
- const Backlog = (props) => {
- const { projectId } = useParams();
- const { data, loading } = useRequest(getPendingList, {
- defaultParams: [{ project_id: projectId }],
- });
- const handleClick = (item) => {
- if (item.type === 0) {
- // task
- UnityAction.sendMsg('OpenTaskModal', `mandate_id=${item.origin_id}`);
- } else {
- // order
- UnityAction.sendMsg(
- 'OpenWorkOrderModal',
- `order_id=${item.origin_id}&order_type=${item.origin_type}`,
- );
- }
- };
- return (
- <div
- className={styles.backlogMain}
- onClick={() => UnityAction.sendMsg('menuItem', '待办事项')}
- >
- <Title title={<div style={{ display: 'flex' }}>待办事项</div>} />
- <div className={styles.backlog}>
- <div>
- {data?.map((item) => (
- <div
- key={item.connect}
- className={styles.item}
- onClick={(e) => {
- e.stopPropagation();
- handleClick(item);
- }}
- >
- <div className={styles.createTime}>
- {dayjs(item.time).format('MM-DD HH:mm')}
- </div>
- <div className={styles.titleCon}>
- <div className={styles.point} />
- <div className={styles.titleText}>{item.title}</div>
- </div>
- <div className={styles.bottomCon}>{item.content}</div>
- </div>
- ))}
- </div>
- </div>
- </div>
- );
- };
- const Title = ({ title }) => {
- return (
- <div className={styles.titleContent}>
- <div className={styles.line} />
- <div className={styles.boxTitle}>{title}</div>
- </div>
- );
- };
- const Box = ({ title, children, onClick, small }) => {
- return (
- <div
- className={`${styles.box} ${small ? '' : styles.boxH}`}
- onClick={onClick}
- >
- <div className={styles.titleContent}>
- <div className={styles.line} />
- <div className={styles.boxTitle}>{title}</div>
- </div>
- {/* <span className={styles.boxTitle}>
- <div className={styles.line}></div>
- {title}
- </span> */}
- {children}
- </div>
- );
- };
- export default HomePage;
|