浏览代码

Merge branch 'task-manage' of http://39.106.8.246:3003/web/ibms into task-manage

LXXXY 5 年之前
父节点
当前提交
b368d96a1e
共有 26 个文件被更改,包括 3023 次插入106 次删除
  1. 84 0
      src/api/data_admin/buildTaskApi.js
  2. 11 7
      src/assets/style/iconfont/iconfont.css
  3. 二进制
      src/assets/style/iconfont/iconfont.eot
  4. 64 61
      src/assets/style/iconfont/iconfont.svg
  5. 二进制
      src/assets/style/iconfont/iconfont.ttf
  6. 二进制
      src/assets/style/iconfont/iconfont.woff
  7. 71 0
      src/components/data_admin/buildTask/detail/assetsDetail.vue
  8. 71 0
      src/components/data_admin/buildTask/detail/deviceDetail.vue
  9. 85 0
      src/components/data_admin/buildTask/dialog/addTaskDialog.vue
  10. 269 0
      src/components/data_admin/buildTask/dialog/modelTaskDialog.vue
  11. 130 0
      src/components/data_admin/buildTask/draw/drawModel.vue
  12. 187 0
      src/components/data_admin/buildTask/table/assetsTable.vue
  13. 207 0
      src/components/data_admin/buildTask/table/deviceTable.vue
  14. 185 0
      src/components/data_admin/buildTask/table/modelTable.vue
  15. 191 0
      src/components/data_admin/buildTask/table/replaceTable.vue
  16. 191 0
      src/components/data_admin/buildTask/table/tearTable.vue
  17. 155 0
      src/components/data_admin/buildTask/taskStatistics.vue
  18. 1 1
      src/components/ledger/lib/assets.vue
  19. 1 1
      src/components/ledger/lib/cascader.vue
  20. 107 0
      src/components/ready/buildfloor/modelFile.vue
  21. 83 0
      src/components/ready/buildfloor/modelFolder.vue
  22. 27 6
      src/router/system.js
  23. 258 0
      src/views/data_admin/buildTask/addTask/addAssetsTask.vue
  24. 303 0
      src/views/data_admin/buildTask/addTask/addDeviceTask.vue
  25. 192 0
      src/views/data_admin/buildTask/addTask/addModelTask.vue
  26. 150 30
      src/views/data_admin/buildTask/index.vue

+ 84 - 0
src/api/data_admin/buildTaskApi.js

@@ -0,0 +1,84 @@
+import http from '../scan/httpUtil'
+const baseUrl = '/api';
+
+/**
+ * info: 查询统计数量(查询总数量不传参数,查询已完成数量TaskState=0,查询未找到TaskState=-1,查询未验证TaskState=1)
+ * @param {Filters:string} param 查询参数
+ * @param {*} success  成功的回调函数
+ * 
+ */
+export function queryTaskCount(param, success) {
+  let url = `${baseUrl}/datacenter/scan-task-base/count`;
+  http.postJson(url, param, success)
+}
+
+/*************************模型任务接口****************************/
+//创建模型任务
+export function createModelTask(param, success) {
+  let url = `${baseUrl}/datacenter/model-scan-task/create`;
+  http.postJson(url, param, success)
+}
+//根据id删除模型任务
+export function deleteModelTask(param, success) {
+  let url = `${baseUrl}/datacenter/model-scan-task/delete`;
+  http.postJson(url, param, success)
+}
+//查询模型任务
+export function queryModelTask(param, success) {
+  let url = `${baseUrl}/datacenter/model-scan-task/page-query`;
+  http.postJson(url, param, success)
+}
+//更新模型任务
+export function updateModelTask(param, success) {
+  let url = `${baseUrl}/datacenter/model-scan-task/update`;
+  http.postJson(url, param, success)
+}
+
+/*************************设备台账任务接口****************************/
+//创建设备台账任务
+export function createDeviceTask(param, success) {
+  let url = `${baseUrl}/datacenter/equip-scan-task/create`;
+  http.postJson(url, param, success)
+}
+//根据id删除设备台账任务
+export function deleteDeviceTask(param, success) {
+  let url = `${baseUrl}/datacenter/equip-scan-task/delete`;
+  http.postJson(url, param, success)
+}
+//查询设备台账任务
+export function queryDeviceTask(param, success) {
+  let url = `${baseUrl}/datacenter/equip-scan-task/page-query`;
+  http.postJson(url, param, success)
+}
+//更新设备台账任务
+export function updateDeviceTask(param, success) {
+  let url = `${baseUrl}/datacenter/equip-scan-task/update`;
+  http.postJson(url, param, success)
+}
+
+/*************************资产台账任务接口****************************/
+//统计数量
+export function countAssetsTask(param, success) {
+  let url = `${baseUrl}/datacenter/property-scan-task/count`;
+  http.postJson(url, param, success)
+}
+//创建设备台账任务
+export function createAssetsTask(param, success) {
+  let url = `${baseUrl}/datacenter/property-scan-task/create`;
+  http.postJson(url, param, success)
+}
+//根据id删除设备台账任务
+export function deleteAssetsTask(param, success) {
+  let url = `${baseUrl}/datacenter/property-scan-task/delete`;
+  http.postJson(url, param, success)
+}
+//查询设备台账任务
+export function queryAssetsTask(param, success) {
+  let url = `${baseUrl}/datacenter/property-scan-task/page-query`;
+  http.postJson(url, param, success)
+}
+//更新设备台账任务
+export function updateAssetsTask(param, success) {
+  let url = `${baseUrl}/datacenter/property-scan-task/update`;
+  http.postJson(url, param, success)
+}

文件差异内容过多而无法显示
+ 11 - 7
src/assets/style/iconfont/iconfont.css


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


文件差异内容过多而无法显示
+ 64 - 61
src/assets/style/iconfont/iconfont.svg


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


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


+ 71 - 0
src/components/data_admin/buildTask/detail/assetsDetail.vue

@@ -0,0 +1,71 @@
+<template>
+  <div class="detail-box">
+    <el-scrollbar style="height:100%;">
+      <div class="attribute-detail"></div>
+      <div class="implement-detail"></div>
+    </el-scrollbar>
+  </div>
+</template>
+
+<script>
+import {  } from "@/api/scan/request"
+import { mapGetters } from "vuex"
+export default {
+  components: {
+    
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  props: {
+    id: String,
+  },
+  data() {
+    return {
+      
+    };
+  },
+  created() {
+    
+  },
+  methods: {
+    
+  },
+  watch: {
+    id: {
+      handler(newName, oldName) {
+        // this.page.pageNumber = 1
+        // this.getTableData()
+      },
+      immediate: true,
+      deep: true
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+  .detail-box{
+    width: 100%;
+    height: 100%;
+    box-sizing: border-box;
+    /deep/ .el-scrollbar__wrap {
+      overflow-x: hidden;
+    }
+    .attribute-detail{
+      width: calc(100% - 30px);
+      height: 500px;
+      margin: 15px 15px 10px;
+      box-sizing: border-box;
+      border-left: 1px solid #eee;
+      box-shadow: 0px 1px 5px 0px rgba(59, 66, 84, 0.15);
+    }
+    .implement-detail{
+      width: calc(100% - 30px);
+      height: 500px;
+      margin: 15px 15px 10px;
+      box-sizing: border-box;
+      border-left: 1px solid #eee;
+      box-shadow: 0px 1px 5px 0px rgba(59, 66, 84, 0.15);
+    }
+  }
+</style>

+ 71 - 0
src/components/data_admin/buildTask/detail/deviceDetail.vue

@@ -0,0 +1,71 @@
+<template>
+  <div class="detail-box">
+    <el-scrollbar style="height:100%;">
+      <div class="attribute-detail"></div>
+      <div class="implement-detail"></div>
+    </el-scrollbar>
+  </div>
+</template>
+
+<script>
+import {  } from "@/api/scan/request"
+import { mapGetters } from "vuex"
+export default {
+  components: {
+    
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  props: {
+    id: String,
+  },
+  data() {
+    return {
+      
+    };
+  },
+  created() {
+    
+  },
+  methods: {
+    
+  },
+  watch: {
+    id: {
+      handler(newName, oldName) {
+        // this.page.pageNumber = 1
+        // this.getTableData()
+      },
+      immediate: true,
+      deep: true
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+  .detail-box{
+    width: 100%;
+    height: 100%;
+    box-sizing: border-box;
+    /deep/ .el-scrollbar__wrap {
+      overflow-x: hidden;
+    }
+    .attribute-detail{
+      width: calc(100% - 30px);
+      height: 500px;
+      margin: 15px 15px 10px;
+      box-sizing: border-box;
+      border-left: 1px solid #eee;
+      box-shadow: 0px 1px 5px 0px rgba(59, 66, 84, 0.15);
+    }
+    .implement-detail{
+      width: calc(100% - 30px);
+      height: 500px;
+      margin: 15px 15px 10px;
+      box-sizing: border-box;
+      border-left: 1px solid #eee;
+      box-shadow: 0px 1px 5px 0px rgba(59, 66, 84, 0.15);
+    }
+  }
+</style>

+ 85 - 0
src/components/data_admin/buildTask/dialog/addTaskDialog.vue

@@ -0,0 +1,85 @@
+<template>
+  <el-dialog :title="title" :visible.sync="addTaskDialog" :before-close="handleClose" width="500px">
+    <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="110px">
+      <el-form-item label="未验证任务" prop="isVerification">
+        <el-switch v-model="ruleForm.isVerification"></el-switch>
+      </el-form-item>
+      <el-form-item label="任务类型" prop="taskType">
+        <div><el-radio v-model="ruleForm.taskType" label="model">现场验证模型</el-radio></div>
+        <div><el-radio v-model="ruleForm.taskType" label="device">现场验证设备台账</el-radio></div>
+        <div><el-radio v-model="ruleForm.taskType" label="assets">现场验证资产台账</el-radio></div>
+      </el-form-item>
+    </el-form>
+    <!-- <el-row>
+      请选择新建现场验证任务的数据源:
+      <el-checkbox v-model="ruleForm.isVerification">只选择未验证的</el-checkbox>
+    </el-row>
+    <el-row style="margin-top:15px;padding-left:15px;">
+      <div><el-radio v-model="ruleForm.taskType" label="model">现场验证模型</el-radio></div>
+      <div><el-radio v-model="ruleForm.taskType" label="device">现场验证设备台账</el-radio></div>
+      <div><el-radio v-model="ruleForm.taskType" label="assets">现场验证资产台账</el-radio></div>
+    </el-row> -->
+    <span slot="footer" class="dialog-footer">
+				<el-button type="primary" @click="$emit('update:addTaskDialog',false)">取  消</el-button>
+				<el-button type="primary" @click="toAddTask()">确  认</el-button>
+			</span>
+  </el-dialog>
+</template>
+
+<script>
+import {  } from "@/api/scan/request";
+import { mapGetters } from "vuex";
+export default {
+  components: {
+    
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  data() {
+    return {
+      title: "添加验证任务",
+      dialogVisible: false,
+      ruleForm: {
+        isVerification: false,
+        taskType: ''
+      },
+      rules: {
+        taskType: [
+          { required: true, message: '请选择任务类型', trigger: 'change' }
+        ]
+      }
+    };
+  },
+  props: {
+    addTaskDialog: Boolean //是否显示弹窗
+  },
+  created() { 
+    
+  },
+  methods: {
+    toAddTask() {
+      this.$refs.ruleForm.validate((valid) => {
+        if (valid) {
+          if (this.ruleForm.taskType == 'model') {
+            this.$router.push({ path: '/floor/addModelTask', query: this.ruleForm });
+          } else if (this.ruleForm.taskType == 'device') {
+            this.$router.push({ path: '/floor/addDeviceTask', query: this.ruleForm });
+          } else if (this.ruleForm.taskType == 'assets') {
+            this.$router.push({ path: '/floor/addAssetsTask', query: this.ruleForm });
+          }
+        } else {
+          console.log('error submit!!');
+          return false;
+        }
+      })
+    },
+    handleClose() {
+      this.$emit('update:addTaskDialog',this.dialogVisible)
+    },
+  }
+};
+</script>
+<style lang="less" scoped>
+
+</style>

+ 269 - 0
src/components/data_admin/buildTask/dialog/modelTaskDialog.vue

@@ -0,0 +1,269 @@
+<template>
+  <el-dialog :title="title" :visible.sync="dialogVisible" :before-close="handleClose" width="900px" id="addEqDialog">
+    <div class="table-box">
+      <el-table :data="tableData" style="width: 100%" height="350" v-loading="loading" :header-cell-style="headerStyle" ref="multipleTable"
+        @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55"></el-table-column>
+        <el-table-column type="expand">
+          <template slot-scope="props">
+            <p v-if="props.row.partsList && props.row.partsList.length" style="color:#99a9bf;line-height:32px;font-size:14px;">包含的部件:</p>
+            <el-form label-position="left" inline class="demo-table-expand" v-if="props.row.partsList && props.row.partsList.length">
+              <el-form-item v-for="item in props.row.partsList" :key="item.name" :label="`${item.name}:`">
+                <span>{{ item.number }}</span>
+              </el-form-item>
+            </el-form>
+          </template>
+        </el-table-column>
+        <el-table-column label="所属模型文件夹" width="110" show-overflow-tooltip>
+          <template slot-scope="scope">{{ scope.row.build }}</template>
+        </el-table-column>
+        <el-table-column label="模型文件名" width="100" show-overflow-tooltip>
+          <template slot-scope="scope">{{ scope.row.floor }}</template>
+        </el-table-column>
+        <el-table-column prop="EquipLocalName" label="设备本地名称" show-overflow-tooltip width="100"></el-table-column>
+        <el-table-column prop="EquipLocalId" label="设备本地编码" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="EquipName" label="设备类" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="installation" label="BIM ID" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="type" label="现场验证操作规定" width="150">
+          <template slot-scope="scope">
+            <el-button @click.native.prevent="handleOpenDetail(scope.row, tableData)" type="text" size="small">详情</el-button>
+          </template>
+        </el-table-column>
+        <template slot="empty">
+          <div style="height: 60%;transform: translateY(50%);">
+            <i class="icon-wushuju iconfont"></i>
+            数据暂无
+          </div>
+        </template>
+      </el-table>
+      <!-- 分页 -->
+      <el-pagination class="fr" v-show="tableData && tableData.length" @size-change="handleSizeChange" @current-change="handleCurrentChange"
+        :current-page="page.pageNumber" :page-sizes="page.pageSizes" :page-size="page.pageSize" layout="total, sizes, prev, pager, next, jumper"
+        :total="page.total"></el-pagination>
+    </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="$emit('update:dialogVisible',false)">返回重选</el-button>
+      <el-button size="small" type="primary" @click="savaRelation">确认创建</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+import {  } from "@/api/scan/request";
+import { mapGetters } from "vuex";
+export default {
+  components: {
+    
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  data() {
+    return {
+      title: "确认创建任务",
+      tableData: [{
+        build: 'A栋',
+        floor: '12F',
+        EquipLocalName: 'XXXXXXXXXXX',
+        EquipLocalId: '5484161891',
+        EquipName: '低压开关柜',
+        installation: '王小虎夫妻店',
+        type: '1'
+      }, {
+        build: 'A栋',
+        floor: '12F',
+        EquipLocalName: 'XXXXXXXXXXX',
+        EquipLocalId: '5484161891',
+        EquipName: '低压开关柜',
+        installation: '王小虎夫妻店',
+        type: '1',
+        partsList: [{
+          name: '部件1',
+          number: 6
+        }, {
+          name: '部件2',
+          number: 23
+        }, {
+          name: '部件3',
+          number: 5
+        }, {
+          name: '部件4',
+          number: 9
+        }, {
+          name: '部件5',
+          number: 1
+        }]
+      }, {
+        build: 'A栋',
+        floor: '12F',
+        EquipLocalName: 'XXXXXXXXXXX',
+        EquipLocalId: '5484161891',
+        EquipName: '低压开关柜',
+        installation: '王小虎夫妻店',
+        type: '1'
+      }, {
+        build: 'A栋',
+        floor: '12F',
+        EquipLocalName: 'XXXXXXXXXXX',
+        EquipLocalId: '5484161891',
+        EquipName: '低压开关柜',
+        installation: '王小虎夫妻店',
+        type: '1'
+      }],
+      loading: false,
+      selections: [], // 选中项
+      page: {
+        pageSize: 50,
+        pageSizes: [10, 20, 50, 100],
+        pageNumber: 1,
+        total: 0
+      },
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      } // 列表样式
+    };
+  },
+  props: {
+    dialogVisible: Boolean,//是否显示弹窗
+    params: Object //模型和设备的信息
+  },
+  created() { },
+  methods: {
+    getTableData() {
+      let params = {
+        Cascade: [{ Name: 'equipCategory' }],
+        Orders: "CreateTime desc, EquipID desc",
+        PageNumber: this.page.pageNumber,
+        PageSize: this.page.pageSize,
+      }
+      // unshaftInSys(params, res => {
+        /**将模型文件夹和模型文件名加入到table数据中 */
+        this.tableData = res.Content
+        this.page.total = res.Total
+      // })
+    },
+    //选中项修改
+    handleSelectionChange(val) {
+      this.selections = val;
+    },
+    savaRelation() {
+      if(this.selections.length){
+        let params = {
+          
+        }
+        // linkSySh(params, res => {
+          this.$emit('update:dialogVisible',false)
+          this.$message.success('创建成功!')
+          this.$router.push({name:'buildTask'})//跳转回首页
+        // })
+      }else {
+        this.$message('请选择要创建的设备!')
+      }
+    },
+    //改变pagesize
+    handleSizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+      this.getTableData();
+    },
+    //改变pageno
+    handleCurrentChange(pageNo) {
+      this.page.pageNumber = pageNo;
+      this.getTableData();
+    },
+    handleClose(){//关闭弹窗
+      this.$emit('update:dialogVisible',false);
+    }
+  },
+  watch: {
+    dialogVisible(newData,oldData){
+      if(newData){
+        this.tableData = [{
+        build: 'A栋',
+        floor: '12F',
+        EquipLocalName: 'XXXXXXXXXXX',
+        EquipLocalId: '5484161891',
+        EquipName: '低压开关柜',
+        installation: '王小虎夫妻店',
+        type: '1'
+      }, {
+        build: 'A栋',
+        floor: '12F',
+        EquipLocalName: 'XXXXXXXXXXX',
+        EquipLocalId: '5484161891',
+        EquipName: '低压开关柜',
+        installation: '王小虎夫妻店',
+        type: '1',
+        partsList: [{
+          name: '部件1',
+          number: 6
+        }, {
+          name: '部件2',
+          number: 23
+        }, {
+          name: '部件3',
+          number: 5
+        }, {
+          name: '部件4',
+          number: 9
+        }, {
+          name: '部件5',
+          number: 1
+        }]
+      }, {
+        build: 'A栋',
+        floor: '12F',
+        EquipLocalName: 'XXXXXXXXXXX',
+        EquipLocalId: '5484161891',
+        EquipName: '低压开关柜',
+        installation: '王小虎夫妻店',
+        type: '1'
+      }, {
+        build: 'A栋',
+        floor: '12F',
+        EquipLocalName: 'XXXXXXXXXXX',
+        EquipLocalId: '5484161891',
+        EquipName: '低压开关柜',
+        installation: '王小虎夫妻店',
+        type: '1'
+      }]
+        this.page.pageNumber = 1
+        this.getTableData()
+      }
+    }
+  },
+};
+</script>
+<style lang="less" scoped>
+#addEqDialog {
+  .filters {
+    margin-bottom: 10px;
+    /deep/ .el-input__inner {
+      vertical-align: baseline;
+    }
+  }
+  .table-box {
+    height: 370px;
+    .fr{
+      margin-top: 10px;
+    }
+  }
+}
+</style>
+
+<style>
+  .demo-table-expand {
+    font-size: 0;
+  }
+  .demo-table-expand label {
+    width: 90px;
+    color: #99a9bf;
+  }
+  .demo-table-expand .el-form-item {
+    margin-right: 0;
+    margin-bottom: 0;
+    margin-left: 120px;
+    width: 100%;
+  }
+</style>

+ 130 - 0
src/components/data_admin/buildTask/draw/drawModel.vue

@@ -0,0 +1,130 @@
+<template>
+  <div :id="`drawFloor${id}`" class="drawFloor" v-loading="canvasLoading">
+    <canvas :id="`floorCanvas${id}`" :width="cadWidth" :height="cadHeight" ref="canvas" tabindex="0"></canvas>
+  </div>
+</template>
+
+<script>
+import { SGraphyView } from "@sybotan-web/graphy/lib";
+import { DivideFloorScene } from "cad-engine"
+import { SColor, SPoint } from "@sybotan-web/draw/lib";
+import canvasFun from "@/components/business_space/newGraphy/canvasFun"
+import { floorQuery } from "@/api/scan/request";
+export default {
+  components: {
+    
+  },
+  data() {
+    return {
+      drawMainScene: null,
+      view: null,
+      dataKey: '',
+      cadWidth: 800,
+      cadHeight: 600,
+      canvasLoading: false,
+      modelId: '',
+      FloorID: '',
+      Outline: [],
+    };
+  },
+  props: {
+    id: {
+      default: 0
+    },
+    CurrentModelId: String
+  },
+  created() {},
+  mounted() {
+    this.cadWidth = document.getElementById(`drawFloor${this.id}`).offsetWidth;
+    this.cadHeight = document.getElementById(`drawFloor${this.id}`).offsetHeight;
+  },
+  methods: {
+    initGraphy(ModelId) {
+      this.modelId = ModelId;
+      this.clearGraphy()
+      this.scene = new DivideFloorScene();
+      this.canvasLoading = true;
+      this.scene.getFloorData('/modelapi/base-graph/query', { ModelId: ModelId }).then(res => {
+        let Elements = res.EntityList[0].Elements;
+        let flag = false;
+        for (let key in Elements) {
+          if (Elements[key].length > 0) {
+            flag = true;
+          }
+        }
+        if (flag) {
+          this.view.scene = this.scene
+          this.view.fitSceneToView();
+          this.canvasLoading = false;
+          this.view.maxScale = this.view.scale * 10;
+          this.view.minScale = this.view.scale;
+          this.scene.click(this, this.canvasClick);
+        } else {
+          this.canvasLoading = false;
+        }
+      })
+    },
+    getFloorData() {
+      let pa = {
+        Filters: `FloorID='${this.FloorID}'`
+      }
+      floorQuery(pa, res => {
+        let newArr = res.Content[0].Outline.map(t => {
+          return new SPoint(t.X, t.Y);
+        })
+        this.drawMainScene.addSceneMark(newArr)
+      })
+    },
+    getSelectedSpaces(){//获取选中区域
+      if(this.view && this.view.scene){
+        let list =  this.view.scene.getSelectedSpaces();
+        if(list.length){
+          return list
+        } else {
+          this.$message('请选择模型空间')
+          return []
+        }
+      } else {
+        this.$message('请选择模型空间')
+        return []
+      }
+    },
+    // 清空平面图
+    clearGraphy() {
+      if (this.view) {
+        this.view.scene = null;
+        return
+      }
+      let id = `floorCanvas${this.id}`;
+      this.view = new SGraphyView(id)
+    },
+    canvasClick(item,eventObj){//点击平面图事件
+      
+    }
+  },
+  watch: {
+    CurrentModelId: {
+      handler(newName, oldName){
+        if(newName){
+          this.initGraphy(newName)
+        }
+      },
+      immediate: true,
+    }
+  }
+};
+</script>
+<style scoped lang="less">
+.drawFloor {
+  width: 100%;
+  height: 100%;
+  position: relative;
+  .operate {
+    position: absolute;
+    left: 50%;
+    bottom: 20px;
+    transform: translateX(-50%);
+    z-index: 99;
+  }
+}
+</style>

+ 187 - 0
src/components/data_admin/buildTask/table/assetsTable.vue

@@ -0,0 +1,187 @@
+<template>
+  <div class="table-container">
+    <div class="table-list" :style="tableData && tableData.length?'height:calc(100% - 50px);':'height:100%;'">
+      <el-table :data="tableData" style="width: 100%" height="100%" v-loading="loading" :header-cell-style="headerStyle">
+        <el-table-column label="所属建筑楼层" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.Building?scope.row.Building.BuildLocalName?scope.row.Building.BuildLocalName:'':''}} -
+              {{scope.row.Floor?scope.row.Floor.FloorLocalName?scope.row.Floor.FloorLocalName:'':''}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="LocalName" :label="`${inSpaceType}本地名称`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="LocalId" :label="`${inSpaceType}本地编码`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="Family" label="设备族" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="InstallLocation" label="安装位置" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="TaskState" label="任务执行情况" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="action" label="操作" min-width="100">
+          <template slot-scope="scope">
+            <i v-if="scope.row.TaskState == '待验证' || scope.row.TaskState == '未找到'" title="查看详情" class="iconfont icon-xiangqing table-button" @click="handleDetail(scope.$index, scope.row)"></i>
+            <i v-if="scope.row.TaskState == '未找到'" title="重新生成任务" class="iconfont icon-Update table-button" @click="handleRegenerate(scope.$index, scope.row)"></i>
+            <i v-if="scope.row.TaskState == '待验证'" title="删除任务" class="iconfont icon-delete table-button" @click="handleDelete(scope.$index, scope.row)"></i>
+            <i v-if="scope.row.TaskState == '未找到'" title="认可此任务执行情况" class="iconfont icon-lijiqueren table-button" @click="handleConfirm(scope.$index, scope.row)"></i>
+          </template>
+        </el-table-column>
+        <template slot="empty">
+          <div style="height: 60%;transform: translateY(50%);">
+            <i class="icon-wushuju iconfont"></i>
+            数据暂无
+          </div>
+        </template>
+      </el-table>
+    </div>
+    <el-pagination class="right" v-show="tableData && tableData.length" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="page.pageNumber"
+     :page-sizes="page.pageSizes" :page-size="page.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="page.total">
+    </el-pagination>
+    <el-drawer title="任务详情" :visible.sync="drawer" direction="rtl" size="600px">
+      <assets-detail :id="detailId"></assets-detail>
+    </el-drawer>
+  </div>
+</template>
+
+<script>
+import { queryAssetsTask, deleteAssetsTask } from "@/api/data_admin/buildTaskApi"
+import { mapGetters } from "vuex"
+import assetsDetail from '../detail/assetsDetail'
+export default {
+  components: {
+    assetsDetail
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  props: {
+    paramsData: Object,
+  },
+  data() {
+    return {
+      inSpaceType: '资产',
+      loading: false, // loading
+      drawer: false, // 详情侧弹窗
+      detailId: '',
+      tableData: [], //列表数据
+      page: {
+        pageSize: 50,
+        pageSizes: [10, 20, 50, 100],
+        pageNumber: 1,
+        total: 0
+      },
+      taskStateMap: {
+        '-1': '未找到',
+        '0': '已完成',
+        '1': '待验证'
+      },
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      }, // 列表样式
+    };
+  },
+  created() {
+    // this.getTableData()
+  },
+  methods: {
+    // 获取列表数据
+    getTableData() {
+      let params = {
+        Filters: `ProjectId='${this.projectId}'`,
+        Cascade: [
+          {
+            Name: 'familyName'
+          }, {
+            Name: 'building',
+          }, {
+            Name: 'floor',
+          }
+        ],
+        Orders: "CreateTime desc, TaskId asc",
+        PageNumber: this.page.pageNumber,
+        PageSize: this.page.pageSize
+      }
+      if (this.paramsData.buildfloor[0] == "noKnow") {
+        params.Filters += `;BuildingId isNull`
+      } else if (this.paramsData.buildfloor[0] && this.paramsData.buildfloor[0] != "all") {
+        params.Filters += `;BuildingId='${this.paramsData.buildfloor[0]}'`
+        if (this.paramsData.buildfloor[1] == "noKnow") {
+          params.Filters += `;FloorId isNull`
+        } else if (this.paramsData.buildfloor[1] && this.paramsData.buildfloor[1] != "all") {
+          params.Filters += `;FloorId='${this.paramsData.buildfloor[1]}'`
+        }
+      }
+      if(this.paramsData.taskState !== ''){
+        params.Filters += `;TaskState=${this.paramsData.taskState}`
+      }
+      if(this.paramsData.family){
+        params.Filters += `;Family='${this.paramsData.family}'`
+      }
+      queryAssetsTask(params, res => {
+        this.page.total = res.Total;
+        this.tableData = res.Content.map(item => {
+          item.TaskState = this.taskStateMap[item.TaskState]
+          return item
+        })
+      })
+    },
+    // 删除关系
+    handleDelete(index, row) {
+      this.$confirm("确认删除该任务?", "提示", {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        let params = [{TaskId: row.TaskId}]
+        deleteAssetsTask(params, res => {
+          this.$message.success('删除成功')
+          this.getTableData()
+        })
+      }).catch(() => {
+        this.$message("取消删除")
+      })
+    },
+    //查看任务详情
+    handleDetail() {
+      this.drawer = true
+      this.detailId = row.TaskId
+    },
+    // 改变pagesize
+    handleSizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+      this.getTableData()
+    },
+    // 改变pageno
+    handleCurrentChange(pageNo) {
+      this.page.pageNumber = pageNo;
+      this.getTableData()
+    }
+  },
+  watch: {
+    paramsData: {
+      handler(newName, oldName) {
+        this.page.pageNumber = 1
+        this.getTableData()
+      },
+      immediate: true,
+      deep: true
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+/deep/ .el-drawer__body {
+  height: calc(100% - 80px);
+  border-top: 1px solid #c9c9c9;
+}
+/deep/ .el-drawer__header {
+  margin-bottom: 12px;
+}
+.table-container {
+  height: 100%;
+  background: #fff;
+  .table-button{
+    cursor: pointer;
+    margin-right: 15px;
+  }
+}
+</style>

+ 207 - 0
src/components/data_admin/buildTask/table/deviceTable.vue

@@ -0,0 +1,207 @@
+<template>
+  <div class="table-container">
+    <div class="table-list" :style="tableData && tableData.length?'height:calc(100% - 50px);':'height:100%;'">
+      <el-table :data="tableData" style="width: 100%" height="100%" v-loading="loading" :header-cell-style="headerStyle">
+        <el-table-column label="所属建筑楼层" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.Building?scope.row.Building.BuildLocalName?scope.row.Building.BuildLocalName:'':''}} -
+              {{scope.row.Floor?scope.row.Floor.FloorLocalName?scope.row.Floor.FloorLocalName:'':''}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column :label="`${inSpaceType}本地名称`" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.LocalName}}
+              <el-badge v-if="scope.row.Equipment?scope.row.Equipment.Component?scope.row.Equipment.Component.length:false:false" 
+                :value="scope.row.Equipment?scope.row.Equipment.Component?scope.row.Equipment.Component.length:0:0" class="item" type="warning">
+              </el-badge>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="LocalId" :label="`${inSpaceType}本地编码`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="Equipment.EquipCategory.EquipName" :label="`${inSpaceType}类型`" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.Equipment?
+              scope.row.Equipment.EquipCategory?
+              scope.row.Equipment.EquipCategory.EquipName?
+              scope.row.Equipment.EquipCategory.EquipName:'':'':''}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="InstallLocation" label="安装位置" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="TaskState" label="任务执行情况" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="action" label="操作" min-width="100">
+          <template slot-scope="scope">
+            <i v-if="scope.row.TaskState == '待验证' || scope.row.TaskState == '未找到'" title="查看详情" class="iconfont icon-xiangqing table-button" @click="handleDetail(scope.$index, scope.row)"></i>
+            <i v-if="scope.row.TaskState == '未找到'" title="重新生成任务" class="iconfont icon-Update table-button" @click="handleRegenerate(scope.$index, scope.row)"></i>
+            <i v-if="scope.row.TaskState == '待验证'" title="删除任务" class="iconfont icon-delete table-button" @click="handleDelete(scope.$index, scope.row)"></i>
+            <i v-if="scope.row.TaskState == '未找到'" title="认可此任务执行情况" class="iconfont icon-lijiqueren table-button" @click="handleConfirm(scope.$index, scope.row)"></i>
+          </template>
+        </el-table-column>
+        <template slot="empty">
+          <div style="height: 60%;transform: translateY(50%);">
+            <i class="icon-wushuju iconfont"></i>
+            数据暂无
+          </div>
+        </template>
+      </el-table>
+    </div>
+    <el-pagination class="right" v-show="tableData && tableData.length" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="page.pageNumber"
+     :page-sizes="page.pageSizes" :page-size="page.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="page.total">
+    </el-pagination>
+    <el-drawer title="任务详情" :visible.sync="drawer" direction="rtl" size="600px">
+      <device-detail :id="detailId"></device-detail>
+    </el-drawer>
+  </div>
+</template>
+
+<script>
+import { queryDeviceTask, deleteDeviceTask } from "@/api/data_admin/buildTaskApi"
+import { mapGetters } from "vuex"
+import deviceDetail from '../detail/deviceDetail'
+export default {
+  components: {
+    deviceDetail
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  props: {
+    paramsData: Object,
+  },
+  data() {
+    return {
+      inSpaceType: '设备',
+      loading: false, // loading
+      drawer: false, // 详情侧弹窗
+      detailId: '',
+      tableData: [], //列表数据
+      page: {
+        pageSize: 50,
+        pageSizes: [10, 20, 50, 100],
+        pageNumber: 1,
+        total: 0
+      },
+      taskStateMap: {
+        '-1': '未找到',
+        '0': '已完成',
+        '1': '待验证'
+      },
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      }, // 列表样式
+    };
+  },
+  created() {
+    // this.getTableData()
+  },
+  methods: {
+    // 获取列表数据
+    getTableData() {
+      let params = {
+        Filters: `ProjectId='${this.projectId}'`,
+        Cascade: [
+          {
+            Name: 'component'
+          }, {
+            Name: 'building',
+          }, {
+            Name: 'floor',
+          }, {
+            Name: 'equipCategory'
+          }
+        ],
+        Orders: "CreateTime desc, TaskId asc",
+        PageNumber: this.page.pageNumber,
+        PageSize: this.page.pageSize
+      }
+      if (this.paramsData.buildfloor[0] == "noKnow") {
+        params.Filters += `;BuildingId isNull`
+      } else if (this.paramsData.buildfloor[0] && this.paramsData.buildfloor[0] != "all") {
+        params.Filters += `;BuildingId='${this.paramsData.buildfloor[0]}'`
+        if (this.paramsData.buildfloor[1] == "noKnow") {
+          params.Filters += `;FloorId isNull`
+        } else if (this.paramsData.buildfloor[1] && this.paramsData.buildfloor[1] != "all") {
+          params.Filters += `;FloorId='${this.paramsData.buildfloor[1]}'`
+        }
+      }
+      if(this.paramsData.taskState !== ''){
+        params.Filters += `;TaskState=${this.paramsData.taskState}`
+      }
+      if(this.paramsData.category){
+        params.Filters += `;Category='${this.paramsData.category}'`
+      }
+      queryDeviceTask(params, res => {
+        this.page.total = res.Total;
+        this.tableData = res.Content.map(item => {
+          item.TaskState = this.taskStateMap[item.TaskState]
+          return item
+        })
+      })
+    },
+    // 删除关系
+    handleDelete(index, row) {
+      this.$confirm("确认删除该任务?", "提示", {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        let params = [{TaskId: row.TaskId}]
+        deleteDeviceTask(params, res => {
+          this.$message.success('删除成功')
+          this.getTableData()
+        })
+      }).catch(() => {
+        this.$message("取消删除")
+      })
+    },
+    //查看任务详情
+    handleDetail(index, row) {
+      this.drawer = true
+      this.detailId = row.TaskId
+    },
+    // 改变pagesize
+    handleSizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+      this.getTableData()
+    },
+    // 改变pageno
+    handleCurrentChange(pageNo) {
+      this.page.pageNumber = pageNo;
+      this.getTableData()
+    }
+  },
+  watch: {
+    paramsData: {
+      handler(newName, oldName) {
+        this.page.pageNumber = 1
+        this.getTableData()
+      },
+      immediate: true,
+      deep: true
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+/deep/ .el-drawer__body {
+  height: calc(100% - 80px);
+  border-top: 1px solid #c9c9c9;
+}
+/deep/ .el-drawer__header {
+  margin-bottom: 12px;
+}
+.table-container {
+  height: 100%;
+  background: #fff;
+  .table-button{
+    cursor: pointer;
+    margin-right: 15px;
+  }
+}
+</style>

+ 185 - 0
src/components/data_admin/buildTask/table/modelTable.vue

@@ -0,0 +1,185 @@
+<template>
+  <div class="table-container">
+    <div class="table-list" :style="tableData && tableData.length?'height:calc(100% - 50px);':'height:100%;'">
+      <el-table :data="tableData" style="width: 100%" height="100%" v-loading="loading" :header-cell-style="headerStyle">
+        <el-table-column prop="FolderName" label="所属模型文件夹" show-overflow-tooltip min-width="80"></el-table-column>
+        <el-table-column prop="FileName" label="模型文件名" show-overflow-tooltip min-width="80"></el-table-column>
+        <el-table-column :label="`${inSpaceType}本地名称`" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.LocalName}}
+              <el-badge v-if="scope.row.Equipment?scope.row.Equipment.Component?scope.row.Equipment.Component.length:false:false" 
+                :value="scope.row.Equipment?scope.row.Equipment.Component?scope.row.Equipment.Component.length:0:0" class="item" type="warning">
+              </el-badge>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="LocalId" :label="`${inSpaceType}本地编码`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column :label="`${inSpaceType}类型`" show-overflow-tooltip min-width="80">
+          <template slot-scope="scope">
+            <div>{{scope.row.EquipCategory?scope.row.EquipCategory.EquipName?scope.row.EquipCategory.EquipName:'':''}}</div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="BIMID" label="BIM ID" show-overflow-tooltip min-width="190"></el-table-column>
+        <el-table-column prop="TaskState" label="任务执行情况" show-overflow-tooltip min-width="60"></el-table-column>
+        <el-table-column prop="action" label="操作" min-width="100">
+          <template slot-scope="scope">
+            <i v-if="scope.row.TaskState == '待验证' || scope.row.TaskState == '未找到'" title="查看详情" class="iconfont icon-xiangqing table-button" @click="handleDetail(scope.$index, scope.row)"></i>
+            <i v-if="scope.row.TaskState == '未找到'" title="重新生成任务" class="iconfont icon-Update table-button" @click="handleRegenerate(scope.$index, scope.row)"></i>
+            <i v-if="scope.row.TaskState == '待验证'" title="删除任务" class="iconfont icon-delete table-button" @click="handleDelete(scope.$index, scope.row)"></i>
+            <i v-if="scope.row.TaskState == '未找到'" title="认可此任务执行情况" class="iconfont icon-lijiqueren table-button" @click="handleConfirm(scope.$index, scope.row)"></i>
+          </template>
+        </el-table-column>
+        <template slot="empty">
+          <div style="height: 60%;transform: translateY(50%);">
+            <i class="icon-wushuju iconfont"></i>
+            数据暂无
+          </div>
+        </template>
+      </el-table>
+    </div>
+    <el-pagination class="right" v-show="tableData && tableData.length" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="page.pageNumber"
+     :page-sizes="page.pageSizes" :page-size="page.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="page.total">
+    </el-pagination>
+    <el-drawer title="任务详情" :visible.sync="drawer" direction="rtl" size="600px">
+      <device-detail :id="detailId"></device-detail>
+    </el-drawer>
+  </div>
+</template>
+
+<script>
+import { queryModelTask, deleteModelTask } from "@/api/data_admin/buildTaskApi"
+import { mapGetters } from "vuex"
+import deviceDetail from '../detail/deviceDetail'
+export default {
+  components: {
+    deviceDetail
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  props: {
+    paramsData: Object,
+  },
+  data() {
+    return {
+      inSpaceType: '设备',
+      loading: false, // loading
+      drawer: false, // 详情侧弹窗
+      detailId: '',
+      tableData: [], //列表数据
+      taskStateMap: {
+        '-1': '未找到',
+        '0': '已完成',
+        '1': '待验证'
+      },
+      page: {
+        pageSize: 50,
+        pageSizes: [10, 20, 50, 100],
+        pageNumber: 1,
+        total: 0
+      },
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      }, // 列表样式
+    };
+  },
+  created() {
+    // this.getTableData()
+  },
+  methods: {
+    // 获取列表数据
+    getTableData() {
+      let params = {
+        Filters: `ProjectId='${this.projectId}'`,
+        Cascade: [
+          {
+            Name: 'component'
+          }, {
+            Name: 'equipCategory'
+          }
+        ],
+        Orders: "CreateTime desc, TaskId asc",
+        PageNumber: this.page.pageNumber,
+        PageSize: this.page.pageSize
+      }
+      if(this.paramsData.taskState !== ''){
+        params.Filters += `;TaskState=${this.paramsData.taskState}`
+      }
+      if(this.paramsData.modelFile){
+        params.Filters += `;FileId='${this.paramsData.modelFile}'`
+      }
+      if(this.paramsData.category){
+        params.Filters += `;Category='${this.paramsData.category}'`
+      }
+      queryModelTask(params, res => {
+        this.page.total = res.Total;
+        this.tableData = res.Content.map(item => {
+          item.TaskState = this.taskStateMap[item.TaskState]
+          return item
+        })
+      })
+    },
+    // 删除关系
+    handleDelete(index, row) {
+      this.$confirm("确认删除该任务?", "提示", {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        let params = [{TaskId: row.TaskId}]
+        deleteModelTask(params, res => {
+          this.$message.success('删除成功')
+          this.getTableData()
+        })
+      }).catch(() => {
+        this.$message("取消删除")
+      })
+    },
+    //查看任务详情
+    handleDetail(index, row) {
+      this.drawer = true
+      this.detailId = row.TaskId
+    },
+    // 改变pagesize
+    handleSizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+      this.getTableData()
+    },
+    // 改变pageno
+    handleCurrentChange(pageNo) {
+      this.page.pageNumber = pageNo;
+      this.getTableData()
+    }
+  },
+  watch: {
+    paramsData: {
+      handler(newName, oldName) {
+        this.page.pageNumber = 1
+        this.getTableData()
+      },
+      immediate: true,
+      deep: true
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+/deep/ .el-drawer__body {
+  height: calc(100% - 80px);
+  border-top: 1px solid #c9c9c9;
+}
+/deep/ .el-drawer__header {
+  margin-bottom: 12px;
+}
+.table-container {
+  height: 100%;
+  background: #fff;
+  .table-button{
+    cursor: pointer;
+    margin-right: 15px;
+  }
+}
+</style>

+ 191 - 0
src/components/data_admin/buildTask/table/replaceTable.vue

@@ -0,0 +1,191 @@
+<template>
+  <div class="table-container">
+    <div class="table-list" :style="tableData && tableData.length?'height:calc(100% - 50px);':'height:100%;'">
+      <el-table :data="tableData" style="width: 100%" height="100%" v-loading="loading" :header-cell-style="headerStyle">
+        <el-table-column label="所属建筑楼层" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.Building?scope.row.Building.BuildLocalName?scope.row.Building.BuildLocalName:'':''}} -
+              {{scope.row.Floor?scope.row.Floor.FloorLocalName?scope.row.Floor.FloorLocalName:'':''}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="LocalName" :label="`${inSpaceType}本地名称`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="LocalId" :label="`${inSpaceType}本地编码`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="Family" label="设备族" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="InstallLocation" label="安装位置" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="TaskType" label="任务执行情况" show-overflow-tooltip min-width="100"></el-table-column>
+        <!-- <el-table-column prop="action" label="操作" min-width="100">
+          <template slot-scope="scope">
+            <i v-if="scope.row.TaskState == '待验证' || scope.row.TaskState == '未找到'" title="查看详情" class="iconfont icon-xiangqing table-button" @click="handleDetail(scope.$index, scope.row)"></i>
+            <i v-if="scope.row.TaskState == '未找到'" title="重新生成任务" class="iconfont icon-Update table-button" @click="handleRegenerate(scope.$index, scope.row)"></i>
+            <i v-if="scope.row.TaskState == '待验证'" title="删除任务" class="iconfont icon-delete table-button" @click="handleDelete(scope.$index, scope.row)"></i>
+            <i v-if="scope.row.TaskState == '未找到'" title="认可此任务执行情况" class="iconfont icon-lijiqueren table-button" @click="handleConfirm(scope.$index, scope.row)"></i>
+          </template>
+        </el-table-column> -->
+        <template slot="empty">
+          <div style="height: 60%;transform: translateY(50%);">
+            <i class="icon-wushuju iconfont"></i>
+            数据暂无
+          </div>
+        </template>
+      </el-table>
+    </div>
+    <el-pagination class="right" v-show="tableData && tableData.length" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="page.pageNumber"
+     :page-sizes="page.pageSizes" :page-size="page.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="page.total">
+    </el-pagination>
+    <el-drawer title="任务详情" :visible.sync="drawer" direction="rtl" size="600px">
+      <assets-detail :id="detailId"></assets-detail>
+    </el-drawer>
+  </div>
+</template>
+
+<script>
+import { queryAssetsTask, deleteAssetsTask } from "@/api/data_admin/buildTaskApi"
+import { mapGetters } from "vuex"
+import assetsDetail from '../detail/assetsDetail'
+export default {
+  components: {
+    assetsDetail
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  props: {
+    paramsData: Object,
+  },
+  data() {
+    return {
+      inSpaceType: '资产',
+      loading: false, // loading
+      drawer: false, // 详情侧弹窗
+      detailId: '',
+      tableData: [], //列表数据
+      page: {
+        pageSize: 50,
+        pageSizes: [10, 20, 50, 100],
+        pageNumber: 1,
+        total: 0
+      },
+      taskTypeMap: {//待撕码,待换码
+
+      },
+      taskStateMap: {
+        '-1': '未找到',
+        '0': '已完成',
+        '1': '待验证'
+      },
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      }, // 列表样式
+    };
+  },
+  created() {
+    // this.getTableData()
+  },
+  methods: {
+    // 获取列表数据
+    getTableData() {
+      let params = {
+        Filters: `ProjectId='${this.projectId}'`,
+        Cascade: [
+          {
+            Name: 'familyName'
+          }, {
+            Name: 'building',
+          }, {
+            Name: 'floor',
+          }
+        ],
+        Orders: "CreateTime desc, TaskId asc",
+        PageNumber: this.page.pageNumber,
+        PageSize: this.page.pageSize
+      }
+      if (this.paramsData.buildfloor[0] == "noKnow") {
+        params.Filters += `;BuildingId isNull`
+      } else if (this.paramsData.buildfloor[0] && this.paramsData.buildfloor[0] != "all") {
+        params.Filters += `;BuildingId='${this.paramsData.buildfloor[0]}'`
+        if (this.paramsData.buildfloor[1] == "noKnow") {
+          params.Filters += `;FloorId isNull`
+        } else if (this.paramsData.buildfloor[1] && this.paramsData.buildfloor[1] != "all") {
+          params.Filters += `;FloorId='${this.paramsData.buildfloor[1]}'`
+        }
+      }
+      if(this.paramsData.taskState !== ''){
+        params.Filters += `;TaskState=${this.paramsData.taskState}`
+      }
+      if(this.paramsData.family){
+        params.Filters += `;Family='${this.paramsData.family}'`
+      }
+      queryAssetsTask(params, res => {
+        this.page.total = res.Total;
+        this.tableData = res.Content.map(item => {
+          item.TaskState = this.taskStateMap[item.TaskState]
+          item.TaskType = this.taskTypeMap[item.TaskType]
+          return item
+        })
+      })
+    },
+    // 删除关系
+    handleDelete(index, row) {
+      this.$confirm("确认删除该任务?", "提示", {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        let params = [{TaskId: row.TaskId}]
+        deleteAssetsTask(params, res => {
+          this.$message.success('删除成功')
+          this.getTableData()
+        })
+      }).catch(() => {
+        this.$message("取消删除")
+      })
+    },
+    //查看任务详情
+    handleDetail() {
+      this.drawer = true
+      this.detailId = row.TaskId
+    },
+    // 改变pagesize
+    handleSizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+      this.getTableData()
+    },
+    // 改变pageno
+    handleCurrentChange(pageNo) {
+      this.page.pageNumber = pageNo;
+      this.getTableData()
+    }
+  },
+  watch: {
+    paramsData: {
+      handler(newName, oldName) {
+        this.page.pageNumber = 1
+        this.getTableData()
+      },
+      immediate: true,
+      deep: true
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+/deep/ .el-drawer__body {
+  height: calc(100% - 80px);
+  border-top: 1px solid #c9c9c9;
+}
+/deep/ .el-drawer__header {
+  margin-bottom: 12px;
+}
+.table-container {
+  height: 100%;
+  background: #fff;
+  .table-button{
+    cursor: pointer;
+    margin-right: 15px;
+  }
+}
+</style>

+ 191 - 0
src/components/data_admin/buildTask/table/tearTable.vue

@@ -0,0 +1,191 @@
+<template>
+  <div class="table-container">
+    <div class="table-list" :style="tableData && tableData.length?'height:calc(100% - 50px);':'height:100%;'">
+      <el-table :data="tableData" style="width: 100%" height="100%" v-loading="loading" :header-cell-style="headerStyle">
+        <el-table-column label="所属建筑楼层" show-overflow-tooltip min-width="100">
+          <template slot-scope="scope">
+            <div>
+              {{scope.row.Building?scope.row.Building.BuildLocalName?scope.row.Building.BuildLocalName:'':''}} -
+              {{scope.row.Floor?scope.row.Floor.FloorLocalName?scope.row.Floor.FloorLocalName:'':''}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="LocalName" :label="`${inSpaceType}本地名称`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="LocalId" :label="`${inSpaceType}本地编码`" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="Family" label="设备族" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="InstallLocation" label="安装位置" show-overflow-tooltip min-width="100"></el-table-column>
+        <el-table-column prop="TaskType" label="任务执行情况" show-overflow-tooltip min-width="100"></el-table-column>
+        <!-- <el-table-column prop="action" label="操作" min-width="100">
+          <template slot-scope="scope">
+            <i v-if="scope.row.TaskState == '待验证' || scope.row.TaskState == '未找到'" title="查看详情" class="iconfont icon-xiangqing table-button" @click="handleDetail(scope.$index, scope.row)"></i>
+            <i v-if="scope.row.TaskState == '未找到'" title="重新生成任务" class="iconfont icon-Update table-button" @click="handleRegenerate(scope.$index, scope.row)"></i>
+            <i v-if="scope.row.TaskState == '待验证'" title="删除任务" class="iconfont icon-delete table-button" @click="handleDelete(scope.$index, scope.row)"></i>
+            <i v-if="scope.row.TaskState == '未找到'" title="认可此任务执行情况" class="iconfont icon-lijiqueren table-button" @click="handleConfirm(scope.$index, scope.row)"></i>
+          </template>
+        </el-table-column> -->
+        <template slot="empty">
+          <div style="height: 60%;transform: translateY(50%);">
+            <i class="icon-wushuju iconfont"></i>
+            数据暂无
+          </div>
+        </template>
+      </el-table>
+    </div>
+    <el-pagination class="right" v-show="tableData && tableData.length" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="page.pageNumber"
+     :page-sizes="page.pageSizes" :page-size="page.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="page.total">
+    </el-pagination>
+    <el-drawer title="任务详情" :visible.sync="drawer" direction="rtl" size="600px">
+      <assets-detail :id="detailId"></assets-detail>
+    </el-drawer>
+  </div>
+</template>
+
+<script>
+import { queryAssetsTask, deleteAssetsTask } from "@/api/data_admin/buildTaskApi"
+import { mapGetters } from "vuex"
+import assetsDetail from '../detail/assetsDetail'
+export default {
+  components: {
+    assetsDetail
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"])
+  },
+  props: {
+    paramsData: Object,
+  },
+  data() {
+    return {
+      inSpaceType: '资产',
+      loading: false, // loading
+      drawer: false, // 详情侧弹窗
+      detailId: '',
+      tableData: [], //列表数据
+      page: {
+        pageSize: 50,
+        pageSizes: [10, 20, 50, 100],
+        pageNumber: 1,
+        total: 0
+      },
+      taskTypeMap: {//待撕码,待换码
+
+      },
+      taskStateMap: {
+        '-1': '未找到',
+        '0': '已完成',
+        '1': '待验证'
+      },
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      }, // 列表样式
+    };
+  },
+  created() {
+    // this.getTableData()
+  },
+  methods: {
+    // 获取列表数据
+    getTableData() {
+      let params = {
+        Filters: `ProjectId='${this.projectId}'`,
+        Cascade: [
+          {
+            Name: 'familyName'
+          }, {
+            Name: 'building',
+          }, {
+            Name: 'floor',
+          }
+        ],
+        Orders: "CreateTime desc, TaskId asc",
+        PageNumber: this.page.pageNumber,
+        PageSize: this.page.pageSize
+      }
+      if (this.paramsData.buildfloor[0] == "noKnow") {
+        params.Filters += `;BuildingId isNull`
+      } else if (this.paramsData.buildfloor[0] && this.paramsData.buildfloor[0] != "all") {
+        params.Filters += `;BuildingId='${this.paramsData.buildfloor[0]}'`
+        if (this.paramsData.buildfloor[1] == "noKnow") {
+          params.Filters += `;FloorId isNull`
+        } else if (this.paramsData.buildfloor[1] && this.paramsData.buildfloor[1] != "all") {
+          params.Filters += `;FloorId='${this.paramsData.buildfloor[1]}'`
+        }
+      }
+      if(this.paramsData.taskState !== ''){
+        params.Filters += `;TaskState=${this.paramsData.taskState}`
+      }
+      if(this.paramsData.family){
+        params.Filters += `;Family='${this.paramsData.family}'`
+      }
+      queryAssetsTask(params, res => {
+        this.page.total = res.Total;
+        this.tableData = res.Content.map(item => {
+          item.TaskState = this.taskStateMap[item.TaskState]
+          item.TaskType = this.taskTypeMap[item.TaskType]
+          return item
+        })
+      })
+    },
+    // 删除关系
+    handleDelete(index, row) {
+      this.$confirm("确认删除该任务?", "提示", {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        let params = [{TaskId: row.TaskId}]
+        deleteAssetsTask(params, res => {
+          this.$message.success('删除成功')
+          this.getTableData()
+        })
+      }).catch(() => {
+        this.$message("取消删除")
+      })
+    },
+    //查看任务详情
+    handleDetail() {
+      this.drawer = true
+      this.detailId = row.TaskId
+    },
+    // 改变pagesize
+    handleSizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+      this.getTableData()
+    },
+    // 改变pageno
+    handleCurrentChange(pageNo) {
+      this.page.pageNumber = pageNo;
+      this.getTableData()
+    }
+  },
+  watch: {
+    paramsData: {
+      handler(newName, oldName) {
+        this.page.pageNumber = 1
+        this.getTableData()
+      },
+      immediate: true,
+      deep: true
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+/deep/ .el-drawer__body {
+  height: calc(100% - 80px);
+  border-top: 1px solid #c9c9c9;
+}
+/deep/ .el-drawer__header {
+  margin-bottom: 12px;
+}
+.table-container {
+  height: 100%;
+  background: #fff;
+  .table-button{
+    cursor: pointer;
+    margin-right: 15px;
+  }
+}
+</style>

+ 155 - 0
src/components/data_admin/buildTask/taskStatistics.vue

@@ -0,0 +1,155 @@
+<template>
+  <div class="statistics-box flex-row">
+		<div class="statistics-all flex-row">
+      <div class="statistics-progress">
+        <div class="statistics-progress-num">
+          <p>{{taskProgress + '%'}}</p>
+          <p>完成情况</p>
+        </div>
+        <el-progress :width="90" type="circle" :percentage="taskProgress" :show-text="false"></el-progress>
+      </div>
+      <div class="statistics-all-box flex-col">
+        <span>总任务:<b>{{allCount}}</b></span>
+        <span>已完成:<b>{{alreadyCount}}</b></span>
+      </div>
+    </div>
+		<ul class="statistics-list flex-row">
+      <li>
+        <p class="statistics-list-text">未找到设备:</p>
+        <p class="statistics-list-num">{{notFoundCount}}</p>
+      </li>
+      <li>
+        <p class="statistics-list-text">未完成验证任务:</p>
+        <p class="statistics-list-num">{{waitCount}}</p>
+      </li>
+      <li>
+        <p class="statistics-list-text">未完成撕码任务:</p>
+        <p class="statistics-list-num">{{waitTearCount}}</p>
+      </li>
+      <li>
+        <p class="statistics-list-text">未完成换码任务:</p>
+        <p class="statistics-list-num">{{waitReplaceCount}}</p>
+      </li>
+    </ul>
+	</div>
+</template>
+
+<script>
+import { mapGetters } from "vuex"
+import { queryTaskCount, countAssetsTask } from "@/api/data_admin/buildTaskApi"
+export default {
+  components: {
+    
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId", "secret", "userId" ]),
+    taskProgress(){
+      if(typeof this.alreadyCount == 'number' && typeof this.allCount == 'number'){
+        return Math.round(this.alreadyCount/this.allCount*100)
+      }
+    }
+  },
+  data() {
+    return {
+      allCount: '',//总任务
+      alreadyCount: '',//已完成
+      notFoundCount: '',//未找到
+      waitCount: '',//未完成验证
+      waitTearCount: '',//未完成撕码任务
+      waitReplaceCount: ''//未完成换码任务
+    }
+  },
+  created() {
+    this.getTaskCount();
+  },
+  methods: {
+    getTaskCount(){
+      queryTaskCount({},(res) => {
+        this.allCount = res.Count
+      })
+      queryTaskCount({Filters: `TaskState=0`},(res) => {
+        this.alreadyCount = res.Count
+      })
+      queryTaskCount({Filters: `TaskState=-1`},(res) => {
+        this.notFoundCount = res.Count
+      })
+      queryTaskCount({Filters: `TaskState=1`},(res) => {
+        this.waitCount = res.Count
+      })
+      countAssetsTask({Filters: `TaskState=1&&TaskType='3'`},(res) => {
+        this.waitTearCount = res.Count
+      })
+      countAssetsTask({Filters: `TaskState=1&&TaskType='2'`},(res) => {
+        this.waitReplaceCount = res.Count
+      })
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+	.statistics-box {
+		height: 120px;
+    color: #333;
+    .statistics-all{
+      flex: 2;
+      border: 1px solid #c9c9c9;
+      margin-right: 10px;
+      background: #fff;
+      .statistics-progress{
+        flex: 1;
+        position: relative;
+        height: 120px;
+        box-sizing: border-box;
+        text-align: center;
+        padding: 15px 0;
+        .statistics-progress-num{
+          font-size: 12px;
+          line-height: 18px;
+          position: absolute;
+          top: 50%;
+          left: 50%;
+          transform: translate(-50%, -50%);
+        }
+      }
+      .statistics-all-box{
+        flex: 1;
+        font-weight: bold;
+        padding: 25px 0;
+        >span{
+          flex: 1;
+          font-size: 15px;
+          line-height: 35px;
+        } 
+      }
+    }
+    .statistics-list{
+      flex: 7;
+      >li{
+        flex: 1;
+        border: 1px solid #c9c9c9;
+        padding: 10px;
+        margin-left: 10px;
+        background: #fff;
+        .statistics-list-text{
+          font-size: 15px;
+          line-height: 30px;
+          font-weight: bold;
+        }
+        .statistics-list-num{
+          text-align: center;
+          font-size: 20px;
+          line-height: 50px;
+          font-weight: bold;
+        }
+      }
+    }
+	}
+  .flex-row{
+    display: flex;
+		flex-direction: row;
+  }
+  .flex-col{
+    display: flex;
+		flex-direction: column;
+  }
+</style>

+ 1 - 1
src/components/ledger/lib/assets.vue

@@ -1,7 +1,7 @@
 <template>
   <div id="cascaderMap">
     <span class="buildFloor" style="padding-right: 12px;">设备族</span>
-    <el-select v-model="value" placeholder="请选择" :props="props" filterable :style="isWidth ? '' : 'width:160px;'" size="small" @change="changeVal">
+    <el-select v-model="value" placeholder="请选择" clearable :props="props" filterable :style="isWidth ? '' : 'width:160px;'" size="small" @change="changeVal">
       <el-option  v-for="item in options" :key="item.code" :label="item.facility" :value="item.code"></el-option>
     </el-select>
     <!-- <el-cascader

+ 1 - 1
src/components/ledger/lib/cascader.vue

@@ -1,7 +1,7 @@
 <template>
   <div id="cascaderMap">
     <span class="buildFloor" style="margin-right: 12px;">设备类别</span>
-    <el-select v-model="value" placeholder="请选择" :props="props" filterable :style="isWidth ? '' : 'width:160px;'" size="small" @change="changeVal">
+    <el-select v-model="value" placeholder="请选择" clearable :props="props" filterable :style="isWidth ? '' : 'width:160px;'" size="small" @change="changeVal">
       <el-option  v-for="item in options" :key="item.code" :label="item.facility" :value="item.code"></el-option>
     </el-select>
     <!-- <el-cascader placeholder="请选择" :options="options" v-model="value" :props="props" filterable :style="isWidth ? '' : 'width:160px;'" size="small"

+ 107 - 0
src/components/ready/buildfloor/modelFile.vue

@@ -0,0 +1,107 @@
+<template>
+    <div id="modelFile">
+        <span class="modelFile" style="margin-right: 12px;">模型文件</span>
+        <el-cascader :options="options" :show-all-levels="false" @change="handleChange" style="width:160px;"
+        @active-item-change='handleItemChange' clearable placeholder="请选择模型文件" v-model="casVal"></el-cascader>
+    </div>
+</template>
+<script>
+import tools from "@/utils/scan/tools"
+import request from "@/api/model/file.js";
+import { mapGetters, mapActions } from "vuex"
+
+export default {
+  computed: {
+    ...mapGetters("layout", [ "projectId", "secret", "userId" ])
+  },
+  data() {
+    return {
+      casVal: [],
+      options: [],
+      modelIdToFloorId: {}
+    };
+  },
+  created() {
+    this.init()
+  },
+  watch: {
+    projectId() {
+      this.casVal =[]
+      this.options = []
+      this.init()
+    }
+  },
+  methods: {
+    //设置默认选项
+    setValue(val) {
+        if (val && val.length) {
+          this.casVal = val
+        }
+    },
+    //获取数据
+    init() {
+      this.getDirectory()
+    },
+    // 获取文件夹
+    getDirectory() {
+      request.queryModel("", res => {
+        this.options = res.Content.map(t => {
+          return {
+            value: t.Id,
+            label: t.Name,
+            children: []
+          }
+        })
+      });
+    },
+    // 通过id查询文件夹下模型文件
+    handleItemChange(val) {
+      let data = {
+        FolderId: val[0],
+        ProjectId: this.projectId
+      };
+      request.queryFloorList(data, res => {
+        let tempArr = res.Content.map(t => {
+          this.modelIdToFloorId[t.CurrentModelId] = t.Id;
+          return {
+            value: t.CurrentModelId,
+            label: t.FloorName
+          }
+        })
+        this.pushChild(this.options, tempArr, val[0])
+      })
+    },
+    // 将模型文件list填到相应的文件夹下
+    pushChild(options, arr, Code) {
+      options.map(option => {
+        if (option.value == Code) {
+          option.children = arr;
+        } else {
+          if (option.children) {
+            this.pushChild(option.children, arr, Code)
+          }
+        }
+      })    
+    },
+    //改变item
+    handleChange(value) {
+      this.$emit("change", value)
+    }
+  }
+};
+</script>
+<style lang="less">
+    .el-cascader .el-input .el-input__inner {
+        vertical-align: bottom;
+    }
+</style>
+<style lang="less" scoped>
+    #modelFile {
+        margin-left: 10px;
+        float: left;
+        .modelFile {
+            color: #999999;
+            font-size: 14px;
+        }
+    }
+</style>

+ 83 - 0
src/components/ready/buildfloor/modelFolder.vue

@@ -0,0 +1,83 @@
+<template>
+  <div id="modelFile">
+    <span class="modelFile" style="margin-right: 12px;">模型文件夹</span>
+    <el-select v-model="casVal" filterable clearable placeholder="请选择模型文件夹" style="width:160px;" @change="handleChange">
+      <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
+    </el-select>
+  </div>
+</template>
+<script>
+import tools from "@/utils/scan/tools"
+import request from "@/api/model/file.js";
+import { mapGetters, mapActions } from "vuex"
+
+export default {
+  computed: {
+    ...mapGetters("layout", ["projectId", "secret", "userId"])
+  },
+  data() {
+    return {
+      casVal: '',
+      options: []
+    };
+  },
+  created() {
+    this.init()
+  },
+  watch: {
+    projectId() {
+      this.casVal = ''
+      this.options = []
+      this.init()
+    }
+  },
+  methods: {
+    //设置默认选项
+    setValue(val) {
+      if (val && val.length) {
+        this.casVal = val
+      }
+    },
+    //获取数据
+    init() {
+      this.getDirectory()
+    },
+    // 获取文件夹
+    getDirectory() {
+      request.queryModel("", res => {
+        this.options = res.Content.map(t => {
+          return {
+            value: t.Id,
+            label: t.Name
+          }
+        })
+      });
+    },
+    //改变item
+    handleChange(value) {
+      this.options.map(item =>{
+        if (item.value == value) {
+          value = item
+        }
+      })
+      value = value?value:{value:''}
+      this.$emit("change", value)
+    }
+  }
+};
+</script>
+<style lang="less">
+.el-cascader .el-input .el-input__inner {
+  vertical-align: bottom;
+}
+</style>
+<style lang="less" scoped>
+#modelFile {
+  margin-left: 10px;
+  float: left;
+  .modelFile {
+    color: #999999;
+    font-size: 14px;
+  }
+}
+</style>

+ 27 - 6
src/router/system.js

@@ -36,6 +36,9 @@ import spaceRela from '@/views/point/dynamicdata/addRelation/spaceRela'
 
 /** 扫楼作业 */
 import buildTask from '@/views/data_admin/buildTask'
+import addDeviceTask from '@/views/data_admin/buildTask/addTask/addDeviceTask'
+import addAssetsTask from '@/views/data_admin/buildTask/addTask/addAssetsTask'
+import addModelTask from '@/views/data_admin/buildTask/addTask/addModelTask'
 import buildAssets from '@/views/data_admin/buildAssets'
 import buildLog from '@/views/data_admin/buildLog'
 import buildData from '@/views/data_admin/buildData'
@@ -191,36 +194,54 @@ export default [
         name: 'LayoutMain',
         component: LayoutMain,
         children: [
-            { path: '', name: 'buildData', component: buildData },
+            { path: '', name: 'buildTask', component: buildTask },
             {
                 path: 'task',
                 name: 'buildTask',
                 component: buildTask,
-                meta: { keepAlive: false, breadcrumbs: [{ label: '扫楼作业', path: '/floor/task' }, { label: '现场任务管理' }] }
+                meta: { keepAlive: false, breadcrumbs: [{ label: '扫楼作业', path: '/floor' }, { label: '现场任务管理' }] }
+            },
+            {
+                path: 'addDeviceTask',
+                name: 'addDeviceTask',
+                component: addDeviceTask,
+                meta: { keepAlive: false, breadcrumbs: [{ label: '扫楼作业', path: '/floor' }, { label: '现场任务管理', path: '/floor/task' }, { label: '现场验证设备台账' }] }
+            },
+            {
+                path: 'addAssetsTask',
+                name: 'addAssetsTask',
+                component: addAssetsTask,
+                meta: { keepAlive: false, breadcrumbs: [{ label: '扫楼作业', path: '/floor' }, { label: '现场任务管理', path: '/floor/task' }, { label: '现场验证资产台账' }] }
+            },
+            {
+                path: 'addModelTask',
+                name: 'addModelTask',
+                component: addModelTask,
+                meta: { keepAlive: false, breadcrumbs: [{ label: '扫楼作业', path: '/floor' }, { label: '现场任务管理', path: '/floor/task' }, { label: '现场验证模型' }] }
             },
             {
                 path: 'data',
                 name: 'buildData',
                 component: buildData,
-                meta: { keepAlive: false, breadcrumbs: [{ label: '扫楼作业', path: '/floor/task' }, { label: '现场数据整理', path: '/floor/data' }, { label: '信息点整理' }] }
+                meta: { keepAlive: false, breadcrumbs: [{ label: '扫楼作业', path: '/floor' }, { label: '现场数据整理', path: '/floor/data' }, { label: '信息点整理' }] }
             },
             {
                 path: 'plan',
                 name: 'buildGraphy',
                 component: buildGraphy,
-                meta: { keepAlive: false, breadcrumbs: [{ label: '扫楼作业', path: '/floor/task' }, { label: '现场数据整理', path: '/floor/data' }, { label: '位置标签整理' }] }
+                meta: { keepAlive: false, breadcrumbs: [{ label: '扫楼作业', path: '/floor' }, { label: '现场数据整理', path: '/floor/data' }, { label: '位置标签整理' }] }
             },
             {
                 path: 'abnormalprop',
                 name: 'buildAssets',
                 component: buildAssets,
-                meta: { keepAlive: false, breadcrumbs: [{ label: '扫楼作业', path: '/floor/task' }, { label: '扫楼报告' }] }
+                meta: { keepAlive: false, breadcrumbs: [{ label: '扫楼作业', path: '/floor' }, { label: '扫楼报告' }] }
             },
             {
                 path: 'log',
                 name: 'buildLog',
                 component: buildLog,
-                meta: { keepAlive: false, breadcrumbs: [{ label: '扫楼作业', path: '/floor/task' }, { label: '扫楼日志查看' }] }
+                meta: { keepAlive: false, breadcrumbs: [{ label: '扫楼作业', path: '/floor' }, { label: '扫楼日志查看' }] }
             }
         ]
     },

+ 258 - 0
src/views/data_admin/buildTask/addTask/addAssetsTask.vue

@@ -0,0 +1,258 @@
+<template>
+  <div class="box">
+    <div class="condition">
+      <div class="header">
+        <!-- <i style="float:left;font-size:30px;padding-right:10px;cursor:pointer;" title="返回" @click="goBack" class="el-icon-back"></i> -->
+        <el-button style="float:left;" size="small" type="default" icon="el-icon-back" @click="goBack"></el-button>
+        <floor-cascader ref="floorCascader" @change="changeFloor"></floor-cascader>
+        <my-cascader ref="cascader" @change="changeDevice"></my-cascader>
+        <el-input placeholder="请输入安装位置" style="width: 200px;margin-left:20px;" v-model="keycode" clearable @keyup.enter.native="getTableData">
+          <i slot="suffix" class="el-input__icon el-icon-search" style="cursor:pointer;" @click="getTableData"></i>
+        </el-input>
+        <el-button style="float:right;margin-top:1px;" @click="handleClickCreate">创建已选</el-button>
+      </div>
+      <div class="main" :style="tableData && tableData.length?'height: calc(100% - 96px);':'height: calc(100% - 46px);'">
+        <el-table ref="multipleTable" :data="tableData" v-loading='loading' stripe height="100%" @selection-change="handleSelectionChange" :header-cell-style="headerStyle">
+          <el-table-column type="selection" width="55"></el-table-column>
+          <el-table-column label="所属建筑楼层" width="200">
+            <template slot-scope="scope">{{ scope.row.build }}-{{ scope.row.floor }}</template>
+          </el-table-column>
+          <el-table-column prop="EquipLocalName" label="资产本地名称" show-overflow-tooltip></el-table-column>
+          <el-table-column prop="EquipLocalId" label="资产本地编码" show-overflow-tooltip width="200"></el-table-column>
+          <el-table-column prop="EquipName" label="设备族"></el-table-column>
+          <el-table-column prop="installation" label="安装位置"></el-table-column>
+          <template slot="empty">
+          <div style="height: 60%;transform: translateY(50%);">
+            <i class="icon-wushuju iconfont"></i>
+            数据暂无
+          </div>
+        </template>
+        </el-table>
+      </div>
+      <div class=footer>
+        <el-pagination
+          class="right"
+          v-show="tableData && tableData.length"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+          :current-page="page.pageNumber"
+          :page-sizes="page.pageSizes"
+          :page-size="page.pageSize"
+          layout="total, sizes, prev, pager, next, jumper"
+          :total="page.total">
+        </el-pagination>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from "vuex"
+//组件
+import floorCascader from "@/components/ledger/lib/floorCascader"
+import myCascader from "@/components/ledger/lib/assets"
+//api
+import { queryPartsDie, createPropertys } from "@/api/scan/request";
+export default {
+  data() {
+    return {
+      params: {},
+      loading: false,
+      page: {
+        pageSize: 50,
+        pageSizes: [10, 20, 50, 100],
+        pageNumber: 1,
+        total: 0
+      },
+      tableData: [{
+        build: 'A栋',
+        floor: '12F',
+        EquipLocalName: 'XXXXXXXXXXX',
+        EquipLocalId: '5484161891',
+        EquipName: '低压开关柜',
+        installation: '王小虎夫妻店',
+        type: '1'
+      }, {
+        build: 'A栋',
+        floor: '12F',
+        EquipLocalName: 'XXXXXXXXXXX',
+        EquipLocalId: '5484161891',
+        EquipName: '低压开关柜',
+        installation: '王小虎夫妻店',
+        type: '1'
+      }, {
+        build: 'A栋',
+        floor: '12F',
+        EquipLocalName: 'XXXXXXXXXXX',
+        EquipLocalId: '5484161891',
+        EquipName: '低压开关柜',
+        installation: '王小虎夫妻店',
+        type: '1'
+      }, {
+        build: 'A栋',
+        floor: '12F',
+        EquipLocalName: 'XXXXXXXXXXX',
+        EquipLocalId: '5484161891',
+        EquipName: '低压开关柜',
+        installation: '王小虎夫妻店',
+        type: '1'
+      }],
+      multipleSelection:[],
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      }, // 列表样式
+    }
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId", "userId", "secret"])
+  },
+  components: {
+    floorCascader,
+    myCascader
+  },
+  created() {
+    this.params = this.$route.query
+  },
+  mounted() {
+    
+  },
+  watch: {
+    projectId() {}
+  },
+  methods: {
+    //返回
+    goBack() {
+      this.$router.push({ name: "buildTask" })
+    },
+    //选择设备或部件
+    changeDevice(val) {
+      if(val.code) {
+        this.params.category = val.code
+      } else {
+        this.params.category = ''
+      }
+      this.page.pageNumber = 1
+      this.getTableData()
+    },
+    //选择建筑楼层
+    changeFloor(value) {
+      if (value[0]) {
+        this.params.buildId = value[0]
+      }
+      if (value[1]) {
+        this.params.floorId = value[1]
+      } else {
+        this.params.floorId = ''
+      }
+      this.page.pageNumber = 1
+      this.getTableData()
+    },
+    //获取表格数据
+    getTableData() {
+      this.loading = true
+      let param = this.formatFilter()
+      queryPartsDie(param, res => {
+        this.tableData = res.Content
+        this.page.total = res.Total
+        this.loading = false
+      })
+    },
+    //格式化条件
+    formatFilter() {
+      let param = {
+        Cascade: [
+          {
+            Name: "equipCategory",
+            Projection: ["EquipCode", "EquipName"]
+          },
+          {
+            Name: "building",
+            Projection: [ "BuildLocalName", "BuildName", "BuildID" ]
+          },
+          {
+            Name: "floor",
+            Projection: [ "FloorLocalName", "FloorName", "FloorID" ]
+          }
+        ],
+        Filters: `category='${this.params.category}';PropertyId isNull`,
+        Orders: "createTime desc, EquipID asc",
+        PageNumber: this.page.pageNumber,
+        PageSize: this.page.pageSize
+      }
+
+      if (this.params.buildId == "noKnow") {
+        param.Filters += `;buildingId isNull`
+      } else if (this.params.buildId && this.params.buildId != "all") {
+        param.Filters += `;buildingId='${this.params.buildId}'`
+      }
+
+      if (this.params.floorId == "noKnow") {
+        param.Filters += `;floorId isNull`
+      } else if (this.params.floorId && this.params.floorId != "all") {
+        param.Filters += `;floorId='${this.params.floorId}'`
+      }
+
+      return param
+    },
+    //选择的设备或部件
+    handleSelectionChange(val) {
+      this.multipleSelection = val;
+    },
+    //切换每页显示多少条数据
+    handleSizeChange(val) {
+      this.page.pageSize = val
+      this.getTableData()
+    },
+    //切换页数
+    handleCurrentChange(val) {
+      this.page.pageNumber = val
+      this.getTableData()
+    },
+    //查看详情
+    handleOpenDetail(row) {
+      // window.open(`http://adm.sagacloud.cn:8058/spread?id=${row.EquipID}&pid=${this.projectId}&secret=${this.secret}`,"_blank")
+      this.$message("开发中...")
+    },
+    //创建已选
+    handleClickCreate() {
+      let list = this.multipleSelection.map((item) => {
+        return item.EquipID
+      })
+      let param = {
+        Filters: `EquipID in ${JSON.stringify(list)}`
+      }
+      createPropertys(param, res => {
+        this.$message.success("创建成功!")
+        this.$router.push({
+          name: "propertyLedger",
+          params: { Family: this.params.Family }
+        })
+      })
+    }
+  }
+};
+</script>
+
+<style scoped lang='less'>
+.box {
+  .condition {
+    padding: 10px;
+    display: flex;
+    height: 100%;
+    flex-direction: column;
+    border: 1px solid #dfe6ec;
+    background: #fff;
+    margin-bottom: 10px;
+    .header{
+      padding-bottom: 10px;
+      border-bottom: 1px solid #bcbcbc;
+    }
+    .main{
+      margin-top: 10px;
+    }
+  }
+}
+</style>
+

+ 303 - 0
src/views/data_admin/buildTask/addTask/addDeviceTask.vue

@@ -0,0 +1,303 @@
+<template>
+  <div class="box">
+    <div class="condition">
+      <div class="header">
+        <el-button style="float:left;" size="small" type="default" icon="el-icon-back" @click="goBack"></el-button>
+        <floor-cascader ref="floorCascader" @change="changeFloor"></floor-cascader>
+        <my-cascader ref="cascader" @change="changeDevice"></my-cascader>
+        <el-input placeholder="请输入安装位置" style="width: 200px;margin-left:20px;" v-model="keycode" clearable @keyup.enter.native="getTableData">
+          <i slot="suffix" class="el-input__icon el-icon-search" style="cursor:pointer;" @click="getTableData"></i>
+        </el-input>
+        <el-button style="float:right;margin-top:1px;" @click="handleClickCreate">创建已选</el-button>
+      </div>
+      <div class="main" :style="tableData && tableData.length?'height: calc(100% - 96px);':'height: calc(100% - 46px);'">
+        <el-table ref="multipleTable" :data="tableData" v-loading='loading' stripe height="100%" @selection-change="handleSelectionChange" :header-cell-style="headerStyle">
+          <el-table-column type="selection" width="55"></el-table-column>
+          <el-table-column type="expand">
+            <template slot-scope="props">
+              <p v-if="props.row.partsList && props.row.partsList.length" style="color:#99a9bf;line-height:32px;font-size:14px;">包含的部件:</p>
+              <el-form label-position="left" inline class="demo-table-expand" v-if="props.row.partsList && props.row.partsList.length">
+                <el-form-item v-for="item in props.row.partsList" :key="item.name" :label="`${item.name}:`">
+                  <span>{{ item.number }}</span>
+                </el-form-item>
+              </el-form>
+            </template>
+          </el-table-column>
+          <el-table-column label="所属建筑楼层" width="200">
+            <template slot-scope="scope">{{ scope.row.build }}-{{ scope.row.floor }}</template>
+          </el-table-column>
+          <el-table-column prop="EquipLocalName" label="设备本地名称" show-overflow-tooltip></el-table-column>
+          <el-table-column prop="EquipLocalId" label="设备本地编码" show-overflow-tooltip width="200"></el-table-column>
+          <el-table-column prop="EquipName" label="设备类"></el-table-column>
+          <el-table-column prop="installation" label="安装位置"></el-table-column>
+          <el-table-column prop="type" label="现场验证操作规定" width="200">
+            <template slot-scope="scope">
+              <el-button @click.native.prevent="handleOpenDetail(scope.row, tableData)" type="text" size="small">详情</el-button>
+            </template>
+          </el-table-column>
+          <template slot="empty">
+            <div style="height: 60%;transform: translateY(50%);">
+              <i class="icon-wushuju iconfont"></i>
+              数据暂无
+            </div>
+          </template>
+        </el-table>
+      </div>
+      <div class=footer>
+        <el-pagination
+          class="right"
+          v-show="tableData && tableData.length"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+          :current-page="page.pageNumber"
+          :page-sizes="page.pageSizes"
+          :page-size="page.pageSize"
+          layout="total, sizes, prev, pager, next, jumper"
+          :total="page.total">
+        </el-pagination>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from "vuex"
+//组件
+import floorCascader from "@/components/ledger/lib/floorCascader"
+import myCascader from "@/components/ledger/lib/cascader"
+//api
+import { queryPartsDie, createPropertys } from "@/api/scan/request";
+export default {
+  data() {
+    return {
+      params: {},
+      loading: false,
+      keycode: '',
+      page: {
+        pageSize: 50,
+        pageSizes: [10, 20, 50, 100],
+        pageNumber: 1,
+        total: 0
+      },
+      tableData: [{
+        build: 'A栋',
+        floor: '12F',
+        EquipLocalName: 'XXXXXXXXXXX',
+        EquipLocalId: '5484161891',
+        EquipName: '低压开关柜',
+        installation: '王小虎夫妻店',
+        type: '1'
+      }, {
+        build: 'A栋',
+        floor: '12F',
+        EquipLocalName: 'XXXXXXXXXXX',
+        EquipLocalId: '5484161891',
+        EquipName: '低压开关柜',
+        installation: '王小虎夫妻店',
+        type: '1',
+        partsList: [{
+          name: '部件1',
+          number: 6
+        }, {
+          name: '部件2',
+          number: 23
+        }, {
+          name: '部件3',
+          number: 5
+        }, {
+          name: '部件4',
+          number: 9
+        }, {
+          name: '部件5',
+          number: 1
+        }]
+      }, {
+        build: 'A栋',
+        floor: '12F',
+        EquipLocalName: 'XXXXXXXXXXX',
+        EquipLocalId: '5484161891',
+        EquipName: '低压开关柜',
+        installation: '王小虎夫妻店',
+        type: '1'
+      }, {
+        build: 'A栋',
+        floor: '12F',
+        EquipLocalName: 'XXXXXXXXXXX',
+        EquipLocalId: '5484161891',
+        EquipName: '低压开关柜',
+        installation: '王小虎夫妻店',
+        type: '1'
+      }],
+      multipleSelection:[],
+      headerStyle: {
+        backgroundColor: '#e1e4e5',
+        color: '#2b2b2b',
+        lineHeight: '30px'
+      }, // 列表样式
+    }
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId", "userId", "secret"])
+  },
+  components: {
+    floorCascader,
+    myCascader
+  },
+  created() {
+    this.params = this.$route.query
+  },
+  mounted() {
+    
+  },
+  watch: {
+    projectId() {}
+  },
+  methods: {
+    //返回
+    goBack() {
+      this.$router.push({ name: "buildTask" })
+    },
+    //选择设备或部件
+    changeDevice(val) {
+      if(val.code) {
+        this.params.category = val.code
+      } else {
+        this.params.category = ''
+      }
+      this.page.pageNumber = 1
+      this.getTableData()
+    },
+    //选择建筑楼层
+    changeFloor(value) {
+      if (value[0]) {
+        this.params.buildId = value[0]
+      }
+      if (value[1]) {
+        this.params.floorId = value[1]
+      } else {
+        this.params.floorId = ''
+      }
+      this.page.pageNumber = 1
+      this.getTableData()
+    },
+    //获取表格数据
+    getTableData() {
+      this.loading = true
+      let param = this.formatFilter()
+      queryPartsDie(param, res => {
+        this.tableData = res.Content
+        this.page.total = res.Total
+        this.loading = false
+      })
+    },
+    //格式化条件
+    formatFilter() {
+      let param = {
+        Cascade: [
+          {
+            Name: "equipCategory",
+            Projection: ["EquipCode", "EquipName"]
+          },
+          {
+            Name: "building",
+            Projection: [ "BuildLocalName", "BuildName", "BuildID" ]
+          },
+          {
+            Name: "floor",
+            Projection: [ "FloorLocalName", "FloorName", "FloorID" ]
+          }
+        ],
+        Filters: `category='${this.params.category}';PropertyId isNull`,
+        Orders: "createTime desc, EquipID asc",
+        PageNumber: this.page.pageNumber,
+        PageSize: this.page.pageSize
+      }
+
+      if (this.params.buildId == "noKnow") {
+        param.Filters += `;buildingId isNull`
+      } else if (this.params.buildId && this.params.buildId != "all") {
+        param.Filters += `;buildingId='${this.params.buildId}'`
+      }
+
+      if (this.params.floorId == "noKnow") {
+        param.Filters += `;floorId isNull`
+      } else if (this.params.floorId && this.params.floorId != "all") {
+        param.Filters += `;floorId='${this.params.floorId}'`
+      }
+
+      return param
+    },
+    //选择的设备或部件
+    handleSelectionChange(val) {
+      this.multipleSelection = val;
+    },
+    //切换每页显示多少条数据
+    handleSizeChange(val) {
+      this.page.pageSize = val
+      this.getTableData()
+    },
+    //切换页数
+    handleCurrentChange(val) {
+      this.page.pageNumber = val
+      this.getTableData()
+    },
+    //查看详情
+    handleOpenDetail(row) {
+      // window.open(`http://adm.sagacloud.cn:8058/spread?id=${row.EquipID}&pid=${this.projectId}&secret=${this.secret}`,"_blank")
+      this.$message("开发中...")
+    },
+    //创建已选
+    handleClickCreate() {
+      let list = this.multipleSelection.map((item) => {
+        return item.EquipID
+      })
+      let param = {
+        Filters: `EquipID in ${JSON.stringify(list)}`
+      }
+      createPropertys(param, res => {
+        this.$message.success("创建成功!")
+        this.$router.push({
+          name: "propertyLedger",
+          params: { Family: this.params.Family }
+        })
+      })
+    }
+  }
+};
+</script>
+
+<style scoped lang='less'>
+.box {
+  .condition {
+    padding: 10px;
+    display: flex;
+    height: 100%;
+    flex-direction: column;
+    border: 1px solid #dfe6ec;
+    background: #fff;
+    .header{
+      padding-bottom: 10px;
+      border-bottom: 1px solid #bcbcbc;
+    }
+    .main{
+      margin-top: 10px;
+    }
+  }
+}
+</style>
+
+<style>
+  .demo-table-expand {
+    font-size: 0;
+  }
+  .demo-table-expand label {
+    width: 90px;
+    color: #99a9bf;
+  }
+  .demo-table-expand .el-form-item {
+    margin-right: 0;
+    margin-bottom: 0;
+    margin-left: 120px;
+    width: 100%;
+  }
+</style>

+ 192 - 0
src/views/data_admin/buildTask/addTask/addModelTask.vue

@@ -0,0 +1,192 @@
+<template>
+  <div id="bd-fl-manage">
+    <div class="header-nav">
+      <el-button style="float:left;margin-right:20px;" size="small" type="default" icon="el-icon-back" @click="goBack"></el-button>
+      <model-folder ref="modelFolder" @change="handleChangeModelFolder" style="margin-right:10px;"></model-folder>
+      <my-cascader :isWidth="false" ref="cascader" @change="changeDevice"></my-cascader>
+      <el-button style="float:right;margin-top:1px;" @click="handleClickCreate">创建所选</el-button>
+    </div>
+    <el-row>
+      <div class="l-list">
+        <h4>模型文件</h4>
+        <div class="model-file-list">
+          <el-scrollbar style="height:100%;">
+            <div v-for="item in modelFileList" :key="item.Id" :class="{'model-file-item':true,'active':item.active}" @click="handleChangeModelFile(item)">
+              <span>{{item.FloorName}}</span>
+            </div>
+          </el-scrollbar>
+        </div>
+      </div>
+      <div class="r-model">
+        <draw-model ref="drawModel" :id="1" :CurrentModelId="CurrentModelId"></draw-model>
+      </div>
+    </el-row>
+    <modelTask-dialog :dialogVisible.sync="dialogVisible" :params="params"></modelTask-dialog>
+  </div>
+</template>
+
+<script>
+import modelFolder from "@/components/ready/buildfloor/modelFolder"
+import myCascader from "@/components/ledger/lib/cascader"
+import drawModel from "@/components/data_admin/buildTask/draw/drawModel"
+import modelTaskDialog from "@/components/data_admin/buildTask/dialog/modelTaskDialog"
+import { mapGetters, mapActions } from "vuex";
+import request from "@/api/model/file.js";
+import {} from "@/api/scan/request";
+export default {
+  components: {
+    modelFolder,
+    myCascader,
+    drawModel,
+    modelTaskDialog
+  },
+  data() {
+    return {
+      dialogVisible: false,//是否显示弹窗
+      modelFolderName: '',//模型文件夹名字
+      modelFileName: '',//模型文件名字
+      modelFileList: [],
+      CurrentModelId: '',
+      device: '',//设备类别
+      spaceList: []//选中的空间
+    };
+  },
+  computed: {
+    ...mapGetters("layout", ["projectId"]),
+    params(){
+      return {
+        device: this.device,
+        modelFolderName: this.modelFolderName,
+        modelFileName: this.modelFileName,
+        spaceList: this.spaceList
+      }
+    }
+  },
+  mounted() { },
+  created() {
+    
+  },
+  methods: {
+    goBack(){//返回
+      this.$router.push({name:'buildTask'})
+    },
+    handleChangeModelFolder(item){//切换模型文件夹
+      let val = item.value
+      if(val){
+        this.modelFolderName = item.label
+        let data = {
+          FolderId: val,
+          ProjectId: this.projectId
+        };
+        request.queryFloorList(data, res => {
+          this.modelFileList = res.Content.map(item => {
+            item.active = false
+            return item
+          })
+          if (this.modelFileList.length) {
+            this.handleChangeModelFile(this.modelFileList[0]);
+          }
+        })
+      } else {
+        this.resetSelected()
+      }
+    },
+    resetSelected(){
+      this.modelFileList = []
+      this.CurrentModelId = ''
+      this.modelFolderName = ''
+      this.spaceList = []
+      this.$refs.drawModel.clearGraphy()
+    },
+    handleChangeModelFile(file){//切换模型文件
+      this.modelFileList.map(item => {
+        file.Id == item.Id?item.active = true:item.active = false
+        return item
+      })
+      this.CurrentModelId = file.CurrentModelId
+      this.modelFileName = file.FloorName
+    },
+    changeDevice(val){//切换设备类别
+      this.device = val.code
+    },
+    handleClickCreate(){//创建已选
+      this.spaceList = this.$refs.drawModel.getSelectedSpaces().map(item => {
+        return item.data.SourceId
+      })
+      this.dialogVisible = true
+    }
+  },
+  watch: {
+    projectId() {
+      this.resetSelected()
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+#bd-fl-manage {
+  overflow: hidden;
+  height: 100%;
+  position: relative;
+  .header-nav{
+    height: 32px;
+    padding-bottom: 10px;
+  }
+  .el-row {
+    height: calc(100% - 50px);
+    & > div {
+      float: left;
+      height: 100%;
+      overflow: hidden;
+      background-color: #fff;
+      box-sizing: border-box;
+      border: 1px solid #dfe6ec;
+      .action-box {
+        padding: 10px;
+        .el-button--small {
+          padding: 10px 11px;
+        }
+      }
+    }
+    .l-list {
+      width: 250px;
+      height: 100%;
+      border-right: 0;
+      h4 {
+        padding-left: 10px;
+        border-top: 1px solid #d9d9d9;
+        border-bottom: 1px solid #dfe6ec;
+        background: #d9d9d9;
+        color: #333;
+        line-height: 44px;
+      }
+      .model-file-list {
+        height: calc(100% - 46px);
+        line-height: 48px;
+        /deep/.el-scrollbar__wrap {
+          overflow-x: hidden;
+        }
+        .model-file-item {
+          white-space: nowrap;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          cursor: pointer;
+          span {
+            margin-left: 10px;
+          }
+        }
+        .model-file-item.active,
+        .model-file-item:hover {
+          background-color: #f5f7fa;
+          color: #000;
+        }
+      }
+    }
+    .r-model {
+      width: calc(100% - 250px);
+      box-sizing: border-box;
+      padding: 10px;
+    }
+  }
+}
+</style>

+ 150 - 30
src/views/data_admin/buildTask/index.vue

@@ -1,36 +1,156 @@
 <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>
+		<task-statistics></task-statistics>
+		<div class="hanson-bar">
+			<el-cascader v-model="taskTypes" :options="taskTypeList" filterable @change="handleChangeTask"></el-cascader>
+			<el-divider direction="vertical"></el-divider>
+			<div class="condition-list">
+				<floor-cascader  v-show="taskType == 'device' || taskType == 'assets'" :isWidth="false" @change="changeFloor"></floor-cascader>
+				<div class="task-state" v-show="taskType == 'model' || taskType == 'device' || taskType == 'assets'">
+					<span class="task-stete-title" style="margin-right: 12px;">任务执行情况</span>
+					<el-select v-model="taskState" placeholder="请选择" filterable style="width:120px;" size="small" @change="changeState">
+						<el-option  v-for="item in taskStateList" :key="item.code" :label="item.label" :value="item.value"></el-option>
+					</el-select>
+				</div>
+				<model-file  v-show="taskType == 'model'" ref="modelFile" @change="handleChangeModel"></model-file>
+				<my-cascader  v-show="taskType == 'model' || taskType == 'device'" :isWidth="false" ref="cascader" @change="changeDevice"></my-cascader>
+				<assets-cascader  v-show="taskType == 'assets'" :isWidth="false" ref="assets" @change="changeAssets"></assets-cascader>
+			</div>
+			<el-button class="add-task" @click="addTaskDialog = true">添加验证任务</el-button>
+		</div>
+		<div class="tabel-box">
+			<model-table :paramsData="{taskState, modelFile, category}" v-if="taskType == 'model'"></model-table>
+			<device-table :paramsData="{buildfloor, taskState, category}" v-else-if="taskType == 'device'"></device-table>
+			<assets-table :paramsData="{buildfloor, taskState, family}" v-else-if="taskType == 'assets'"></assets-table>
+			<tear-table v-else-if="taskType == 'tear'"></tear-table>
+			<replace-table v-else-if="taskType == 'replace'"></replace-table>
+		</div>
+		<add-task :addTaskDialog.sync="addTaskDialog"></add-task>
+	</div>
 </template>
 
 <script>
-import dasBoard from "@/views/dasboard/index";
+import { mapGetters } from "vuex"
+import taskStatistics from '@/components/data_admin/buildTask/taskStatistics'
+import floorCascader from "@/components/ledger/lib/floorCascader"
+import assetsCascader from "@/components/ledger/lib/assets"
+import myCascader from "@/components/ledger/lib/cascader"
+import modelFile from "@/components/ready/buildfloor/modelFile"
+import modelTable from "@/components/data_admin/buildTask/table/modelTable"
+import deviceTable from "@/components/data_admin/buildTask/table/deviceTable"
+import assetsTable from "@/components/data_admin/buildTask/table/assetsTable"
+import tearTable from "@/components/data_admin/buildTask/table/tearTable"
+import replaceTable from "@/components/data_admin/buildTask/table/replaceTable"
+import addTask from "@/components/data_admin/buildTask/dialog/addTaskDialog"
 export default {
-    components: {
-      dasBoard
-    },
-    data() {
-        return {
-          plan: "2019-08-21",
-          finish: "2019-09-06",
-          onLine: "2019-09-30",
-          explain: "现场任务的创建和修改;v1.2:任务完成情况的查看"
-        }
-    },
-    mounted() {}
+  components: {
+		taskStatistics,
+		floorCascader,
+		modelFile,
+		myCascader,
+		assetsCascader,
+		modelTable,
+		deviceTable,
+		assetsTable,
+		tearTable,
+		replaceTable,
+		addTask
+	},
+	computed: {
+		...mapGetters("layout", [  "projectId",  "secret", "userId" ]),
+		taskType(){
+			return this.taskTypes.slice(-1)[0]
+		}
+	},
+  data() {
+    return {
+			taskTypeList: [
+				{ value: "verification", label: '现场验证任务', children:[
+					{value: "model", label: '现场验证模型'},
+					{value: "device", label: '现场验证设备台账'},
+					{value: "assets", label: '现场验证资产台账'}
+				]}, 
+				{ value: "tear", label: '现场撕码任务' }, 
+				{ value: "replace", label: '现场换码任务' }
+			],
+			taskStateList: [{
+				value: '',
+				label: '全部'
+			}, {
+				value: 1,
+				label: '待验证'
+			}, {
+				value: 0,
+				label: '已完成'
+			}, {
+				value: -1,
+				label: '未找到'
+			}],
+			taskState: '',//任务执行情况
+			modelFile: '',//模型文件
+			category: '',//设备类型
+			family: '',//设备族
+			buildfloor: ['all'],//建筑楼层
+			taskTypes: ['verification','model'],
+			addTaskDialog: false, //是否显示添加任务弹窗
+    }
+  },
+  mounted() { },
+  methods: {
+		handleChangeTask(val){//切换任务类型
+			
+		},
+		handleChangeModel(val) {//修改模型文件
+			if(val[1]){
+				this.modelFile = val[1]
+			} else {
+        this.modelFile = ''
+      }
+		},
+		changeState(val) {//修改任务执行情况
+			this.taskState = val
+		},
+		changeFloor(val){//修改建筑楼层
+			this.buildfloor = val
+		},
+		changeDevice(val){//修改设备类型
+			this.category = val.code
+		},
+		changeAssets(val){//修改设备族
+			this.family = val.code
+		}
+  }
 }
-</script>
+</script>
+<style lang="scss" scoped>
+	.hanson-bar {
+    height: 40px;
+    padding: 5px 0;
+    font-size: 14px;
+    overflow: hidden;
+    margin-top: 0;
+    line-height: 40px;
+		position: relative;
+		.condition-list{
+			display: inline-block;
+			vertical-align: middle;
+			line-height: 32px;
+			.task-state{
+				float: left;
+  			margin-left: 10px;
+				.task-stete-title{
+					color: #999999;
+    			font-size: 14px;
+				}
+			}
+		}
+		.add-task{
+			position: absolute;
+			right: 0;
+			top: 9px;
+		}
+	}
+	.tabel-box{
+		height: calc(100% - 170px);
+	}
+</style>