|  | @@ -0,0 +1,943 @@
 | 
	
		
			
				|  |  | +<template>
 | 
	
		
			
				|  |  | +  <BasicModal
 | 
	
		
			
				|  |  | +    @register="register"
 | 
	
		
			
				|  |  | +    title="局部通风机运行工况智能决策"
 | 
	
		
			
				|  |  | +    :maskStyle="{ backgroundColor: '#000000aa', backdropFilter: 'blur(3px)' }"
 | 
	
		
			
				|  |  | +    :width="isComputeGas ? '1400px' : '950px'"
 | 
	
		
			
				|  |  | +    v-bind="$attrs"
 | 
	
		
			
				|  |  | +    @ok="onSubmit"
 | 
	
		
			
				|  |  | +    :closeFunc="onCancel"
 | 
	
		
			
				|  |  | +    :canFullscreen="false"
 | 
	
		
			
				|  |  | +    :destroyOnClose="true"
 | 
	
		
			
				|  |  | +    :footer="null"
 | 
	
		
			
				|  |  | +    :maskClosable="false"
 | 
	
		
			
				|  |  | +  >
 | 
	
		
			
				|  |  | +    <div class="modal-box">
 | 
	
		
			
				|  |  | +      <div v-if="isComputeGas" class="left-box" style="width: 550px; height: 400px">
 | 
	
		
			
				|  |  | +        <BarAndLine
 | 
	
		
			
				|  |  | +          class="echarts-line"
 | 
	
		
			
				|  |  | +          xAxisPropType="time"
 | 
	
		
			
				|  |  | +          :dataSource="monitorData"
 | 
	
		
			
				|  |  | +          height="400px"
 | 
	
		
			
				|  |  | +          :chartsColumns="chartsColumnList"
 | 
	
		
			
				|  |  | +          :option="echatsOption"
 | 
	
		
			
				|  |  | +          chartsType="listMonitor"
 | 
	
		
			
				|  |  | +        />
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +      <div class="center-box">
 | 
	
		
			
				|  |  | +        <a-spin :spinning="loadding" tip="正在计算,请稍等。。。">
 | 
	
		
			
				|  |  | +          <div ref="ChartRef" class="info-echarts" :style="{ width: isComputeGas ? '450px' : '520px', height: '400px' }"></div>
 | 
	
		
			
				|  |  | +        </a-spin>
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +      <div class="right-box">
 | 
	
		
			
				|  |  | +        <!-- <div class="box-title">曲线方程</div> -->
 | 
	
		
			
				|  |  | +        <dv-decoration7 style="height: 20px">
 | 
	
		
			
				|  |  | +          <div class="box-title">曲线方程</div>
 | 
	
		
			
				|  |  | +        </dv-decoration7>
 | 
	
		
			
				|  |  | +        <div class="info-lines">
 | 
	
		
			
				|  |  | +          <div v-for="(item, index) in lineEquation" class="info-item" :key="index">
 | 
	
		
			
				|  |  | +            <div class="title">{{ item }}</div>
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +        </div>
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +      <div class="tip-box">
 | 
	
		
			
				|  |  | +        <div class="title">最佳工况点 <SendOutlined class="ml-5px" /></div>
 | 
	
		
			
				|  |  | +        <div class="tip-container" :style="{ width: isComputeGas ? '898px' : '400px' }">
 | 
	
		
			
				|  |  | +          <template v-if="resultObj && isHaCross">
 | 
	
		
			
				|  |  | +            <div class="ml-10px">
 | 
	
		
			
				|  |  | +              <span>频率:</span>
 | 
	
		
			
				|  |  | +              <span style="color: #d066ff; padding: 0 10px; font-weight: 600">{{ formatNum(resultObj.Hz) }}Hz</span>
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +            <div class="ml-10px">
 | 
	
		
			
				|  |  | +              <span>风量:</span>
 | 
	
		
			
				|  |  | +              <span style="color: #3adeff; padding: 0 10px; font-weight: 600">{{ formatNum(resultObj.x) }} m³/min</span>
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +            <div class="ml-10px">
 | 
	
		
			
				|  |  | +              <span>负压</span>
 | 
	
		
			
				|  |  | +              <span style="color: #ffbe34; padding: 0 10px; font-weight: 600">{{ formatNum(resultObj.y) }} Pa</span>
 | 
	
		
			
				|  |  | +            </div>
 | 
	
		
			
				|  |  | +          </template>
 | 
	
		
			
				|  |  | +          <div v-else-if="isHaCross" class="ml-10px">暂无</div>
 | 
	
		
			
				|  |  | +          <div v-else style="color: #ffbe34; padding: 0 10px; font-weight: 600" class="ml-10px">无有效工况点</div>
 | 
	
		
			
				|  |  | +        </div>
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +    </div>
 | 
	
		
			
				|  |  | +    <div class="setting-box">
 | 
	
		
			
				|  |  | +      <div class="right-inputs">
 | 
	
		
			
				|  |  | +        <div class="vent-flex-row">
 | 
	
		
			
				|  |  | +          <div class="input-title">风量(m³/min):</div>
 | 
	
		
			
				|  |  | +          <InputNumber :disabled="isComputeGas" class="input-box" size="large" v-model:value="uQ1" />
 | 
	
		
			
				|  |  | +          <div class="input-title">风压(Pa):</div>
 | 
	
		
			
				|  |  | +          <InputNumber :disabled="isComputeGas" class="input-box" size="large" v-model:value="uH" />
 | 
	
		
			
				|  |  | +          <div v-if="!isComputeGas" class="btn btn1" @click="makeLine">决策工况</div>
 | 
	
		
			
				|  |  | +          <template v-else>
 | 
	
		
			
				|  |  | +            <div class="btn btn1" @click="startCompute">一键调控</div>
 | 
	
		
			
				|  |  | +            <div class="btn btn1" @click="resetCompute">一键复位</div>
 | 
	
		
			
				|  |  | +          </template>
 | 
	
		
			
				|  |  | +        </div>
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +    </div>
 | 
	
		
			
				|  |  | +  </BasicModal>
 | 
	
		
			
				|  |  | +</template>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +<script lang="ts" setup>
 | 
	
		
			
				|  |  | +  //ts语法
 | 
	
		
			
				|  |  | +  import { ref, onMounted, reactive, nextTick, computed } from 'vue';
 | 
	
		
			
				|  |  | +  import echarts from '/@/utils/lib/echarts';
 | 
	
		
			
				|  |  | +  import { option, initData, fanInfoData, chartsColumnList, echatsOption } from '../fanLocal.data';
 | 
	
		
			
				|  |  | +  import { BasicModal, useModalInner } from '/@/components/Modal';
 | 
	
		
			
				|  |  | +  import { useForm } from '/@/components/Form/index';
 | 
	
		
			
				|  |  | +  import { Input, InputNumber } from 'ant-design-vue';
 | 
	
		
			
				|  |  | +  import { Decoration7 as DvDecoration7 } from '@kjgl77/datav-vue3';
 | 
	
		
			
				|  |  | +  import { message } from 'ant-design-vue';
 | 
	
		
			
				|  |  | +  import { formatNum } from '/@/utils/ventutil';
 | 
	
		
			
				|  |  | +  import BarAndLine from '/@/components/chart/BarAndLine.vue';
 | 
	
		
			
				|  |  | +  import { cloneDeep } from 'lodash-es';
 | 
	
		
			
				|  |  | +  import dayjs from 'dayjs';
 | 
	
		
			
				|  |  | +  import { SendOutlined } from '@ant-design/icons-vue';
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  const emit = defineEmits(['close', 'register', 'openModal']);
 | 
	
		
			
				|  |  | +  const props = defineProps({
 | 
	
		
			
				|  |  | +    dataSource: {
 | 
	
		
			
				|  |  | +      type: Array,
 | 
	
		
			
				|  |  | +      default: () => [],
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    frequency: {
 | 
	
		
			
				|  |  | +      type: Number,
 | 
	
		
			
				|  |  | +      default: 30,
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    m3: {
 | 
	
		
			
				|  |  | +      type: Number,
 | 
	
		
			
				|  |  | +      default: 670.8,
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    // gasWarningMax: { type: Number, default: 0.5 },
 | 
	
		
			
				|  |  | +    // gasWarningVal: { type: Number, default: 0.6 },
 | 
	
		
			
				|  |  | +    // windQuantity: { type: Number, default: 635.84 },
 | 
	
		
			
				|  |  | +  });
 | 
	
		
			
				|  |  | +  type AssistanceItemType = {
 | 
	
		
			
				|  |  | +    angle: number;
 | 
	
		
			
				|  |  | +    Hz: number;
 | 
	
		
			
				|  |  | +    a: number;
 | 
	
		
			
				|  |  | +    b: number;
 | 
	
		
			
				|  |  | +    c: number;
 | 
	
		
			
				|  |  | +    min: number;
 | 
	
		
			
				|  |  | +    max: number;
 | 
	
		
			
				|  |  | +  };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 注册 modal
 | 
	
		
			
				|  |  | +  const [register, { closeModal }] = useModalInner((data) => {
 | 
	
		
			
				|  |  | +    nextTick(() => {
 | 
	
		
			
				|  |  | +      computeAssistance();
 | 
	
		
			
				|  |  | +      if (option['xAxis']) option['xAxis']['data'] = xData;
 | 
	
		
			
				|  |  | +      option['series'] = yDataList;
 | 
	
		
			
				|  |  | +      if (JSON.stringify(data) !== '{}') {
 | 
	
		
			
				|  |  | +        uQ1.value = Number(data['m3']);
 | 
	
		
			
				|  |  | +        uHz.value = Math.ceil(data['frequency']);
 | 
	
		
			
				|  |  | +        gasWarningVal.value = data['gasWarningVal'];
 | 
	
		
			
				|  |  | +        isComputeGas.value = true;
 | 
	
		
			
				|  |  | +        nextTick(() => {
 | 
	
		
			
				|  |  | +          computeUH(data['frequency'], data['m3']);
 | 
	
		
			
				|  |  | +          initEcharts();
 | 
	
		
			
				|  |  | +          setTimeout(() => {
 | 
	
		
			
				|  |  | +            // 根据频率计算uH
 | 
	
		
			
				|  |  | +            makeLine();
 | 
	
		
			
				|  |  | +          }, 2000);
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        initEcharts();
 | 
	
		
			
				|  |  | +        isComputeGas.value = false;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  });
 | 
	
		
			
				|  |  | +  const loadding = ref<boolean>(false);
 | 
	
		
			
				|  |  | +  const formShow = ref(false);
 | 
	
		
			
				|  |  | +  const formType = ref('');
 | 
	
		
			
				|  |  | +  const ChartRef = ref();
 | 
	
		
			
				|  |  | +  const myChart = ref();
 | 
	
		
			
				|  |  | +  const refresh = ref(true);
 | 
	
		
			
				|  |  | +  const xDataMax = 1200;
 | 
	
		
			
				|  |  | +  let xDataMin = 0;
 | 
	
		
			
				|  |  | +  const xData: any[] = [];
 | 
	
		
			
				|  |  | +  const yDataList: [] = [];
 | 
	
		
			
				|  |  | +  let lineNum = 0;
 | 
	
		
			
				|  |  | +  const lineEquation = ref<string[]>([]);
 | 
	
		
			
				|  |  | +  const assistanceData = ref([]);
 | 
	
		
			
				|  |  | +  const monitorData = ref([]);
 | 
	
		
			
				|  |  | +  const gasWarningVal = ref(0);
 | 
	
		
			
				|  |  | +  const gasWarningMax = ref(0.5);
 | 
	
		
			
				|  |  | +  const isComputeGas = ref(false);
 | 
	
		
			
				|  |  | +  const isStartCompute = ref(0);
 | 
	
		
			
				|  |  | +  const uHz = ref(0);
 | 
	
		
			
				|  |  | +  const uQ1 = ref(0);
 | 
	
		
			
				|  |  | +  const uQ = computed(() => {
 | 
	
		
			
				|  |  | +    if (uQ1.value) {
 | 
	
		
			
				|  |  | +      if (gasWarningVal.value) {
 | 
	
		
			
				|  |  | +        return ((uQ1.value * gasWarningVal.value) / gasWarningMax.value) * 1.08;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      return uQ1.value;
 | 
	
		
			
				|  |  | +    } else {
 | 
	
		
			
				|  |  | +      return 0;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  });
 | 
	
		
			
				|  |  | +  const uH = ref<number | undefined>(undefined); //  - 1000
 | 
	
		
			
				|  |  | +  const isHaCross = ref(true);
 | 
	
		
			
				|  |  | +  const resultObj = ref<{ x: number; y: number; Hz: number } | null>(null);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  const [registerForm, {}] = useForm({
 | 
	
		
			
				|  |  | +    labelWidth: 120,
 | 
	
		
			
				|  |  | +    actionColOptions: {
 | 
	
		
			
				|  |  | +      span: 24,
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    compact: true,
 | 
	
		
			
				|  |  | +    showSubmitButton: true,
 | 
	
		
			
				|  |  | +    submitButtonOptions: {
 | 
	
		
			
				|  |  | +      text: '提交',
 | 
	
		
			
				|  |  | +      preIcon: '',
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    showResetButton: true,
 | 
	
		
			
				|  |  | +    resetButtonOptions: {
 | 
	
		
			
				|  |  | +      text: '关闭',
 | 
	
		
			
				|  |  | +      preIcon: '',
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    resetFunc: async () => {
 | 
	
		
			
				|  |  | +      formShow.value = false;
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +  });
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function computeAssistance() {
 | 
	
		
			
				|  |  | +    assistanceData.value = initData();
 | 
	
		
			
				|  |  | +    lineNum = 0;
 | 
	
		
			
				|  |  | +    const assistanceDataList = [];
 | 
	
		
			
				|  |  | +    const lineEquationList: string[] = [];
 | 
	
		
			
				|  |  | +    for (const key in assistanceData.value) {
 | 
	
		
			
				|  |  | +      const item = assistanceData.value[key];
 | 
	
		
			
				|  |  | +      assistanceDataList.push(item);
 | 
	
		
			
				|  |  | +      lineEquationList.push(
 | 
	
		
			
				|  |  | +        `H${parseInt(item['Hz'])} = ${item['a']}Q² ${Number(item['b']) > 0 ? '+' : '-'} ${Math.abs(Number(item['b'])).toFixed(4)}Q ${
 | 
	
		
			
				|  |  | +          Number(item['c']) > 0 ? '+' : '-'
 | 
	
		
			
				|  |  | +        } ${Math.abs(Number(item['c'])).toFixed(4)}`
 | 
	
		
			
				|  |  | +      );
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    lineEquation.value = lineEquationList;
 | 
	
		
			
				|  |  | +    lineNum = assistanceDataList.length;
 | 
	
		
			
				|  |  | +    xDataMin =
 | 
	
		
			
				|  |  | +      Math.min.apply(
 | 
	
		
			
				|  |  | +        Math,
 | 
	
		
			
				|  |  | +        assistanceDataList.map((item) => {
 | 
	
		
			
				|  |  | +          return item.min;
 | 
	
		
			
				|  |  | +        })
 | 
	
		
			
				|  |  | +      ) - 100;
 | 
	
		
			
				|  |  | +    // const xDataMax = Math.max.apply(Math, assistanceDataList.map(item => { return item.max }))
 | 
	
		
			
				|  |  | +    fanInfoData.flfw = `${xDataMin}~${xDataMax}`;
 | 
	
		
			
				|  |  | +    const computeItem = (item: AssistanceItemType) => {
 | 
	
		
			
				|  |  | +      const min = item.min;
 | 
	
		
			
				|  |  | +      const max = item.max;
 | 
	
		
			
				|  |  | +      const HList: number[] = [];
 | 
	
		
			
				|  |  | +      for (let i = xDataMin; i <= xDataMax; i++) {
 | 
	
		
			
				|  |  | +        if (i < min) {
 | 
	
		
			
				|  |  | +          HList.push(null);
 | 
	
		
			
				|  |  | +        } else if (i > max) {
 | 
	
		
			
				|  |  | +          HList.push(null);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          HList.push(item.a * i * i + item.b * i + item.c);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      return HList;
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    for (const key in assistanceData.value) {
 | 
	
		
			
				|  |  | +      const element: AssistanceItemType = assistanceData.value[key];
 | 
	
		
			
				|  |  | +      const yData: number[] = computeItem(element);
 | 
	
		
			
				|  |  | +      const series = {
 | 
	
		
			
				|  |  | +        type: 'line',
 | 
	
		
			
				|  |  | +        name: `${element['Hz']}Hz`,
 | 
	
		
			
				|  |  | +        smooth: true,
 | 
	
		
			
				|  |  | +        showSymbol: false,
 | 
	
		
			
				|  |  | +        symbol: 'none',
 | 
	
		
			
				|  |  | +        emphasis: {
 | 
	
		
			
				|  |  | +          focus: 'series',
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        itemStyle: { normal: { label: { show: true } } },
 | 
	
		
			
				|  |  | +        lineStyle: {
 | 
	
		
			
				|  |  | +          width: 1,
 | 
	
		
			
				|  |  | +          color: '#ffffff88',
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        zlevel: 0,
 | 
	
		
			
				|  |  | +        z: 1,
 | 
	
		
			
				|  |  | +        endLabel: {
 | 
	
		
			
				|  |  | +          show: true,
 | 
	
		
			
				|  |  | +          formatter: '{a}',
 | 
	
		
			
				|  |  | +          distance: 0,
 | 
	
		
			
				|  |  | +          color: '#39E9FE99',
 | 
	
		
			
				|  |  | +          backgroundColor: 'transparent',
 | 
	
		
			
				|  |  | +          padding: [3, 3, 2, 3],
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        data: yData,
 | 
	
		
			
				|  |  | +      };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      yDataList.push(series);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    for (let i = xDataMin; i <= xDataMax; i++) {
 | 
	
		
			
				|  |  | +      xData.push(i);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function computeUH(Hz: number, uQ: number) {
 | 
	
		
			
				|  |  | +    const equation = assistanceData.value.find((item) => {
 | 
	
		
			
				|  |  | +      return Math.ceil(Hz) == item['Hz'];
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    if (equation) {
 | 
	
		
			
				|  |  | +      const uHMax = Math.round((equation['a'] * equation['min'] * equation['min'] + equation['b'] * equation['min'] + equation['c']) * 100) / 100;
 | 
	
		
			
				|  |  | +      const uHMin = Math.round((equation['a'] * equation['max'] * equation['max'] + equation['b'] * equation['max'] + equation['c']) * 100) / 100;
 | 
	
		
			
				|  |  | +      const uH1 = Math.round((equation['a'] * uQ * uQ + equation['b'] * uQ + equation['c']) * 100) / 100;
 | 
	
		
			
				|  |  | +      if (uH1 >= uHMin && uH1 <= uHMax) {
 | 
	
		
			
				|  |  | +        uH.value = uH1;
 | 
	
		
			
				|  |  | +        isHaCross.value = true;
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        isHaCross.value = false;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function computeRLine() {
 | 
	
		
			
				|  |  | +    console.log('计算后的风量为------------>', uQ.value);
 | 
	
		
			
				|  |  | +    if (uH.value && uQ.value) {
 | 
	
		
			
				|  |  | +      const R = uH.value / Number(uQ.value) / Number(uQ.value);
 | 
	
		
			
				|  |  | +      const yAxis: number[] = [];
 | 
	
		
			
				|  |  | +      for (let i = 0; i < xData.length; i++) {
 | 
	
		
			
				|  |  | +        const x = xData[i];
 | 
	
		
			
				|  |  | +        const y = R * x * x;
 | 
	
		
			
				|  |  | +        if (x == uQ.value) {
 | 
	
		
			
				|  |  | +          uH.value = y;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        yAxis.push(y);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      const series = {
 | 
	
		
			
				|  |  | +        name: 'R',
 | 
	
		
			
				|  |  | +        type: 'line',
 | 
	
		
			
				|  |  | +        smooth: true,
 | 
	
		
			
				|  |  | +        showSymbol: false,
 | 
	
		
			
				|  |  | +        zlevel: 0,
 | 
	
		
			
				|  |  | +        emphasis: {
 | 
	
		
			
				|  |  | +          focus: 'series',
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        itemStyle: { normal: { label: { show: true } } },
 | 
	
		
			
				|  |  | +        lineStyle: {
 | 
	
		
			
				|  |  | +          width: 2,
 | 
	
		
			
				|  |  | +          color: '#D0A343',
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        endLabel: {
 | 
	
		
			
				|  |  | +          show: true,
 | 
	
		
			
				|  |  | +          formatter: '{a}',
 | 
	
		
			
				|  |  | +          distance: 0,
 | 
	
		
			
				|  |  | +          color: '#D0A343',
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        data: yAxis,
 | 
	
		
			
				|  |  | +      };
 | 
	
		
			
				|  |  | +      yDataList[lineNum] = series;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function reSetLine() {
 | 
	
		
			
				|  |  | +    let minIndex = -1;
 | 
	
		
			
				|  |  | +    for (let i = 0; i < yDataList.length; i++) {
 | 
	
		
			
				|  |  | +      if (i !== lineNum && i != lineNum + 1) {
 | 
	
		
			
				|  |  | +        if (yDataList[i]['lineStyle']) yDataList[i]['lineStyle']['color'] = '#ffffff88';
 | 
	
		
			
				|  |  | +        if (yDataList[i]['lineStyle']) yDataList[i]['lineStyle']['width'] = 1;
 | 
	
		
			
				|  |  | +        if (yDataList[i]['endLabel'] && yDataList[i]['endLabel']['color']) {
 | 
	
		
			
				|  |  | +          if (i % 5 == 0) {
 | 
	
		
			
				|  |  | +            yDataList[i]['endLabel']['color'] = '#39E9FE99';
 | 
	
		
			
				|  |  | +          } else {
 | 
	
		
			
				|  |  | +            yDataList[i]['endLabel']['color'] = '#39E9FE00';
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (yDataList[i]['endLabel'] && yDataList[i]['endLabel']['backgroundColor']) yDataList[i]['endLabel']['backgroundColor'] = 'transparent';
 | 
	
		
			
				|  |  | +        if (yDataList[i]['z']) yDataList[i]['z'] = 1;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      if (resultObj.value && `${resultObj.value.Hz}Hz` == yDataList[i]['name']) {
 | 
	
		
			
				|  |  | +        minIndex = i;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if (minIndex != -1) {
 | 
	
		
			
				|  |  | +      yDataList[minIndex]['lineStyle']['color'] = '#9A60B4';
 | 
	
		
			
				|  |  | +      yDataList[minIndex]['lineStyle']['width'] = 2;
 | 
	
		
			
				|  |  | +      yDataList[minIndex]['endLabel']['color'] = '#9A60B4';
 | 
	
		
			
				|  |  | +      yDataList[minIndex]['endLabel']['backgroundColor'] = '#111';
 | 
	
		
			
				|  |  | +      yDataList[minIndex]['z'] = 999;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 根据风量计算压差
 | 
	
		
			
				|  |  | +  function computePa() {
 | 
	
		
			
				|  |  | +    const R = uH.value / Number(uQ.value) / Number(uQ.value);
 | 
	
		
			
				|  |  | +    const pointX = Number(uQ.value);
 | 
	
		
			
				|  |  | +    const pointY = Number(uH.value);
 | 
	
		
			
				|  |  | +    type ItemType = {
 | 
	
		
			
				|  |  | +      x: number;
 | 
	
		
			
				|  |  | +      y: number;
 | 
	
		
			
				|  |  | +      Hz: number;
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    const paList = new Map<number, ItemType>(); // key 是最近距离
 | 
	
		
			
				|  |  | +    const getIntersectionPoint = (a, b, c, R, min, max) => {
 | 
	
		
			
				|  |  | +      const obj: { x: undefined | number; y: undefined | number; min: number; max: number } = { x: undefined, y: undefined, min: min, max: max };
 | 
	
		
			
				|  |  | +      // 计算二次方程的判别式
 | 
	
		
			
				|  |  | +      const discriminant = b * b - 4 * (a - R) * c;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      if (discriminant > 0) {
 | 
	
		
			
				|  |  | +        // 有两个实根
 | 
	
		
			
				|  |  | +        const x1 = (-b + Math.sqrt(discriminant)) / (2 * (a - R));
 | 
	
		
			
				|  |  | +        const x2 = (-b - Math.sqrt(discriminant)) / (2 * (a - R));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        const y1 = R * x1 * x1;
 | 
	
		
			
				|  |  | +        const y2 = R * x2 * x2;
 | 
	
		
			
				|  |  | +        if (x1 >= min && x1 <= max) {
 | 
	
		
			
				|  |  | +          obj.x = x1;
 | 
	
		
			
				|  |  | +          obj.y = y1;
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          obj.x = x2;
 | 
	
		
			
				|  |  | +          obj.y = y2;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      } else if (discriminant === 0) {
 | 
	
		
			
				|  |  | +        // 有一个实根
 | 
	
		
			
				|  |  | +        const x = -b / (2 * (a - R));
 | 
	
		
			
				|  |  | +        const y = R * x * x;
 | 
	
		
			
				|  |  | +        if (x >= min && x <= max) {
 | 
	
		
			
				|  |  | +          obj.x = x;
 | 
	
		
			
				|  |  | +          obj.y = y;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        // console.log(`唯一交点: (${x}, ${y})`);
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // 没有实根,交点在虚数域
 | 
	
		
			
				|  |  | +        console.log('没有实数交点');
 | 
	
		
			
				|  |  | +        isHaCross.value = false;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      return obj;
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    for (let key in assistanceData.value) {
 | 
	
		
			
				|  |  | +      const item: AssistanceItemType = assistanceData.value[key];
 | 
	
		
			
				|  |  | +      paList.set(item.Hz, getIntersectionPoint(item.a, item.b, item.c, R, item.min, item.max));
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const min = (points: Map<number, ItemType>) => {
 | 
	
		
			
				|  |  | +      const targetX = uQ.value;
 | 
	
		
			
				|  |  | +      const targetY = uH.value;
 | 
	
		
			
				|  |  | +      let minDistance = Number.POSITIVE_INFINITY;
 | 
	
		
			
				|  |  | +      let closestPoint = null;
 | 
	
		
			
				|  |  | +      let keyVal = '';
 | 
	
		
			
				|  |  | +      // 遍历已知点数组,计算距离并更新最小距离和对应的点
 | 
	
		
			
				|  |  | +      for (const [key, point] of points) {
 | 
	
		
			
				|  |  | +        const distance = Math.sqrt((targetX - point.x) ** 2 + (targetY - point.y) ** 2);
 | 
	
		
			
				|  |  | +        if (distance < minDistance) {
 | 
	
		
			
				|  |  | +          minDistance = distance;
 | 
	
		
			
				|  |  | +          closestPoint = point;
 | 
	
		
			
				|  |  | +          keyVal = key;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      if (closestPoint !== null) {
 | 
	
		
			
				|  |  | +        // console.log(`距离最小的点是 (${closestPoint.x}, ${closestPoint.y}), 距离为 ${minDistance}`);
 | 
	
		
			
				|  |  | +        if (closestPoint.x < closestPoint.min || closestPoint.x > closestPoint.max) {
 | 
	
		
			
				|  |  | +          resultObj.value = null;
 | 
	
		
			
				|  |  | +          isHaCross.value = false;
 | 
	
		
			
				|  |  | +          console.log('没有找到最小距离的点');
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          resultObj.value = { x: closestPoint.x, y: closestPoint.y, Hz: keyVal };
 | 
	
		
			
				|  |  | +          isHaCross.value = true;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        resultObj.value = null;
 | 
	
		
			
				|  |  | +        isHaCross.value = false;
 | 
	
		
			
				|  |  | +        console.log('没有找到最小距离的点');
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    min(paList);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function computeR() {
 | 
	
		
			
				|  |  | +    if (uQ.value && uH.value) {
 | 
	
		
			
				|  |  | +      computeRLine();
 | 
	
		
			
				|  |  | +      computePa();
 | 
	
		
			
				|  |  | +      const x = resultObj.value && resultObj.value.x ? resultObj.value.x.toFixed(0) : -100;
 | 
	
		
			
				|  |  | +      const y = resultObj.value && resultObj.value.y ? Number(resultObj.value.y.toFixed(0)) : -100;
 | 
	
		
			
				|  |  | +      const series = {
 | 
	
		
			
				|  |  | +        type: 'effectScatter',
 | 
	
		
			
				|  |  | +        symbolSize: 5,
 | 
	
		
			
				|  |  | +        // symbolOffset:[1, 1],
 | 
	
		
			
				|  |  | +        showEffectOn: 'render',
 | 
	
		
			
				|  |  | +        // 涟漪特效相关配置。
 | 
	
		
			
				|  |  | +        rippleEffect: {
 | 
	
		
			
				|  |  | +          // 波纹的绘制方式,可选 'stroke' 和 'fill'。
 | 
	
		
			
				|  |  | +          brushType: 'stroke',
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        zlevel: 1,
 | 
	
		
			
				|  |  | +        z: 999,
 | 
	
		
			
				|  |  | +        itemStyle: {
 | 
	
		
			
				|  |  | +          color: '#C60000',
 | 
	
		
			
				|  |  | +        },
 | 
	
		
			
				|  |  | +        data: [[x, y]],
 | 
	
		
			
				|  |  | +      };
 | 
	
		
			
				|  |  | +      yDataList[lineNum + 1] = series;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    // // 根据计算后的得到的频率,风量,瓦斯浓度
 | 
	
		
			
				|  |  | +    // getMonitor();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function getMonitor() {
 | 
	
		
			
				|  |  | +    clearTimeout(timer);
 | 
	
		
			
				|  |  | +    timer = undefined;
 | 
	
		
			
				|  |  | +    const n = 10;
 | 
	
		
			
				|  |  | +    const windQuantity = uQ1.value;
 | 
	
		
			
				|  |  | +    const obj = {
 | 
	
		
			
				|  |  | +      m3: windQuantity,
 | 
	
		
			
				|  |  | +      gas: gasWarningVal.value,
 | 
	
		
			
				|  |  | +      time: '',
 | 
	
		
			
				|  |  | +      Hz: uHz.value,
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    const monitorList: { m3: number; gas: number; Hz: number; time: string }[] = [];
 | 
	
		
			
				|  |  | +    for (let i = 0; i < n; i++) {
 | 
	
		
			
				|  |  | +      const item = cloneDeep(obj);
 | 
	
		
			
				|  |  | +      const m3Temp = (Math.random() * 2 - 1) * Math.random() * 20;
 | 
	
		
			
				|  |  | +      const gas = m3Temp * 0.0002;
 | 
	
		
			
				|  |  | +      item.time = dayjs(new Date().getTime() - (n + i) * 3000).format('HH:mm:ss');
 | 
	
		
			
				|  |  | +      item.m3 = (obj.m3 + m3Temp).toFixed(2);
 | 
	
		
			
				|  |  | +      item.gas = (obj.gas + gas).toFixed(4);
 | 
	
		
			
				|  |  | +      item.Hz = (obj.Hz + Math.random()).toFixed(2);
 | 
	
		
			
				|  |  | +      monitorList.unshift(item);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    monitorData.value = cloneDeep(monitorList);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    setTimeout(() => {
 | 
	
		
			
				|  |  | +      clearTimeout(timer);
 | 
	
		
			
				|  |  | +      timer = undefined;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      timer = 0;
 | 
	
		
			
				|  |  | +      if (uQ1.value && uH.value && uQ.value) {
 | 
	
		
			
				|  |  | +        openTimer(cloneDeep(obj), 0);
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        openTimer(cloneDeep(obj), 0);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }, 1000);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function startCompute() {
 | 
	
		
			
				|  |  | +    setTimeout(() => {
 | 
	
		
			
				|  |  | +      message.success('指令下发成功!');
 | 
	
		
			
				|  |  | +      isStartCompute.value = 1;
 | 
	
		
			
				|  |  | +    }, 800);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function resetCompute() {
 | 
	
		
			
				|  |  | +    setTimeout(() => {
 | 
	
		
			
				|  |  | +      message.success('指令下发成功!');
 | 
	
		
			
				|  |  | +      isStartCompute.value = -1;
 | 
	
		
			
				|  |  | +      tempList.length = 0;
 | 
	
		
			
				|  |  | +      n = 0;
 | 
	
		
			
				|  |  | +    }, 800);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  let timer = undefined;
 | 
	
		
			
				|  |  | +  let n = 0;
 | 
	
		
			
				|  |  | +  let tempList = [];
 | 
	
		
			
				|  |  | +  function openTimer(obj: { m3: number; gas: number; Hz: number; time: string }) {
 | 
	
		
			
				|  |  | +    // 打开定时器
 | 
	
		
			
				|  |  | +    const monitorList = cloneDeep(monitorData.value);
 | 
	
		
			
				|  |  | +    if (timer !== undefined) {
 | 
	
		
			
				|  |  | +      timer = setTimeout(() => {
 | 
	
		
			
				|  |  | +        obj.m3 = Number(obj.m3);
 | 
	
		
			
				|  |  | +        obj.gas = Number(obj.gas);
 | 
	
		
			
				|  |  | +        obj.Hz = Number(obj.Hz);
 | 
	
		
			
				|  |  | +        const item = cloneDeep(obj);
 | 
	
		
			
				|  |  | +        item.time = dayjs(new Date().getTime()).format('HH:mm:ss');
 | 
	
		
			
				|  |  | +        if (resultObj.value && resultObj.value.x && resultObj.value.y && isStartCompute.value != 0) {
 | 
	
		
			
				|  |  | +          if (isStartCompute.value == 1 && Number(obj.m3) > uQ.value && Number(obj.gas) < gasWarningMax.value) {
 | 
	
		
			
				|  |  | +            isStartCompute.value = 0;
 | 
	
		
			
				|  |  | +            n = 0;
 | 
	
		
			
				|  |  | +          } else if (isStartCompute.value == -1 && Number(obj.m3) < uQ1.value) {
 | 
	
		
			
				|  |  | +            isStartCompute.value = 0;
 | 
	
		
			
				|  |  | +            n = 0;
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (!isStartCompute.value) {
 | 
	
		
			
				|  |  | +          const m3Temp = (Math.random() * 2 - 1) * Math.random() * Math.random() * 10;
 | 
	
		
			
				|  |  | +          const gas = m3Temp * 0.0002;
 | 
	
		
			
				|  |  | +          item.m3 = (obj.m3 + m3Temp).toFixed(2);
 | 
	
		
			
				|  |  | +          item.gas = (obj.gas + gas).toFixed(4);
 | 
	
		
			
				|  |  | +          item.Hz = (obj.Hz + Math.random()).toFixed(2);
 | 
	
		
			
				|  |  | +          n = 0;
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          if (n < 2) {
 | 
	
		
			
				|  |  | +            const item1 = cloneDeep(obj);
 | 
	
		
			
				|  |  | +            const m3Temp = Math.random() * Math.random() * 10;
 | 
	
		
			
				|  |  | +            const gas = m3Temp * 0.0002;
 | 
	
		
			
				|  |  | +            item1.m3 = (obj.m3 + m3Temp).toFixed(2);
 | 
	
		
			
				|  |  | +            item1.gas = (obj.gas + gas).toFixed(4);
 | 
	
		
			
				|  |  | +            item1.Hz = (obj.Hz + (Math.random() * 2 - 1) * Math.random()).toFixed(2);
 | 
	
		
			
				|  |  | +            tempList.push(item1);
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +          // 计算  uQ1 -> uQ  gas -> gasWarningMax.value Hz -> resultObj.value.Hz
 | 
	
		
			
				|  |  | +          if (isStartCompute.value == 1) {
 | 
	
		
			
				|  |  | +            if (resultObj.value.Hz - obj.Hz > 0) {
 | 
	
		
			
				|  |  | +              item.Hz = (uHz.value + (2 * n * (resultObj.value.Hz - uHz.value)) / 20).toFixed(2);
 | 
	
		
			
				|  |  | +              if (resultObj.value.Hz - obj.Hz < 0) {
 | 
	
		
			
				|  |  | +                item.Hz = (resultObj.value.Hz + Math.random() * 0.5).toFixed(2);
 | 
	
		
			
				|  |  | +              }
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +              // item.Hz = (resultObj.value.Hz + (Math.random() * 2 - 1) * Math.random() * 2).toFixed(2);
 | 
	
		
			
				|  |  | +              item.Hz = (resultObj.value.Hz + Math.random() * 0.5).toFixed(2);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            item.m3 = (obj.m3 + (0.017 * n * item.Hz * (item.Hz - uHz.value) * (uQ.value - uQ1.value)) / 600).toFixed(2);
 | 
	
		
			
				|  |  | +            if (Number(item.m3) > uQ.value) {
 | 
	
		
			
				|  |  | +              item.m3 = (uQ.value + Math.random() * 10).toFixed(2);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            item.gas = (
 | 
	
		
			
				|  |  | +              gasWarningVal.value -
 | 
	
		
			
				|  |  | +              (0.015 * item.Hz * n * (item.Hz - uHz.value) * (gasWarningVal.value - gasWarningMax.value)) / 200
 | 
	
		
			
				|  |  | +            ).toFixed(4);
 | 
	
		
			
				|  |  | +          } else {
 | 
	
		
			
				|  |  | +            // 复位
 | 
	
		
			
				|  |  | +            if (obj.Hz - uHz.value > 0) {
 | 
	
		
			
				|  |  | +              item.Hz = (obj.Hz - (2 * n * (resultObj.value.Hz - uHz.value)) / 30).toFixed(2);
 | 
	
		
			
				|  |  | +              if (item.Hz - uHz.value < 0) {
 | 
	
		
			
				|  |  | +                item.Hz = uHz.value - 0.3;
 | 
	
		
			
				|  |  | +              }
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +              item.Hz = (uHz.value + (Math.random() * 2 - 1) * Math.random() * 2).toFixed(2);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            item.m3 = (obj.m3 - (0.02 * n * n * item.Hz * (resultObj.value.Hz - uHz.value) * (uQ.value - uQ1.value)) / 400).toFixed(2);
 | 
	
		
			
				|  |  | +            if (item.m3 < uQ1.value) {
 | 
	
		
			
				|  |  | +              item.m3 = uQ1.value - Math.random() * 10;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            item.gas = (obj.gas + (0.015 * item.Hz * n * (uHz.value - item.Hz) * (gasWarningVal.value - gasWarningMax.value)) / 800).toFixed(4);
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (monitorList.length >= 10) {
 | 
	
		
			
				|  |  | +          monitorList.shift();
 | 
	
		
			
				|  |  | +          const monitor = cloneDeep(item);
 | 
	
		
			
				|  |  | +          const data = tempList.shift();
 | 
	
		
			
				|  |  | +          if (data) {
 | 
	
		
			
				|  |  | +            item['m3'] = data['m3'];
 | 
	
		
			
				|  |  | +            item['gas'] = data['gas'];
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +          tempList.push(monitor);
 | 
	
		
			
				|  |  | +          monitorList.push(item);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          monitorList.push(item);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        monitorData.value = monitorList;
 | 
	
		
			
				|  |  | +        // console.log('瓦斯监测数据-------------->', monitorData.value);
 | 
	
		
			
				|  |  | +        if (timer) {
 | 
	
		
			
				|  |  | +          if (!isStartCompute.value) {
 | 
	
		
			
				|  |  | +            // n++;
 | 
	
		
			
				|  |  | +            openTimer(cloneDeep(obj));
 | 
	
		
			
				|  |  | +          } else {
 | 
	
		
			
				|  |  | +            n++;
 | 
	
		
			
				|  |  | +            openTimer(cloneDeep(item));
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }, 3000);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function edit(flag) {
 | 
	
		
			
				|  |  | +    if (flag == 'info') {
 | 
	
		
			
				|  |  | +      formType.value = '编辑风机信息';
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if (flag == 'line') {
 | 
	
		
			
				|  |  | +      formType.value = '编辑特性曲线';
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if (formShow.value == true) {
 | 
	
		
			
				|  |  | +      formShow.value = false;
 | 
	
		
			
				|  |  | +      nextTick(() => {
 | 
	
		
			
				|  |  | +        formShow.value = true;
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +    } else {
 | 
	
		
			
				|  |  | +      formShow.value = true;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function onSubmit() {
 | 
	
		
			
				|  |  | +    emit('close');
 | 
	
		
			
				|  |  | +    closeModal();
 | 
	
		
			
				|  |  | +    ChartRef.value = null;
 | 
	
		
			
				|  |  | +    uQ.value = undefined;
 | 
	
		
			
				|  |  | +    uH.value = undefined;
 | 
	
		
			
				|  |  | +    formType.value = '';
 | 
	
		
			
				|  |  | +    refresh.value = true;
 | 
	
		
			
				|  |  | +    xData.length = 0;
 | 
	
		
			
				|  |  | +    yDataList.length = 0;
 | 
	
		
			
				|  |  | +    lineNum = 0;
 | 
	
		
			
				|  |  | +    lineEquation.value = [];
 | 
	
		
			
				|  |  | +    resultObj.value = null;
 | 
	
		
			
				|  |  | +    monitorData.value = [];
 | 
	
		
			
				|  |  | +    clearTimeout(timer);
 | 
	
		
			
				|  |  | +    timer = undefined;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  async function onCancel() {
 | 
	
		
			
				|  |  | +    return new Promise((resolve) => {
 | 
	
		
			
				|  |  | +      if (isStartCompute.value == 0) {
 | 
	
		
			
				|  |  | +        onSubmit();
 | 
	
		
			
				|  |  | +        resolve(true);
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        message.warning('为保障矿井安全生产,请确保已复位!!!');
 | 
	
		
			
				|  |  | +        resolve(false);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function initEcharts() {
 | 
	
		
			
				|  |  | +    if (ChartRef.value) {
 | 
	
		
			
				|  |  | +      reSetLine();
 | 
	
		
			
				|  |  | +      myChart.value = echarts.init(ChartRef.value);
 | 
	
		
			
				|  |  | +      option && myChart.value.setOption(option);
 | 
	
		
			
				|  |  | +      refresh.value = false;
 | 
	
		
			
				|  |  | +      getMonitor();
 | 
	
		
			
				|  |  | +      nextTick(() => {
 | 
	
		
			
				|  |  | +        setTimeout(() => {
 | 
	
		
			
				|  |  | +          refresh.value = true;
 | 
	
		
			
				|  |  | +        }, 0);
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function makeLine() {
 | 
	
		
			
				|  |  | +    if (uQ.value && uH.value) {
 | 
	
		
			
				|  |  | +      loadding.value = true;
 | 
	
		
			
				|  |  | +      setTimeout(() => {
 | 
	
		
			
				|  |  | +        computeR();
 | 
	
		
			
				|  |  | +        reSetLine();
 | 
	
		
			
				|  |  | +        option && myChart.value.setOption(option);
 | 
	
		
			
				|  |  | +        loadding.value = false;
 | 
	
		
			
				|  |  | +      }, 1200);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  function handleSubmit() {
 | 
	
		
			
				|  |  | +    message.success('提交成功');
 | 
	
		
			
				|  |  | +    setTimeout(() => {
 | 
	
		
			
				|  |  | +      formShow.value = false;
 | 
	
		
			
				|  |  | +    }, 800);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  onMounted(() => {
 | 
	
		
			
				|  |  | +    timer = undefined;
 | 
	
		
			
				|  |  | +  });
 | 
	
		
			
				|  |  | +</script>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +<style scoped lang="less">
 | 
	
		
			
				|  |  | +  .modal-box {
 | 
	
		
			
				|  |  | +    display: flex;
 | 
	
		
			
				|  |  | +    flex-direction: row;
 | 
	
		
			
				|  |  | +    background-color: #ffffff05;
 | 
	
		
			
				|  |  | +    padding: 20px 8px;
 | 
	
		
			
				|  |  | +    border: 1px solid #00d8ff22;
 | 
	
		
			
				|  |  | +    position: relative;
 | 
	
		
			
				|  |  | +    // min-height: 600px;
 | 
	
		
			
				|  |  | +    .box-title {
 | 
	
		
			
				|  |  | +      width: calc(100% - 40px);
 | 
	
		
			
				|  |  | +      text-align: center;
 | 
	
		
			
				|  |  | +      background-color: #1dc1f522;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    .info-item {
 | 
	
		
			
				|  |  | +      display: flex;
 | 
	
		
			
				|  |  | +      justify-content: space-between;
 | 
	
		
			
				|  |  | +      align-items: center;
 | 
	
		
			
				|  |  | +      padding: 2px 0px;
 | 
	
		
			
				|  |  | +      margin: 4px 0;
 | 
	
		
			
				|  |  | +      background-image: linear-gradient(to right, #39deff15, #3977e500);
 | 
	
		
			
				|  |  | +      &:first-child {
 | 
	
		
			
				|  |  | +        margin-top: 0;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      .title {
 | 
	
		
			
				|  |  | +        width: 200px;
 | 
	
		
			
				|  |  | +        text-align: left;
 | 
	
		
			
				|  |  | +        padding-left: 20px;
 | 
	
		
			
				|  |  | +        color: #f1f1f1cc;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      .value {
 | 
	
		
			
				|  |  | +        width: 150px;
 | 
	
		
			
				|  |  | +        color: #00d8ff;
 | 
	
		
			
				|  |  | +        padding-right: 20px;
 | 
	
		
			
				|  |  | +        text-align: right;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    .right-box {
 | 
	
		
			
				|  |  | +      width: 320px;
 | 
	
		
			
				|  |  | +      .info-lines {
 | 
	
		
			
				|  |  | +        width: calc(100% - 2px);
 | 
	
		
			
				|  |  | +        height: 450px;
 | 
	
		
			
				|  |  | +        box-shadow: 0px 0px 50px #86baff08 inset;
 | 
	
		
			
				|  |  | +        overflow-y: auto;
 | 
	
		
			
				|  |  | +        margin-top: 5px;
 | 
	
		
			
				|  |  | +        .title {
 | 
	
		
			
				|  |  | +          width: 100%;
 | 
	
		
			
				|  |  | +          color: #f1f1f1cc;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    .center-box {
 | 
	
		
			
				|  |  | +      flex: 1;
 | 
	
		
			
				|  |  | +      margin: 0 10px;
 | 
	
		
			
				|  |  | +      display: flex;
 | 
	
		
			
				|  |  | +      .info-echarts {
 | 
	
		
			
				|  |  | +        // background-color: #ffffff11;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      .result-tip {
 | 
	
		
			
				|  |  | +        text-align: center;
 | 
	
		
			
				|  |  | +        background-color: #00000011;
 | 
	
		
			
				|  |  | +        line-height: 28px;
 | 
	
		
			
				|  |  | +        margin: 10px 50px 0 50px;
 | 
	
		
			
				|  |  | +        border: 1px solid #00d8ff22;
 | 
	
		
			
				|  |  | +        border-radius: 2px;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    .tip-box {
 | 
	
		
			
				|  |  | +      width: 1040px;
 | 
	
		
			
				|  |  | +      height: 44px;
 | 
	
		
			
				|  |  | +      position: absolute;
 | 
	
		
			
				|  |  | +      top: 447px;
 | 
	
		
			
				|  |  | +      display: flex;
 | 
	
		
			
				|  |  | +      padding: 0 20px;
 | 
	
		
			
				|  |  | +      .title {
 | 
	
		
			
				|  |  | +        width: 142px;
 | 
	
		
			
				|  |  | +        height: 43px;
 | 
	
		
			
				|  |  | +        display: flex;
 | 
	
		
			
				|  |  | +        align-items: center;
 | 
	
		
			
				|  |  | +        padding-left: 30px;
 | 
	
		
			
				|  |  | +        background-image: url('@/assets/images/fanlocal-tip/tip-title.png');
 | 
	
		
			
				|  |  | +        position: relative;
 | 
	
		
			
				|  |  | +        &::before {
 | 
	
		
			
				|  |  | +          content: '';
 | 
	
		
			
				|  |  | +          display: inline-block;
 | 
	
		
			
				|  |  | +          position: absolute;
 | 
	
		
			
				|  |  | +          width: 31px;
 | 
	
		
			
				|  |  | +          height: 31px;
 | 
	
		
			
				|  |  | +          top: 5px;
 | 
	
		
			
				|  |  | +          left: -8px;
 | 
	
		
			
				|  |  | +          background-image: url('@/assets/images/fanlocal-tip/tip-icon.png');
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      .tip-container {
 | 
	
		
			
				|  |  | +        width: 898px;
 | 
	
		
			
				|  |  | +        height: 44px;
 | 
	
		
			
				|  |  | +        line-height: 44px;
 | 
	
		
			
				|  |  | +        display: flex;
 | 
	
		
			
				|  |  | +        background-image: url('@/assets/images/fanlocal-tip/tip-bg.png');
 | 
	
		
			
				|  |  | +        background-size: cover;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  .setting-box {
 | 
	
		
			
				|  |  | +    width: 1170px;
 | 
	
		
			
				|  |  | +    height: 70px;
 | 
	
		
			
				|  |  | +    margin: 10px 0;
 | 
	
		
			
				|  |  | +    background-color: #ffffff05;
 | 
	
		
			
				|  |  | +    border: 1px solid #00d8ff22;
 | 
	
		
			
				|  |  | +    display: flex;
 | 
	
		
			
				|  |  | +    align-items: center;
 | 
	
		
			
				|  |  | +    justify-content: space-between;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    .right-inputs {
 | 
	
		
			
				|  |  | +      width: 100%;
 | 
	
		
			
				|  |  | +      display: flex;
 | 
	
		
			
				|  |  | +      height: 40px;
 | 
	
		
			
				|  |  | +      margin: 0 10px;
 | 
	
		
			
				|  |  | +      justify-content: space-between;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    .left-buttons {
 | 
	
		
			
				|  |  | +      display: flex;
 | 
	
		
			
				|  |  | +      height: 40px;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      .btn {
 | 
	
		
			
				|  |  | +        margin: 0 10px;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    .border-clip {
 | 
	
		
			
				|  |  | +      width: 1px;
 | 
	
		
			
				|  |  | +      height: 25px;
 | 
	
		
			
				|  |  | +      border-right: 1px solid #8b8b8b77;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    .input-title {
 | 
	
		
			
				|  |  | +      max-width: 150px;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    .input-box {
 | 
	
		
			
				|  |  | +      width: 220px !important;
 | 
	
		
			
				|  |  | +      background: transparent !important;
 | 
	
		
			
				|  |  | +      border-color: #00d8ff44 !important;
 | 
	
		
			
				|  |  | +      margin-right: 20px;
 | 
	
		
			
				|  |  | +      color: #fff !important;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    .btn {
 | 
	
		
			
				|  |  | +      padding: 8px 20px;
 | 
	
		
			
				|  |  | +      position: relative;
 | 
	
		
			
				|  |  | +      border-radius: 2px;
 | 
	
		
			
				|  |  | +      color: #fff;
 | 
	
		
			
				|  |  | +      width: fit-content;
 | 
	
		
			
				|  |  | +      cursor: pointer;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      &::before {
 | 
	
		
			
				|  |  | +        position: absolute;
 | 
	
		
			
				|  |  | +        display: block;
 | 
	
		
			
				|  |  | +        content: '';
 | 
	
		
			
				|  |  | +        width: calc(100% - 4px);
 | 
	
		
			
				|  |  | +        height: calc(100% - 4px);
 | 
	
		
			
				|  |  | +        top: 2px;
 | 
	
		
			
				|  |  | +        left: 2px;
 | 
	
		
			
				|  |  | +        border-radius: 2px;
 | 
	
		
			
				|  |  | +        z-index: -1;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    .btn1 {
 | 
	
		
			
				|  |  | +      border: 1px solid #5cfaff;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      &::before {
 | 
	
		
			
				|  |  | +        background-image: linear-gradient(#2effee92, #0cb1d592);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      &:hover {
 | 
	
		
			
				|  |  | +        border: 1px solid #5cfaffaa;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        &::before {
 | 
	
		
			
				|  |  | +          background-image: linear-gradient(#2effee72, #0cb1d572);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  .is-open {
 | 
	
		
			
				|  |  | +    animation: open 0.5s;
 | 
	
		
			
				|  |  | +    animation-iteration-count: 1;
 | 
	
		
			
				|  |  | +    animation-fill-mode: forwards;
 | 
	
		
			
				|  |  | +    animation-timing-function: ease-in;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  .is-close {
 | 
	
		
			
				|  |  | +    height: 0px;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  @keyframes open {
 | 
	
		
			
				|  |  | +    0% {
 | 
	
		
			
				|  |  | +      height: 0px;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    100% {
 | 
	
		
			
				|  |  | +      height: fit-content;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  @keyframes close {
 | 
	
		
			
				|  |  | +    0% {
 | 
	
		
			
				|  |  | +      height: fit-content;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    100% {
 | 
	
		
			
				|  |  | +      height: 0px;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  :deep(.zxm-divider-inner-text) {
 | 
	
		
			
				|  |  | +    color: #cacaca88 !important;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  :deep(.zxm-form-item) {
 | 
	
		
			
				|  |  | +    margin-bottom: 10px;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +</style>
 |