yangyin
2023-07-14 6a4254ee140fa16d922db221ddf06e66c2164057
src/views/HomeView.vue
@@ -1,15 +1,679 @@
<template>
  <div class="home">
    {{ state.name }}
  <div class="main_contain">
    <div class="ec_header">
      <div class="ec_header_left">
        <div class="ec_header_left_view">{{ pointName }}</div>
        <div class="ec_header_left_view">
          <span class="ec_header_val">{{
            state.currentRecordParas.RecordValue
          }}</span>
        </div>
      </div>
      <div class="ec_header_right">
        <div class="ec_header_right_view">
          <div>状态:{{ state.currentRecordParas.RecordStatusName }}</div>
          <div>警报:{{ state.currentRecordParas.AlarmNumber }}</div>
        </div>
        <div class="ec_header_right_view">
          <div>{{ state.currentRecordParas.RecordTime }}</div>
          <div>{{ lastRefreshTime }}s后刷新</div>
        </div>
      </div>
    </div>
    <div class="container">
      <div id="chartMain" style="width: 100%; height: 418px"></div>
    </div>
    <!--先隐藏详情,目前接口返回值
       <div class="ykt-detail-wraper">
      <van-collapse v-model="state.activeNames">
        <van-collapse-item name="1">
          <template #title>
            <div>详情</div>
          </template>
          <van-cell :value="state.MonitorPointID">
            <template #title>
              <div class="custom-title">测点编号</div>
            </template>
          </van-cell>
          <van-cell value="瞬时压力">
            <template #title>
              <div class="custom-title">监控名称</div>
            </template>
          </van-cell>
          <van-cell value="MPa">
            <template #title>
              <div class="custom-title">单位</div>
            </template>
          </van-cell>
          <van-cell value="">
            <template #title>
              <div class="custom-title">上次报警</div>
            </template>
          </van-cell>
          <van-cell>
            <template #title>
              <div class="custom-title">是否显示报警点</div>
            </template>
            <template #value>
              <van-switch v-model="state.checked" size="24px" />
            </template>
          </van-cell>
          <van-cell value="阈值">
            <template #title>
              <div class="custom-title">警报类型</div>
            </template>
          </van-cell>
        </van-collapse-item>
      </van-collapse>
    </div> -->
    <div class="ykt-detail-wrapers">
      <div class="hykt_header" style="margin-bottom: 5px">
        <div class="hykt_span">时间</div>
        <div
          class="hykt_span"
          @click="changeMonitorStatus"
          :style="state.isMonitorChange ? 'color:red;' : ''"
        >
          状态
        </div>
        <div class="hykt_span">监控值</div>
      </div>
      <div
        class="hykt_li"
        v-for="(monitor, index) in state.c_monitorList"
        :key="index"
      >
        <div class="hykt_span">{{ monitor.RecordTime }}</div>
        <div class="hykt_span">
          {{
            monitor.RecordStatusText.length > 0 &&
            monitor.RecordStatusText[0] == "BJ"
              ? "中断"
              : "正常"
          }}
        </div>
        <div class="hykt_span">{{ monitor.RecordValue }}</div>
      </div>
    </div>
    <!-- 刷新 -->
    <div style="bottom: 140px" class="icon_view">
      <van-icon name="revoke" size="20px" @click="onTapRefresh()" />
    </div>
    <!-- 间隔 -->
    <div style="bottom: 200px" class="icon_view" @click="onTapInterval">
      <van-icon
        :name="state.isOnTapInterval ? 'exchange' : 'shrink'"
        size="20px"
      />
    </div>
  </div>
</template>
<script setup>
import {reactive, onMounted } from "vue"
import { reactive, onMounted, ref, shallowRef, onBeforeUnmount } from "vue";
import moment from "moment";
import * as echarts from "echarts"; //引入echarts
import axios from "axios";
import { useRouter } from "vue-router";
import { showLoadingToast, showFailToast, allowMultipleToast } from "vant";
const router = useRouter();
const pointName = ref("");
const myChart = shallowRef(null);
const lastRefreshTime = ref(120);
let times = ref(null);
const now = new Date();
const minDate = new Date(
  now.getFullYear(),
  now.getMonth(),
  now.getDate(),
  0,
  0,
  0
);
const maxDate = new Date(
  now.getFullYear(),
  now.getMonth(),
  now.getDate(),
  23,
  59,
  59
);
let state = reactive({
  name:'Hello World'
})
  currentRecordParas: {
    RecordValue: "",
    RecordStatusName: "",
    AlarmNumber: 0,
    RecordTime: "",
  },
  chartData: [],
  x_yData: [],
  activeNames: [""],
  checked: false, //是否显示报警点
  loading: false, //加载状态
  isMonitorChange: false, //监测界面 --- 是否启用状态筛选
  isOnTapInterval: false,
  monitorList: [],
  c_monitorList: [],
  PointID: "",
  CorpID: "",
  token: "",
});
onMounted(() => {
  state.PointID = router.currentRoute.value.query.PointID;
  state.token = router.currentRoute.value.query.Token;
  state.CorpID = router.currentRoute.value.query.CorpID;
  allowMultipleToast();
  if (state.token == "") {
    showFailToast("token无效,请重试");
    return;
  }
  if (state.PointID == "") {
    showFailToast("测点ID需要>0,请重试");
    return;
  }
  if (state.CorpID == undefined || state.CorpID == "") {
    showFailToast("CorpID需要>0,请重试");
    return;
  }
  state.currentRecordParas.RecordTime = moment().format("YYYY-MM-DD");
  initialRealTimeRecord();
  getRecordDetail();
});
const countdown = () => {
  if (lastRefreshTime.value === 0) {
    onTapRefresh();
    lastRefreshTime.value = 120;
    return;
  } else {
    lastRefreshTime.value--;
  }
};
onBeforeUnmount(() => {
  console.log("mounted!", 307);
  clearInterval(times.value);
  times.value = null;
});
})
//刷新
const onTapRefresh = () => {
  axios({
    url: "http://47.101.141.88:9019/Run/MonitorRealRecord/Mobile/GetLastRecordByMonitorPointID@V1.0",
    method: "GET",
    headers: {
      Authorization: `Bearer ${state.token}`,
    },
    params: {
      CorpID: state.CorpID,
      MonitorPointID: state.PointID,
    },
  })
    .then((res) => {
      if (res.data.Code != 0) {
        return;
      }
      if (res.data.Data == null || res.data.Data == "") {
        return;
      }
      var refreshData = res.data.Data;
      var last_record = state.chartData[state.chartData.length - 1]; //获取最后一条数据
      refreshData.forEach((item) => {
        let getStatus = DataStatusTextEmun(item.DataStatus);
        state.currentRecordParas.RecordStatusName = getStatus;
        state.currentRecordParas.RecordValue = item.DataValue;
        if (
          item.DataValue != last_record.DataValue ||
          item.DataTime != last_record.DataTime
        ) {
          state.chartData.push(item);
        }
      });
      setTimeout(() => {
        drawBar();
      }, 200);
    })
    .catch((error) => {
      console.log(error);
    });
};
//监控图标间隔
const onTapInterval = () => {
  if (!state.isOnTapInterval) {
    myChart.value.setOption({
      yAxis: {
        boundaryGap: ["0%", "0%"],
        scale: true,
      },
    });
    state.isOnTapInterval = true;
    return;
  }
  if (state.isOnTapInterval) {
    myChart.value.setOption({
      yAxis: {
        boundaryGap: ["15%", "15%"],
        scale: false,
      },
    });
    state.isOnTapInterval = false;
    return;
  }
};
//初始化获取数据
const initialRealTimeRecord = () => {
  let loading = showLoadingToast({
    message: "加载中...",
    forbidClick: true,
  });
  axios({
    url: "http://47.101.141.88:9019/Run/MonitorRealRecord/Mobile/GetByMonitorPointIDOfDay@V1.0",
    method: "GET",
    headers: {
      Authorization: `Bearer ${state.token}`,
    },
    params: {
      CorpID: state.CorpID,
      MonitorPointID: state.PointID,
      Day: state.currentRecordParas.RecordTime,
    },
  })
    .then((res) => {
      loading.close();
      if (res.data.Code != 0) {
        return;
      }
      if (res.data.Data == null || res.data.Data == "") {
        return;
      }
      var data = res.data.Data || [];
      state.chartData = data;
      var last_record = state.chartData[state.chartData.length - 1]; //获取最后一条数据
      state.currentRecordParas.RecordStatusName = DataStatusTextEmun(
        last_record.DataStatus
      );
      state.currentRecordParas.RecordValue = last_record.DataValue;
      let m_MonitorList = [];
      let monitor_List = [];
      data.forEach((item) => {
        let totalState = DataStatusTextEmun(item.DataStatus);
        m_MonitorList.push({
          RecordTime: subTime(item.DataTime, 11, 16),
          RecordStatusText: totalState,
          RecordValue: item.DataValue,
        });
      });
      data.forEach((item) => {
        let normalState = DataStatusTextEmun(item.DataStatus);
        if (normalState == "正常") {
          monitor_List.push({
            RecordTime: subTime(item.DataTime, 11, 16),
            RecordStatusText: normalState,
            RecordValue: item.DataValue,
          });
        }
      });
      state.monitorList = m_MonitorList; //源数据
      state.c_monitorList = monitor_List.reverse(); //切换数据
      setTimeout(() => {
        drawBar();
      }, 200);
    })
    .catch((error) => {
      console.log(error);
    });
};
//  初始化echarts折线图
const drawBar = () => {
  //先获取Dom上的实例
  let chartDom = echarts.getInstanceByDom(document.getElementById("chartMain"));
  //然后判断实例是否存在,如果不存在,就创建新实例
  if (chartDom == null) {
    chartDom = echarts.init(document.getElementById("chartMain"));
    myChart.value = chartDom;
  }
  let x_yData = [];
  state.chartData.forEach((item) => {
    x_yData.push({ value: [item.DataTime, item.DataValue] });
  });
  state.x_yData = x_yData;
  let series_arr = [];
  series_arr.push({
    type: "line",
    showSymbol: false,
    emphasis: { scale: false },
    data: state.x_yData,
    itemStyle: {
      color: "#4169E1",
    },
  });
  let option = {
    tooltip: {
      trigger: "axis",
    },
    legend: {
      show: false,
      fontSize: 12,
      color: "#7e8390",
    },
    grid: {
      left: "5%",
      right: "5%",
      bottom: "10%",
      top: "12%",
      containLabel: true,
    },
    xAxis: {
      type: "time",
      boundaryGap: false,
      min: minDate,
      max: maxDate,
      axisLabel: {
        showMaxLabel: true,
        formatter: function (value) {
          // 如果时间是 23:59:59 , 格式化为 24:00
          if (
            value ===
            new Date(
              moment().endOf("day").format("YYYY-MM-DD HH:mm:ss")
            ).getTime()
          ) {
            return moment(value).format("24:00");
          } else {
            // 其他的时间返回格式化 00:00
            return moment(value).format("HH:mm");
          }
        },
      },
      axisLine: { onZero: true, show: true },
      minorTick: {
        show: false,
        splitNumber: 2,
      },
      splitLine: {
        show: true, //是否显示分隔线
        interval: "auto", //坐标轴分隔线的显示间隔
      },
    },
    yAxis: {
      boundaryGap: ["20%", "20%"],
      type: "value",
      axisLabel: {
        formatter: "{value}",
      },
      // 整条y轴
      axisLine: {
        show: true,
      },
    },
    dataZoom: [
      {
        type: "slider", //图表下方的伸缩条
        show: true, //是否显示
        realtime: true, //
        start: 0, //伸缩条开始位置(1-100),可以随时更改
        end: 100, //伸缩条结束位置(1-100),可以随时更改
        left: 10,
        right: 15,
        bottom: 5, //底部的距离
        fillerColor: "rgba(22,181,203,0.4)", //选中范围的填充颜色。
        borderColor: "#ddd", //边框颜色。
        backgroundColor: "rgba(167,183,204,0.4)", //组件的背景颜色
        throttle: 100, //设置触发视图刷新的频率。单位为毫秒(ms)。
        handleIcon:
          "path://M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z",
        handleSize: "80%", //  控制手柄的尺寸,可以是像素大小,也可以是相对于 dataZoom 组件宽度的百分比,默认跟 dataZoom 宽度相同。
        handleStyle: {
          color: "#16b5cb",
          shadowBlur: 3, // shadowBlur图片阴影模糊值,shadowColor阴影的颜色
          shadowColor: "#77CCD8",
          shadowOffsetX: 1,
          shadowOffsetY: 1,
          opacity: 0.6,
        },
      },
    ],
    series: series_arr,
  };
  myChart.value.clear();
  myChart.value.setOption(option, true);
  window.addEventListener("resize", selfAdaption);
  if (times.value) {
    // 判断清除
    clearInterval(times.value);
  }
  times.value = setInterval(countdown, 1000);
};
//  自适应
const selfAdaption = () => {
  if (!myChart.value) return;
  myChart.value.resize();
  setTimeout(() => {
    drawBar();
  }, 100);
};
//获取详情
const getRecordDetail = () => {
  axios({
    url: "http://47.101.141.88:9019/Monitor/MonitorPoint/GetByID@V1.0",
    method: "GET",
    headers: {
      Authorization: `Bearer ${state.token}`,
    },
    params: {
      CorpID: state.CorpID,
      ID: state.PointID,
    },
  })
    .then((res) => {
      let getDetailData = res.data.Data || [];
      if (res.data.Code != 0) {
        return;
      }
      if (getDetailData == null || getDetailData == "") {
        return;
      }
      pointName.value = getDetailData.Name;
    })
    .catch((error) => {
      console.log(error);
    });
};
//切换状态(正常/中断)
const changeMonitorStatus = () => {
  if (!state.isMonitorChange) {
    let arr = [];
    state.monitorList.forEach((item) => {
      if (item.RecordStatusText != "正常") {
        arr.push({
          RecordTime: item.RecordTime,
          RecordStatusText: item.RecordStatusText,
          RecordValue: item.RecordValue,
        });
      }
    });
    state.isMonitorChange = true;
    state.c_monitorList = arr.reverse();
    return;
  } else {
    let arr = [];
    state.monitorList.forEach((item) => {
      if (item.RecordStatusText == "正常") {
        arr.push({
          RecordTime: item.RecordTime,
          RecordStatusText: item.RecordStatusText,
          RecordValue: item.RecordValue,
        });
      }
    });
    state.isMonitorChange = false;
    state.c_monitorList = arr.reverse();
    return;
  }
};
const DataStatusTextEmun = (value) => {
  if (value.length == 0) return "正常";
  let text = "";
  if (value[0] == "GLSB") {
    text = "过滤失败";
  }
  if (value[0] == "SZGSCW") {
    text = "数据格式错误";
  }
  if (value[0] == "ZHSB") {
    text = "转换失败";
  }
  if (value[0] == "BJ") {
    text = "报警";
  }
  if (value[0] == "BC") {
    text = "正常";
  }
  return text;
};
//切割数字
const subTime = (val, start, end) => {
  var getVal = val.substring(start, end);
  return getVal;
};
</script>
<style scoped lang="scss">
.main_contain {
  background-color: #efeff4;
  // overflow-y: unset;
  .ec_header {
    width: 100%;
    font-size: 10px;
    color: #fff;
    display: flex;
    .ec_header_left {
      width: 55%;
      height: 82px;
      background: linear-gradient(to left, #97d8e0, #16b5cb);
      border-radius: 5px;
      .ec_header_left_view {
        height: 40px;
        font-size: 20px;
        font-weight: 600;
        display: flex;
        align-items: center;
        justify-content: center;
        .ec_header_name {
          font-size: 14px;
        }
      }
    }
    .ec_header_right {
      width: 45%;
      font-size: 10px;
      .ec_header_right_view {
        height: 40px;
        display: flex;
        justify-content: space-around;
        align-items: center;
        background: linear-gradient(45deg, #97d8e0, #16b5cb);
        border-radius: 3px;
        margin: 1px 1px;
      }
    }
  }
  .container {
    /* position: relative; */
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
    box-sizing: border-box;
    background-color: #fff;
    border-radius: 3px;
  }
  .ykt-detail-wraper {
    width: 100%;
    display: flex;
    flex-direction: column;
    margin: 10px auto;
    background: #fff;
    border-radius: 3px;
  }
  .ykt-detail-wrapers {
    padding: 8px 0px 0px 0px;
    // background: #fff;
    width: 100%;
    height: auto;
    // height: calc(100vh - 60px);
    // overflow-y: auto;
    font-size: 12px;
    justify-content: center;
  }
  .hykt_header {
    width: 100%;
    min-height: 25px;
    background-color: #16b5cb;
    color: #fff;
    font-weight: 600;
    border-radius: 50px;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    justify-content: space-between;
    .hykt_span {
      font-size: 12px;
      height: 100%;
      min-width: 100px;
      display: flex;
      justify-content: center;
      align-items: center;
    }
  }
  .hykt_li {
    width: 100%;
    min-height: 25px;
    background-color: #fff;
    color: #000;
    font-weight: 500;
    border-radius: 50px;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    justify-content: space-between;
    margin-bottom: 5px;
    .hykt_span {
      font-size: 12px;
      height: 100%;
      min-width: 100px;
      display: flex;
      justify-content: center;
      align-items: center;
    }
  }
  .custom-title {
    text-align: left;
  }
  .icon_view {
    font-size: 30px;
    color: #fff;
    width: 40px;
    height: 40px;
    position: fixed;
    right: 10px;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #16b5cb;
    border-radius: 5px;
    box-shadow: 0 2px 6px 0 rgba(114, 124, 245, 0.5);
  }
}
.loading {
  position: absolute;
  padding-top: 75%;
  padding-left: 45%;
}
</style>