Browse Source

Merge branch 'device'

haojianlong 5 years ago
parent
commit
e9a5c4670a

+ 68 - 11
src/api/scan/request.js

@@ -4,7 +4,7 @@ import http from './httpUtil'
 let arithmetic = '/arithmetic'
 
 var Comming = 'revit'
-//获取打印标签模板test
+    //获取打印标签模板test
 export function getTest() {
     return fetch({ method: 'GET', url: `${api}/service/template/note_template` })
 }
@@ -393,11 +393,11 @@ export function setHeader(param) {
 //获取头部接口
 export function getHeader(param) {
     let data = {
-        "AppType": Comming,
-        "Code": param.code,
-        "ProjId": param.perjectId
-    }
-    // return fetch({ method: 'POST', url: `${api}/service/dict/equipment_family_info_header`, data })
+            "AppType": Comming,
+            "Code": param.code,
+            "ProjId": param.perjectId
+        }
+        // return fetch({ method: 'POST', url: `${api}/service/dict/equipment_family_info_header`, data })
     return fetch({ method: 'POST', url: `${api}/service/dict/infocode_query_header`, data })
 }
 
@@ -446,7 +446,7 @@ export function getSpaceFloor(param) {
 export function createBusiness(param) {
     let data = param.data
     return fetch({ method: "POST", url: `${physics}/space/create?projectId=${param.ProjId}&secret=${param.secret}`, data })
-    // return fetch({ method: "POST", url: `/test/space/create?projectId=${param.ProjId}&secret=${param.secret}`, data })
+        // return fetch({ method: "POST", url: `/test/space/create?projectId=${param.ProjId}&secret=${param.secret}`, data })
 }
 
 //批量创建业务空间
@@ -496,7 +496,7 @@ export function getGraphyId(param) {
 export function getBussines(param) {
     let data = param.data
     return fetch({ method: "POST", url: `${physics}/object/outside_query?projectId=${param.ProjId}&secret=${param.secret}`, data })
-    // return fetch({ method: "POST", url: `/test/object/outside_query?projectId=${param.ProjId}&secret=${param.secret}`, data })
+        // return fetch({ method: "POST", url: `/test/object/outside_query?projectId=${param.ProjId}&secret=${param.secret}`, data })
 }
 
 //替代前一个接口
@@ -929,7 +929,7 @@ export function equipLinkSys(param, success) {
 export function sysLinkEquip(param, success) {
     let url = `${baseUrl}/datacenter/sy-in-eq/link-sy-eq`;
     http.postJson(url, param, success)
-} 
+}
 
 //设备清单 - 根据对象删除系统和设备的关系
 export function sysUnlinkEquip(param, success) {
@@ -994,7 +994,7 @@ export function queryPartsDie(param, success) {
 }
 
 //查询项目下设备或部件的类别、以及名称
-export function TypePartsDie( success) {
+export function TypePartsDie(success) {
     let url = `${baseUrl}/equip-component/equip-query/equip-compon-category`;
     http.getJson(url, {}, success)
 }
@@ -1072,7 +1072,7 @@ export function queryPhysicsAllType(param, success) {
 }
 
 //查询所有设备族信息
-export function queryFamilyAll( success) {
+export function queryFamilyAll(success) {
     let url = `${baseUrl}/datacenter/data-dictionary/family-query-All`;
     http.getJson(url, {}, success)
 }
@@ -1414,4 +1414,61 @@ export function createRelateInZoneAndISp(param, success) {
 export function groupCreRelaZoneAndISp(param, success) {
     let url = `${baseUrl}/datacenter/si-in-sp-base/link-list?type=${param.type}`;
     http.postJson(url, param.data, success)
+}
+
+/**系统集成成果管理 */
+//系统集成统计条形图
+export function getIntegrateStatisticsToBar(param, success) {
+    let url = `/pointconfig/report/point-statis    `
+    http.postJson(url, param, success)
+}
+//系统集成统计环形图
+export function getIntegrateStatisticsToLoop(param, success) {
+    let url = `/pointconfig/report/meterfunc-statis`
+    http.postJson(url, param, success)
+}
+//表号功能号总览
+export function getTabFunNumOverview(param, success) {
+    let url = `/pointconfig/report/meterfunc-overview`
+    http.postJson(url, param, success)
+}
+//表号功能号对应历史数据
+export function getHistoryData(query, param, success) {
+    let url = `/data-platform-3/hisdata/batch_query_period_data_by_metfun`
+    url += `?projectId=${query.projectId}&secret=${query.secret}`
+    fetch({ url: url, method: 'post', data: param, headers: { 'ProjectId': query.projectId, 'Comming': 'adm', 'Account': query.userInfo.username } }).then((response) => {
+        success(response.data);
+    }).catch(error => {
+        console.error(error);
+    });
+}
+//获取表号功能号的源数据
+export function getTabFunNumSourceData(param, success) {
+    let url = `/pointconfig/report/query-point`
+    http.postJson(url, param, success)
+}
+//获取表号功能号对应的对象实例
+export function getTabFunNumObjInstance(param, success) {
+    let url = `/pointconfig/report/query-instance`
+    http.postJson(url, param, success)
+}
+//添加表号功能号
+export function addTabFunNum(param, success) {
+    let url = `/pointconfig/report/custom-meter-func`
+    http.postJson(url, param, success)
+}
+//表号功能号对应总览
+export function tableFuncRelatedOverview(param, success) {
+    let url = `/pointconfig/report/meter-related`
+    http.postJson(url, param, success)
+}
+//实例中查询设备信息
+export function getEquipByEqID(param, success) {
+    let url = `${baseUrl}/datacenter/equip/query`
+    http.postJson(url, param, success)
+}
+//获取楼层信息
+export function getFloorMsgByFloorID(param, success) {
+    let url = `${baseUrl}/datacenter/floor/query`
+    http.postJson(url, param, success)
 }

+ 120 - 0
src/components/point/report/addTabFunNum.vue

@@ -0,0 +1,120 @@
+<template>
+  <!-- 新增表号-功能号 -->
+  <div id="addTabFunNum">
+    <el-form :model='form' label-width="150px" ref="ruleForm" :rules="rules" style="overflow:auto;">
+      <el-form-item label="表号-功能号" prop="MeterFunc">
+        <el-input v-model="form.MeterFunc" placeholder="请输入表号-功能号"></el-input>
+      </el-form-item>
+      <el-form-item label="设定采集间隔时间" prop="CollectInterval">
+        <el-input v-model="form.CollectInterval" placeholder="设定时间不能小于10s"></el-input>
+      </el-form-item>
+      <el-form-item label="值单位" prop="Unit">
+        <el-cascader :options='options' v-model='form.Unit'></el-cascader>
+      </el-form-item>
+      <el-form-item label="取值公式" prop="DataRuleContent">
+        <el-input type="textarea" placeholder="请输入取值公式" v-model="form.DataRuleContent"></el-input>
+      </el-form-item>
+      <el-form-item label="" style="text-align:right;margin-bottom:0px">
+        <el-button @click="$emit('closeDrawer')">取消</el-button>
+        <el-button type="primary" @click="add()">新增</el-button>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import { Message } from 'element-ui';
+import {
+  addTabFunNum
+} from '@/api/scan/request'
+import { batchQueryUnit } from '@/fetch/point_http'
+export default {
+  data() {
+    return {
+      form: {
+        MeterFunc: '',//表号-功能号
+        CollectInterval: '',//采集间隔时间
+        DataRuleContent: '',//取值公式
+        Unit: '',//值单位
+      },
+      //下拉框选项
+      options: [
+      ],
+      //验证规则
+      rules: {
+        MeterFunc: [
+          { required: true, message: '请输入表号-功能号', trigger: 'blur' }
+        ],
+        CollectInterval: [
+          { required: true, message: '请输入采集间隔时间', trigger: 'blur' }
+        ],
+        Unit: [
+          { required: true, message: '请选择值单位', trigger: 'change' }
+        ],
+        DataRuleContent: [
+          { required: true, message: '请填写取直公式', trigger: 'blur' }
+        ]
+      }
+    }
+  },
+  methods: {
+    //添加
+    add() {
+      //验证参数
+      this.$refs.ruleForm.validate((valid) => {
+        if (valid) {
+          this.form.Unit = this.form.Unit.toString();
+          addTabFunNum(this.form, res => {
+            //成功提示
+            Message.success('添加成功');
+            //清楚当前表单数据,500ms后关闭
+            let that = this;
+            that.$emit('reloadData');
+            setTimeout(() => {
+              that.$emit('closeDrawer');
+              that.form = {
+                MeterFunc: '',
+                CollectInterval: '',
+                DataRuleContent: '',
+                Unit: '',
+              }
+            }, 500);
+          });
+        } else {
+          return false;
+        }
+      });
+    },
+    //加载下拉框
+    initSelect() {
+      batchQueryUnit({}, res => {
+        let data = res.Content
+        let arr = []
+        data.forEach(item => {
+          let first = {
+            value: item.Type,
+            label: item.Type,
+            children: []
+          }
+          item.Units.forEach(ele => {
+            let second = {}
+            second = {
+              value: ele.Name,
+              label: ele.Name
+            }
+            first.children.push(second)
+          })
+          arr.push(first)
+        })
+        this.options = arr
+      })
+    }
+  },
+  mounted() {
+    this.initSelect();
+  }
+}
+</script>
+
+<style lang="less" scoped>
+</style>

+ 79 - 0
src/components/point/report/dataSource.vue

@@ -0,0 +1,79 @@
+<template>
+  <!-- 子系统点位(数据来源) -->
+  <div id="dataSource" v-loading="loading">
+    <div class="data-item" v-for="form in forms" :key="form.id">
+      <el-form :model="form" label-width="150px">
+        <el-form-item label="数据源名称:">
+          {{form.Name || '--'}}
+        </el-form-item>
+        <el-form-item label="值单位说明:">
+          {{form.ValueDescription || '--'}}
+        </el-form-item>
+        <el-form-item label="原始点位值:">
+          {{form.Data || '--'}}
+        </el-form-item>
+        <el-form-item label="原始点位描述:">
+          {{form.Description || '--'}}
+        </el-form-item>
+        <el-form-item label="位置标签:">
+          {{form.LocationFlag.toString() || '--'}}
+        </el-form-item>
+        <el-form-item label="原始值处理规则详情:">
+          {{form.DataRuleContent  || '--'}}
+        </el-form-item>
+      </el-form>
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  getTabFunNumSourceData
+} from '@/api/scan/request'
+export default {
+  data() {
+    return {
+      forms: [
+      ],
+      loading: true
+    }
+  },
+  methods: {
+    //加载数据
+    loadDataSource() {
+      this.loading = true;
+      let pa = {
+        Filters: "Infos='" + this.tabFunNum + "'"
+      };
+      getTabFunNumSourceData(pa, res => {
+        this.forms = res.Content;
+        this.loading = false;
+      });
+    }
+  },
+  props: {
+    tabFunNum: String
+  },
+  mounted() {
+    this.loadDataSource();
+  },
+  watch: {
+    tabFunNum() {
+      this.loadDataSource();
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+#dataSource {
+  height: 100%;
+  overflow: auto;
+}
+.data-item {
+  margin: 15px 10px;
+  box-shadow: 0px 4px 10px 0px rgba(0,0,0,0.2);
+  background-color: white;
+  padding: 10px 10px;
+}
+</style>

+ 195 - 0
src/components/point/report/historyChart.vue

@@ -0,0 +1,195 @@
+<template>
+  <!-- 历史数据 -->
+  <div id="historyChart">
+    <!-- 精度选择 -->
+    <div class="query-area">
+      <span>当下分精度下采集数量:{{ chartData.length }}</span>
+      <el-select v-model="selectValue" style="float:right;margin-right:10px;" @change='loadTable()'>
+        <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
+      </el-select>
+    </div>
+    <!-- 图表 -->
+    <div class="chart-area" ref="chart">
+
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import {
+  getHistoryData
+} from '@/api/scan/request'
+import echarts from 'echarts'
+
+export default {
+  data() {
+    return {
+      lineChart: null,//折线表
+      selectValue: '5min',//下拉框默认值
+      options: [//精度
+        { value: '1min', label: '1分钟' },
+        { value: '5min', label: '5分钟' },
+        { value: '15min', label: '15分钟' },
+        { value: '30min', label: '30分钟' },
+        { value: '1hour', label: '1小时' },
+        { value: '1day', label: '1天' },
+      ],
+      //数据表
+      chartData: []
+    }
+  },
+  props: {
+    tabFunNum: String//表号功能号
+  },
+  methods: {
+    //加载表格
+    loadTable() {
+      let query = {
+        secret: this.secret,
+        projectId: this.projectId,
+        userInfo: this.userInfo
+      };
+      //时间处理
+      let nowDate = new Date().getTime();
+      let gteDate = 0;
+      if (this.selectValue == '1min' || this.selectValue == '5min') {
+        gteDate = nowDate - 3600 * 1000;
+      }
+      else if (this.selectValue == '15min' || this.selectValue == '30min') {
+        gteDate = nowDate - 24 * 3600 * 1000;
+      }
+      else {
+        gteDate = nowDate - 30 * 24 * 3600 * 1000;
+      }
+      let pa = {
+        criterias: [
+          {
+            "met_fun": this.tabFunNum,      //表号功能号
+            "period": this.selectValue,
+            "receivetime": {
+              "$gte": this.date2String(gteDate),
+              "$lt": this.date2String(nowDate)
+            }
+          }
+        ]
+      };
+      //获取历史数据
+      getHistoryData(query, pa, res => {
+        this.chartData = res[`${this.tabFunNum}`].Content;
+        //折线图参数
+        let lineChartOption = {
+          tooltip: {
+            trigger: 'axis',
+            position: function (pt) {
+              return [pt[0], '10%'];
+            }
+          },
+          xAxis: {
+            type: 'category',
+            boundaryGap: false,
+            data: this.chartData.map(item => item.data_time)
+          },
+          yAxis: {
+            type: 'value',
+            boundaryGap: [0, '100%']
+          },
+          dataZoom: [{
+            type: 'inside',
+            start: 80,
+            end: 100
+          }, {
+            start: 0,
+            end: 10,
+            handleIcon: '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%',
+            handleStyle: {
+              color: '#fff',
+              shadowBlur: 3,
+              shadowColor: 'rgb(144, 147, 153)',
+              shadowOffsetX: 2,
+              shadowOffsetY: 2
+            }
+          }],
+          series: [
+            {
+              name: '数值',
+              type: 'line',
+              smooth: true,
+              symbol: 'none',
+              sampling: 'average',
+              itemStyle: {
+                color: 'rgb(103, 194, 58)'
+              },
+              areaStyle: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+                  offset: 0,
+                  color: 'rgb(225, 243, 216)'
+                }, {
+                  offset: 1,
+                  color: 'rgb(225, 243, 216)'
+                }])
+              },
+              data: this.chartData.map(item => item.data_value)
+            }
+          ]
+        };
+        this.lineChart.setOption(lineChartOption);
+      });
+    },
+    //时间戳转string 例:标准时间 => 20190929120000
+    date2String(d) {
+      let dateString = new Date(d).toLocaleString().split("/");
+      if (dateString[1].length == 1) {
+        dateString[1] = '0' + dateString[1];
+      }
+      dateString = dateString.toString();
+      dateString = dateString.split(/(\d\d)/);
+      var r = [];
+      dateString.map((value, key) => {
+        if (key % 2 != 0) {
+          r.push(value);
+        }
+      })
+      return r.join("");
+    },
+    init() {
+      this.lineChart = echarts.init(this.$refs.chart);
+      this.loadTable();
+    },
+  },
+  computed: {
+    ...mapGetters('layout', ['projectId', 'secret', 'userInfo'])
+  },
+  mounted() {
+    //实例化
+    this.init();
+    let that = this;
+    //图表大小随窗口变化
+    window.onresize = () => {
+      that.lineChart.resize();
+    }
+  },
+  watch: {
+    //切换时更新数据
+    tabFunNum() {
+      this.loadTable();
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+#historyChart {
+  height: 100%;
+  width: 100%;
+  padding: 10px 5px;
+}
+.query-area {
+  height: 40px;
+  line-height: 40px;
+}
+.chart-area {
+  height: 450px;
+}
+</style>

+ 279 - 0
src/components/point/report/integrateStatistics.vue

@@ -0,0 +1,279 @@
+<template>
+  <div id="integrateStatistics">
+    <!-- 环形表 -->
+    <div class="statistics-chart">
+      <div class="chart-title">表号功能号总数量:{{ pointData.tabFuncNumSum }}</div>
+      <hr style="width:90%" />
+      <div ref="loopchart" class="chart" id="loopchart"></div>
+      <div class="chart-title" style="padding-left:10%;">目前可能断数的数量:{{ pointData.disConn }}</div>
+      <hr style="width:80%" />
+      <div style="padding:15px 10%;line-height:2;">
+        1点位对多表号功能号:{{ pointData.oneToM }}
+        <br />
+        多点为对1表号功能号:{{ pointData.mToOne }}
+        <!-- 查看表号功能号一对多多对一总览 -->
+        <el-button @click="showOverview" type="info" icon="el-icon-arrow-right" circle
+          style="margin:-25px 0 0 50px;background:rgb(121, 187, 255);color:rgb(225, 228, 229);border:none;"></el-button>
+      </div>
+    </div>
+    <!-- 图形图 -->
+    <div class="statistics-chart" style="border-top:5px solid #eee;">
+      <div class="chart-title">共包含原始点位:{{ originalPoint }} 个</div>
+      <hr style="width:90%" />
+      <div ref="barchart" class="chart" id="barchart" :style="{height:barChartData.length * 120 + 'px'}"></div>
+    </div>
+    <!-- 点位/表号共更好对应总览 -->
+    <pointTabOverview ref="overviewDialog"></pointTabOverview>
+  </div>
+</template>
+
+<script>
+//echarts
+import echarts from "echarts";
+import "echarts/lib/chart/bar";
+import "echarts/lib/component/tooltip";
+import "echarts/lib/component/title";
+
+import {
+  getIntegrateStatisticsToLoop,
+  getIntegrateStatisticsToBar
+} from "@/api/scan/request";
+import pointTabOverview from "./pointTabOverview";
+
+export default {
+  data() {
+    return {
+      //环形图
+      loopChart: null,
+      //条形图
+      barChart: null,
+      //环形图数据
+      loopChartData: [],
+      //条形图数据
+      barChartData: [],
+      //点位-标号功能号数据
+      pointData: {
+        tabFuncNumSum: 0,//总数
+        oneToM: 0,//一对多
+        mToOne: 0,//多对一
+        disConn: 0//可能断数数量
+      },
+      //原始点数量
+      originalPoint: null
+    };
+  },
+  methods: {
+    //加载图表数据
+    loadChart() {
+      //获取环形图数据
+      getIntegrateStatisticsToLoop({}, res => {
+        //设置点位-表号功能号数据
+        this.pointData = {
+          tabFuncNumSum: res.Content[0].Sum,
+          oneToM: res.Content[0].OtoM,
+          mToOne: res.Content[0].MtoO,
+          disConn: res.Content[0].Disconn
+        };
+        //设置环形表数据
+        this.loopChartData = [
+          { value: res.Content[0].RelatedCount, name: "已对实例数量" },
+          { value: res.Content[0].Sum - res.Content[0].RelatedCount, name: "未对应实例数量" }
+        ];
+
+        let that = this;
+        //环形图参数
+        let loopOption = {
+          tooltip: {
+            trigger: "item",
+            formatter: "{a} <br/>{b}: {c} ({d}%)"
+          },
+          color: ['rgb(121, 187, 255)', 'rgb(225, 228, 229)'],
+          legend: {
+            orient: "vertical",
+            x: "5%",
+            y: "top",
+            data: that.loopChartData.map(item => item.name)
+          },
+          graphic: {
+            elements: [
+              {
+                type: "text",
+                left: "center",
+                top: "center",
+                style: {
+                  text: (() => {
+                    let s = 0;
+                    that.loopChartData.map(item => {
+                      s += item["value"];
+                    });
+                    return s + "\n总数";
+                  })(),
+                  textAlign: "center",
+                  fontSize: 20,
+                  fontWeight: 300
+                }
+              }
+            ]
+          },
+          series: [
+            {
+              name: "实例总数",
+              type: "pie",
+              radius: ["50%", "70%"],
+              avoidLabelOverlap: false,
+              legendHoverLink: false,
+              selectedOffset: 0,
+              label:{
+                  color:'rgb(121, 187, 255)',
+              },
+              emphasis: {
+                itemStyle: {
+                  // 高亮时点的颜色。
+                  color: undefined
+                }
+              },
+              data: this.loopChartData
+            }
+          ]
+        };
+
+        setTimeout(() => {
+          //实例化
+          that.loopChart = echarts.init(document.getElementById("loopchart"));
+          //设置参数并加载
+          that.loopChart.setOption(loopOption);
+          //消除高亮
+          that.loopChart.on('mouseover', function (param) {
+            if (param.dataIndex == 1) {
+              loopOption.series[0].emphasis.itemStyle.color = 'rgb(225, 228, 229)';
+              that.loopChart.setOption(loopOption);
+            }
+            else {
+              loopOption.series[0].emphasis.itemStyle.color = 'rgb(121, 187, 255)';
+              that.loopChart.setOption(loopOption);
+            }
+          });
+        }, 100);
+
+      })
+
+      //获取条形图数据
+      getIntegrateStatisticsToBar({}, res => {
+        this.barChartData = res.Content;
+        this.originalPoint = (() => {
+          let sum = 0;
+          this.barChartData.map(item => {
+            sum += item["Sum"];
+          });
+          return sum;
+        })();
+
+        //条形图参数
+        let barOption = {
+          tooltip: {
+            trigger: "axis",
+            axisPointer: {
+              // 坐标轴指示器,坐标轴触发有效
+              type: "shadow" // 默认为直线,可选为:'line' | 'shadow'
+            }
+          },
+          color: ['rgb(121, 187, 255)', 'rgb(225, 228, 229)'],
+          legend: {
+            data: ["已接入", "未接入"]
+          },
+          grid: {
+            left: "3%",
+            right: "4%",
+            bottom: "3%",
+            containLabel: true
+          },
+          xAxis: [
+            {
+              type: "value",
+              position: "top"
+            }
+          ],
+          yAxis: [
+            {
+              type: "category",
+              axisTick: { show: false },
+              data: this.barChartData.map(item => item.Name)
+            }
+          ],
+          series: [
+            {
+              name: "已接入",
+              type: "bar",
+              label: {
+                normal: {
+                  show: true,
+                  position: "inside"
+                }
+              },
+              data: this.barChartData.map(item => item.Relatedall)
+            },
+            {
+              name: "未接入",
+              type: "bar",
+              stack: "总量",
+              label: {
+                normal: {
+                  show: true
+                }
+              },
+              data: this.barChartData.map(item => item.Notrelatedall)
+            }
+          ]
+        };
+
+        /* 条形图高度随数量变化,延时初始化 */
+        let that = this;
+        setTimeout(() => {
+          that.barChart = echarts.init(document.getElementById("barchart"));
+          that.barChart.setOption(barOption);
+        }, 100);
+      });
+    },
+    //点位/表号
+    showOverview() {
+      this.$refs.overviewDialog.loadOverviewData();
+    },
+    init() {
+      this.loadChart();
+    }
+  },
+  mounted() {
+    this.init();
+    //图表随窗口变化
+    let that = this;
+    window.onresize = () => {
+      if (that.loopChart != null)
+        that.loopChart.resize();
+      if (that.barChart != null)
+        that.barChart.resize();
+    };
+  },
+  components: {
+    pointTabOverview
+  }
+};
+</script>
+
+<style lang="less" scoped>
+#integrateStatistics {
+  border-top: 5px solid #eee;
+}
+.statistics-chart {
+  min-height: calc(50% - 3px);
+}
+.chart-title {
+  padding: 5px 5%;
+  font-size: 16px;
+  font-weight: 500;
+}
+.chart {
+  min-height: 200px;
+  height: auto;
+  width: 100%;
+}
+</style>

+ 197 - 0
src/components/point/report/objectInstance.vue

@@ -0,0 +1,197 @@
+<template>
+  <!-- 对象实例 -->
+  <div id="objectInstance" v-loading="loading">
+    <div ref="test1"></div>
+    <div class="obj-item" v-for="form in forms" :key="form.id" :style="{height:drawCanvas? '600px' : '350px'}">
+      <el-form :model="form" label-width="150px">
+        <el-form-item label="对象类型:">
+          {{form.TypeName || '--'}}
+        </el-form-item>
+        <el-form-item label="对象实例本地名称:">
+          {{form.ObjectLocalName || '--'}}
+        </el-form-item>
+        <el-form-item label="对象实例本地编码:">
+          {{form.ObjectLocalCode || '--'}}
+        </el-form-item>
+        <el-form-item label="对象实例ID:">
+          {{form.ObjectID || '--'}}
+        </el-form-item>
+        <el-form-item label="信息点名称:">
+          {{form.InfomationPointName || '--'}}
+        </el-form-item>
+        <el-form-item label="对应值:">
+          {{ reValue || '--'}}
+        </el-form-item>
+        <el-form-item label="对象实例位置图:">
+          <span v-show="!drawCanvas">--</span>
+          <div v-show="drawCanvas" style="border:1px solid rgba(0, 0, 0, 0.2);height:300px;">
+            <canvas v-show="drawCanvas" height="300" width="450" class="instanceMap" :id="form.instanceId" :k="refreshCanvas"></canvas>
+          </div>
+        </el-form-item>
+      </el-form>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import { SGraphyView } from "@saga-web/graphy/lib";
+import { LocationPointScene, DivideFloorScene } from "@saga-web/cad-engine"
+import { SColor } from "@saga-web/draw/lib";
+
+import {
+  getTabFunNumObjInstance, getEquipByEqID, getFloorMsgByFloorID, queryZone
+} from '@/api/scan/request'
+
+export default {
+  data() {
+    return {
+      forms: [],//实例数据
+      views: [],//canvas view
+      scenes: [],//canvas scene
+      loading: true,
+      refreshCanvas: '',//重载canvas组件
+      drawCanvas: false//是否画canvas
+    }
+  },
+  methods: {
+    //加载对象实例
+    loadObjectInstance() {
+      this.loading = true;
+      let pa = {
+        Filters: `MeterFuncid='${this.tabFunNum}';Related='true'`//
+      };
+      let that = this;
+      //获取所有实例信息
+      getTabFunNumObjInstance(pa, res => {
+        that.loading = false;
+        that.forms = res.Content;
+        res.Content.map((item, key) => {
+          //存在实例ID
+          if (item.ObjectID) {
+            that.forms[key].instanceId = item.ObjectID;
+            //设备或者组件
+            if (item.TypeCode == 'Eq' || item.TypeCode == 'Ec') {
+              let pa = {
+                Filters: `EquipID='${item.TypeCode + this.projectId.substring(2) + item.ObjectID}'`
+              }
+              //获取设备信息
+              getEquipByEqID(pa, equipMsg => {
+                if (equipMsg.Content[0] && equipMsg.Content[0].LocationJson && equipMsg.Content[0].FloorId) {
+                  let canvasOption = {
+                    /** 标记的id  */
+                    Id: equipMsg.Content[0].EquipID,
+                    /** 标记的名称  */
+                    Name: equipMsg.Content[0].EquipName,
+                    /** X坐标 */
+                    X: equipMsg.Content[0].LocationJson.X,
+                    /** Y坐标 */
+                    Y: -equipMsg.Content[0].LocationJson.Y
+                  }
+                  this.loadDataToInstanceByFloorID(equipMsg.Content[0].FloorId, key, item.TypeCode, canvasOption);
+                }
+              })
+            }
+            //空间
+            else if (item.TypeCode == 'Sp') {
+              let pa = {
+                data: {
+                  Filters: `RoomID='${item.TypeCode + this.projectId.substring(2) + item.ObjectID}'`
+                },
+                zone: item.SubTypeCode
+              }
+              //获取空间信息
+              queryZone(pa, zoneMsg => {
+                if (zoneMsg.Content[0] && zoneMsg.Content[0].Outline) {
+                  let canvasOption = {
+                    RoomLocalName: zoneMsg.Content[0].RoomLocalName,
+                    OutLine: zoneMsg.Content[0].Outline,
+                    RoomID: zoneMsg.Content[0].RoomID,
+                    Color: new SColor('#F9C3C3')
+                  }
+                  this.loadDataToInstanceByFloorID(zoneMsg.Content[0].FloorId, key, item.TypeCode, canvasOption);
+                }
+              });
+            }
+          }
+        });
+      })
+    },
+    //通过floorid获取信息,后通过floormap获取数据后绘制canvas
+    loadDataToInstanceByFloorID(floorId, key, typecode, options) {
+      let param = {
+        Filters: `FloorId='${floorId}'`
+      }
+      let that = this;
+      //获取楼层信息
+      getFloorMsgByFloorID(param, floorMsg => {
+        //刷新canvas
+        that.refreshCanvas = new Date().getTime();
+        if (!that.views[key]) {
+          that.views[key] = new SGraphyView(`${that.forms[key].instanceId}`)
+        }
+        that.views[key].scene = null;
+        that.scenes[key] = null;
+        //类型
+        if (typecode == 'Eq' || typecode == 'Ec') {
+          that.scenes[key] = new LocationPointScene();
+        }
+        else if (typecode == 'Sp') {
+          that.scenes[key] = new DivideFloorScene();
+        }
+        if (floorMsg.Content[0] && floorMsg.Content[0].StructureInfo && floorMsg.Content[0].StructureInfo.FloorMap) {
+          //获取数据,并加载canvas
+          that.scenes[key].loadUrl(`/image-service/common/file_get?systemId=revit&key=${floorMsg.Content[0].StructureInfo.FloorMap}`).then(() => {
+            that.drawCanvas = true;
+            that.views[key].scene = that.scenes[key];
+            that.scenes[key].isSpaceSelectable = false;
+            if (typecode == 'Eq' || typecode == 'Ec') {
+              that.scenes[key].addMarker(options);
+            }
+            else if (typecode == 'Sp') {
+              that.scenes[key].addZone(options);
+            }
+            that.views[key].fitSceneToView();
+          })
+        }
+        else{
+          that.drawCanvas = false;
+        }
+      });
+    }
+  },
+  mounted() {
+    this.loadObjectInstance();
+  },
+  props: {
+    tabFunNum: String,//表号功能号,
+    reValue: String//对应值
+  },
+  computed: {
+    ...mapGetters('layout', ['projectId'])
+  },
+  watch: {
+    //切换时更新数据
+    tabFunNum() {
+      this.loadObjectInstance();
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+#objectInstance {
+  height: 100%;
+  overflow: auto;
+}
+.instanceMap {
+  min-height: 100px;
+}
+.obj-item {
+  margin: 15px 10px;
+  box-shadow: 0px 4px 10px 0px rgba(0,0,0,0.2);
+  background-color: white;
+  padding: 10px 10px;
+  height: 600px;
+}
+</style>

+ 82 - 0
src/components/point/report/pointTabOverview.vue

@@ -0,0 +1,82 @@
+<template>
+  <!-- 点位/表号共更好对应总览 -->
+  <div id="pointTabOverview">
+    <!-- 对话框 -->
+    <el-dialog title="点位/表号共更好对应总览" :visible.sync="dialogVisiable">
+      <el-tabs v-model="activeName" style="height:600px;overflow:auto;">
+        <!-- 一对多数据 -->
+        <el-tab-pane label="一对多" name="otm">
+          <el-table :data="oTMData" style="width: 100%">
+            <el-table-column prop="Description" label="点位名称" show-overflow-tooltip min-width="100"></el-table-column>
+            <el-table-column prop="Name" label="数据源" show-overflow-tooltip min-width="100"></el-table-column>
+            <el-table-column prop="MeterList" label="表号功能号" show-overflow-tooltip min-width="100">
+              <template slot-scope="scope">
+                <div v-for="(item, index) in scope.row.MeterList" :key="index">{{ item }}</div>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-tab-pane>
+        <!-- 多对一数据 -->
+        <el-tab-pane label="多对一" name="mto">
+          <el-table :data="mTOData" style="width: 100%">
+            <el-table-column prop="Data" label="点位名称" show-overflow-tooltip min-width="100">
+              <template slot-scope="scope">
+                <div v-for="(item, index) in scope.row.Data" :key="index">{{ item.Description }}</div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="Data" label="数据源" show-overflow-tooltip min-width="100">
+              <template slot-scope="scope">
+                <div v-for="(item, index) in scope.row.Data" :key="index">{{ item.Name }}</div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="MeterFunc" label="表号功能号" show-overflow-tooltip min-width="100"></el-table-column>
+          </el-table>
+        </el-tab-pane>
+      </el-tabs>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { tableFuncRelatedOverview } from '@/api/scan/request'
+export default {
+  data() {
+    return {
+      activeName: "otm", //默认展示一对多
+      dialogVisiable: false, //显示对话
+      mTOData: [], //多对一数据
+      oTMData: [] //一对多数据
+    };
+  },
+  methods: {
+    //加载数据
+    loadOverviewData() {
+      tableFuncRelatedOverview({}, res => {
+        this.dialogVisiable = true;
+        //去掉非多对一数据
+        let mD = res.Content[0].MtoO;
+        this.mTOData = [];
+        for (let k in mD) {
+          if (mD[k].length > 1) {
+            this.mTOData.push({
+              "MeterFunc": k,
+              "Data": mD[k]
+            })
+          }
+        };
+        //去掉非一对多数据
+        this.oTMData = [];
+        let oD = res.Content[0].OtoM;
+        for (let k in oD) {
+          if (oD[k].MeterList.length > 1) {
+            this.oTMData.push(oD[k]);
+          }
+        }
+      });
+    }
+  }
+};
+</script>
+
+<style lang="less" scoped>
+</style>

+ 217 - 0
src/components/point/report/tabFunNumOverview.vue

@@ -0,0 +1,217 @@
+<template>
+  <div id="tabFunNumOverview">
+    <!-- 查询 新增 -->
+    <div class="query-area" style="padding:10px;">
+      <el-input :placeholder="`请输入表号功能号`" v-model="tabFunNum" @keyup.enter.native="getOverViewList()" style="width:240px;">
+        <i slot="suffix" class="el-input__icon el-icon-search" @click="getOverViewList()"></i>
+      </el-input>
+      <p style="overflow: hidden;float:right;">
+        <el-button style="height:32px" @click='handleDrawer({},3)'>新增自定义</el-button>
+      </p>
+    </div>
+    <!-- 数据表格 -->
+    <div class="table-area">
+      <el-table :data="tableData" style="width: 100%" height="calc(100% - 32px)" v-loading="loading" :header-cell-style="headerStyle">
+        <el-table-column prop='' label='' show-overflow-tooltip width="30" header-align='center'>
+          <template slot-scope="scope">
+            <el-tooltip v-if="scope.row.DataQuality!=0" content="已断数,请检查" effect="dark" placement="top">
+              <i class="el-icon-warning-outline" style="float:left;margin: 0 5px;color: red;"></i>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+        <el-table-column prop='MeterFunc' label='表号-功能号' show-overflow-tooltip min-width="100" header-align='center'></el-table-column>
+        <el-table-column prop='Data.Data' label='对应值(单位)' show-overflow-tooltip min-width="90" header-align='center'>
+          <template slot-scope="scope">
+            <span style="line-height:29px;">{{ scope.row.Data? scope.row.Data.Data : '' }}</span>
+            <el-button style="padding:7px 15px;float:right;" @click="handleDrawer(scope.row, 0)"><i class="el-icon-s-data"></i></el-button>
+          </template>
+        </el-table-column>
+        <el-table-column prop='Data.Time' label='获取时间' show-overflow-tooltip min-width="130" header-align='center'>
+          <template slot-scope="scope">
+            <span style="line-height:29px;">{{ scope.row.Data? scope.row.Data.Time: '' }}</span>
+            <el-button style="padding:7px 15px;float:right;" @click="refreshThisRow(scope.row)"><i class="el-icon-refresh"></i></el-button>
+          </template>
+        </el-table-column>
+        <el-table-column prop='RelatedPoint' label='涉及子系统点位(数据来源)' show-overflow-tooltip min-width="150" align='center'>
+          <template slot-scope="scope">
+            <span style="display:inline-block;width:16px;line-height:29px;">{{ scope.row.RelatedPoint }}</span>
+            <p style="width:55.33px;display:inline-block;">
+              <el-button v-if="scope.row.RelatedPoint" style="padding:7px 15px;margin-left:10px;" @click="handleDrawer(scope.row, 1)"><i
+                  class="el-icon-coin"></i></el-button>
+            </p>
+          </template>
+        </el-table-column>
+        <el-table-column prop='RelatedInstance' label='涉及的对象实例(应用到)' show-overflow-tooltip min-width="150" align='center'>
+          <template slot-scope="scope">
+            <span style="display:inline-block;width:16px;line-height:29px;">{{ scope.row.RelatedInstance }}</span>
+            <p style="width:55.33px;display:inline-block;">
+              <el-button v-if="scope.row.RelatedInstance" style="padding:7px 15px;margin-left:10px;" @click="handleDrawer(scope.row, 2)"><i
+                  class="el-icon-coin"></i></el-button>
+            </p>
+          </template>
+        </el-table-column>
+      </el-table>
+      <!-- 分页 -->
+      <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage" :page-sizes="pageSizes"
+        :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="allTableData.length"
+        style="float:right;margin-top:10px;padding:2px 5px;">
+      </el-pagination>
+    </div>
+    <!-- 对话框和抽屉统一放在drawers中 -->
+    <!-- 对话框 -->
+    <el-dialog :title="'< ' + drawers[0].objId + ' > 的历史数据'" :visible.sync="drawers[0].drawer">
+      <historyChart :tabFunNum='drawers[0].objId'></historyChart>
+    </el-dialog>
+    <!-- 抽屉 -->
+    <el-drawer :title="'< ' + drawers[1].objId + ' > 的子系统点位'" :visible.sync="drawers[1].drawer" :direction="drawers[1].direction" size="35%">
+      <dataSource :tabFunNum='drawers[1].objId'></dataSource>
+    </el-drawer>
+    <el-drawer :title="'< ' + drawers[2].objId + ' > 的对象实例'" :visible.sync="drawers[2].drawer" :direction="drawers[2].direction" size="35%">
+      <objectInstance :tabFunNum='drawers[2].objId' :reValue='drawers[2].value'></objectInstance>
+    </el-drawer>
+    <el-dialog title="新增表号功能号" :visible.sync="drawers[3].drawer">
+      <addTabFunNum @closeDrawer="closeDrawer()" @reloadData="reloadData()"></addTabFunNum>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { Message } from 'element-ui';
+import {
+  getTabFunNumOverview
+} from '@/api/scan/request'
+import historyChart from './historyChart'
+import dataSource from './dataSource'
+import objectInstance from './objectInstance'
+import addTabFunNum from './addTabFunNum'
+export default {
+  data() {
+    return {
+      //表格头样式
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      },
+      allTableData: [],//所有表格数据
+      pageSizes: [10, 20, 50, 100],
+      pageSize: 50,
+      currentPage: 1,
+      loading: false,//加载
+      tabFunNum: null,//表号功能号
+      //抽屉
+      drawers: [
+        { drawer: false, direction: 'rtl', objId: '' },
+        { drawer: false, direction: 'rtl', objId: '' },
+        { drawer: false, direction: 'rtl', objId: '', value: '' },
+        { drawer: false, direction: 'rtl', objId: '' }
+      ]
+    }
+  },
+  methods: {
+    //抽屉处理
+    handleDrawer(row, index) {
+      if (index == 2 || index == 1) {
+        //实例数量大于0才能打开
+        if ((row.RelatedInstance > 0 && index == 2) || (row.RelatedPoint > 0 && index == 1)) {
+          this.drawers[index].value = row.Data ? row.Data.Data : '';
+          this.drawers[index].objId = row.MeterFunc;
+          this.drawers[index].drawer = true;
+        }
+      }
+      else {
+        if (index != 3)
+          this.drawers[index].objId = row.MeterFunc;
+        this.drawers[index].drawer = true;
+      }
+    },
+    //获取统计数据
+    getOverViewList() {
+      this.loading = true;
+      getTabFunNumOverview({ MeterFunc: this.tabFunNum }, res => {
+        this.allTableData = res.Content;
+        this.loading = false;
+      });
+    },
+    //刷新当前行数据
+    refreshThisRow(row) {
+      let index = this.tableData.indexOf(row);
+      let pa = {
+        MeterFunc: row.MeterFunc
+      }
+      getTabFunNumOverview(pa, res => {
+        if (res.Content[0].Data) {
+          this.tableData[index].Data.Data = res.Content[0].Data.Data;
+          this.tableData[index].Data.Time = res.Content[0].Data.Time;
+        }
+        this.tableData[index].DataQuality = res.Content[0].DataQuality;
+        this.tableData[index].RelatedInstance = res.Content[0].RelatedInstance;
+        this.tableData[index].RelatedPoint = res.Content[0].RelatedPoint;
+        Message.success('已刷新');
+      });
+    },
+    //分页更换size
+    handleSizeChange(val) {
+      this.pageSize = val;
+    },
+    //分页更换页
+    handleCurrentChange(val) {
+      this.currentPage = val;
+    },
+    //子组件关闭抽屉
+    closeDrawer() {
+      this.drawers[3].drawer = false;
+    },
+    //新建自定义后重载页面
+    reloadData() {
+      this.$emit('reloadData');
+    },
+    init() {
+      this.getOverViewList();
+    }
+  },
+  mounted() {
+    this.init();
+  },
+  computed: {
+    //根据分页,获取要展示的tableData
+    tableData: function () {
+      return this.allTableData.slice(
+        (this.currentPage - 1) * this.pageSize,
+        (this.currentPage * this.pageSize < this.allTableData.length) ? this.currentPage * this.pageSize : this.allTableData.length);
+
+    }
+  },
+  components: {
+    historyChart,
+    dataSource,
+    objectInstance,
+    addTabFunNum
+  }
+}
+</script>
+
+<style lang="less" scoped>
+#tabFunNumOverview {
+  border-top: 5px solid #eee;
+  height: calc(100% - 5px);
+  width: 100%;
+  overflow: hidden;
+}
+.table-area {
+  height: calc(100% - 72px);
+  padding: 0px 10px 10px 10px;
+}
+.table-area i {
+  text-align: right;
+  font-size: 12px;
+  cursor: pointer;
+  float: right;
+}
+/deep/ .el-drawer__body {
+  height: 90%;
+}
+/deep/ .el-dialog__body {
+  padding-bottom:20px;
+}
+</style>

+ 72 - 29
src/views/point/report/index.vue

@@ -1,36 +1,79 @@
 <template>
-    <div>
-      <das-board>
-        <template v-slot:plan>
-          <span>{{plan?plan:"yyyy-mm-dd"}}</span>
-        </template>
-        <template v-slot:finish>
-          <span>{{finish?finish:"yyyy-mm-dd"}}</span>
-        </template>
-        <template v-slot:onLine>
-          <span>{{onLine?onLine:"yyyy-mm-dd"}}</span>
-        </template>
-        <template v-slot:explain>
-          <span>{{explain?explain:"yyyy-mm-dd"}}</span>
-        </template>
-      </das-board>
+  <div>
+    <!-- 系统集成统计页面 -->
+    <div class="contain-block" style="width:calc(30% - 15px);margin-right:15px;min-width:385px;">
+      <span class="contain-title-leftblock">系统集成统计</span>
+      <div class="contain-data">
+        <integrateStatistics ref="chart" style="height: calc(100% - 5px);" :key="refresh"></integrateStatistics>
+      </div>
     </div>
+    <!-- 表号功能号总览页面 -->
+    <div class="contain-block meterFunc">
+      <span class="contain-title-leftblock">表号功能号总览</span>
+      <div class="contain-data">
+        <tabFunNumOverview ref="table" :key="refresh" @reloadData="reloadData()"></tabFunNumOverview>
+      </div>
+    </div>
+  </div>
 </template>
 
 <script>
-import dasBoard from "@/views/dasboard/index";
+import { mapGetters } from 'vuex'
+import integrateStatistics from '@/components/point/report/integrateStatistics'
+import tabFunNumOverview from '@/components/point/report/tabFunNumOverview'
+
 export default {
-    components: {
-      dasBoard
-    },
-    data() {
-        return {
-          plan: "2019-8-5",
-          finish: "2019-9-24",
-          onLine: "2019-10-31",
-          explain: "表号功能号检索查看,点位信息维护"
-        }
-    },
-    mounted() {}
+  components: {
+    integrateStatistics,
+    tabFunNumOverview
+  },
+  computed: {
+    ...mapGetters('layout', ['projectId']),
+  },
+  data() {
+    return {
+      refresh: ''//刷新组件
+    }
+  },
+  methods: {
+    //子组件中的新建完成后刷新
+    reloadData() {
+      this.refresh = new Date().getTime();
+    }
+  },
+  watch: {
+    //监听项目变化
+    projectId() {
+      this.refresh = new Date().getTime();
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.contain-block {
+  float: left;
+  height: 100%;
+  background: white;
+  width: 70%;
+}
+.contain-title-leftblock {
+  height: 30px;
+  line-height: 30px;
+  border-left: 8px solid black;
+  display: inline-block;
+  margin: 8px 8px;
+  font-weight: 600;
+  padding-left: 8px;
+  cursor: default;
+}
+.contain-data {
+  overflow: auto;
+  height: calc(100% - 46px);
+}
+@media screen and (max-width: 1600px){
+  .meterFunc{
+    width:calc(100% - 400px);
+  }
 }
-</script>
+</style>