Newer
Older
KaiFengPC / src / views / floodSys / floodOneMap / commonPopupJCGJ.vue
@鲁yixuan 鲁yixuan on 19 Aug 19 KB updata
<template>
  <!-- 监测告警弹窗 -->
  <div class="jcgjPopup" v-show="allData.popupShow">
    <div class="title">
      <div class="titleName">
        {{ allData.dataList.stName }}
        <el-button size="small" type="warning" @click="handleWarn" style="margin-left: 30px">报警处理</el-button>
      </div>
      <div class="closePopup">
        <el-icon :size="18" @click="closePopup"><Close /></el-icon>
      </div>
    </div>
    <div class="allContent">
      <div class="basicInfo">
        <div class="basicContent">
          <div class="contentInfo">
            <div class="contentName">站点编码:</div>
            <div class="contentValue">{{ allData.dataList.stCode }}</div>
          </div>
          <div class="contentInfo">
            <div class="contentName">安装地址:</div>
            <div class="contentValue" :title="allData.dataList.address">{{ allData.dataList.address }}</div>
          </div>
          <div class="contentInfo">
            <div class="contentName">经度:</div>
            <div class="contentValue">{{ allData.dataList.lonLat && allData.dataList.lonLat.split(',')[0] }}</div>
          </div>
          <div class="contentInfo">
            <div class="contentName">纬度:</div>
            <div class="contentValue">{{ allData.dataList.lonLat && allData.dataList.lonLat.split(',')[1] }}</div>
          </div>
          <div class="contentInfo">
            <div class="contentName">监测指标:</div>
            <div class="contentValue">{{ allData.dataList.dynamicTableMonitor }}</div>
          </div>
          <div class="contentInfo">
            <div class="contentName">站点类型:</div>
            <div class="contentValue"><dict-tag :options="siteTypes" :value="allData.dataList.siteType" /></div>
          </div>
        </div>
        <el-image
          v-if="allData.dataList['coverPhotosFileList']"
          :src="allData.dataList['coverPhotosFileList'][0]"
          :preview-src-list="srcList"
          style="padding-left: 50px"
        />
      </div>
      <div class="dividerLine"></div>
      <div class="trend">
        <el-date-picker
          v-model="allData.dataTime1"
          type="date"
          value-format="YYYY-MM-DD"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          size="small"
          style="width: 120px; margin-left: 10px"
          @change="changeDate"
        />
        -
        <el-date-picker
          v-model="allData.dataTime2"
          type="date"
          value-format="YYYY-MM-DD"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          size="small"
          style="width: 120px"
          @change="changeDate"
        />
        <el-select v-model="selectCode" style="margin: 0px 0px 0px 10px; width: 120px" size="small" @change="changeSuperType">
          <el-option v-for="(item, index) in dataOption" :key="index" :label="item.label" :value="item.value" />
        </el-select>
        <div id="chartPopupJCGJ" v-if="propertyMonitorXList.length > 0"></div>
        <!-- 暂无数据 -->
        <el-empty :image-size="80" v-if="propertyMonitorXList.length == 0" style="margin-top: 50px" />
      </div>
    </div>
    <!-- 故障报警详情弹窗 -->
    <el-dialog v-model="dialogShow" :title="allData.dataList.stName + '监测站点详情'" width="800px" append-to-body>
      <div class="publicDetail flex50">
        <div class="part">
          <p class="title">站点名称:</p>
          <p class="content">{{ allData.dataList.stName }}</p>
        </div>
        <div class="part">
          <p class="title">站点编号:</p>
          <p class="content">{{ allData.dataList.stCode }}</p>
        </div>
        <div class="part" style="width: 100%">
          <p class="title">辖区负责人:</p>
          <p class="content">{{ allData.dataList.chargeUser }}</p>
        </div>
        <el-radio-group v-model="warnType" @change="changeType">
          <el-radio label="1">设备报警</el-radio>
          <el-radio label="2">指标报警</el-radio>
        </el-radio-group>
        <el-table :data="tableData" max-height="300">
          <el-table-column prop="qdCode" label="故障类型" v-if="warnType == '1'">
            <template #default="scope">
              <span>
                {{
                  scope.row.faultType == 'low_battery'
                    ? '低电压'
                    : scope.row.faultType == 'low_signal'
                    ? '低信号'
                    : scope.row.faultType == 'exception'
                    ? '异常值'
                    : scope.row.faultType == 'offline'
                    ? '离线'
                    : '--'
                }}
              </span>
            </template>
          </el-table-column>
          <el-table-column prop="fromDatetime" label="开始时间" v-if="warnType == '1'" />
          <el-table-column prop="toDatetime" label="结束时间" v-if="warnType == '1'" />
          <el-table-column prop="durationTime" label="停留时长(h)" v-if="warnType == '1'" />

          <el-table-column prop="warnFactorName" label="因子名称" v-if="warnType == '2'" />
          <el-table-column prop="warnFactorValueName" label="监测值" v-if="warnType == '2'" />
          <el-table-column prop="warnCount" label="报警次数" v-if="warnType == '2'" />
          <el-table-column prop="updateTime" label="报警时间" v-if="warnType == '2'" />
          <el-table-column prop="continueMinute" label="停留时长(min)" v-if="warnType == '2'" />
        </el-table>
        <!-- 有数据时才显示 -->
        <div class="flex flex-justcontent-center" style="width: 100%; margin-top: 10px" v-if="tableData.length > 0">
          <el-button size="small" type="primary" @click="goIgnore">误报忽略</el-button>
          <el-button size="small" type="warning" @click="goOrder">去处理</el-button>
        </div>
      </div>
    </el-dialog>

    <!-- 去处理转工单 -->
    <el-dialog v-model="dialogOrder" title="设备故障报警转维修工单" width="500px" append-to-body>
      <el-form ref="formRef" :model="formData" :rules="rulesForm" label-width="120px" class="publicForm">
        <el-form-item label="维修人员" prop="rpUserNo">
          <el-select v-model="formData.rpUserNo" placeholder="请选择" clearable>
            <el-option v-for="item in userList" :key="item.userName" :label="item.nickName" :value="item.userName" />
          </el-select>
        </el-form-item>
        <el-form-item label="期望完成时间" prop="rpExpectTime">
          <el-date-picker type="datetime" v-model="formData.rpExpectTime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择日期">
          </el-date-picker>
        </el-form-item>
        <el-form-item label="事件紧急程度" prop="rpUrgency">
          <el-select v-model="formData.rpUrgency" placeholder="请选择" clearable>
            <el-option v-for="item in urgencyType" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="维修要求" prop="rpRequire">
          <el-input type="textarea" v-model="formData.rpRequire" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="维修类型" prop="rpType">
          <el-select v-model="formData.rpType" placeholder="请选择" clearable>
            <el-option v-for="item in repairType" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="info" @click="dialogOrder = false">取 消</el-button>
          <el-button type="primary" @click="goOrderSubmit">确 定</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup name="commonjcgjPopup">
import bus from '@/bus';
import chartOption from '@/components/Echarts/pieChart_1.js';
import * as echarts from 'echarts';
import { graphicReport } from '@/api/dataAnalysis/syntherticData';
import { listUser } from '@/api/system/user';
import {
  transferWarnRepairOrder,
  transferDeviceFaultRepairOrder,
  warnOrderIgnore,
  deviceFaultOrderIgnore,
  rtuSiteInfoDetail,
  rtuWarnConfiglist,
} from '@/api/floodSys/repair';
import { rtuWarnRecordRealtimeDetail, rtuFaultTimeSectionRealtimeDetail } from '@/api/floodSys/oneMap';
import { ref } from 'vue';

const { proxy } = getCurrentInstance();
const dialogShow = ref(false);
const dialogOrder = ref(false);
const siteTypes = proxy.fixDict['siteTypes']; //站点类型
const dataOption = ref([]);
const selectData = ref([]);
const selectCode = ref('');
const seleceName = ref('');
const unitName = ref('');
const siteWarnConfigList = ref([]);
const propertyMonitorXList = ref([]);
const allData = reactive({
  popupShow: false,
  currentIndex: 1,
  dataTime1: proxy.moment(new Date()).subtract(3, 'days').format('YYYY-MM-DD'),
  dataTime2: proxy.moment(new Date()).format('YYYY-MM-DD'),
  dataList: {},
  gaojingType: '',
  warnFormulaValue: '',
  formData: {
    eventRelationId: '',
    rpUserName: '',
    rpUserNo: '',
    rpUrgency: '',
    rpType: '',
    rpRequire: '',
    rpExpectTime: '',
  },
  rulesForm: {
    rpUserNo: [{ required: true, message: '请输入', trigger: 'blur' }],
    rpUrgency: [{ required: true, message: '请输入', trigger: 'blur' }],
  },
});
const { formData, rulesForm } = toRefs(allData);
const urgencyType = proxy.fixDict['urgencyType']; //事件紧急程度
const repairType = ref([
  { label: '小修', value: 'minor' },
  { label: '专项维修', value: 'special' },
]);
const userList = ref([]);
const tableData = ref([]);
const warnType = ref('1');

// 弹窗关闭
const closePopup = () => {
  allData.popupShow = false;
  allData.dataTime1 = proxy.moment(new Date()).subtract(3, 'days').format('YYYY-MM-DD');
  allData.dataTime2 = proxy.moment(new Date()).format('YYYY-MM-DD');
  newfiberMapbox.map.easeTo({
    center: [114.312, 34.802],
    zoom: 12.9,
    pitch: 55,
  });
  let clearSelectedFeature = [];
  newfiberMapbox.getLayers().forEach(feature => {
    if (feature.newfiberId == 'highlight_point') {
      clearSelectedFeature.push(feature);
    }
  });

  if (!!clearSelectedFeature.length) {
    clearSelectedFeature[0].setData({ type: 'FeatureCollection', features: [] });
  }
};

// 报警点击
async function handleWarn() {
  dialogShow.value = true;
  warnType.value = allData.gaojingType.toString();
  getWarnData();
}
// 设备、指标切换
function changeType(val) {
  warnType.value = val;
  getWarnData();
}
// 获取故障和指标报警数据
async function getWarnData() {
  if (warnType.value == '1') {
    // 设备
    let res = await rtuFaultTimeSectionRealtimeDetail({ stCode: allData.dataList.stCode });
    if (res && res.code == 200) {
      tableData.value = res.data || [];
    }
  } else {
    // 指标
    let res = await rtuWarnRecordRealtimeDetail({ stCode: allData.dataList.stCode });
    if (res && res.code == 200) {
      tableData.value = res.data || [];
    }
  }
  if (tableData.value.length > 0) {
    formData.value.eventRelationId = tableData.value[0].id;
  } else {
    formData.value.eventRelationId = '';
  }
}

// 误报忽略点击
async function goIgnore() {
  let res = null;
  if (warnType.value == '1') {
    // 设备故障
    res = await deviceFaultOrderIgnore({ stCode: allData.dataList.stCode });
  } else {
    // 设备告警指标
    res = await warnOrderIgnore({ stCode: allData.dataList.stCode });
  }
  if (res && res.code == 200) {
    proxy.$modal.msgSuccess('忽略成功');
    bus.emit('refreshGJ'); //主列表刷新数据
    getWarnData();
    dialogShow.value = false;
  }
}

// 工单处理点击
function goOrder() {
  proxy.resetForm('formRef'); //清空表单
  dialogOrder.value = true;
  formData.value.stCode = allData.dataList.stCode;
}

// 工单处理提交确定
function goOrderSubmit() {
  proxy.$refs['formRef'].validate(valid => {
    if (valid) {
      formData.value.rpUserName = userList.value.filter(item => item.userName == formData.value.rpUserNo)[0].nickName;
      if (warnType.value == '1') {
        // 设备故障
        transferDeviceFaultRepairOrder(formData.value).then(response => {
          proxy.$modal.msgSuccess('转维修工单成功');
          dialogOrder.value = false;
          bus.emit('refreshGJ'); //主列表刷新数据
          getWarnData();
          dialogShow.value = false;
        });
      } else {
        // 设备告警指标
        transferWarnRepairOrder(formData.value).then(response => {
          proxy.$modal.msgSuccess('转维修工单成功');
          dialogOrder.value = false;
          bus.emit('refreshGJ'); //主列表刷新数据
          getWarnData();
          dialogShow.value = false;
        });
      }
    }
  });
}

//时间格式化
const getYearMonthDay = time => {
  return proxy.moment(time).format('YYYY-MM-DD');
};
const changeDate = () => {
  getJCGJData();
};
function changeSuperType(val) {
  selectCode.value = val;
  let obj = dataOption.value.filter(item => item.value == val)[0];
  selectCode.value = obj.value;
  seleceName.value = obj.label;
  unitName.value = obj.propertyUnit;
  selectData.value = obj.ylist;
  allData.warnFormulaValue = '';
  if (Boolean(siteWarnConfigList.value.length) && seleceName.value) {
    let alist = siteWarnConfigList.value;
    alist.forEach(element => {
      if (element.warnFactorName.includes(seleceName.value)) {
        allData.warnFormulaValue = element.warnFormulaValue;
      }
    });
  }

  initEcharts1();
}
//获取监测数据
const getJCGJData = async () => {
  let params = {
    // startTime: '2024-01-01',
    // endTime: '2024-01-02',
    startTime: allData.dataTime1,
    endTime: allData.dataTime2,
    stCode: allData.dataList.stCode,
  };

  let res = await graphicReport(params);
  if (res && res.code == 200) {
    let datas = res.data;
    dataOption.value = [];
    datas.propertyMonitorList.map(item => {
      dataOption.value.push({
        value: item.stCode + item.monitorPropertyName,
        label: item.monitorPropertyName,
        propertyUnit: item.propertyUnit,
        ylist: item.ylist,
      });
    });
    propertyMonitorXList.value = datas.propertyMonitorXList;
    if (datas.propertyMonitorXList.length == 0) return;
    selectCode.value = dataOption.value[0].value;
    seleceName.value = dataOption.value[0].label;
    unitName.value = dataOption.value[0].propertyUnit;
    selectData.value = dataOption.value[0].ylist;
    if (Boolean(siteWarnConfigList.value.length) && seleceName.value) {
      let alist = siteWarnConfigList.value;
      alist.forEach(element => {
        if (element.warnFactorName.includes(seleceName.value)) {
          allData.warnFormulaValue = element.warnFormulaValue;
        }
      });
    }

    setTimeout(() => {
      initEcharts1();
    });
  }
};
//监测告警趋势图
let chartPopupSup = null;
const initEcharts1 = () => {
  if (!!chartPopupSup) chartPopupSup.dispose();
  chartPopupSup = echarts.init(document.getElementById('chartPopupJCGJ'));
  chartOption.floodOneMapPipeWarns.legend.data = [seleceName.value];
  chartOption.floodOneMapPipeWarns.yAxis[0].name = unitName.value;
  chartOption.floodOneMapPipeWarns.yAxis[1].name = '';
  chartOption.floodOneMapPipeWarns.xAxis[0].data = propertyMonitorXList.value;
  chartOption.floodOneMapPipeWarns.series[0].name = seleceName.value;
  chartOption.floodOneMapPipeWarns.series[0].data = selectData.value;
  chartOption.floodOneMapPipeWarns.series[1].data = [];
  if (allData.gaojingType == 2) {
    chartOption.floodOneMapPipeWarns.series[0].markLine = {
      symbol: 'none',
      label: {
        show: !!allData.warnFormulaValue,
        position: 'middle',
        formatter: seleceName.value + '警戒值:{c}',
        color: 'red',
        fontWeight: 'bold',
      },
      lineStyle: {
        color: 'red',
        width: 2,
        type: 'solid',
      },
      data: [
        {
          name: '警戒值',
          yAxis: allData.warnFormulaValue,
        },
      ],
    };
  } else {
    chartOption.floodOneMapPipeWarns.series[0].markLine = '';
  }

  // 设置鼠标滚轮放大缩小展示数据区间
  chartOption.floodOneMapPipeWarns.dataZoom = [
    { type: 'inside', startValue: propertyMonitorXList.value[propertyMonitorXList.value.length / 2] },
  ];
  if (propertyMonitorXList.value.length > 0) {
    chartOption.floodOneMapPipeWarns.graphic.invisible = true; //暂无数据
  } else {
    chartOption.floodOneMapPipeWarns.graphic.invisible = false; //暂无数据
  }
  chartPopupSup.clear();
  chartPopupSup.setOption(chartOption.floodOneMapPipeWarns);
};
//搜索维修人员列表
function getUserList() {
  listUser().then(res => {
    userList.value = res.data;
  });
}
// 获取站点详情数据
async function getDetailData(stCode) {
  let res = await rtuSiteInfoDetail(stCode);
  if (res && res.code == 200) {
    allData.dataList = res.data;
    getJCGJData();
  }
}

// 获取站点告警数据
async function getDetailwarnData(stCode) {
  console.log(stCode, 11111);
  let res = await rtuWarnConfiglist({ stCode: stCode });
  if (res && res.code == 200) {
    siteWarnConfigList.value = res.data;
  }
}
onMounted(() => {
  getUserList();
  bus.on('closeCommonPopup', closeCommonPopup => {
    allData.popupShow = closeCommonPopup;
  });
  bus.on('popupJCGJData', data => {
    allData.popupShow = true;

    allData.gaojingType = data.gaojingType;
    if (allData.gaojingType == 2) {
      getDetailwarnData(data.stCode);
    }
    getDetailData(data.stCode); //获取详情数据
  });
});
onBeforeUnmount(() => {
  bus.off('popupJCGJData');
  bus.off('closeCommonPopup');
});
</script>
<style lang="scss">
.jcgjPopup {
  width: 748px;
  height: 476px;
  background-image: url('@/assets/newImgs/layer1.png');
  background-size: 100% 100%;
  z-index: 115;
  position: absolute;
  top: 80px;
  left: 330px;
  .title {
    padding-top: 30px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    .titleName {
      display: flex;
      align-items: center;
      height: 22px;
      font-size: 16px;
      font-family: PingFang SC;
      font-weight: 400;
      color: #ccf1ff;
      line-height: 22px;
      padding-left: 80px;
      &:before {
        display: block;
        content: '';
        width: 3px;
        height: 16px;
        background: #00d1ff;
        margin-right: 10px;
      }
    }
    .closePopup {
      padding-right: 40px;
      height: 22px;
      cursor: pointer;
    }
  }

  .allContent {
    display: flex;
    .basicInfo {
      width: 270px;
      margin-top: 10px;
      .basicContent {
        .contentInfo {
          display: flex;
          align-items: center;
          padding-left: 80px;
          .contentName {
            margin: 3px;
            height: 20px;
            width: 70px;
            font-size: 14px;
            font-weight: 400;
            line-height: 20px;
            color: #00d1ff;
          }
          .contentValue {
            width: 100px;
            font-size: 14px;
            font-weight: 400;
            color: #00d1ff;
            word-wrap: break-word;
          }
        }
      }
    }
    .dividerLine {
      width: 3px;
      height: 350px;
      position: absolute;
      left: 250px;
      border: 1px;
      background: linear-gradient(90deg, rgba(0, 115, 165, 0) 0.79%, #0073a5 20.43%, #0073a5 82.43%, rgba(0, 115, 165, 0) 100%);
    }
    .trend {
      width: 450px;
      #chartPopupJCGJ {
        width: 90%;
        height: 300px;
        margin-top: 20px;
      }
    }
  }
}
</style>