zmc
2023-08-07 1e18f0bcee0358e13c0e2cb750d17cd7ef5bf4d6
src/views/IndexView.vue
@@ -1,90 +1,219 @@
<!-- 实时监测 -->
<script>
import axiosInstance from '../utils/request.js';
import axiosInstanceInstance from '../utils/request.js';
// 异步组件
const DashBoard = defineAsyncComponent(() =>
  import('../sfc/DashboardChart.vue')
)
);
export default {
  components:{
  components: {
    DashBoard
  },
  data() {
    return {
      totalData: [],
      // 保存设置
      save: false,
      // 默认打开的折叠面板
      activeNames:'1',
      // isShow:false,
      // 要展示的仪表盘数量
      // totalCharts: 0,
      // 实时更新间隔 3秒
      timeInterval:60000,
      activeNames: '1',
      // 实时更新间隔 60秒
      timeInterval: 60000,
      // 外部设备
      outside: {
        // 搜索
        searchText: '',
        isall: false,
        isLoading: false,
        // 设备信息表的数据
        shopnames: [],
        // 当前展示的多选框组值
        displayedShopnames: [],
        // 当前页
        currentPage: 1,
        // 每页显示的数量
        pageSize: 5,
        // 是否已加载完所有数据
        allDataLoaded: false,
        // 是否全选
        checkAll: false,
        isIndeterminate: false,
        // 已选择店铺
        checkedShops: [],
        //返回选择的所有店铺的数据
        realTimeData: []
      },
      // 内部设备
      inner: {
        searchText: '',
        isall: false,
        isLoading: false,
        // 内部接口返回的所有数据
        getData:[],
        getData: [],
        // 选中的店铺对应全部字段信息
        inFumeValue:[],
        // 店铺名字
        inFumeValue: [],
        // 所有店铺名字
        shopnames: [],
        // 当前展示的多选框组值
        displayedShopnames: [],
        // 当前页
        currentPage: 1,
        // 每页显示的数量
        pageSize: 2,
        // 是否已加载完所有数据
        allDataLoaded: false,
        // 是否全选
        checkAll: false,
        isIndeterminate: false,
        // 已选择店铺
        checkedShops: []
      },
      }
      // chartInstance: []
      // // 内部设备
      // devices: []
    };
  },
  watch: {
    // 'outside.checkedShops'(){
    //   this.saveOutsideData()
    //     console.log('111');
    // }
  },
  methods: {
    //获取所有店铺名字
    getDeviceInfo() {
      // 获取外部设备的店铺名称
      axiosInstance.get('/fume/device').then((result) => {
      // 获取所有外部设备的店铺名称
      axiosInstanceInstance.get('/fume/device').then((result) => {
        result.data.data.forEach((item) => {
          this.outside.shopnames.push(item.diName);
        });
        this.outside.displayedShopnames = this.outside.shopnames.slice(
          0,
          this.outside.pageSize
        );
        if (this.outside.shopnames.length <= this.outside.pageSize) {
          this.outside.allDataLoaded = true;
        }
      });
      //从内部接口获取实时数据的所有店铺名称
      axiosInstance
      axiosInstanceInstance
        .get('https://fyami.com.cn/device/min/value/real_time', {
          params: { page: 1, per_page: 20 }
        })
        .then((result) => {
          // 保存内部接口获取的所有信息
          this.getData = result.data.data
          this.getData = result.data.data;
          result.data.data.forEach((item) => {
            this.inner.shopnames.push(item.siteName);
          });
          this.inner.displayedShopnames = this.inner.shopnames.slice(
            0,
            this.inner.pageSize
          );
          if (this.inner.shopnames.length <= this.inner.pageSize) {
            this.inner.allDataLoaded = true;
          }
        });
    },
    loadMore() {
      this.outside.isLoading = true;
      setTimeout(() => {
        const startIndex = this.outside.currentPage * this.outside.pageSize;
        const endIndex = startIndex + this.outside.pageSize;
        this.outside.displayedShopnames =
          this.outside.displayedShopnames.concat(
            this.outside.shopnames.slice(startIndex, endIndex)
          );
        this.outside.currentPage++;
        if (
          this.outside.displayedShopnames.length ===
          this.outside.shopnames.length
        ) {
          this.outside.allDataLoaded = true;
          this.outside.isall = true;
        }
        this.outside.isLoading = false;
      }, 100);
    },
    loadMoreInner() {
      this.inner.isLoading = true;
      setTimeout(() => {
        const startIndex = this.inner.currentPage * this.inner.pageSize;
        const endIndex = startIndex + this.inner.pageSize;
        this.inner.displayedShopnames = this.inner.displayedShopnames.concat(
          this.inner.shopnames.slice(startIndex, endIndex)
        );
        this.inner.currentPage++;
        if (
          this.inner.displayedShopnames.length === this.inner.shopnames.length
        ) {
          this.inner.allDataLoaded = true;
          this.inner.isall = true;
        }
        this.inner.isLoading = false;
      }, 100);
    },
    // 过滤数据
    filterData(keyword) {
      return this.outside.shopnames.filter((item) => item.includes(keyword));
    },
    // 处理搜索
    handleSearch() {
      if (this.outside.searchText != '') {
        this.outside.displayedShopnames = this.filterData(
          this.outside.searchText
        );
        this.outside.currentPage = 1; // 重置页码
        this.outside.allDataLoaded =
          this.outside.displayedShopnames === this.outside.shopnames.length;
      } else {
        // 加载默认数量的
        this.outside.displayedShopnames = this.outside.shopnames.slice(
          0,
          this.outside.pageSize
        );
        if (this.outside.shopnames.length <= this.outside.pageSize) {
          this.outside.allDataLoaded.value = true;
        }
        this.outside.checkedShops = [];
      }
    },
    // 处理搜索
    handleSearchInner() {
      if (this.inner.searchText != '') {
        this.inner.displayedShopnames = this.filterData(this.inner.searchText);
        this.inner.currentPage = 1; // 重置页码
        this.inner.allDataLoaded =
          this.inner.displayedShopnames === this.inner.shopnames.length;
      } else {
        // 加载默认数量的
        this.inner.displayedShopnames = this.inner.shopnames.slice(
          0,
          this.inner.pageSize
        );
        if (this.inner.shopnames.length <= this.inner.pageSize) {
          this.inner.allDataLoaded.value = true;
        }
        this.inner.checkedShops = [];
      }
    },
    // 外部设备全选
    handleCheckAllChangeOutside(val) {
      this.outside.checkedShops = val ? this.outside.shopnames : [];
      this.outside.checkedShops = val ? this.outside.displayedShopnames : [];
      this.outside.isIndeterminate = false;
    },
    handleCheckedCitiesChangOutside(value) {
      const checkedCount = value.length;
      this.outside.checkAll = checkedCount === this.outside.shopnames.length;
      this.outside.checkAll =
        checkedCount === this.outside.displayedShopnames.length;
      this.outside.isIndeterminate =
        checkedCount > 0 && checkedCount < this.outside.shopnames.length;
        checkedCount > 0 &&
        checkedCount < this.outside.displayedShopnames.length;
    },
    // 内部设备全选
@@ -100,76 +229,86 @@
    },
    // 判断一个数组是否包含该元素
     hasElement(array, element) {
    hasElement(array, element) {
      return array.includes(element);
    },
    //根据所选店铺求请并渲染仪表盘
    request() {
      if(this.outside.checkedShops.length!=0){
      // 外部设备
      if (this.outside.checkedShops.length != 0) {
        let temp = this.outside.checkedShops.join();
        let params = {};
        if (this.outside.checkedShops.length != 0) {
          params['shops'] = temp;
        }
        axiosInstance.get('/fume/lastest', { params: params }).then((result) => {
          this.outside.realTimeData = result.data.data;
          console.log('66', this.outside.realTimeData);
          // console.log('长度为:',this.outside.realTimeData.length);
          // 渲染折线图
          // this.updateCharts();
        });
        axiosInstanceInstance
          .get('/fume/lastest', { params: params })
          .then((result) => {
            this.outside.realTimeData = result.data.data;
            console.log('66', this.outside.realTimeData);
            // console.log('长度为:',this.outside.realTimeData.length);
            // 渲染折线图
            // this.updateCharts();
          });
      }
      // 选择了内部设备
      if(this.inner.checkedShops.length!=0){
      if (this.inner.checkedShops.length != 0) {
        // 清空数据
        this.inner.inFumeValue=[]
        this.getData.forEach(item=>{
          let itemOne = item.siteName
        this.inner.inFumeValue = [];
        this.getData.forEach((item) => {
          let itemOne = item.siteName;
          // 拿到选中的店铺对应的浓度值
          if(this.hasElement(this.inner.checkedShops,itemOne)){
            this.inner.inFumeValue.push(item)
          if (this.hasElement(this.inner.checkedShops, itemOne)) {
            this.inner.inFumeValue.push(item);
          }
        })
        });
        console.log(this.inner.inFumeValue);
      }
      // 合并
      setTimeout(() => {
        // 试点设备排在前面
        this.totalData = [
          ...this.inner.inFumeValue,
          ...this.outside.realTimeData
        ];
        console.log('总选数据', this.totalData);
        console.log('长度为:', this.totalData.length);
      }, 200);
      console.log('调用了');
    },
    // 点击按钮触发
    show() {
      // 当取消选择时,防止图形还保留在页面。
      if(this.outside.checkedShops.length==0){
        this.outside.realTimeData = []
      if (this.outside.checkedShops.length == 0) {
        this.outside.realTimeData = [];
      }
      if(this.inner.checkedShops.length == 0){
        this.inner.inFumeValue = []
      if (this.inner.checkedShops.length == 0) {
        this.inner.inFumeValue = [];
      }
      // 根据所选的店铺请求数据
      this.request();
      setInterval(() => {
        this.request();
      }, this.timeInterval);
      // 得到要展示的仪表盘数量
      // this.totalCharts =
      //   this.outside.checkedShops.length + this.inner.checkedShops.length;
    }
  },
  mounted() {
    // 获取所有店铺名字
    this.getDeviceInfo();
    // 优先展示浏览器缓存中的
    // this.getOutsideData()
  }
}
};
</script>
<template>
  <div>
    <el-collapse v-model="activeNames" >
      <el-collapse-item  name="1">
    <el-collapse v-model="activeNames">
      <el-collapse-item name="1">
        <template #title>
          <el-tooltip
            class="box-item"
@@ -177,144 +316,225 @@
            content="点击可折叠"
            placement="right-start"
          >
          <h2>选择某个设备的实时数据:</h2>
            <h2 style="margin-left: 10px">监控配置</h2>
          </el-tooltip>
        </template>
    <el-card shadow="always" class="form-card">
    <el-form label-width="120px">
      <el-form-item label="外部设备">
        <el-checkbox
          v-model="outside.checkAll"
          :indeterminate="outside.isIndeterminate"
          @change="handleCheckAllChangeOutside"
          >全选</el-checkbox
        >
        <el-checkbox-group
          v-model="outside.checkedShops"
          @change="handleCheckedCitiesChangOutside"
        >
          <el-checkbox
            v-for="shop in outside.shopnames"
            :key="shop"
            :label="shop"
            >{{ shop }}
          </el-checkbox>
        </el-checkbox-group>
      </el-form-item>
      <el-form-item>
        <div>已选择外部设备数量为:{{outside.checkedShops.length}}</div>
      </el-form-item>
        <el-card shadow="always" class="form-card">
          <h1>监测点配置</h1>
          <br />
          <el-form label-width="120px">
            <el-form-item label="试点设备">
              <el-checkbox
                v-model="inner.checkAll"
                :indeterminate="inner.isIndeterminate"
                @change="handleCheckAllChangeInner"
                >全选</el-checkbox
              >
              <el-checkbox-group
                v-model="inner.checkedShops"
                @change="handleCheckedCitiesChangeInner"
                class="inner-checkbox-group"
              >
                <el-checkbox
                  v-for="shop in inner.displayedShopnames"
                  :key="shop"
                  :label="shop"
                  >{{ shop }}
                </el-checkbox>
              </el-checkbox-group>
            </el-form-item>
            <div class="input-search">
              <el-input
                type="text"
                v-model="inner.searchText"
                placeholder="搜索店铺名称"
                @input="handleSearchInner"
              />
            </div>
      <el-form-item label="内部设备">
        <el-checkbox
          v-model="inner.checkAll"
          :indeterminate="inner.isIndeterminate"
          @change="handleCheckAllChangeInner"
          >全选</el-checkbox
        >
        <el-checkbox-group
          v-model="inner.checkedShops"
          @change="handleCheckedCitiesChangeInner"
          class="inner-checkbox-group"
        >
          <el-checkbox v-for="shop in inner.shopnames" :key="shop" :label="shop"
            >{{ shop }}
          </el-checkbox>
        </el-checkbox-group>
      </el-form-item>
      <el-form-item>
        <div>已选择内部设备数量为:{{inner.checkedShops.length}}</div>
      </el-form-item>
      <el-form-item >
        <div class="time-interval">
          实时更新间隔为:{{timeInterval/1000}}秒
        </div>
      </el-form-item>
    </el-form>
  </el-card>
</el-collapse-item>
  </el-collapse>
            <div>
              <el-button
                type="primary"
                v-if="!inner.allDataLoaded && !inner.isLoading && !inner.isall"
                @click="loadMoreInner"
                >加载更多</el-button
              >
              <el-button
                type="primary"
                loading
                v-if="!inner.allDataLoaded && inner.isLoading"
                @click="loadMoreInner"
                >加载更多</el-button
              >
              <div>已选择试点设备数量为:{{ inner.checkedShops.length }}</div>
            </div>
            <br />
            <hr />
            <br />
            <el-form-item label="其他设备">
              <el-checkbox
                v-model="outside.checkAll"
                :indeterminate="outside.isIndeterminate"
                @change="handleCheckAllChangeOutside"
                >全选</el-checkbox
              >
              <el-checkbox-group
                v-model="outside.checkedShops"
                @change="handleCheckedCitiesChangOutside"
              >
                <el-checkbox
                  v-for="shop in outside.displayedShopnames"
                  :key="shop"
                  :label="shop"
                  >{{ shop }}
                </el-checkbox>
              </el-checkbox-group>
            </el-form-item>
            <div class="input-search">
              <el-input
                type="text"
                v-model="outside.searchText"
                placeholder="搜索店铺名称"
                @input="handleSearch"
              />
            </div>
            <div>
              <el-button
                type="primary"
                v-if="
                  !outside.allDataLoaded && !outside.isLoading && !outside.isall
                "
                @click="loadMore"
                >加载更多</el-button
              >
              <el-button
                type="primary"
                loading
                v-if="!outside.allDataLoaded && outside.isLoading"
                @click="loadMore"
                >加载更多</el-button
              >
              <div>已选择其他设备数量为:{{ outside.checkedShops.length }}</div>
            </div>
            <!-- <el-form-item > -->
            <div class="time-interval">
              实时更新间隔为:{{ timeInterval / 1000 }}秒
            </div>
            <!-- </el-form-item> -->
          </el-form>
        </el-card>
      </el-collapse-item>
    </el-collapse>
  </div>
  <div>
    <el-tooltip
        class="box-item"
        effect="dark"
        content="点击展示实时数据"
        placement="top-start"
      >
      <el-button type="success" @click="show"> 展示 </el-button>
      </el-tooltip>
      class="box-item"
      effect="dark"
      content="点击展示实时数据"
      placement="top-start"
    >
      <el-button type="success" @click="show" style="margin-left: 10px">
        设置
      </el-button>
    </el-tooltip>
    <el-switch
      v-model="save"
      class="save-switch"
      active-text="保存设置"
      inactive-text="不保存设置"
    >
    </el-switch>
  </div>
 <!-- 仪表盘  -->
  <!-- <div class="charts-container" v-for="(device,index) in outside.realTimeData" :key="device.mvStatCode">
      <div ref="chartsOutside" class="echarts" :id="`chartAP-${index}`"></div>
  </div> -->
<h3 v-show="outside.realTimeData.length" class="outside-leble">外部设备:</h3>
<div v-if="outside.realTimeData">
  <el-row :gutter="20">
    <el-col :span="6" v-for="device in outside.realTimeData" :key="device.mvStatCode">
      <el-card>
        <template #header>
            <div class="card-header">{{ device.diName }}</div>
        </template>
      <DashBoard :data="device.mvFumeConcentration2"></DashBoard>
      <div>设备编号:{{ device.mvStatCode }}</div>
      <hr class="divider-margin"/>
      <divr class="data">风机电流(A):{{ device.mvFanElectricity}} </divr>
      <hr class="divider-margin">
      <div class="data">净化器电流(A):{{ device.mvPurifierElectricity}}</div>
      <hr class="divider-margin"/>
      <div>产生时间:{{ device.mvDataTime }}</div>
      <div class="status" :class="{'exceed': device.mvFumeConcentration2 >= 1}"> {{ device.mvFumeConcentration2 >= 1 ? '超标' : '' }}</div>
      <!-- <div class="status1" :class="{'exceed1': device.mvFumeConcentration2 < 1}"> {{ device.mvFumeConcentration2 < 1 ? '未超标' : '' }}</div> -->
      </el-card>
    </el-col>
  </el-row>
</div>
<hr v-show="outside.realTimeData.length && inner.inFumeValue.length" class="line-marign"/>
<h3 v-show="inner.inFumeValue.length">内部设备:</h3>
<div v-if="inner.inFumeValue">
  <el-row :gutter="20">
    <el-col :span="6" v-for="device in inner.inFumeValue" :key="device.mnCode">
      <el-card>
        <template #header>
          <div class="card-header">{{ device.siteName }}</div>
        </template>
      <DashBoard :data="device.value"></DashBoard>
      <div>设备编号:{{ device.mnCode }}</div>
      <hr class="divider-margin"/>
      <div>产生时间:{{ device.time }}</div>
      <div class="status" :class="{'exceed': device.value > 1}"> {{ device.value >= 1 ? '超标' : '' }}</div>
      <!-- <div class="status1" :class="{'exceed1': device.value < 1}"> {{ device.value < 1 ? '未超标' : '' }}</div> -->
    </el-card>
    </el-col>
  </el-row>
</div>
  <div>
    <el-row :gutter="20">
      <el-col
        :span="6"
        v-for="(device, index) in totalData"
        :key="device.mvStatCode"
      >
        <!-- 内部设备 -->
        <el-card v-if="index < inner.inFumeValue.length" height="1900px">
          <template #header>
            <div class="card-header">{{ device.siteName }}</div>
          </template>
          <DashBoard :data="device.value"></DashBoard>
          <div>设备编号:{{ device.mnCode }}</div>
          <hr class="divider-margin" />
          <div>数据发布时间:{{ device.time }}</div>
          <div class="status" :class="{ exceed: device.value > 1 }">
            {{ device.value >= 1 ? '超标' : '' }}
          </div>
          <br />
          <br />
          <br />
        </el-card>
        <!-- 外部设备 -->
        <el-card v-else>
          <template #header>
            <div class="card-header">
              {{ device.diName }}
              <el-tooltip
                class="box-item"
                effect="dark"
                content="其他设备"
                placement="top-start"
              >
                <i-ep-Shop></i-ep-Shop>
              </el-tooltip>
              <span> </span>
            </div>
          </template>
          <DashBoard :data="device.mvFumeConcentration2"></DashBoard>
          <div>设备编号:{{ device.mvStatCode }}</div>
          <hr class="divider-margin" />
          <divr class="data">风机电流(A):{{ device.mvFanElectricity }} </divr>
          <hr class="divider-margin" />
          <div class="data">
            净化器电流(A):{{ device.mvPurifierElectricity }}
          </div>
          <hr class="divider-margin" />
          <div>数据发布时间:{{ device.mvDataTime }}</div>
          <div
            class="status"
            :class="{ exceed: device.mvFumeConcentration2 >= 1 }"
          >
            {{ device.mvFumeConcentration2 >= 1 ? '超标' : '' }}
          </div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>
<style lang="scss" scoped>
.time-interval {
  display: flex;
  justify-content: right;
  font-size: 16px;
}
.form-card {
  margin: 20px 10px;
  // width: 96%;
  border:1px solid #ebeef5;
  border: 1px solid #ebeef5;
  border-radius: 4px;
}
.inner-checkbox-group {
  margin-left: 15px;
}
.el-card {
  margin-bottom: 10px;
  border-radius: 9px;
}
.card-header {
  // display: flex;
@@ -322,7 +542,15 @@
  // position: center;
  text-align: center;
}
.card-header-item {
  display: flex;
  text-align: right;
}
.outside-leble {
  margin-top: 10px;
}
.inner-leble {
  margin-top: 10px;
}
// 分割线
@@ -331,6 +559,9 @@
}
.el-dialog {
  width: 700px;
}
.dashBorder-area {
  margin-left: 10px;
}
.dashboard {
  margin-bottom: 20px;
@@ -342,10 +573,6 @@
  text-align: center;
  padding: 10px 0;
  background-color: #f5f7fa;
}
.echarts {
  height: 300px;
}
/* 超标 文字效果*/
@@ -379,6 +606,23 @@
}
// 分割线上下距离
.divider-margin {
  margin: 3px 0px ;
  margin-top: 3px;
}
.el-input {
  width: calc(100% / 6);
  // margin-left: 70px;
}
// .input-search {
//   display: flex;
//   justify-content: left;
// }
.save-switch {
  margin-top: 20px;
  margin-left: 20px;
}
:deep() .el-card_body {
  padding: 0px;
  margin: 0px;
}
</style>