zmc
2023-09-05 c2f95b0b9090a2394b5b068582b932a5e57b86aa
src/views/exception/FlightInspection.vue
@@ -1,22 +1,27 @@
<script>
import InputSearch from '../../sfc/InputSearch.vue';
import ExceptionType from '../../sfc/ExceptionType.vue';
import TimeSelectWithShortCuts from '../../sfc/TimeSelectWithShortCuts.vue';
import DustExceptionText from '../../sfc/DustExceptionText.vue';
import InputSearch from '@/sfc/InputSearch.vue';
import ExceptionType from '@/sfc/ExceptionType.vue';
import TimeSelectWithShortCuts from '@/sfc/TimeSelectWithShortCuts.vue';
import DustExceptionText from './components/DustExceptionText.vue';
import { useFetch } from '../../utils/fetch.js';
import { useCommonFunction } from '../../utils/common.js';
import AreaAndmonitorType from '../../sfc/AreaAndmonitorType.vue'
import AreaAndmonitorType from '@/sfc/AreaAndmonitorType.vue'
import ButtonClick from '@/sfc/ButtonClick.vue'
import index from '@/utils/exception_common_function/index.js'
//  异常图形异步组件
const DustLineChart = defineAsyncComponent(() =>
  import('../../sfc/DustLineChart.vue')
  import('./components/DustLineChart.vue')
);
import exceptionApi from '@/api/exceptionApi.js';
import dayjs from 'dayjs';
export default {
  components: {
    ExceptionType,
    // InputSearch,
    TimeSelectWithShortCuts,
    DustExceptionText,
    DustLineChart,
    ButtonClick,
    AreaAndmonitorType
  },
  data() {
@@ -37,15 +42,17 @@
      displayData: [],
      // 表格高度
      tableHeight: 400,
      // 表格数据
      // 表格显示
      isTableShow:false,
      // 当前页
      currentPage: 1,
      // 每页条数
      pageSize: 20,
      // 表格的总记录数
      total: 0,
  
      // 表格查询无数据时
      isNoData: false,
      // isNoData: false,
      // 对话框显示
      dialogTableVisible: false,
      // 保存异常对应的店铺名称和设备编号
@@ -81,8 +88,6 @@
      // 站点总数量
      siteTotal: 0,
      // 异常的站点总数量
      // exceptionSiteNum:0,
      // 选中表格当前行的数据
      tableCurrentRowData: null,
@@ -100,8 +105,6 @@
        afterButton: false,
        // 折线图
        lineChart: false,
        // 异常站点名子文本
        text:false
        
      },
@@ -126,8 +129,9 @@
        banTouch:0,
        // 0代表分页,1代表不分页
        originClick:0
      }
      },
      // 条件查询对话框
      conditionDialogVisible:false
    };
  },
  setup() {
@@ -168,7 +172,6 @@
    },
    // 当选择的时间发生变化时,异常分析部分的异常店铺数量同步变化
        beginTime() {
          this.getShopNames();
      },
@@ -180,31 +183,21 @@
    }
  },
  mounted() {
    // 测试组合式函数
    // let param = {
    //   siteName: '金山区金山新城JSC1-0401单元1-11-01地块项目09',
    //   beginTime: '2023-07-01 00:00:00',
    //   endTime: '2023-07-10 00:00:00'
    // };
    // this.backData = this.request('/dust/history1', param);
    // console.log('历史数据为:', this.backData.value);
    this.backExceptionDataAWeekAgo();
    // this.calTableHeight();
    // 查询时间段的各异常的站点,查询该时间区间的各异常数量
    this.getShopNames();
    // this.exception.exception0 = this.getSiteNameByExceptionType('0',this.beginTime,this.endTime)
    // console.log('异常数据为:',this.exception.exception0);
    this.getSiteNume()
  },
  methods: {
   // 放回站点总数量
    getSiteNume(){
      exceptionApi.getSitesNum().then(res => {
      this.siteTotal = res.data.data.length
    })
    },
    // getExceptionSiteNum(){
    //   this.$http.get('/dust/exceptionsitenum').then(result => {
    //     this.exceptionSiteNum = result.data.data.length
    //   })
    // },
    /**
     * description:点击异常站点名字时 返回的数据
     * @param: 
@@ -225,35 +218,12 @@
      this.selectedRowIndex = this.displayData.indexOf(this.tableCurrentRowData);
    },
    /**
     * description:返回时间数组,从开始时间的后15分钟到结束时间为止。
     * @param: 异常的开始,异常结束时间
     * @createTime:2023-08-17
     * @returns:比如12:00:00-13:00:00 所以返回的数组元素是 12:00:00 ,12:15:00,12:30:00,12:45:00,13:00:00
     */
    descTenTime(begin, end) {
      let time = [];
      if (begin == end) {
        time.push(begin);
        return time;
      }
      time.push(begin);
      let temp = dayjs(begin).add(15, 'minute').format('YYYY-MM-DD HH:mm:ss');
      while (temp != end) {
        time.push(temp);
        temp = dayjs(temp).add(15, 'minute').format('YYYY-MM-DD HH:mm:ss');
      }
      // 加上异常的结束时间
      time.push(temp);
      return time;
    },
    /**
     * description:断电或断网时设置的表格数据
     */
    setOfflineTbleData(){
      // 无数据时的时间数组 时间相差15分钟
      const abnormalTimeTenMinute = this.descTenTime(
      const abnormalTimeTenMinute = index.descFiftyTime(
        this.tableCurrentRowData.beginTime,
        this.tableCurrentRowData.endTime
      );
@@ -274,63 +244,9 @@
      this.exceptionTotal = abnormalTimeTenMinute.length;
    },
    /**
     * description:返回开始时间的前45分钟的时间点,结束时间后45分钟的时间点
     * @param: 异常的开始时间,异常的结束时间。
     * @returns:数组。time[0],time[1],time[2],time[3]分别代表异常区间前45分钟的时间点,前15分钟的时间点,后15分钟的时间点,后45分钟的时间点
     */
    before45AndAfter45(begin, end) {
      let time = [];
      // 前一段的开始时间
      const before45MinBegin = dayjs(begin)
        .subtract(45, 'minute')
        .format('YYYY-MM-DD HH:mm:ss');
      // 前一段的结束时间
      const before15MinBegin = dayjs(begin)
        .subtract(15, 'minute')
        .format('YYYY-MM-DD HH:mm:ss');
      // 后一段的开始时间
      const after15MinBegin = dayjs(end)
        .add(15, 'minute')
        .format('YYYY-MM-DD HH:mm:ss');
      // 往后40分钟
      const after45MinEnd = dayjs(end)
        .add(45, 'minute')
        .format('YYYY-MM-DD HH:mm:ss');
      time.push(before45MinBegin);
      time.push(before15MinBegin);
      time.push(after15MinBegin);
      time.push(after45MinEnd);
      return time;
    },
    /**
     * description:返回某站点在该时段历史数据的get请求参数
     * @param: 站点名称, 开始时间, 结束时间
     * @returns:对象
     */
    requestGetParms(name, begin, end) {
      return {
        siteName: name,
        beginTime: begin,
        endTime: end
      };
    },
    /**
     * description:相差多少个15分钟  计算中包括开始时间,结束时间。
     * @param: 异常开始时间,异常结束时间
     * @returns:整数
     */
    diffFiftyMinutesNum(beginNormal, endNormal) {
      // 将开始时间和结束时间转换为dayjs对象
      const start = dayjs(beginNormal).subtract(15, 'minute');
      const end = dayjs(endNormal);
      // 计算结束时间减去开始时间中间相差多少个十分钟
      const diffInMinutes = end.diff(start, 'minute');
      const diffInTenMinutes = Math.floor(diffInMinutes / 15);
      return diffInTenMinutes;
    },
    // 段电或断网区间无数据,需要补充。其他的都有数据,直接一次请求全部时段就好
    // 根据异常区间构造前后端首尾 前区间 中间区间 后区间
@@ -361,7 +277,7 @@
        let timeAndValue = {};
        // 从添加了首位区间的开始和结束时间进行遍历 保证时间以10分钟为间隔
        timeAndValue = this.keepContinuousByEachFiftyMinutes(
        timeAndValue = index.keepContinuousByEachFiftyMinutes(
            allTime[0],
            allTime[3],
            this.dialog.allExceptionTimeData
@@ -383,59 +299,7 @@
            });
       
    },
    /**
     * description:判断data中是否有该日期时间,存在返回该时间对应的浓度值,否则返回-1
     * @param: 加上前后区间的异常数据,时间字符串
     * @returns:
     */
    findTimeInExceptionData(data, time) {
      for (let i = 0; i < data.length; i++) {
        if (data[i] == null) {
          continue;
        }
        if (data[i]['lst'] == time) {
          return data[i]['dustValue'];
        }
      }
      return -1;
    },
    /**
     * description:根据开始和结束时间,返回以15分钟为间隔的时间和对应的值
     * @param: 前区间的开始时间, 后区间的结束时间, 加上前后区间的总时间段的异常数据的对象数组
     * @returns:对象。包含了折线图的x轴,y轴的配置数据
     */
    keepContinuousByEachFiftyMinutes(
      intervalStarTime,
      intervalEndTime,
      headAndTailExceptionData
    ) {
      let xAxis = [];
      let yAxis = [];
      let obj = {};
      let current = intervalStarTime;
      let tail = dayjs(intervalEndTime)
        .add(15, 'minute')
        .format('YYYY-MM-DD HH:mm:ss');
      while (current != tail) {
        let value = this.findTimeInExceptionData(
          headAndTailExceptionData,
          current
        );
        if (value != -1) {
          xAxis.push(current);
          yAxis.push(value);
        } else {
          xAxis.push(current);
          yAxis.push(null);
        }
        current = dayjs(current)
          .add(15, 'minute')
          .format('YYYY-MM-DD HH:mm:ss');
      }
      obj['xAxis'] = xAxis;
      obj['yAxis'] = yAxis;
      return obj;
    },
    /**
     * description:绘制折线图
@@ -890,13 +754,13 @@
      // beforeAndAfterTime[1]:前15分钟的时间点
      // beforeAndAfterTime[2]:后15分钟的时间点
      // beforeAndAfterTime[3]:后45分钟的时间点
      let beforeAndAfterTime = this.before45AndAfter45(
      let beforeAndAfterTime = index.before45AndAfter45(
        exceptionBeginTime,
        exceptionEndTime
      );
      // 构造异常时间前后区间数据请求参数(除了断网中都用到)
      let paramsAllTime = this.requestGetParms(
      let paramsAllTime = index.requestGetParms(
        this.tableCurrentRowData.name,
        beforeAndAfterTime[0],
        beforeAndAfterTime[3]
@@ -923,7 +787,7 @@
        // 得到上一行的数据
        this.tableCurrentRowData = this.displayData[this.selectedRowIndex]
        let params = this.requestGetParms(this.tableCurrentRowData.name,this.tableCurrentRowData.beginTime,this.tableCurrentRowData.endTime)
        let params = index.requestGetParms(this.tableCurrentRowData.name,this.tableCurrentRowData.beginTime,this.tableCurrentRowData.endTime)
        this.loading.preButton = true
        this.$http
          .get('/dust/history', { params: params })
@@ -959,7 +823,7 @@
         // 得到上一行的数据
         this.tableCurrentRowData = this.displayData[this.selectedRowIndex]
        let params = this.requestGetParms(this.tableCurrentRowData.name,this.tableCurrentRowData.beginTime,this.tableCurrentRowData.endTime)
        let params = index.requestGetParms(this.tableCurrentRowData.name,this.tableCurrentRowData.beginTime,this.tableCurrentRowData.endTime)
        this.loading.afterButton = true
        this.$http
          .get('/dust/history', { params: params })
@@ -1242,15 +1106,18 @@
          this.displayData = response.data.data.rows;
          this.loading.queryButton = false
          this.loading.tableLoading = false;
          if (response.data.data.total == 0) {
            ElMessage('该时段无数据');
            this.isNoData = true;
            this.isTableShow = false
            return;
          }
          this.isTableShow = true
          this.total = response.data.data.total;
          // 移除空数据状态
          this.isNoData = false;
        });
      this.conditionDialogVisible = false
    },
    /**
@@ -1278,9 +1145,10 @@
          if (response.data.data.total == 0) {
            ElMessage('该时段无数据');
            this.isNoData = true;
            this.isTableShow = false
            return;
          }
          this.isTableShow = true
          this.total = response.data.data.total;
          this.loading.tableLoading = false;
        });
@@ -1349,7 +1217,16 @@
</script>
<template>
 <el-button type="primary" @click="conditionDialogVisible = true">
    搜索条件
  </el-button>
  <el-dialog
    v-model="conditionDialogVisible"
    title="Tips"
    width="30%"
    class="condition-dialog"
  >
  <el-row ref="h1">
    <el-col>
      <el-form :inline="true">
@@ -1358,20 +1235,55 @@
          <AreaAndmonitorType ></AreaAndmonitorType>
          </el-form-item>
          <!-- <el-form-item>
            <InputSearch
              isNeedDefaultSite="0"
              @submit-value="(n) => (form.name = n)"
              @submit-site-Nums="(n) => (siteTotal = n)"
            >
            </InputSearch>
          </el-form-item> -->
          <el-form-item>
            <TimeSelectWithShortCuts @submit-time="giveTime"></TimeSelectWithShortCuts>
            <TimeSelectWithShortCuts timeType="day" @submit-time="giveTime" ></TimeSelectWithShortCuts>
          </el-form-item>
          <el-form-item>
            <ExceptionType
              @submit-value="(n) => form.exceptionName = n"
            ></ExceptionType>
          </el-form-item>
        </div>
        <div class="head-container-search">
          <el-form-item>
            <el-button type="warning" :loading="loading.queryButton" @click="handleSubmit">查询</el-button>
            <!-- <el-button type="warning" :loading="loading.queryButton" @click="handleSubmit">查询</el-button> -->
            <ButtonClick content="分析" type="warning" :loading="loading.queryButton" @do-search="handleSubmit"></ButtonClick>
          </el-form-item>
        </div>
      </el-form>
    </el-col>
  </el-row>
<!--
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisible = false">Cancel</el-button>
        <el-button type="primary" @click="dialogVisible = false">
          Confirm
        </el-button>
      </span>
    </template> -->
  </el-dialog>
  <el-row class="head-describtion-text" ref="h2">
    <el-row>
@@ -1431,7 +1343,7 @@
              </div>
              <hr />
              <!-- 异常的店铺名字 -->
              <div class="card-exception-buttom"   v-loading="loading.text" >
              <div class="card-exception-buttom">
                <el-scrollbar max-height="90px">
                  <DustExceptionText
                  :site-name="item.name"
@@ -1439,7 +1351,7 @@
                  :begin-time="beginTime"
                  :end-time="endTime"
                    @submit-exception-data="getAbnormalDataByClick"
                    @subloading="(n)=>loading.text=n"
                    v-for="(item, index) in exception.exception4"
                    :key="item"
                    >{{ item.name }}
@@ -1498,7 +1410,7 @@
              </div>
              <hr />
              <!-- 异常的店铺名字 -->
              <div class="card-exception-buttom"   v-loading="loading.text">
              <div class="card-exception-buttom">
                <el-scrollbar max-height="90px">
                  <DustExceptionText
                  :site-name="item.name"
@@ -1565,7 +1477,7 @@
              </div>
              <hr />
              <!-- 异常的店铺名字 -->
              <div class="card-exception-buttom"   v-loading="loading.text">
              <div class="card-exception-buttom">
                <el-scrollbar max-height="90px">
                  <DustExceptionText
                  :site-name="item.name"
@@ -1632,7 +1544,7 @@
              </div>
              <hr />
              <!-- 异常的店铺名字 -->
              <div class="card-exception-buttom"   v-loading="loading.text">
              <div class="card-exception-buttom">
                <el-scrollbar max-height="90px">
                  <DustExceptionText
                  :site-name="item.name"
@@ -1703,7 +1615,7 @@
              </div>
              <hr />
              <!-- 异常的店铺名字 -->
              <div class="card-exception-buttom"   v-loading="loading.text">
              <div class="card-exception-buttom">
                <el-scrollbar max-height="90px">
                  <DustExceptionText
                  :site-name="item.name"
@@ -1765,7 +1677,7 @@
              </div>
              <hr />
              <!-- 异常的店铺名字 -->
              <div class="card-exception-buttom"   v-loading="loading.text">
              <div class="card-exception-buttom">
                <el-scrollbar max-height="90px">
                  <DustExceptionText
                  :site-name="item.name"
@@ -1827,7 +1739,7 @@
              </div>
              <hr />
              <!-- 异常的店铺名字 -->
              <div class="card-exception-buttom"   v-loading="loading.text">
              <div class="card-exception-buttom">
                <el-scrollbar max-height="90px">
                  <DustExceptionText
                  :site-name="item.name"
@@ -1958,7 +1870,7 @@
              </div>
              <hr />
              <!-- 异常的店铺名字 -->
              <div class="card-exception-buttom"   v-loading="loading.text">
              <div class="card-exception-buttom">
                <el-scrollbar max-height="90px">
                  <DustExceptionText
                  :site-name="item.name"
@@ -1989,12 +1901,256 @@
    </el-col>
  </el-row>
  <el-row v-show="isTableShow">
    <el-col >
      <el-table
        ref="table"
        :data="displayData"
        :height="tableHeight"
        :highlight-current-row="true"
        size="default"
        v-loading="loading.tableLoading"
        border
      >
        <el-table-column
          type="index"
          label="序号"
          width="60px"
          align="center"
          fixed
          :index="indexMethod1"
        />
        <el-table-column prop="name" label="站点名称" show-overflow-tooltip />
        <el-table-column
          prop="mnCode"
          label="设备编号"
          align="center"
          show-overflow-tooltip
        />
        <el-table-column
          prop="exception"
          label="异常类型"
          align="center"
          show-overflow-tooltip
        />
        <el-table-column
          prop="region"
          label="区域"
          align="center"
          show-overflow-tooltip
        />
        <el-table-column
          prop="beginTime"
          label="开始时间"
          align="center"
          show-overflow-tooltip
        />
        <el-table-column
          prop="endTime"
          label="结束时间"
          align="center"
          show-overflow-tooltip
        />
        <el-table-column
          prop="typename"
          label="场景"
          align="center"
          show-overflow-tooltip
        />
        <el-table-column
          prop="address"
          label="地址"
          align="center"
          show-overflow-tooltip
        />
        <el-table-column
          prop="dutyCompany"
          label="运维商"
          align="center"
          show-overflow-tooltip
        />
        <el-table-column label="操作" align="center">
          <template #default="{ row }">
            <el-button
              type="primary"
              class="table-button"
              @click="showDialog(row)"
              >查看详情</el-button
            >
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        ref="h4"
        background
        layout="total, sizes, prev, pager, next, jumper"
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :total="total"
        :page-sizes="[10, 20, 50, 100]"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      >
      </el-pagination>
    </el-col>
  </el-row>
  <el-dialog v-model="dialogTableVisible" draggable align-center height="300px">
    <!-- 头 -->
    <template #header>
      <div class="diag-head">
        <div class="diag-head-text">
          <div>
          <span class="diag-head-text1">站点名称:</span
          >{{ tableCurrentRowData.name }}
          </div>
          <div>
          <span class="diag-head-text1">异常类型:</span>
          <span v-if="tableCurrentRowData.exceptionType == '0'"
            >断电或断网</span
          >
          <span v-else-if="tableCurrentRowData.exceptionType == '1'"
            >数据超低</span
          >
          <span v-else-if="tableCurrentRowData.exceptionType == '2'">超标</span>
          <span v-else-if="tableCurrentRowData.exceptionType == '3'"
            >数据长时间无波动</span
          >
          <span v-else-if="tableCurrentRowData.exceptionType == '4'"
            >量级突变异常</span
          > <span v-else-if="tableCurrentRowData.exceptionType == '5'"
            >临近超标异常</span
          > <span v-else-if="tableCurrentRowData.exceptionType == '6'"
            >单日超标次数临界异常</span
          > <span v-else-if="tableCurrentRowData.exceptionType == '7'"
            >滑动平均值异常</span
          >
        </div>
          <div>
            <span class="diag-head-text1">异常时间段:</span
            >{{ tableCurrentRowData.beginTime }} ~
            {{ tableCurrentRowData.endTime }}
          </div>
        </div>
        <div class="chart-jump-button">
          <el-button
            type="danger"
            :loading="loading.preButton"
            :disabled="dialog.isPreCantouch || flag.banTouch"
            @click="getPreviousRowData"
            >上条异常</el-button
          >
          <el-button
            type="danger"
            :loading="loading.afterButton"
            :disabled="dialog.isNextCantouch || flag.banTouch"
            @click="getNextRowData"
            >下条异常</el-button
          >
        </div>
      </div>
    </template>
    <!-- :option="dialog.option" -->
    <!-- 图形 -->
    <DustLineChart
      :option="dialog.option"
      :is-open-dialog="dialogTableVisible"
      v-loading="loading.lineChart"
    ></DustLineChart>
    <!-- 表格 -->
    <div>
      <el-table :data="dialog.historyData" size="default" height="200" border>
        <el-table-column
          type="index"
          label="序号"
          width="60px"
          align="center"
          fixed
          :index="indexMethod2"
        ></el-table-column>
        <el-table-column
          fixed
          prop="name"
          label="站点名称"
          show-overflow-tooltip
        />
        <el-table-column
          prop="mnCode"
          label="设备编号"
          align="center"
          show-overflow-tooltip
        />
        <el-table-column
          prop="dutyCompany"
          label="运维商"
          align="center"
          show-overflow-tooltip
        />
        <el-table-column
          prop="lst"
          label="采集时间"
          align="center"
          show-overflow-tooltip
        />
        <el-table-column
          prop="dustValue"
          label="颗粒物浓度(mg/m³)"
          align="center"
          show-overflow-tooltip
        />
      </el-table>
    </div>
    <template #footer>
      <el-tag type="success" class="mx-1" effect="dark" round
        ><span
          class="table-line-lable"
          v-show="tableCurrentRowData.exceptionType == '0'"
          >缺失数据:
        </span>
        <span
          v-show="
            tableCurrentRowData.exceptionType == '1' ||
            tableCurrentRowData.exceptionType == '2' ||
            tableCurrentRowData.exceptionType == '3' ||
            tableCurrentRowData.exceptionType == '4'
          "
          >异常数据:</span
        >
        <span class="table-line-num">{{ dialog.exceptionTotal }}条</span>
        <span
          v-show="
            tableCurrentRowData.exceptionType === '0'
          "
        >
          (逻辑计算)</span
        >
      </el-tag>
    </template>
  </el-dialog>
</template>
<style lang="scss" scoped>
.el-row {
  margin-left: 10px;
}
/* 下拉菜单开始 */
.example-showcase .el-dropdown-link {
  cursor: pointer;
  color: var(--el-color-primary);
  display: flex;
  align-items: center;
}
/* 下拉菜单结束 */
/* 条件查询模块的样式 */
.head-container-search {
@@ -2084,9 +2240,7 @@
/* 查看详情对话框模块的样式 */
:deep(.el-dialog) {
  // 对话框高度
}
.diag-head {
  // 对话框头部区域
  min-height: 200px;
@@ -2111,20 +2265,10 @@
  border: 2px solid #7bc0fc;
}
.chart-jump-button {
  // ‘上一条’,‘下一条’ 按钮
  // border: 1px solid #fdc2db;
  min-height: 30px;
  width: 200px;
  float: right;
  display: flex;
  justify-content: right;
}
.line-chart {
  // 异常折线图
  width: 920px;
  height: 300px;
  margin-bottom: 20px;
  min-width: 600px;
}
.mx-1 {
  position: absolute;
  left: 10px;