zmc
2023-09-05 c2f95b0b9090a2394b5b068582b932a5e57b86aa
src/views/exception/FlightInspection.vue
@@ -1,25 +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,
    // InputSearch,
    TimeSelectWithShortCuts,
    DustExceptionText,
    DustLineChart,
    ButtonClick,
    AreaAndmonitorType
  },
  data() {
@@ -40,15 +42,17 @@
      displayData: [],
      // 表格高度
      tableHeight: 400,
      // 表格数据
      // 表格显示
      isTableShow:false,
      // 当前页
      currentPage: 1,
      // 每页条数
      pageSize: 20,
      // 表格的总记录数
      total: 0,
  
      // 表格查询无数据时
      isNoData: false,
      // isNoData: false,
      // 对话框显示
      dialogTableVisible: false,
      // 保存异常对应的店铺名称和设备编号
@@ -84,8 +88,6 @@
      // 站点总数量
      siteTotal: 0,
      // 异常的站点总数量
      // exceptionSiteNum:0,
      // 选中表格当前行的数据
      tableCurrentRowData: null,
@@ -127,8 +129,9 @@
        banTouch:0,
        // 0代表分页,1代表不分页
        originClick:0
      }
      },
      // 条件查询对话框
      conditionDialogVisible:false
    };
  },
  setup() {
@@ -169,7 +172,6 @@
    },
    // 当选择的时间发生变化时,异常分析部分的异常店铺数量同步变化
        beginTime() {
          this.getShopNames();
      },
@@ -181,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: 
@@ -226,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
      );
@@ -275,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;
    },
    // 段电或断网区间无数据,需要补充。其他的都有数据,直接一次请求全部时段就好
    // 根据异常区间构造前后端首尾 前区间 中间区间 后区间
@@ -362,7 +277,7 @@
        let timeAndValue = {};
        // 从添加了首位区间的开始和结束时间进行遍历 保证时间以10分钟为间隔
        timeAndValue = this.keepContinuousByEachFiftyMinutes(
        timeAndValue = index.keepContinuousByEachFiftyMinutes(
            allTime[0],
            allTime[3],
            this.dialog.allExceptionTimeData
@@ -384,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:绘制折线图
@@ -891,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]
@@ -924,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 })
@@ -960,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 })
@@ -1243,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
    },
    /**
@@ -1279,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;
        });
@@ -1350,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,34 +1234,56 @@
          <el-form-item >
          <AreaAndmonitorType ></AreaAndmonitorType>
          </el-form-item>
          <el-form-item>
          <!-- <el-form-item>
            <InputSearch
              :isNeedDefaultSite="0"
              isNeedDefaultSite="0"
              @submit-value="(n) => (form.name = n)"
              @submit-site-Nums="(n) => (siteTotal = n)"
            >
            </InputSearch>
          </el-form-item>
          </el-form-item> -->
          <el-form-item>
            <TimeSelectWithShortCuts timeType="day" @submit-time="giveTime" ></TimeSelectWithShortCuts>
          </el-form-item>
          <el-form-item>
            <ExceptionType
              @submit-value="(n) => form.exceptionName = n"
            ></ExceptionType>
          </el-form-item>
          <el-form-item>
            <TimeSelectWithShortCuts @submit-time="giveTime"></TimeSelectWithShortCuts>
          </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>
@@ -1608,7 +1506,7 @@
              <!-- 标头 -->
              <div class="card-text1">
                <image class="card-header-image"></image>
                <span class="card-header-text">滑动平均值异常</span>
                <span class="card-header-text">变化趋势异常</span>
              </div>
              <div class="card-content-text">
@@ -1745,7 +1643,7 @@
              <!-- 标头 -->
              <div class="card-text1">
                <image class="card-header-image"></image>
                <span class="card-header-text">断电或断网</span>
                <span class="card-header-text">数据缺失异常</span>
              </div>
              <div class="card-content-text">
@@ -2003,13 +1901,13 @@
    </el-col>
  </el-row>
  <el-row>
    <el-col v-show="!isNoData">
  <el-row v-show="isTableShow">
    <el-col >
      <el-table
        ref="table"
        :data="displayData"
        :height="tableHeight"
        highlight-current-row="true"
        :highlight-current-row="true"
        size="default"
        v-loading="loading.tableLoading"
        border
@@ -2098,7 +1996,6 @@
    </el-col>
  </el-row>
  <el-empty v-show="isNoData" :image-size="200" />
  <el-dialog v-model="dialogTableVisible" draggable align-center height="300px">
    <!-- 头 -->
@@ -2241,9 +2138,19 @@
</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 {
@@ -2333,10 +2240,7 @@
/* 查看详情对话框模块的样式 */
:deep(.el-dialog) {
  // 对话框高度
}
.diag-head {
  // 对话框头部区域
  min-height: 200px;
@@ -2361,11 +2265,6 @@
  border: 2px solid #7bc0fc;
}
.chart-jump-button {
  // ‘上一条’,‘下一条’ 按钮
  // border: 1px solid #fdc2db;
  // min-height: 30px;
  // width: 200px;
  // float: right;
  display: flex;
  justify-content: right;
}