|  | @@ -0,0 +1,325 @@
 | 
	
		
			
				|  |  | +// 能耗详情
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import ChartModule from '@/components/ManagementPage/chartModule';
 | 
	
		
			
				|  |  | +import PageContent from '@/components/PageContent';
 | 
	
		
			
				|  |  | +import PageTitle from '@/components/PageTitle';
 | 
	
		
			
				|  |  | +import {
 | 
	
		
			
				|  |  | +  queryAccumulativeEnergy,
 | 
	
		
			
				|  |  | +  queryChartList,
 | 
	
		
			
				|  |  | +  queryEnergyConfig,
 | 
	
		
			
				|  |  | +  queryEnergyWaterChart,
 | 
	
		
			
				|  |  | +} from '@/services/OperationManagement';
 | 
	
		
			
				|  |  | +import { ArrowDownOutlined, ArrowUpOutlined } from '@ant-design/icons';
 | 
	
		
			
				|  |  | +import { useParams, useRequest } from '@umijs/max';
 | 
	
		
			
				|  |  | +import { Spin } from 'antd';
 | 
	
		
			
				|  |  | +import dayjs from 'dayjs';
 | 
	
		
			
				|  |  | +import { useMemo } from 'react';
 | 
	
		
			
				|  |  | +import styles from './manage.less';
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const EnergyCostDetail = () => {
 | 
	
		
			
				|  |  | +  const { projectId } = useParams();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  const TIMER = 3600000;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 全场概况
 | 
	
		
			
				|  |  | +  const { data: allFactoryData, loading: allFacLoading } = useRequest(
 | 
	
		
			
				|  |  | +    queryEnergyConfig,
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +      defaultParams: [projectId],
 | 
	
		
			
				|  |  | +      pollingInterval: TIMER,
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +  );
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 当日累计能耗、吨水电耗、环比
 | 
	
		
			
				|  |  | +  const { data: energyData, loading: energyLoading } = useRequest(
 | 
	
		
			
				|  |  | +    queryAccumulativeEnergy,
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +      defaultParams: [projectId],
 | 
	
		
			
				|  |  | +      pollingInterval: TIMER,
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +  );
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 吨水电耗折线图
 | 
	
		
			
				|  |  | +  const { data: chartData, loading: chartLosding } = useRequest(
 | 
	
		
			
				|  |  | +    queryEnergyWaterChart,
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +      defaultParams: [
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +          project_id: Number(projectId),
 | 
	
		
			
				|  |  | +          start_time: dayjs().startOf('day').format('YYYY-MM-DD 00:00:00'),
 | 
	
		
			
				|  |  | +          end_time: dayjs().format('YYYY-MM-DD 23:59:59'),
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +      ],
 | 
	
		
			
				|  |  | +      pollingInterval: TIMER,
 | 
	
		
			
				|  |  | +      formatResult(data) {
 | 
	
		
			
				|  |  | +        const tempData = data.data;
 | 
	
		
			
				|  |  | +        if (!tempData) {
 | 
	
		
			
				|  |  | +          return null;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return {
 | 
	
		
			
				|  |  | +          xData: tempData?.map((item) => item.data_time) || [],
 | 
	
		
			
				|  |  | +          dataList: [
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +              type: 0,
 | 
	
		
			
				|  |  | +              name: '吨水电耗',
 | 
	
		
			
				|  |  | +              data: tempData?.map((item) => item.value) || [],
 | 
	
		
			
				|  |  | +            },
 | 
	
		
			
				|  |  | +          ],
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +  );
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 电量折线图
 | 
	
		
			
				|  |  | +  const { data: electricChartData, loading: electricLosding } = useRequest(
 | 
	
		
			
				|  |  | +    () =>
 | 
	
		
			
				|  |  | +      queryChartList({
 | 
	
		
			
				|  |  | +        project_id: Number(projectId),
 | 
	
		
			
				|  |  | +        metric_code: 'plant_electricity',
 | 
	
		
			
				|  |  | +        start_time: dayjs().startOf('day').format('YYYY-MM-DD 00:00:00'),
 | 
	
		
			
				|  |  | +        end_time: dayjs().format('YYYY-MM-DD 23:59:59'),
 | 
	
		
			
				|  |  | +      }),
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +      pollingInterval: TIMER,
 | 
	
		
			
				|  |  | +      formatResult(data) {
 | 
	
		
			
				|  |  | +        if (!data?.data) return null;
 | 
	
		
			
				|  |  | +        const tempData = data.data;
 | 
	
		
			
				|  |  | +        const reversedData = tempData.reverse();
 | 
	
		
			
				|  |  | +        return {
 | 
	
		
			
				|  |  | +          xData: reversedData?.map((item) => item.data_time) || [],
 | 
	
		
			
				|  |  | +          dataList: [
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +              type: 2,
 | 
	
		
			
				|  |  | +              name: '实际',
 | 
	
		
			
				|  |  | +              data: reversedData?.map((item) => item.value) || [],
 | 
	
		
			
				|  |  | +            },
 | 
	
		
			
				|  |  | +          ],
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +  );
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 全场概况  包括两个折线图的y 轴名称
 | 
	
		
			
				|  |  | +  const allFactory = useMemo(() => {
 | 
	
		
			
				|  |  | +    const data = allFactoryData || {
 | 
	
		
			
				|  |  | +      voltage: '-',
 | 
	
		
			
				|  |  | +      transformer: '-',
 | 
	
		
			
				|  |  | +      capacity: '-',
 | 
	
		
			
				|  |  | +      runtime_capacity: '-',
 | 
	
		
			
				|  |  | +      voltage_unit: 'kV',
 | 
	
		
			
				|  |  | +      transformer_unit: '台',
 | 
	
		
			
				|  |  | +      capacity_unit: 'kVA',
 | 
	
		
			
				|  |  | +      runtime_capacity_unit: 'kVA',
 | 
	
		
			
				|  |  | +      energy_unit: 'kWh/t',
 | 
	
		
			
				|  |  | +      energy_water_unit: 'kWh',
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    return [
 | 
	
		
			
				|  |  | +      {
 | 
	
		
			
				|  |  | +        title: '电量等级',
 | 
	
		
			
				|  |  | +        data: data.voltage,
 | 
	
		
			
				|  |  | +        unit: data.voltage_unit,
 | 
	
		
			
				|  |  | +        color: '#eb0ce2',
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +      {
 | 
	
		
			
				|  |  | +        title: '变压器台数',
 | 
	
		
			
				|  |  | +        data: data.transformer,
 | 
	
		
			
				|  |  | +        unit: data.transformer_unit,
 | 
	
		
			
				|  |  | +        color: '#eb8c0c',
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +      {
 | 
	
		
			
				|  |  | +        title: '装机容器',
 | 
	
		
			
				|  |  | +        data: data.capacity,
 | 
	
		
			
				|  |  | +        unit: data.capacity_unit,
 | 
	
		
			
				|  |  | +        color: '#0cafeb',
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +      {
 | 
	
		
			
				|  |  | +        title: '运行容器',
 | 
	
		
			
				|  |  | +        data: data.runtime_capacity,
 | 
	
		
			
				|  |  | +        unit: data.runtime_capacity_unit,
 | 
	
		
			
				|  |  | +        color: '#50bb0a',
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +    ];
 | 
	
		
			
				|  |  | +  }, [allFactoryData]);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  const powerData = useMemo(() => {
 | 
	
		
			
				|  |  | +    const power = energyData || {
 | 
	
		
			
				|  |  | +      energy_change: '-',
 | 
	
		
			
				|  |  | +      energy_water_change: '-',
 | 
	
		
			
				|  |  | +      today_energy: '-',
 | 
	
		
			
				|  |  | +      today_energy_water: '-',
 | 
	
		
			
				|  |  | +      yesterday_energy: '-',
 | 
	
		
			
				|  |  | +      yesterday_energy_water: '-',
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return [
 | 
	
		
			
				|  |  | +      {
 | 
	
		
			
				|  |  | +        title: '当日吨水电耗',
 | 
	
		
			
				|  |  | +        data:
 | 
	
		
			
				|  |  | +          typeof power.today_energy_water == 'string'
 | 
	
		
			
				|  |  | +            ? power.today_energy_water
 | 
	
		
			
				|  |  | +            : power.today_energy_water?.toFixed(2),
 | 
	
		
			
				|  |  | +        unit: 'kWh/t',
 | 
	
		
			
				|  |  | +        color: '#eb0ce2',
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +      {
 | 
	
		
			
				|  |  | +        title: '昨日吨水电耗',
 | 
	
		
			
				|  |  | +        data:
 | 
	
		
			
				|  |  | +          typeof power.yesterday_energy_water == 'string'
 | 
	
		
			
				|  |  | +            ? power.yesterday_energy_water
 | 
	
		
			
				|  |  | +            : power.yesterday_energy_water?.toFixed(2),
 | 
	
		
			
				|  |  | +        unit: 'kWh/t',
 | 
	
		
			
				|  |  | +        color: '#eb8c0c',
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +      {
 | 
	
		
			
				|  |  | +        title: '环比增长',
 | 
	
		
			
				|  |  | +        data:
 | 
	
		
			
				|  |  | +          typeof power.energy_water_change == 'string'
 | 
	
		
			
				|  |  | +            ? power.energy_water_change
 | 
	
		
			
				|  |  | +            : power.energy_water_change?.toFixed(2),
 | 
	
		
			
				|  |  | +        unit: '%',
 | 
	
		
			
				|  |  | +        icon: power.energy_water_change >= 0 ? 1 : 2,
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +      {
 | 
	
		
			
				|  |  | +        title: '当日用电',
 | 
	
		
			
				|  |  | +        data: power.today_energy,
 | 
	
		
			
				|  |  | +        unit: 'kWh',
 | 
	
		
			
				|  |  | +        color: '#eb0ce2',
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +      {
 | 
	
		
			
				|  |  | +        title: '昨日用电',
 | 
	
		
			
				|  |  | +        data: power.yesterday_energy,
 | 
	
		
			
				|  |  | +        unit: 'kWh',
 | 
	
		
			
				|  |  | +        color: '#eb8c0c',
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +      {
 | 
	
		
			
				|  |  | +        title: '环比增长',
 | 
	
		
			
				|  |  | +        data:
 | 
	
		
			
				|  |  | +          typeof power.energy_change == 'string'
 | 
	
		
			
				|  |  | +            ? power.energy_change
 | 
	
		
			
				|  |  | +            : power.energy_change?.toFixed(2),
 | 
	
		
			
				|  |  | +        unit: '%',
 | 
	
		
			
				|  |  | +        icon: power.energy_change >= 0 ? 1 : 2,
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +    ];
 | 
	
		
			
				|  |  | +  }, [energyData]);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  const loading = useMemo(() => allFacLoading, [allFacLoading]);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  return (
 | 
	
		
			
				|  |  | +    <PageContent closeable={false}>
 | 
	
		
			
				|  |  | +      <PageTitle returnable>能耗数据</PageTitle>
 | 
	
		
			
				|  |  | +      <Spin spinning={loading}>
 | 
	
		
			
				|  |  | +        <div className={styles.infoContainer}>
 | 
	
		
			
				|  |  | +          <div>
 | 
	
		
			
				|  |  | +            <SubTitle title="全厂概览" />
 | 
	
		
			
				|  |  | +            <div style={{ display: 'flex' }}>
 | 
	
		
			
				|  |  | +              {allFactory.map((item, index) => (
 | 
	
		
			
				|  |  | +                <DataCard key={`all_${index}`} {...item} type={4} />
 | 
	
		
			
				|  |  | +              ))}
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +          <div>
 | 
	
		
			
				|  |  | +            <SubTitle title="用电概况" />
 | 
	
		
			
				|  |  | +            <div style={{ display: 'flex', flexWrap: 'wrap' }}>
 | 
	
		
			
				|  |  | +              {powerData.map((item, index) => (
 | 
	
		
			
				|  |  | +                <DataCard key={`power_${index}`} {...item} type={3} />
 | 
	
		
			
				|  |  | +              ))}
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +          <div>
 | 
	
		
			
				|  |  | +            <SubTitle title="吨水电耗" />
 | 
	
		
			
				|  |  | +            <div style={{ height: '3rem' }}>
 | 
	
		
			
				|  |  | +              {chartData && allFactoryData && (
 | 
	
		
			
				|  |  | +                <ChartModule
 | 
	
		
			
				|  |  | +                  yName={allFactoryData?.energy_water_unit || 'kWh'}
 | 
	
		
			
				|  |  | +                  xData={chartData.xData}
 | 
	
		
			
				|  |  | +                  dataList={chartData.dataList}
 | 
	
		
			
				|  |  | +                />
 | 
	
		
			
				|  |  | +              )}
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +          <div>
 | 
	
		
			
				|  |  | +            <SubTitle title="电量" />
 | 
	
		
			
				|  |  | +            <div style={{ height: '3rem' }}>
 | 
	
		
			
				|  |  | +              {electricChartData && allFactoryData && (
 | 
	
		
			
				|  |  | +                <ChartModule
 | 
	
		
			
				|  |  | +                  yName={allFactoryData?.energy_unit || 'kWh/t'}
 | 
	
		
			
				|  |  | +                  xData={electricChartData.xData}
 | 
	
		
			
				|  |  | +                  dataList={electricChartData.dataList}
 | 
	
		
			
				|  |  | +                />
 | 
	
		
			
				|  |  | +              )}
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +        </div>
 | 
	
		
			
				|  |  | +      </Spin>
 | 
	
		
			
				|  |  | +    </PageContent>
 | 
	
		
			
				|  |  | +  );
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +export default EnergyCostDetail;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const DataCard = ({ title, data, unit, icon, color, type }) => {
 | 
	
		
			
				|  |  | +  const width = Math.floor(100 / type - 2) + '%';
 | 
	
		
			
				|  |  | +  return (
 | 
	
		
			
				|  |  | +    <div style={{ width }} className={`${styles.itemContent} card-box`}>
 | 
	
		
			
				|  |  | +      <div style={{ fontSize: '0.26rem' }}>{title}</div>
 | 
	
		
			
				|  |  | +      <div style={{ position: 'relative' }}>
 | 
	
		
			
				|  |  | +        <span
 | 
	
		
			
				|  |  | +          style={{ color: !icon ? color : icon === 1 ? 'red' : '#50bb0a' }}
 | 
	
		
			
				|  |  | +          className={styles.data}
 | 
	
		
			
				|  |  | +        >
 | 
	
		
			
				|  |  | +          {data}
 | 
	
		
			
				|  |  | +        </span>
 | 
	
		
			
				|  |  | +        {unit}
 | 
	
		
			
				|  |  | +        {icon === 1 && (
 | 
	
		
			
				|  |  | +          <ArrowUpOutlined
 | 
	
		
			
				|  |  | +            style={{
 | 
	
		
			
				|  |  | +              height: '0.2rem',
 | 
	
		
			
				|  |  | +              color: 'red',
 | 
	
		
			
				|  |  | +              position: 'absolute',
 | 
	
		
			
				|  |  | +              fontSize: '0.34rem',
 | 
	
		
			
				|  |  | +              right: '0.4rem',
 | 
	
		
			
				|  |  | +            }}
 | 
	
		
			
				|  |  | +          />
 | 
	
		
			
				|  |  | +        )}
 | 
	
		
			
				|  |  | +        {icon === 2 && (
 | 
	
		
			
				|  |  | +          <ArrowDownOutlined
 | 
	
		
			
				|  |  | +            style={{
 | 
	
		
			
				|  |  | +              height: '0.2rem',
 | 
	
		
			
				|  |  | +              color: '#50bb0a',
 | 
	
		
			
				|  |  | +              position: 'absolute',
 | 
	
		
			
				|  |  | +              fontSize: '0.36rem',
 | 
	
		
			
				|  |  | +              right: '0.4rem',
 | 
	
		
			
				|  |  | +            }}
 | 
	
		
			
				|  |  | +          />
 | 
	
		
			
				|  |  | +        )}
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +    </div>
 | 
	
		
			
				|  |  | +  );
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const SubTitle = ({ title }) => {
 | 
	
		
			
				|  |  | +  return (
 | 
	
		
			
				|  |  | +    <div
 | 
	
		
			
				|  |  | +      style={{
 | 
	
		
			
				|  |  | +        display: 'flex',
 | 
	
		
			
				|  |  | +        justifyContent: 'flex-start',
 | 
	
		
			
				|  |  | +        alignItems: 'center',
 | 
	
		
			
				|  |  | +        marginBottom: '0.2rem',
 | 
	
		
			
				|  |  | +        fontSize: '0.28rem',
 | 
	
		
			
				|  |  | +        fontWeight: '600',
 | 
	
		
			
				|  |  | +      }}
 | 
	
		
			
				|  |  | +    >
 | 
	
		
			
				|  |  | +      <div
 | 
	
		
			
				|  |  | +        style={{
 | 
	
		
			
				|  |  | +          width: '0.15rem',
 | 
	
		
			
				|  |  | +          height: '0.15rem',
 | 
	
		
			
				|  |  | +          background: '#0139f1',
 | 
	
		
			
				|  |  | +          marginRight: '0.1rem',
 | 
	
		
			
				|  |  | +          borderRadius: '0.16rem',
 | 
	
		
			
				|  |  | +        }}
 | 
	
		
			
				|  |  | +      />
 | 
	
		
			
				|  |  | +      {title}
 | 
	
		
			
				|  |  | +    </div>
 | 
	
		
			
				|  |  | +  );
 | 
	
		
			
				|  |  | +};
 |