浏览代码

Merge branch 'dev' of http://39.106.8.246:3003/web/ibms into dev

shaun-sheep 4 年之前
父节点
当前提交
4dfbf495da
共有 43 个文件被更改,包括 1265 次插入30 次删除
  1. 1 1
      package.json
  2. 13 0
      src/api/model/file.js
  3. 14 0
      src/api/topo/index.js
  4. 二进制
      src/assets/image/model/arrowBlue.png
  5. 二进制
      src/assets/image/model/arrowGray.png
  6. 二进制
      src/assets/image/model/arrowGreen.png
  7. 二进制
      src/assets/image/model/columnBlue.png
  8. 二进制
      src/assets/image/model/columnGray.png
  9. 二进制
      src/assets/image/model/columnGreen.png
  10. 二进制
      src/assets/image/model/delModelBlue.png
  11. 二进制
      src/assets/image/model/delModelGray.png
  12. 二进制
      src/assets/image/model/downJsonBlue.png
  13. 二进制
      src/assets/image/model/downJsonGray.png
  14. 二进制
      src/assets/image/model/downJsonGreen.png
  15. 二进制
      src/assets/image/model/downModelBlue.png
  16. 二进制
      src/assets/image/model/downModelGray.png
  17. 二进制
      src/assets/image/model/downModelGreen.png
  18. 二进制
      src/assets/image/model/rightDownBlue.png
  19. 二进制
      src/assets/image/model/rightDownGray.png
  20. 二进制
      src/assets/image/model/rightDownGreen.png
  21. 二进制
      src/assets/image/model/upJsonBlue.png
  22. 二进制
      src/assets/image/model/upJsonGray.png
  23. 二进制
      src/assets/image/model/upJsonGreen.png
  24. 二进制
      src/assets/image/model/upModelBlue.png
  25. 二进制
      src/assets/image/model/upModelGray.png
  26. 二进制
      src/assets/image/model/upModelGreen.png
  27. 二进制
      src/assets/image/model/waitingAnlBlue.png
  28. 二进制
      src/assets/image/model/waitingAnlGray.png
  29. 二进制
      src/assets/image/model/waitingAnlGreen.png
  30. 二进制
      src/assets/image/model/waitingManageBlue.png
  31. 二进制
      src/assets/image/model/waitingManageGray.png
  32. 二进制
      src/assets/image/model/waitingManageGreen.png
  33. 二进制
      src/assets/style/iconfont/iconfont.eot
  34. 二进制
      src/assets/style/iconfont/iconfont.ttf
  35. 二进制
      src/assets/style/iconfont/iconfont.woff
  36. 4 0
      src/components/config_point/location_flag.vue
  37. 20 2
      src/components/config_point/step3_edit/index.vue
  38. 22 12
      src/components/model/file/floorTable.vue
  39. 135 0
      src/components/model/file/nodeDialog.vue
  40. 86 0
      src/components/model/file/pathCard.vue
  41. 7 0
      src/router/system.js
  42. 90 15
      src/views/business_space/dataUtil/topology.vue
  43. 873 0
      src/views/model/file/pathcontrol/index.vue

+ 1 - 1
package.json

@@ -23,7 +23,7 @@
     "@saga-web/cad-engine": "2.0.560",
     "@saga-web/draw": "2.1.75",
     "@saga-web/graphy": "2.1.47",
-    "@saga-web/topology": "1.0.76",
+    "@saga-web/topology": "1.0.77",
     "axios": "^0.18.0",
     "echarts": "^4.1.0",
     "el-cascader-multi": "^1.1.8",

+ 13 - 0
src/api/model/file.js

@@ -2,6 +2,7 @@ import httputils from '@/api/scan/httpUtil'
 import { Message } from 'element-ui';
 import axios from 'axios'
 const baseUrl = '/modelapi';
+const revitUrl = '/schedulerapi';
 
 let api = {
     // 新建模型文件夹
@@ -329,4 +330,16 @@ export function querySyncLogCount(param, success) {
 export function queryFileByModelId(param, success) {
     let url = `${baseUrl}/model-file/query`;
     httputils.postJson(url, param, success)
+}
+
+// 模型流程监控
+export function modelPathControl(param, success) {
+    let url = `${baseUrl}/model-monitor/query`;
+    httputils.postJson(url, param, success)
+}
+
+// 模型流程监控-获取待分配模型数量
+export function unassignQuery(param, success) {
+    let url = `${revitUrl}/task/query`;
+    httputils.postJson(url, param, success)
 }

+ 14 - 0
src/api/topo/index.js

@@ -0,0 +1,14 @@
+import httputils from '@/api/scan/httpUtil'
+const baseUrl = '/api';
+
+// 创建拓扑图
+export function topoCreate(param, success) {
+  let url = `${baseUrl}/datacenter/topo/create`;
+  httputils.postJson(url, param, success)
+}
+
+// 查询拓扑图
+export function topoQuery(param, success) {
+  let url = `${baseUrl}/datacenter/topo/query`;
+  httputils.postJson(url, param, success)
+}

二进制
src/assets/image/model/arrowBlue.png


二进制
src/assets/image/model/arrowGray.png


二进制
src/assets/image/model/arrowGreen.png


二进制
src/assets/image/model/columnBlue.png


二进制
src/assets/image/model/columnGray.png


二进制
src/assets/image/model/columnGreen.png


二进制
src/assets/image/model/delModelBlue.png


二进制
src/assets/image/model/delModelGray.png


二进制
src/assets/image/model/downJsonBlue.png


二进制
src/assets/image/model/downJsonGray.png


二进制
src/assets/image/model/downJsonGreen.png


二进制
src/assets/image/model/downModelBlue.png


二进制
src/assets/image/model/downModelGray.png


二进制
src/assets/image/model/downModelGreen.png


二进制
src/assets/image/model/rightDownBlue.png


二进制
src/assets/image/model/rightDownGray.png


二进制
src/assets/image/model/rightDownGreen.png


二进制
src/assets/image/model/upJsonBlue.png


二进制
src/assets/image/model/upJsonGray.png


二进制
src/assets/image/model/upJsonGreen.png


二进制
src/assets/image/model/upModelBlue.png


二进制
src/assets/image/model/upModelGray.png


二进制
src/assets/image/model/upModelGreen.png


二进制
src/assets/image/model/waitingAnlBlue.png


二进制
src/assets/image/model/waitingAnlGray.png


二进制
src/assets/image/model/waitingAnlGreen.png


二进制
src/assets/image/model/waitingManageBlue.png


二进制
src/assets/image/model/waitingManageGray.png


二进制
src/assets/image/model/waitingManageGreen.png


二进制
src/assets/style/iconfont/iconfont.eot


二进制
src/assets/style/iconfont/iconfont.ttf


二进制
src/assets/style/iconfont/iconfont.woff


+ 4 - 0
src/components/config_point/location_flag.vue

@@ -97,6 +97,10 @@
                     this.$message("请确定输入字符不为空")
                     return false
                 }
+                let flag = this.queryLocaltionArr.map(item => item.Name).indexOf(param.Name) > -1;
+                if (flag) {
+                    return this.$message.warning('已添加过此标签');
+                }
                 addLocaltionFlag(param,res => {
                     this.queryData()
                     this.$message.success("添加成功")

+ 20 - 2
src/components/config_point/step3_edit/index.vue

@@ -131,7 +131,8 @@ export default {
       formulaHandleShow: {},
       splitHandleShow: {},
       dictionaryData: [],
-      typeList: []
+      typeList: [],
+      pointToRelationID: {}, //保存信息点->relationid map
     }
   },
   props: {
@@ -253,6 +254,10 @@ export default {
           //设备-部件-空间
           eachData.EquipmentTypeCode = temp[1]
           eachData.EquipmentType = tempNames[1]
+          let key = `${eachData.TypeCode}-${eachData.EquipmentTypeCode}-${eachData.InfomationPointCode}`
+          if (this.pointToRelationID[key]) {
+            eachData.Id = this.pointToRelationID[key]
+          }
         } else if (temp.length == 4) {
           eachData.SpecialtyCode = temp[1]
           eachData.Specialty = tempNames[1]
@@ -260,6 +265,15 @@ export default {
           eachData.System = tempNames[2]
           eachData.EquipmentTypeCode = eachData.SystemCode  //为了配置从动参取值存储
           eachData.EquipmentType = eachData.System
+          let key = `${eachData.TypeCode}-${eachData.SpecialtyCode}-${eachData.SystemCode}-${eachData.InfomationPointCode}`
+          if (this.pointToRelationID[key]) {
+            eachData.Id = this.pointToRelationID[key]
+          }
+        } else if (temp.length == 2) {
+          let key = `${eachData.TypeCode}-${eachData.InfomationPointCode}`
+          if (this.pointToRelationID[key]) {
+            eachData.Id = this.pointToRelationID[key]
+          }
         }
         let type = t.DataRuleType;
         updateParams.data.Content[0].EquipmentMark = eachData.EquipmentMark
@@ -491,15 +505,19 @@ export default {
       if (length) {
         var data = val.RelationList[0]
         let dict = [data.SpecialtyCode, data.SystemCode, data.EquipmentTypeCode]
-        //回显字典
+        //回显字典--并保存信息点->relationid map
+        this.pointToRelationID = {}
         let tempArr = val.RelationList.map(t => {
           let eachData = [];
           if (t.TypeCode == 'Eq' || t.TypeCode == 'Ec' || t.TypeCode == 'Sp') {
             eachData = [t.TypeCode, t.EquipmentTypeCode, t.InfomationPointCode]
+            this.pointToRelationID[`${t.TypeCode}-${t.EquipmentTypeCode}-${t.InfomationPointCode}`] = t.Id
           } else if (t.TypeCode == 'Sy') {
             eachData = [t.TypeCode, t.SpecialtyCode, t.SystemCode, t.InfomationPointCode]
+            this.pointToRelationID[`${t.TypeCode}-${t.SpecialtyCode}-${t.SystemCode}-${t.InfomationPointCode}`] = t.Id
           } else {
             eachData = [t.TypeCode, t.InfomationPointCode]
+            this.pointToRelationID[`${t.TypeCode}-${t.InfomationPointCode}`] = t.Id
           }
           return eachData;
         })

+ 22 - 12
src/components/model/file/floorTable.vue

@@ -3,10 +3,14 @@
     <el-table ref="filterTable" :data="tableData" style="width: 100%" height="100%" :header-cell-style="{background:'#d9d9d9',color:'#2b2b2b'}">
       <el-table-column prop="FloorName" label="模型文件" width="180">
         <template slot-scope="scope">
-          <i v-if="scope.row.Status == 4" class="iconfont icon-yun--tianchong" style="color:#67C23A;cursor:pointer;fontSize:18px;" title="模型校验完成..."></i>
-          <i v-else-if="scope.row.Status == 31" class="iconfont icon-yun--tianchong1" style="color:#F56C6C;cursor:pointer;fontSize:18px;" title="同步到数据中心出问题..."></i>
-          <i v-else-if="scope.row.Status == 21" class="iconfont icon-yun--tianchong1" style="color:#F56C6C;cursor:pointer;fontSize:18px;" title="模型数据导出出问题..."></i>
-          <i v-else class="iconfont icon-yun--tianchong2" style="color:#E6A23C;cursor:pointer;fontSize:18px;" title="模型校验进行中..."></i>
+          <i v-if="scope.row.Status == 4" class="iconfont icon-yun--tianchong" style="color:#67C23A;cursor:pointer;fontSize:18px;" title="模型校验完成..."
+            @click="toPathControl(scope.row)"></i>
+          <i v-else-if="scope.row.Status == 31" class="iconfont icon-yun--tianchong1" style="color:#F56C6C;cursor:pointer;fontSize:18px;"
+            title="同步到数据中心出问题..." @click="toPathControl(scope.row)"></i>
+          <i v-else-if="scope.row.Status == 21" class="iconfont icon-yun--tianchong1" style="color:#F56C6C;cursor:pointer;fontSize:18px;"
+            title="模型数据导出出问题..." @click="toPathControl(scope.row)"></i>
+          <i v-else class="iconfont icon-yun--tianchong2" style="color:#E6A23C;cursor:pointer;fontSize:18px;" title="模型校验进行中..."
+            @click="toPathControl(scope.row)"></i>
           <span style="margin-left: 10px">{{ scope.row.FloorName }}</span>
         </template>
       </el-table-column>
@@ -26,14 +30,9 @@
             <el-button title="替换模型" type="primary" size="mini" class="iconfont icon-replace" @click="repliaceModel(scope.row)"></el-button>
             <el-button title="查看版本日志" type="primary" size="mini" class="iconfont icon-Log" @click="queryModelLog(scope.row)"></el-button>
           </div>
-          <div
-            :class="['upLoad-loading']"
-            v-show="scope.row.Status != 4">
+          <div :class="['upLoad-loading']" v-show="scope.row.Status != 4">
             <div class="progress">
-              <el-progress
-                :text-inside="false"
-                :stroke-width="20" :percentage="100"
-                :color="scope.row.Status?'#909399':'#67C23A'"></el-progress>
+              <el-progress :text-inside="false" :stroke-width="20" :percentage="100" :color="scope.row.Status?'#909399':'#67C23A'"></el-progress>
             </div>
             <div class="progress-right">
               <span v-if="!scope.row.Status">上传中...</span>
@@ -121,7 +120,7 @@ export default {
     },
     // 下载模型文件
     downloadModel(item) {
-      let url = item.Url.match(/(\/image-service\S*)$/g)?item.Url.match(/(\/image-service\S*)$/g)[0]:''
+      let url = item.Url.match(/(\/image-service\S*)$/g) ? item.Url.match(/(\/image-service\S*)$/g)[0] : ''
       if (url) {
         let a = document.createElement("a");
         a.href = url;
@@ -144,6 +143,17 @@ export default {
           type: "error"
         });
       }
+    },
+    // 跳转至模型流程处理监控
+    toPathControl(row) {
+      this.$router.push({
+        path: '/model/path',
+        query: {
+          Id: row.CurrentModelId,
+          Size: row.Size,
+          OriginalName: row.OriginalName
+        }
+      })
     }
   },
   watch: {

+ 135 - 0
src/components/model/file/nodeDialog.vue

@@ -0,0 +1,135 @@
+<template>
+  <el-dialog :title="title" :visible.sync="dialogVisible" width="500px" id="nodeDialog">
+    <div class="node-des">
+      <p>节点检查说明</p>
+      <div class="gray-border">
+        <div v-if='checkType=="firstCheck"||checkType=="secondCheck"'>
+          <p>强制检查项</p>
+          <p v-for="(t,i) in check[checkType].checkList" :key='i'>
+            <i class="el-icon-check" v-if="!t.check"></i>
+            <i class="el-icon-close" v-else></i>
+            {{t.name}}
+          </p>
+          <p>非强制检查项</p>
+          <p v-for="(t,i) in check[checkType].notCheckList" :key='-i-1'>
+            <i class="el-icon-check" v-if="!t.check"></i>
+            <i class="el-icon-close" v-else></i>
+            {{t.name}}
+          </p>
+        </div>
+      </div>
+    </div>
+    <div class="result-des" v-if="0">
+      <p>处理结果</p>
+      <div class="gray-border"></div>
+    </div>
+    <div class="err-des">
+      <p>错误说明</p>
+      <div>{{errMsg}}</div>
+    </div>
+  </el-dialog>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      dialogVisible: false,
+      title: '节点名称',
+      check: {
+        firstCheck: {
+          checkList: [
+            { name: '楼层平面图命名规范检查', check: false },
+            { name: '项目长度单位检查', check: false },
+          ],
+          notCheckList: [
+            { name: '楼层缺失检查', check: false },
+            { name: '构件范围检查', check: false },
+            { name: '设备族编码检查', check: false },
+            { name: '部件所在位置检查', check: false },
+            { name: '柱边界检查', check: false },
+            { name: '连接件检查', check: false },
+            { name: '系统类型名称检查', check: false },
+            { name: '未在空间中的设备', check: false },
+            { name: '管段检查', check: false },
+            { name: '管网及相关设备检查', check: false },
+            { name: 'Revit族参数完整性检查', check: false },
+            { name: 'xyz坐标重叠检查', check: false }
+          ],
+        },
+        secondCheck: {
+          checkList: [
+            { name: '楼层标高与楼层顺序号检查', check: false, value: 'LevelCheck' },
+            { name: '轴网检查', check: false, value: 'GridCheck' }
+          ],
+          notCheckList: [],
+        }
+      },
+      errMsg: '',
+      checkType: ''
+    };
+  },
+  methods: {
+    showDialog(msg, type) {
+      this.errMsg = msg.ErrorMsg || '';
+      this.checkType = type || '';
+      if (type) {
+        this.check[type].checkList.forEach(t => {
+          if (t.value && t.value == 'GridCheck') {
+            t.check = msg.GridCheck || false
+          }
+          if (t.value && t.value == 'LevelCheck') {
+            t.check = msg.LevelCheck || false
+          }
+        })
+      }
+      this.dialogVisible = true;
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+#nodeDialog {
+  .node-des,
+  .result-des {
+    color: #89969f;
+    & > div {
+      min-height: 50px;
+      padding: 5px;
+      p {
+        font-size: 12px;
+        i {
+          margin: 0 5px 0 0;
+        }
+      }
+    }
+    & > p {
+      margin: 5px 0;
+    }
+  }
+  .err-des {
+    color: #ff6660;
+    & > div {
+      border: 1px solid #ff6660;
+      min-height: 50px;
+    }
+  }
+  .gray-border {
+    border: 1px solid #dedee0;
+  }
+  .red-border {
+    border: 1px solid #ff6660;
+  }
+  .el-icon-check {
+    font-size: 14px;
+    color: #4cba38;
+  }
+  .el-icon-close {
+    font-size: 14px;
+    color: #ff6660;
+  }
+  /deep/ .el-dialog__body {
+    max-height: 400px;
+    overflow-y: auto;
+  }
+}
+</style>

+ 86 - 0
src/components/model/file/pathCard.vue

@@ -0,0 +1,86 @@
+<template>
+  <div
+    :class="{'pathCard':true,'borderB':data.BeginTime&&!data.EndTime,'borderY':!data.EndTime&&!data.HasError&&data.HasRetry,'borderR':!data.EndTime&&data.HasError}"
+    @click="cardClick">
+    <div class="path-title">
+      <i v-if="!data.BeginTime" class="iconfont icon-iconfontgengduo" style="color:#333333"></i>
+      <i v-else-if="data.BeginTime&&!data.EndTime" class="iconfont icon-conduct" style="color:#409eff"></i>
+      <i v-else class="el-icon-success" style="color:#67C23A"></i>
+      {{title}}
+      <i v-if="data.HasError" class="iconfont icon-Error pos" style="color:#ff7c77"></i>
+      <i v-else-if="data.HasRetry" class="iconfont icon-trouble pos" style="color:#fcc636"></i>
+    </div>
+    <div class="path-content">
+      <slot></slot>
+      <p v-if="!isCustomize">耗时: {{data.TakeTime||'--'}}</p>
+      <p v-if="!isCustomize">开始时间: {{data.BeginTime||'--'}}</p>
+      <p v-if="!isCustomize">结束时间: {{data.EndTime||'--'}}</p>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  props: {
+    title: {
+      type: String,
+      default: '提示'
+    },
+    data: {
+      type: Object,
+      default: {}
+    },
+    isCustomize: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+    }
+  },
+  methods: {
+    cardClick() {
+      this.$emit('click', this.data, this.title);
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+.pathCard {
+  width: 296px;
+  height: 144px;
+  border: 1px solid transparent;
+  box-shadow: 0 2px 11px 0 rgba(0, 0, 0, 0.1);
+  border-radius: 4px;
+  &.borderY {
+    border-color: #fcc636;
+  }
+  &.borderR {
+    border-color: #ff7c77;
+  }
+  &.borderB {
+    border-color: #409eff;
+  }
+  .path-title {
+    position: relative;
+    background-color: #f3f5f6;
+    font-size: 14px;
+    padding: 5px 10px;
+    i {
+      margin-right: 5px;
+      &.pos {
+        position: absolute;
+        top: -1px;
+        right: 18px;
+        font-size: 24px;
+        line-height: 1;
+      }
+    }
+  }
+  .path-content {
+    font-size: 12px;
+    padding: 4px 10px 0;
+    color: #acb5bb;
+  }
+}
+</style>

+ 7 - 0
src/router/system.js

@@ -12,6 +12,7 @@ import buildUser from '@/views/ready/appuser'
 import repetitionGraphy from '@/views/ready/buildfloor/repetitionGraphy'
 /**模型管理 */
 import modelFile from '@/views/model/file'
+import pathControl from '@/views/model/file/pathcontrol'
 import modelReport from '@/views/model/report'
 import deleted from '@/views/model/report/deleted'
 import supplement from '@/views/model/report/supplement'
@@ -165,6 +166,12 @@ export default [{
                 meta: { keepAlive: false, breadcrumbs: [{ label: '模型管理', path: '/model/file' }, { label: '模型文件管理' }] }
             },
             {
+                path: 'path',
+                name: 'pathControl',
+                component: pathControl,
+                meta: { keepAlive: false, breadcrumbs: [{ label: '模型管理', path: '/model/file' }, { label: '模型文件管理', path: '/model/file' }, { label: '模型后台处理监控' }] }
+            },
+            {
                 path: 'report',
                 name: 'modelReport',
                 component: modelReport,

文件差异内容过多而无法显示
+ 90 - 15
src/views/business_space/dataUtil/topology.vue


+ 873 - 0
src/views/model/file/pathcontrol/index.vue

@@ -0,0 +1,873 @@
+<template>
+  <div id="path-control" v-loading="loading">
+    <el-row class="title-time">
+      <div style="width:220px">
+        <span>模型总耗时:</span>
+        <span>{{allTakeTime}}</span>
+      </div>
+      <div style="width:250px">
+        <span>模型开始上传时间:</span>
+        <span>{{UploadState.BeginTime}}</span>
+      </div>
+      <div style="width:250px">
+        <span>模型处理完成时间:</span>
+        <span>{{SaveLog.EndTime}}</span>
+      </div>
+    </el-row>
+    <el-row class="path-pic">
+      <div id="path-container">
+        <div class="first-column column">
+          <el-row id="baseServer">
+            <div class="updown shadow-box">
+              <div style="background:#b8c5d0;height:20px;"></div>
+              <div style="text-align:center;margin-top: 15px">
+                <i class="el-icon-monitor" style="color:#b8c5d0;font-size:60px"></i>
+                <p style="margin-top:10px;color:#b8c5d0">上传下载功能</p>
+              </div>
+              <img v-if="!UploadState.BeginTime" class="status row-status" src="@/assets/image/model/arrowGray.png" />
+              <img v-else-if="UploadState.BeginTime&&!UploadState.EndTime" class="status row-status" src="@/assets/image/model/arrowBlue.png" />
+              <img v-else class="status row-status" src="@/assets/image/model/arrowGreen.png" />
+            </div>
+            <div class="shadow-box mid-transfer">
+              <div class="first-title">
+                <i class="el-icon-success" style="color:#67C23A"></i>模型中转站
+              </div>
+              <div class="first-content">
+                <p>模型文件存储于OSS服务器</p>
+              </div>
+              <img v-if="!SchedulerCheck.BeginTime" class="status row-waiting-manage" src="@/assets/image/model/waitingManageGray.png" />
+              <img v-else-if="SchedulerCheck.BeginTime&&!SchedulerCheck.EndTime" class="status row-waiting-manage"
+                src="@/assets/image/model/waitingManageBlue.png" />
+              <img v-else class="status row-waiting-manage" src="@/assets/image/model/waitingManageGreen.png" />
+
+              <img v-if="!UploadState.BeginTime" class="status up-model" src="@/assets/image/model/upModelGray.png" />
+              <img v-else-if="UploadState.BeginTime&&!UploadState.EndTime" class="status up-model" src="@/assets/image/model/upModelBlue.png" />
+              <img v-else class="status up-model" src="@/assets/image/model/upModelGreen.png" />
+
+              <!-- 调度器1 -->
+              <div class="path-tips shadow-box" style="top:67px;left:291px;" @click="getNodeDes"
+                v-if='SchedulerCheck.BeginTime&&!SchedulerCheck.EndTime'>
+                <i class="el-icon-error" v-if="SchedulerCheck.HasError"></i>
+                <i class="el-icon-warning" v-else-if="SchedulerCheck.HasRetry"></i>
+                <p>耗时: {{SchedulerCheck.TakeTime||'--'}}</p>
+                <!-- <p>平均上传速度: 1M/s</p> -->
+                <p>开始时间: {{SchedulerCheck.BeginTime||'--'}}</p>
+                <p v-if="!SchedulerCheck.EndTime">待分配模型数量: {{waitAssign}}</p>
+                <p v-else>结束时间: {{SchedulerCheck.EndTime||'--'}}</p>
+              </div>
+            </div>
+            <p style="float:left;width:100%;text-align:center;margin-top:73px;color:#acb5bb;font-size:12px;">本地电脑主机</p>
+          </el-row>
+          <!-- 上传模型文件 -->
+          <div class="path-tips shadow-box" style="top:189px;left:190px;" @click="getNodeDes">
+            <i class="el-icon-error" v-if="UploadState.HasError"></i>
+            <i class="el-icon-warning" v-else-if="UploadState.HasRetry"></i>
+            <p>耗时: {{UploadState.TakeTime||'--'}}</p>
+            <p>平均上传速度: {{UploadStateSpeed}}</p>
+            <p>开始时间: {{UploadState.BeginTime||'--'}}</p>
+            <p>结束时间: {{UploadState.EndTime||'--'}}</p>
+          </div>
+        </div>
+        <div class="second-column column">
+          <div>
+            <div id="ossServer" class="shadow-box">
+              <div style="background:#b8c5d0;height:20px;"></div>
+              <el-row class="server-content">
+                <div style="text-align:center;width:100px" class="sm-box">
+                  <i class="iconfont icon-OSSserver" style="color:#b8c5d0;font-size:50px;"></i>
+                  <p style="margin:18px 0 0;color:#b8c5d0;">oss服务器</p>
+                </div>
+                <el-row class="sm-box">
+                  <div class="image">
+                    <i class="iconfont icon-revit" style="color:#dee6ec;font-size:60px;background:#fff"></i>
+                  </div>
+                  <div class="fixed">
+                    <p :title="OriginalName">模型文件名称{{OriginalName}}</p>
+                    <p style="color:#8d9aa3">模型文件大小: {{(Size/1000/1024).toFixed(1)}}M</p>
+                    <p style="color:#8d9aa3">上传时间: {{UploadState.EndTime||'--'}}</p>
+                  </div>
+                </el-row>
+                <el-row class="sm-box">
+                  <div class="image">
+                    <i class="iconfont icon-json" style="color:#dee6ec;font-size:60px;background:#fff"></i>
+                  </div>
+                  <div class="fixed">
+                    <p>{{OriginalName}} json数据压缩包</p>
+                    <p style="color:#8d9aa3">文件大小: {{ModelExport.JsonzSize?(ModelExport.JsonzSize/1000/1024).toFixed(1)+'M':'--'}}</p>
+                    <p style="color:#8d9aa3">上传时间: {{ModelExport.JsonzEndTime||'--'}}</p>
+                  </div>
+                </el-row>
+              </el-row>
+              <!-- 下载模型文件1 -->
+              <img v-if="!UploadState.EndTime" class="status down-model" src="@/assets/image/model/downModelGray.png" />
+              <img v-else-if="UploadState.EndTime&&!SchedulerCheck.EndTime" class="status down-model" src="@/assets/image/model/downModelBlue.png" />
+              <img v-else class="status down-model" src="@/assets/image/model/downModelGreen.png" />
+              <!-- 下载模型文件2 -->
+              <img v-if="!SchedulerExport.BeginTime" class="status down-model-sec" src="@/assets/image/model/downModelGray.png" />
+              <img v-else-if="SchedulerExport.BeginTime&&!ModelExport.JsonzBeginTime" class="status down-model-sec"
+                src="@/assets/image/model/downModelBlue.png" />
+              <img v-else class="status down-model-sec" src="@/assets/image/model/downModelGreen.png" />
+              <!-- 存储json -->
+              <img v-if="!ModelExport.JsonzBeginTime" class="status up-json" src="@/assets/image/model/upJsonGray.png" />
+              <img v-else-if="ModelExport.JsonzBeginTime&&!ModelExport.JsonzEndTime" class="status up-json"
+                src="@/assets/image/model/upJsonBlue.png" />
+              <img v-else class="status up-json" src="@/assets/image/model/upJsonGreen.png" />
+              <!-- 下载json -->
+              <img v-if="!JsonAnalysis.BeginTime" class="status down-json" src="@/assets/image/model/downJsonGray.png" />
+              <img v-else-if="JsonAnalysis.BeginTime&&!JsonAnalysis.EndTime" class="status down-json" src="@/assets/image/model/downJsonBlue.png" />
+              <img v-else class="status down-json" src="@/assets/image/model/downJsonGreen.png" />
+            </div>
+          </div>
+          <el-row id="revitServer">
+            <pathCard class="revit-item" :title="'楼层模型检查'" @click="getNodeDes" :data="ModelCheck">
+              <p>共检查项: 14项</p>
+            </pathCard>
+            <pathCard class="revit-item" :title="'导出模型json数据并压缩存储'" @click="getNodeDes" :data="ModelExport"></pathCard>
+            <!-- 调度器2 -->
+            <img v-if="!SchedulerExport.BeginTime" class="status row-waiting-manage" src="@/assets/image/model/waitingManageGray.png" />
+            <img v-else-if="SchedulerExport.BeginTime&&!SchedulerExport.EndTime" class="status row-waiting-manage"
+              src="@/assets/image/model/waitingManageBlue.png" />
+            <img v-else class="status row-waiting-manage" src="@/assets/image/model/waitingManageGreen.png" />
+            <!-- 等待解析 -->
+            <img v-if="!JsonAnalysis.BeginTime" class="status waiting-anl" src="@/assets/image/model/waitingAnlGray.png" />
+            <img v-else-if="JsonAnalysis.BeginTime&&!JsonAnalysis.EndTime" class="status waiting-anl" src="@/assets/image/model/waitingAnlBlue.png" />
+            <img v-else class="status waiting-anl" src="@/assets/image/model/waitingAnlGreen.png" />
+            <!-- 未通过 -->
+            <img v-if="ModelCheck.Remove||ModelExport.Remove" class="status del-model" src="@/assets/image/model/delModelBlue.png" />
+            <img v-else class="status del-model" src="@/assets/image/model/delModelGray.png" />
+
+            <!-- 调度器2 -->
+            <div class="path-tips shadow-box" style="top:114px;left:329px;" @click="getNodeDes"
+              v-if="SchedulerExport.BeginTime&&!SchedulerExport.EndTime">
+              <i class="el-icon-error" v-if="SchedulerExport.HasError"></i>
+              <i class="el-icon-warning" v-else-if="SchedulerExport.HasRetry"></i>
+              <p>耗时: {{SchedulerExport.TakeTime||'--'}}</p>
+              <!-- <p>平均上传速度: 1M/s</p> -->
+              <p>开始时间: {{SchedulerExport.BeginTime||'--'}}</p>
+              <p v-if="!SchedulerExport.EndTime">待分配模型数量: {{waitAssign}}</p>
+              <p v-else>结束时间: {{SchedulerExport.EndTime}}</p>
+            </div>
+
+            <p style="float:left;width:100%;text-align:center;margin-top:83px;color:#acb5bb;font-size:12px;">revit本地服务器集群</p>
+          </el-row>
+          <!-- 下载模型文件1 -->
+          <div class="path-tips shadow-box up-model-tips" @click="getNodeDes">
+            <i class="el-icon-error" v-if="ModelCheck.HasError"></i>
+            <i class="el-icon-warning" v-else-if="ModelCheck.HasRetry"></i>
+            <p>耗时: {{ModelCheck.DownTakeTime||'--'}}</p>
+            <p>平均下载速度: {{ModelCheckSpeed}}</p>
+            <p>开始时间: {{UploadState.EndTime||'--'}}</p>
+            <p>结束时间: {{SchedulerCheck.EndTime||'--'}}</p>
+          </div>
+          <!-- 下载模型文件2 -->
+          <div class="path-tips shadow-box up-model-tips2" @click="getNodeDes">
+            <i class="el-icon-error" v-if="ModelExport.HasError"></i>
+            <i class="el-icon-warning" v-else-if="ModelExport.HasRetry"></i>
+            <p>耗时: {{ModelExport.DownTakeTime||'--'}}</p>
+            <p>平均下载速度: {{ModelExportSpeed||'--'}}</p>
+            <p>开始时间: {{SchedulerExport.BeginTime||'--'}}</p>
+            <p>结束时间: {{ModelExport.JsonzBeginTime||'--'}}</p>
+          </div>
+          <!-- 存储json -->
+          <div class="path-tips shadow-box up-json-tips" @click="getNodeDes">
+            <i class="el-icon-error" v-if="ModelExport.HasError"></i>
+            <i class="el-icon-warning" v-else-if="ModelExport.HasRetry"></i>
+            <p>耗时: {{ModelExport.JsonzTakeTime||'--'}}</p>
+            <p>平均上传速度: {{SaveJsonSpeed||'--'}}</p>
+            <p>开始时间: {{ModelExport.JsonzBeginTime||'--'}}</p>
+            <p>结束时间: {{ModelExport.JsonzEndTime||'--'}}</p>
+          </div>
+          <!-- 下载json压缩包 -->
+          <div class="path-tips shadow-box down-json-tips" @click="getNodeDes">
+            <i class="el-icon-error" v-if="JsonAnalysis.HasError"></i>
+            <i class="el-icon-warning" v-else-if="JsonAnalysis.HasRetry"></i>
+            <p>耗时: {{JsonAnalysis.TakeTime||'--'}}</p>
+            <p>平均下载速度: {{DownJsonSpeed||'--'}}</p>
+            <p>开始时间: {{JsonAnalysis.BeginTime||'--'}}</p>
+            <p>结束时间: {{JsonAnalysis.EndTime||'--'}}</p>
+          </div>
+          <div id="secondDel" class="delModel">
+            <i class="iconfont icon-delate" style="color:#89969F;font-size:30px;line-height:1;margin-left:-6px"></i>
+            <p>放弃文件</p>
+          </div>
+        </div>
+        <div class="third-column column">
+          <div>
+            <div id="webDatabase" class="shadow-box">
+              <div style="background:#b8c5d0;height:20px;"></div>
+              <div>
+                <div style="text-align:center;">
+                  <i class="iconfont icon-project-o" style="color:#dee6ec;font-size:40px"></i>
+                  <p style="color:#676767">web服务数据库</p>
+                </div>
+              </div>
+              <img v-if="1||!SaveData.BeginTime" class="status column-up" src="@/assets/image/model/columnGray.png" />
+              <!-- <img v-else-if="SaveData.BeginTime&&!SaveData.EndTime" class="status column-up" src="@/assets/image/model/columnBlue.png" />
+              <img v-else class="status column-up" src="@/assets/image/model/columnGreen.png" /> -->
+
+              <img v-if="1||!MultiFloorCheck.BeginTime" class="status right-down" src="@/assets/image/model/rightDownGray.png" />
+              <!-- <img v-else-if="MultiFloorCheck.BeginTime&&!MultiFloorCheck.EndTime" class="status right-down" src="@/assets/image/model/rightDownBlue.png" />
+              <img v-else class="status right-down" src="@/assets/image/model/rightDownGreen.png" /> -->
+            </div>
+          </div>
+          <el-row id="webServer">
+            <pathCard class="webServer-item" :title="'解压并解析json文件'" :data="JsonAnalysis" @click="getNodeDes"></pathCard>
+            <pathCard class="webServer-item" :title="'存储数据到模型web服务数据库'" :data="SaveData" @click="getNodeDes"></pathCard>
+            <pathCard class="webServer-item" :title="'建筑模型检查'" :data="MultiFloorCheck" @click="getNodeDes">
+              <p>共检查项: 2项</p>
+            </pathCard>
+            <pathCard class="webServer-item" :title="'处理模型数据格式'" :data="SyncDatacenter" @click="getNodeDes"></pathCard>
+
+            <img v-if="!SaveData.BeginTime" class="status path1 path" src="@/assets/image/model/arrowGray.png" />
+            <img v-else-if="SaveData.BeginTime&&!SaveData.EndTime" class="status path1 path" src="@/assets/image/model/arrowBlue.png" />
+            <img v-else class="status path1 path" src="@/assets/image/model/arrowGreen.png" />
+
+            <img v-if="!MultiFloorCheck.BeginTime" class="status path2 path" src="@/assets/image/model/arrowGray.png" />
+            <img v-else-if="MultiFloorCheck.BeginTime&&!MultiFloorCheck.EndTime" class="status path2 path" src="@/assets/image/model/arrowBlue.png" />
+            <img v-else class="status path2 path" src="@/assets/image/model/arrowGreen.png" />
+
+            <img v-if="!SyncDatacenter.BeginTime" class="status path3 path" src="@/assets/image/model/arrowGray.png" />
+            <img v-else-if="SyncDatacenter.BeginTime&&!SyncDatacenter.EndTime" class="status path3 path" src="@/assets/image/model/arrowBlue.png" />
+            <img v-else class="status path3 path" src="@/assets/image/model/arrowGreen.png" />
+
+            <img v-if="!SaveLog.BeginTime" class="status path4 path" src="@/assets/image/model/arrowGray.png" />
+            <img v-else-if="SaveLog.BeginTime&&!SaveLog.EndTime" class="status path4 path" src="@/assets/image/model/arrowBlue.png" />
+            <img v-else class="status path4 path" src="@/assets/image/model/arrowGreen.png" />
+
+            <img v-if="MultiFloorCheck.GridCheck||MultiFloorCheck.LevelCheck" class="status del-model" src="@/assets/image/model/delModelBlue.png" />
+            <img v-else class="status del-model" src="@/assets/image/model/delModelGray.png" />
+
+            <p style="float:left;width:100%;text-align:center;margin-top:83px;color:#acb5bb;font-size:12px;">模型web服务器</p>
+          </el-row>
+          <div id="thirdDel" class="delModel">
+            <i class="iconfont icon-delate" style="color:#89969F;font-size:30px;line-height:1;margin-left:-6px"></i>
+            <p>放弃文件</p>
+          </div>
+        </div>
+        <div class="forth-column column">
+          <div>
+            <div id="dataCenterDatabase" class="shadow-box">
+              <div style="background:#b8c5d0;height:20px;"></div>
+              <div>
+                <div style="text-align:center;">
+                  <i class="iconfont icon-project-o" style="color:#dee6ec;font-size:40px"></i>
+                  <p style="color:#676767">数据中心数据库</p>
+                </div>
+              </div>
+
+              <img v-if="1" class="status column-up" src="@/assets/image/model/columnGray.png" />
+              <!-- <img v-else-if="2" class="status column-up" src="@/assets/image/model/columnBlue.png" />
+              <img v-else class="status column-up" src="@/assets/image/model/columnGreen.png" /> -->
+            </div>
+          </div>
+          <el-row id="dataCenterServer">
+            <pathCard :title="'储存模型数据并记录增删日志'" @click="getNodeDes" :data="SaveLog"></pathCard>
+
+            <img v-if="1" class="status path1" src="@/assets/image/model/arrowGray.png" />
+            <!-- <img v-else-if="2" class="status path1" src="@/assets/image/model/arrowBlue.png" />
+            <img v-else class="status path1" src="@/assets/image/model/arrowGreen.png" /> -->
+
+            <p style="float:left;width:100%;text-align:center;margin-top:83px;color:#acb5bb;font-size:12px;">数据中心服务器 </p>
+          </el-row>
+        </div>
+        <div class="fifth-column column">
+          <pathCard class="finish-item" :title="'完成'" :data="SaveLog" :isCustomize="true">
+            <p>后续关系计算...</p>
+            <p>完成时间: {{SaveLog.EndTime||'--'}}</p>
+          </pathCard>
+        </div>
+      </div>
+    </el-row>
+    <nodeDialog ref="nodeDialog"></nodeDialog>
+  </div>
+</template>
+<script>
+import { mapGetters } from "vuex";
+import pathCard from "@/components/model/file/pathCard"
+import nodeDialog from "@/components/model/file/nodeDialog"
+import { modelPathControl, unassignQuery } from "@/api/model/file";
+import Bus from '@/utils/bus.js'
+export default {
+  components: {
+    pathCard,
+    nodeDialog
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  data() {
+    return {
+      loading: false, //
+      Id: '',
+      Size: 0,
+      OriginalName: '',
+      JsonAnalysis: {}, //解压并解析json文件
+      ModelCheck: {}, //楼层模型检查
+      ModelExport: {}, //导出模型json数据并压缩存储
+      MultiFloorCheck: {}, //建筑模型检查
+      Note: {}, //储存模型数据并记录增删日志
+      SaveData: {}, //存储数据到模型web服务数据库
+      SchedulerCheck: {}, //第一个等待调度器
+      SchedulerExport: {},//第二个等待调度器
+      UploadState: {}, //上传下载功能
+      finish: {},
+      SyncDatacenter: {}, //处理模型数据格式
+      SaveLog: {},// 储存模型数据并记录增删日志
+      timer: null, //定时器
+      timeout: null, //延时器
+      waitAssign: 0,
+      allTakeTime: '', //总耗时
+      UploadStateSpeed: '', // 上传模型文件平均速度
+      ModelCheckSpeed: '',//下载模型文件1平均速度
+      ModelExportSpeed: '',//下载模型文件2平均速度
+      SaveJsonSpeed: '',//存储json平均速度
+      DownJsonSpeed: '',//下载json平均速度
+    }
+  },
+  mounted() {
+    // Bus.$on('modelStatusChange', message => {
+    //   this.init()
+    // })
+  },
+  created() {
+    this.Id = this.$route.query.Id
+    this.Size = this.$route.query.Size
+    this.OriginalName = this.$route.query.OriginalName || '--'
+    this.init();
+  },
+  beforeDestroy() {
+    if (this.timer) {
+      clearInterval(this.timer);
+    }
+    if (this.timeout) {
+      clearTimeout(this.timeout);
+    }
+  },
+  methods: {
+    init() {
+      this.getMessage();
+      if (!this.SchedulerExport.EndTime) {
+        this.getUnassignNum();
+      }
+    },
+    // 弹窗
+    getNodeDes(data, title) {
+      let type = '';
+      if (title == '楼层模型检查') {
+        type = 'firstCheck'
+      } else if (title == '建筑模型检查') {
+        type = 'secondCheck'
+      }
+      this.$refs.nodeDialog.showDialog(data, type)
+    },
+    // 获取流转状态
+    getMessage() {
+      let pa = {
+        Filters: `Id="${this.Id}"`
+      }
+      modelPathControl(pa, res => {
+        if (res.Content.length) {
+          const data = res.Content[0];
+          if (data.SchedulerExport && data.SchedulerExport.BeginTime) {
+            if (data.ModelExport) {
+              data.ModelExport.BeginTime = data.SchedulerExport.BeginTime
+            }
+          }
+          this.updateData(data);
+          this.getSpeed();
+          this.interval(data);
+          if (!this.SaveLog.EndTime) {
+            if (this.timeout) {
+              clearTimeout(this.timeout);
+            }
+            this.timeout = setTimeout(() => {
+              this.init()
+            }, 30000)
+          }
+        } else {
+          this.$message.warning('暂无数据')
+        }
+      })
+    },
+    // 
+    getUnassignNum() {
+      let pa = {
+        Filters: `Status=0 or Status=1 or Status=2`
+      }
+      unassignQuery(pa, res => {
+        this.waitAssign = res.Total
+      })
+    },
+    // 定时器
+    interval(data) {
+      if (this.timer) {
+        clearInterval(this.timer);
+      }
+      this.timer = setInterval(() => {
+        this.updateData(data)
+        this.$forceUpdate()
+      }, 1000)
+    },
+    // 计算耗时
+    updateData(data) {
+      this.JsonAnalysis = this.formatTime(data.JsonAnalysis || {});
+      this.ModelCheck = this.formatTime(data.ModelCheck || {})
+      this.ModelExport = this.formatTime(data.ModelExport || {})
+      this.MultiFloorCheck = this.formatTime(data.MultiFloorCheck || {})
+      this.SaveData = this.formatTime(data.SaveData || {})
+      this.SchedulerCheck = this.formatTime(data.SchedulerCheck || {})
+      this.SchedulerExport = this.formatTime(data.SchedulerExport || {})
+      this.UploadState = this.formatTime(data.UploadState || {})
+      this.SyncDatacenter = this.formatTime(data.SyncDatacenter || {})
+      this.SaveLog = this.formatTime(data.SaveLog || {})
+      if (this.UploadState.BeginTime) {
+        let temp = { BeginTime: this.UploadState.BeginTime }
+        if (this.SaveLog.EndTime) {
+          temp.EndTime = this.SaveLog.EndTime
+        }
+        this.allTakeTime = this.formatTime(temp).TakeTime
+      }
+      if (this.UploadState.EndTime && !this.SchedulerCheck.EndTime) {
+        const sTime = new Date(this.UploadState.EndTime).getTime();
+        const eTime = new Date().getTime();
+        this.ModelCheck.DownTakeTime = this.msToStr(eTime - sTime);
+      } else if (this.UploadState.EndTime && this.SchedulerCheck.EndTime) {
+        const sTime = new Date(this.UploadState.EndTime).getTime();
+        const eTime = new Date(this.SchedulerCheck.EndTime).getTime();
+        this.ModelCheck.DownTakeTime = this.msToStr(eTime - sTime);
+      }
+      if (this.SchedulerExport.BeginTime && !this.ModelExport.JsonzBeginTime) {
+        const sTime = new Date(this.SchedulerExport.BeginTime).getTime();
+        const eTime = new Date().getTime();
+        this.ModelExport.DownTakeTime = this.msToStr(eTime - sTime);
+      } else if (this.SchedulerExport.BeginTime && this.ModelExport.JsonzBeginTime) {
+        const sTime = new Date(this.SchedulerExport.BeginTime).getTime();
+        const eTime = new Date(this.ModelExport.JsonzBeginTime).getTime();
+        this.ModelExport.DownTakeTime = this.msToStr(eTime - sTime);
+      }
+    },
+    // 设置速度
+    getSpeed() {
+      let sTime, eTime;
+      if (this.UploadState.BeginTime && this.UploadState.EndTime) {
+        sTime = new Date(this.UploadState.BeginTime).getTime();
+        eTime = new Date(this.UploadState.EndTime).getTime();
+        if (sTime != eTime) {
+          this.UploadStateSpeed = this.formatSpeed(this.Size / (eTime - sTime))
+        } else {
+          this.UploadStateSpeed = '--'
+        }
+      } else {
+        this.UploadStateSpeed = '--'
+      }
+      if (this.UploadState.EndTime && this.SchedulerCheck.EndTime) {
+        sTime = new Date(this.UploadState.EndTime).getTime();
+        eTime = new Date(this.SchedulerCheck.EndTime).getTime();
+        if (sTime != eTime) {
+          this.ModelCheckSpeed = this.formatSpeed(this.Size / (eTime - sTime))
+        } else {
+          this.ModelCheckSpeed = '--'
+        }
+      } else {
+        this.ModelCheckSpeed = '--'
+      }
+      if (this.SchedulerExport.BeginTime && this.ModelExport.JsonzBeginTime) {
+        sTime = new Date(this.SchedulerExport.BeginTime).getTime();
+        eTime = new Date(this.ModelExport.JsonzBeginTime).getTime();
+        if (sTime != eTime) {
+          this.ModelExportSpeed = this.formatSpeed(this.Size / (eTime - sTime))
+        } else {
+          this.ModelExportSpeed = '--'
+        }
+      } else {
+        this.ModelExportSpeed = '--'
+      }
+      if (this.ModelExport.JsonzBeginTime && this.ModelExport.JsonzEndTime) {
+        sTime = new Date(this.ModelExport.JsonzBeginTime).getTime();
+        eTime = new Date(this.ModelExport.JsonzEndTime).getTime();
+        if (sTime != eTime) {
+          this.SaveJsonSpeed = this.formatSpeed(this.ModelExport.JsonzSize / (eTime - sTime))
+        } else {
+          this.SaveJsonSpeed = '--'
+        }
+      } else {
+        this.SaveJsonSpeed = '--'
+      }
+      if (this.JsonAnalysis.BeginTime && this.JsonAnalysis.EndTime) {
+        sTime = new Date(this.JsonAnalysis.BeginTime).getTime();
+        eTime = new Date(this.JsonAnalysis.EndTime).getTime();
+        if (sTime != eTime) {
+          this.DownJsonSpeed = this.formatSpeed(this.ModelExport.JsonzSize / (eTime - sTime))
+        } else {
+          this.DownJsonSpeed = '--'
+        }
+      } else {
+        this.DownJsonSpeed = '--'
+      }
+    },
+    // 处理时间工具
+    formatTime(data) {
+      if (data.BeginTime && !data.EndTime) {
+        const sTime = new Date(data.BeginTime).getTime();
+        const eTime = new Date().getTime();
+        data.TakeTime = this.msToStr(eTime - sTime);
+      } else if (data.BeginTime && data.EndTime) {
+        const sTime = new Date(data.BeginTime).getTime();
+        const eTime = new Date(data.EndTime).getTime();
+        data.TakeTime = this.msToStr(eTime - sTime);
+      }
+      if (data.JsonzBeginTime && !data.JsonzEndTime) {
+        const sTime = new Date(data.JsonzBeginTime).getTime();
+        const eTime = new Date().getTime();
+        data.JsonzTakeTime = this.msToStr(eTime - sTime);
+      } else if (data.JsonzBeginTime && data.JsonzEndTime) {
+        const sTime = new Date(data.JsonzBeginTime).getTime();
+        const eTime = new Date(data.JsonzEndTime).getTime();
+        data.JsonzTakeTime = this.msToStr(eTime - sTime);
+      }
+      return data;
+    },
+    // 生成speed
+    formatSpeed(speed) {
+      if (speed > 1024) {
+        speed = (speed / 1024).toFixed(1);
+        return `${speed}MB/s`
+      } else {
+        return `${speed.toFixed(1)}KB/s`
+      }
+    },
+    msToStr(mss) {
+      let str = '';
+      const days = parseInt(mss / (1000 * 60 * 60 * 24));
+      const hours = parseInt((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
+      const minutes = parseInt((mss % (1000 * 60 * 60)) / (1000 * 60));
+      const seconds = ((mss % (1000 * 60)) / 1000).toFixed();
+      if (days > 0) {
+        str += `${days}天`
+      }
+      if (hours > 0) {
+        str += `${hours}小时`
+      }
+      if (minutes > 0) {
+        str += `${minutes}分钟`
+      }
+      if (seconds > 0) {
+        str += `${seconds}秒`
+      }
+      return str;
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+#path-control {
+  box-sizing: border-box;
+  padding: 10px;
+  border: 1px solid #e4e4e4;
+  background-color: #fff;
+  overflow: hidden;
+  .title-time {
+    padding: 10px;
+    border-bottom: 1px solid #e4e4e4;
+    & > div {
+      float: left;
+      font-size: 14px;
+    }
+    & > div + div {
+      margin-left: 20px;
+    }
+  }
+  .path-pic {
+    height: calc(100% - 50px);
+    overflow-x: auto;
+    #path-container {
+      position: relative;
+      height: 100%;
+      padding: 20px 0 0;
+      width: 4450px;
+      img.status {
+        position: absolute;
+      }
+      .column {
+        height: 100%;
+        position: relative;
+        float: left;
+        width: 1000px;
+        &.first-column {
+          width: 832px;
+          #baseServer {
+            border: 2px dashed #b8c5d0;
+            border-radius: 4px;
+            padding: 20px 20px 0;
+            margin: 389px 20px 0;
+            width: 584px;
+            height: 270px;
+            .updown {
+              position: relative;
+              width: 150px;
+              height: 150px;
+              float: left;
+              margin-right: 150px;
+            }
+            .mid-transfer {
+              position: relative;
+              width: 235px;
+              height: 90px;
+              float: left;
+              margin-top: 30px;
+            }
+          }
+          .first-title {
+            background-color: #f3f5f6;
+            font-size: 14px;
+            padding: 5px 10px;
+            i {
+              margin-right: 5px;
+            }
+          }
+          .first-content {
+            font-size: 12px;
+            padding: 10px;
+            color: #acb5bb;
+          }
+          .row-status {
+            left: 170px;
+            top: 70px;
+          }
+          .row-waiting-manage {
+            left: 264px;
+            top: 30px;
+          }
+          .up-model {
+            left: 95px;
+            bottom: 96px;
+          }
+        }
+        &.second-column {
+          #ossServer {
+            position: relative;
+            width: 780px;
+            margin: 0 auto;
+            .server-content {
+              padding: 20px 0;
+              .sm-box {
+                float: left;
+                padding: 0 10px;
+                line-height: 1;
+                & > div {
+                  float: left;
+                  font-size: 12px;
+                }
+                &:nth-child(1) {
+                  width: 100px;
+                  margin-right: 30px;
+                }
+                &:nth-child(2),
+                &:nth-child(3) {
+                  padding: 15px 20px;
+                  background: #eef2f6;
+                  border-radius: 4px;
+                  border: 2px dashed #b8c5d0;
+                }
+                &:nth-child(3) {
+                  margin-left: 40px;
+                }
+                .fixed {
+                  p {
+                    width: 167px;
+                    overflow: hidden;
+                    text-overflow: ellipsis;
+                    white-space: nowrap;
+                  }
+                }
+                .image {
+                  margin-right: 20px;
+                }
+                p {
+                  margin-bottom: 8px;
+                }
+              }
+            }
+            .down-model {
+              left: 82px;
+              top: 156px;
+            }
+            .down-model-sec {
+              left: 565px;
+              top: 156px;
+            }
+            .up-json {
+              left: 665px;
+              top: 156px;
+            }
+            .down-json {
+              top: 68px;
+              right: -460px;
+            }
+          }
+          #revitServer {
+            padding: 16px 16px 0;
+            border: 2px dashed #b8c5d0;
+            width: 890px;
+            height: 270px;
+            margin: 235px auto 0;
+            .revit-item {
+              float: left;
+              &:nth-child(1) {
+                margin-right: 255px;
+              }
+            }
+            .row-waiting-manage {
+              left: 300px;
+              top: 80px;
+              transform: scale(0.9);
+            }
+            .waiting-anl {
+              right: -263px;
+              top: 80px;
+            }
+            .del-model {
+              left: 91px;
+              top: 168px;
+            }
+          }
+          .up-model-tips {
+            left: -44px;
+            top: 202px;
+          }
+          .up-model-tips2 {
+            left: 439px;
+            top: 202px;
+          }
+          .up-json-tips {
+            left: 815px;
+            top: 202px;
+          }
+          .down-json-tips {
+            right: -336px;
+            top: 114px;
+          }
+          #secondDel {
+            margin: 48px 0 0 166px;
+          }
+        }
+        &.third-column {
+          width: 1544px;
+          margin-left: 200px;
+          #webDatabase {
+            width: 130px;
+            height: 144px;
+            margin-left: 500px;
+            .column-up {
+              top: 158px;
+              left: 565px;
+              transform: scale(1.1);
+            }
+            .right-down {
+              right: 560px;
+              top: 103px;
+            }
+          }
+          #webServer {
+            border: 2px dashed #b8c5d0;
+            margin-top: 241px;
+            padding: 16px 16px 0;
+            height: 270px;
+            .webServer-item {
+              float: left;
+              & + .webServer-item {
+                margin-left: 105px;
+              }
+            }
+            .path {
+              top: 95px;
+            }
+            .path1 {
+              left: 311px;
+            }
+            .path2 {
+              left: 715px;
+            }
+            .path3 {
+              left: 1117px;
+            }
+            .path4 {
+              left: 1520px;
+            }
+            .del-model {
+              right: 517px;
+              top: 168px;
+            }
+          }
+          #thirdDel {
+            margin: 48px 0 0 925px;
+          }
+        }
+        &.forth-column {
+          width: 335px;
+          margin-left: 70px;
+          margin-right: 87px;
+          #dataCenterDatabase {
+            width: 130px;
+            height: 144px;
+            margin: 0 auto;
+            .column-up {
+              top: 158px;
+              left: 165px;
+              transform: scale(1.1);
+            }
+          }
+          #dataCenterServer {
+            border: 2px dashed #b8c5d0;
+            margin-top: 240px;
+            padding: 16px 16px 0;
+            height: 270px;
+            .path1 {
+              top: 95px;
+              left: 311px;
+            }
+          }
+        }
+        &.fifth-column {
+          width: auto;
+          .finish-item {
+            margin-top: 403px;
+          }
+        }
+      }
+    }
+  }
+  .shadow-box {
+    box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2);
+    border-radius: 4px;
+  }
+  .path-tips {
+    position: absolute;
+    font-size: 12px;
+    width: 204px;
+    height: 93px;
+    padding: 10px;
+    i {
+      position: absolute;
+      font-size: 16px;
+      right: 10px;
+      &.el-icon-warning {
+        color: #fbc636;
+      }
+      &.el-icon-error {
+        color: #ff6660;
+      }
+    }
+  }
+  .delModel {
+    width: 76px;
+    height: 66px;
+    font-size: 12px;
+    text-align: center;
+    padding-top: 10px;
+    background: #eef2f6;
+    border: 2px solid #b8c5d0;
+    border-radius: 5px;
+  }
+}
+</style>