huangmp 4 years ago
parent
commit
b315f69af5

+ 9 - 0
src/api/community/agencymng.js

@@ -0,0 +1,9 @@
+import request from '@/router/axios';
+
+export const saveBatch = (row) => {
+  return request({
+    url: '/api/cyzh-community/agencymng/saveBatch',
+    method: 'post',
+    data: row
+  })
+}

+ 186 - 0
src/components/agency/agencymng.vue

@@ -0,0 +1,186 @@
+<template>
+  <el-dialog :title="title" center width="70%" :visible.sync="agencymngShow" :destroy-on-close="true" :modal-append-to-body="true"
+    :append-to-body="true">
+    <div style="margin-top:-15px;padding-bottom:20px;display:flex;cursor: pointer">
+      <span style="font-size:14px">管理:</span>
+      <el-breadcrumb separator-class="el-icon-arrow-right">
+        <el-breadcrumb-item v-for="(item,index) in breadcrumbList" :key="index">
+          <span @click="breadcrumbClick(item,index)"
+            style="color:#3b8ff4;font-size:16px;cursor: pointer">{{item.label}}</span>
+        </el-breadcrumb-item>
+      </el-breadcrumb>
+    </div>
+    <div class="full">
+      <el-row :gutter="0">
+        <el-col :span="4">
+          <tree ref="tree" @nodeClick="nodeClick"></tree>
+        </el-col>
+        <el-col :span="20">
+          <residential v-if="listShow(0)"></residential>
+          <building v-if="listShow(1)"></building>
+          <unit v-if="listShow(2)"></unit>
+          <floor v-if="listShow(3)"></floor>
+          <room ref="room" v-show="agencymng.level==4||agencymng.level==5"></room>
+        </el-col>
+      </el-row>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+  import tree from "./comps/tree.vue"
+  //列表form
+  import residential from "./form/residential.vue"
+  import building from "./form/building.vue"
+  import unit from "./form/unit.vue"
+  import floor from "./form/floor.vue"
+  import room from "./form/room.vue"
+  //列表form
+  export default {
+    components: {
+      tree,
+      residential,
+      building,
+      unit,
+      floor,
+      room
+    },
+    provide() {
+      return {
+        'agencymng': this.agencymng,
+        'index': this
+      }
+    },
+    data() {
+      return {
+        breadcrumbList: [],
+        agencymng: {
+          level: 0,
+          agencyId: "",
+          residentialId: '',
+          buildingId: '',
+          unitId: '',
+          floorId: '',
+          roomId: '',
+        },
+        agency: {},
+        agencymngShow: false,
+        title: '',
+      };
+    },
+    computed: {
+      listShow() {
+        return data => {
+          if (this.agencymng.level == data && this.agencymng.agencyId) {
+            return true
+          } else {
+            return false
+          }
+        }
+      }
+    },
+    methods: {
+      breadcrumbClick(item, index) {
+        console.log(item,"breadcrumbClick");
+        let list = this.breadcrumbList.reverse()
+        list.splice(0, list.length - index - 1)
+        this.breadcrumbList = list.reverse()
+        this.updateAgencymng(index, item.id)
+      },
+      updateAgencymng(level, id) {
+        let agencyId = this.agencymng.agencyId
+        let residentialId = ''
+        let buildingId = ''
+        let unitId = ''
+        let floorId = ''
+        let roomId = ''
+        switch (level) {
+          case 1:
+            residentialId = id
+            break;
+          case 2:
+            buildingId = id
+            break;
+          case 3:
+            unitId = id
+            break;
+          case 4:
+            floorId = id
+            roomId = ''
+            break;
+          case 5:
+            roomId = id
+            break;
+        }
+        this.agencymng = {
+          level,
+          agencyId,
+          residentialId,
+          buildingId,
+          unitId,
+          floorId,
+          roomId,
+        }
+        if (level==4||level==5) {
+          this.getRoomList()
+        }
+      },
+      getRoomList() {
+        let parmas = {
+          id: this.agencymng.roomId,
+          floorId: this.agencymng.floorId
+        }
+        this.$refs.room.getList(parmas)
+      },
+      nodeClick(obj) {
+        this.breadcrumbList = obj.list
+        console.log(this.breadcrumbList,"this.breadcrumbList");
+        this.initBreadcrumbList()
+        let node = obj.node
+        let level = node.level
+        let id = node.data.id
+        this.updateAgencymng(level, id)
+        console.log(this.breadcrumbList,"this.breadcrumbList");
+      },
+      showDialog(item) {
+        this.agencymngShow = true
+        this.title = item.name
+        this.agency = item
+        this.agencymng.agencyId = item.id
+        this.initBreadcrumbList()
+      },
+      initBreadcrumbList() {
+        let obj = {
+          id: this.agency.id,
+          label: this.agency.name,
+          level: 0
+        }
+        this.breadcrumbList.unshift(obj)
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .full {
+    box-sizing: border-box;
+    width: 100%;
+    height: 100%;
+  }
+
+  .mng {
+    margin-bottom: 30px;
+    padding-bottom: 20px;
+    display: flex;
+    justify-content: space-between;
+    width: 100%;
+    border-bottom: 1px solid #eee;
+
+    i {
+      font-size: 22px;
+      padding-right: 20px;
+      color: #bcbcbc
+    }
+
+  }
+</style>

+ 282 - 0
src/components/agency/comps/batch-add-dialog.vue

@@ -0,0 +1,282 @@
+<template>
+  <div>
+    <el-dialog title="批量添加" ::destroy-on-close="true" :visible.sync="dialogShow" width="52%" :modal-append-to-body="true" :append-to-body="true">
+      <el-form :label-width="labelWidth" :model="form" :rules="rules" ref="form">
+        <el-form-item label="区域名称" prop="residentialId">
+          <el-select style="width: 260px" v-model="form.residentialId" placeholder="请选择区域">
+            <el-option v-for="(item,index) in residentialList" :key="index" :label="item.name" :value="item.id">
+            </el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+
+      <el-form :inline="true" :label-width="labelWidth" :model="buildingForm" :rules="rules" ref="buildingForm">
+        <el-form-item label="楼栋区间" required>
+          <div class="flex">
+            <el-form-item prop="buildingBegin">
+              <el-input type="text" placeholder="起始楼栋" v-model="buildingForm.buildingBegin" :style="formWidth">
+              </el-input>
+            </el-form-item>
+            <div class="center"><i class="el-icon-minus"></i></div>
+            <el-form-item class="ml-10" prop="buildingEnd">
+              <el-input type="text" placeholder="结束楼栋" v-model="buildingForm.buildingEnd" :style="formWidth"></el-input>
+            </el-form-item>
+          </div>
+        </el-form-item>
+        <el-form-item label="前后缀规则">
+          <div class="flex">
+            <el-form-item prop="buildingPrefix">
+              <el-input type="text" placeholder="楼栋前缀" v-model="buildingForm.buildingPrefix" :style="formWidth">
+              </el-input>
+            </el-form-item>
+            <el-form-item class="ml-10" prop="buildingSuffix">
+              <el-input type="text" placeholder="楼栋后缀" v-model="buildingForm.buildingSuffix" :style="formWidth">
+              </el-input>
+            </el-form-item>
+          </div>
+        </el-form-item>
+      </el-form>
+      <el-form :inline="true" :label-width="labelWidth" :model="unitForm" :rules="rules" ref="unitForm">
+        <el-form-item label="单元区间" required>
+          <div class="flex">
+            <el-form-item prop="unitBegin">
+              <el-input type="text" placeholder="起始单元" v-model="unitForm.unitBegin" :style="formWidth"></el-input>
+            </el-form-item>
+            <div class="center"><i class="el-icon-minus"></i></div>
+            <el-form-item class="ml-10" prop="unitEnd">
+              <el-input type="text" placeholder="结束单元" v-model="unitForm.unitEnd" :style="formWidth"></el-input>
+            </el-form-item>
+          </div>
+        </el-form-item>
+        <el-form-item label="前后缀规则">
+          <div class="flex">
+            <el-form-item prop="unitPrefix">
+              <el-input type="text" placeholder="单元前缀" v-model="unitForm.unitPrefix" :style="formWidth"></el-input>
+            </el-form-item>
+            <el-form-item class="ml-10" prop="unitSuffix">
+              <el-input type="text" placeholder="单元后缀" v-model="unitForm.unitSuffix" :style="formWidth"></el-input>
+            </el-form-item>
+          </div>
+        </el-form-item>
+      </el-form>
+
+      <el-form :inline="true" :label-width="labelWidth" :model="floorForm" :rules="rules" ref="floorForm">
+        <el-form-item label="楼层区间" required>
+          <div class="flex">
+            <el-form-item prop="floorBegin">
+              <el-input type="text" placeholder="起始楼层" v-model="floorForm.floorBegin" :style="formWidth"></el-input>
+            </el-form-item>
+            <div class="center"><i class="el-icon-minus"></i></div>
+            <el-form-item class="ml-10" prop="floorEnd">
+              <el-input type="text" placeholder="结束楼层" v-model="floorForm.floorEnd" :style="formWidth"></el-input>
+            </el-form-item>
+          </div>
+        </el-form-item>
+        <el-form-item label="前后缀规则">
+          <div class="flex">
+            <el-form-item prop="floorPrefix">
+              <el-input type="text" placeholder="楼层前缀" v-model="floorForm.floorPrefix" :style="formWidth"></el-input>
+            </el-form-item>
+            <el-form-item class="ml-10" prop="floorSuffix">
+              <el-input type="text" placeholder="楼层后缀" v-model="floorForm.floorSuffix" :style="formWidth"></el-input>
+            </el-form-item>
+          </div>
+        </el-form-item>
+        <el-form-item label="排除楼栋">
+          <el-input type="text" placeholder="排除楼栋" v-model="floorForm.excludeFloor" :style="formWidth"></el-input>
+        </el-form-item>
+      </el-form>
+
+      <el-form :inline="true" :label-width="labelWidth" :model="roomForm" :rules="rules" ref="roomForm">
+        <el-form-item label="房间区间" required>
+          <div class="flex">
+            <el-form-item prop="roomBegin">
+              <el-input type="text" placeholder="起始房间" v-model="roomForm.roomBegin" :style="formWidth"></el-input>
+            </el-form-item>
+            <div class="center"><i class="el-icon-minus"></i></div>
+            <el-form-item class="ml-10" prop="roomEnd">
+              <el-input type="text" placeholder="结束房间" v-model="roomForm.roomEnd" :style="formWidth"></el-input>
+            </el-form-item>
+          </div>
+        </el-form-item>
+        <el-form-item label="前后缀规则">
+          <div class="flex">
+            <el-form-item prop="roomPrefix">
+              <el-input type="text" placeholder="房间前缀" v-model="roomForm.roomPrefix" :style="formWidth"></el-input>
+            </el-form-item>
+            <el-form-item class="ml-10" prop="roomSuffix">
+              <el-input type="text" placeholder="楼层后缀" v-model="roomForm.roomSuffix" :style="formWidth"></el-input>
+            </el-form-item>
+          </div>
+        </el-form-item>
+        <el-form-item label="排除房间">
+          <el-input type="text" placeholder="排除房间" v-model="roomForm.excludeRoom" :style="formWidth"></el-input>
+        </el-form-item>
+      </el-form>
+
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogShow = false">取 消</el-button>
+        <el-button type="primary" @click="submitForm()">确 定</el-button>
+      </div>
+    </el-dialog>
+
+  </div>
+</template>
+
+<script>
+  import {saveBatch} from "@/api/community/agencymng.js"
+  export default {
+    name: '',
+    data() {
+      return {
+        labelWidth: '90px',
+        formWidth: {
+          width: '115px'
+        },
+        dialogShow: false,
+        residentialList: [],
+        form: {
+          residentialId: '',
+        },
+        buildingForm: {
+          buildingBegin: '',
+          buildingEnd: '',
+          buildingPrefix: '',
+          buildingSuffix: '',
+        },
+        unitForm: {
+          unitBegin: '',
+          unitEnd: '',
+          unitPrefix: '',
+          unitSuffix: '',
+        },
+        floorForm: {
+          floorBegin: '',
+          floorEnd: '',
+          floorPrefix: '',
+          floorSuffix: '',
+          excludeFloor: '',
+        },
+        roomForm: {
+          roomBegin: '',
+          roomEnd: '',
+          roomPrefix: '',
+          roomSuffix: '',
+          excludeRoom: '',
+        },
+        rules: {
+          residentialId: [{
+            required: true,
+            message: '请选择操作的区域',
+            trigger: 'change'
+          }],
+          buildingBegin: [{
+            required: true,
+            message: '请输入起始楼栋',
+            trigger: 'blur'
+          }],
+          buildingEnd: [{
+            required: true,
+            message: '请输入结束楼栋',
+            trigger: 'blur'
+          }],
+          unitBegin: [{
+            required: true,
+            message: '请输入起始单元',
+            trigger: 'blur'
+          }],
+          unitEnd: [{
+            required: true,
+            message: '请输入结束单元',
+            trigger: 'blur'
+          }],
+          floorBegin: [{
+            required: true,
+            message: '请输入起始楼层',
+            trigger: 'blur'
+          }],
+          floorEnd: [{
+            required: true,
+            message: '请输入结束楼层',
+            trigger: 'blur'
+          }],
+          roomBegin: [{
+            required: true,
+            message: '请输入起始房间',
+            trigger: 'blur'
+          }],
+          roomEnd: [{
+            required: true,
+            message: '请输入结束房间',
+            trigger: 'blur'
+          }],
+        }
+      };
+    },
+    methods: {
+      show(residentialList) {
+        this.residentialList = residentialList
+        this.dialogShow = true
+      },
+      async submitForm() {
+        let flag = true;
+        try {
+          await this.$refs.form.validate();
+          await this.$refs.buildingForm.validate();
+          await this.$refs.unitForm.validate();
+          await this.$refs.floorForm.validate();
+          await this.$refs.roomForm.validate();
+        } catch (e) {
+          flag = e
+        }
+        if (flag) {
+          let model={};
+          Object.assign(model,this.form,this.buildingForm,this.unitForm,this.floorForm,this.roomForm)
+          saveBatch(model).then(res=>{
+            if (res.data.success) {
+              this.$message.success("操作成功")
+              this.dialogShow=false
+              this.index.agencymngShow=false
+              this.$emit('reloadData')
+            }
+          })
+        }
+      },
+
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .flex {
+    display: flex
+  }
+
+  .ml-20 {
+    margin-left: 20px
+  }
+
+  .ml-10 {
+    margin-left: 10px
+  }
+
+  /deep/ .el-input__inner {
+    -webkit-appearance: none;
+    background-color: #fff;
+    background-image: none;
+    border-radius: 0;
+    border: 1px solid #dcdfe6;
+    -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+    color: #606266;
+    display: inline-block;
+    font-size: inherit;
+    height: 40px;
+    line-height: 40px;
+    outline: 0;
+    padding: 0 15px;
+    -webkit-transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
+    transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
+    width: 100%;
+  }
+</style>

+ 158 - 0
src/components/agency/comps/tree.vue

@@ -0,0 +1,158 @@
+<template>
+  <div>
+    <div style="max-height:650px;overflow: scroll">
+      <el-button @click="batchAdd" type="primary" style="margin-bottom:10px;" size="mini">批量添加</el-button>
+      <el-tree style="height:100%" :props="props" ref="elTree" node-key="id" accordion @node-expand="nodeExpand"
+        @node-click="nodeClick" :load="loadNode" lazy>
+      </el-tree>
+    </div>
+    <batch-add-dialog ref="batchAddDialog"></batch-add-dialog>
+  </div>
+</template>
+
+<script>
+  import batchAddDialog from "./batch-add-dialog.vue"
+  import {
+    getList as getResidentialList
+  } from "@/api/community/residential.js"
+  import {
+    getList as getBuildingList
+  } from "@/api/community/building.js"
+  import {
+    getList as getUnitList
+  } from "@/api/community/unit.js"
+  import {
+    getList as getFloorList
+  } from "@/api/community/floor.js"
+  import {
+    getList as getRoomList
+  } from "@/api/community/room.js"
+  import {deepClone} from "@/util/deepClone.js"
+  export default {
+    inject: ['agencymng'],
+    components: {
+      batchAddDialog
+    },
+    data() {
+      return {
+        residentialList :[],
+        
+        isload: false,
+
+        page: {
+          pageSize: 500,
+          currentPage: 1,
+          total: 0
+        },
+        props: {
+          label: 'name',
+          children: 'children',
+          value: 'id',
+          isLeaf: 'isLeaf'
+        },
+      };
+    },
+    methods: {
+      nodeClick(data, node) {
+        let level = node.level
+        let list = []
+        let item=node
+        for (var i = 0; i < level; i++) {
+          if (item.label) {
+            let obj = {
+              id: item.data.id,
+              label: item.label,
+            }
+            list.unshift(obj)
+          }
+          item = item.parent
+        }
+        let obj={
+          list,
+          node
+        }
+        this.$emit('nodeClick', obj)
+      },
+      nodeExpand(data, node) {
+        if (this.isload) {
+          return
+        }
+        this.updateAgencymng(node.level, data.id)
+        console.log(this.agencymng,"nodeExpand");
+      },
+      async loadNode(node, resolve) {
+        this.isload = true
+        let level = node.level
+        let id = node.data ? node.data.id : this.agencymng.agencyId
+        this.updateAgencymng(level, id)
+        let data = await this.getList(id)
+        this.isload = false
+        return resolve(data);
+      },
+      async getList(id) {
+        let level = this.agencymng.level
+        let data = {}
+        switch (level) {
+          case 0:
+            data = (await getResidentialList(this.page.currentPage, this.page.pageSize, {
+              agencyId: id
+            })).data.data.records
+            this.residentialList=data
+            break;
+          case 1:
+            data = (await getBuildingList(this.page.currentPage, this.page.pageSize, {
+              residentialId: id
+            })).data.data.records
+            break;
+          case 2:
+            data = (await getUnitList(this.page.currentPage, this.page.pageSize, {
+              buildingId: id
+            })).data.data.records
+            break;
+          case 3:
+            data = (await getFloorList(this.page.currentPage, this.page.pageSize, {
+              unitId: id
+            })).data.data.records
+            break;
+          case 4:
+            data = (await getRoomList(this.page.currentPage, this.page.pageSize, {
+              floorId: id
+            })).data.data.records
+            data.forEach(item => {
+              item.isLeaf = true
+            })
+            break;
+          default:
+            break;
+        }
+        return data
+      },
+      batchAdd() {
+        this.$refs.batchAddDialog.show(this.residentialList)
+      },
+      updateAgencymng(level, id) {
+        this.agencymng.level = level
+        switch (level) {
+          case 1:
+            this.agencymng.residentialId = id
+            break;
+          case 2:
+            this.agencymng.buildingId = id
+            break;
+          case 3:
+            this.agencymng.unitId = id
+            break;
+          case 4:
+            this.agencymng.floorId = id
+            break;
+          case 4:
+            this.agencymng.roomId = id
+            break;
+          default:
+            break;
+        }
+      },
+
+    }
+  };
+</script>

+ 312 - 0
src/components/agency/form/building.vue

@@ -0,0 +1,312 @@
+<template>
+  <basic-container style="width:100%;height:100%">
+    <avue-crud :option="option" :table-loading="loading" :data="data" :page.sync="page" :permission="permissionList"
+      :before-open="beforeOpen" v-model="form" ref="crud" @row-update="rowUpdate" @row-save="rowSave" @row-del="rowDel"
+      @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange"
+      @current-change="currentChange" @size-change="sizeChange" @refresh-change="refreshChange" @on-load="onLoad">
+      <template slot="menuLeft">
+        <el-button type="danger" size="small" icon="el-icon-delete" plain v-if="permission.doctor_delete"
+          @click="handleDelete">删 除
+        </el-button>
+      </template>
+    </avue-crud>
+  </basic-container>
+</template>
+
+<script>
+  import {
+    getList,
+    getDetail,
+    add,
+    update,
+    remove
+  } from "@/api/community/building";
+  import {
+    mapGetters
+  } from "vuex";
+  import {
+    validatePhone
+  } from "@/util/validator.js";
+  let _this;
+  export default {
+    inject: ['agencymng'],
+    watch: {
+      agencymng: {
+        handler: (value) => {
+          _this.refreshChange()
+        },
+        deep: true
+      }
+    },
+    created() {
+      _this = this
+    },
+    data() {
+      return {
+        form: {},
+        query: {},
+        loading: true,
+        page: {
+          pageSize: 10,
+          currentPage: 1,
+          total: 0
+        },
+        selectionList: [],
+        option: {
+          dialogWidth: '46%',
+          searchMenuSpan: 5,
+          labelWidth: 120,
+          align: "center",
+          height: '500px',
+          calcHeight: 10,
+          tip: false,
+          searchShow: true,
+          searchMenuSpan: 6,
+          border: true,
+          index: false,
+          viewBtn: true,
+          selection: false,
+          menu: false,
+          searchShow: false,
+          dialogClickModal: false,
+          column: [{
+              label: "楼栋名称",
+              prop: "name",
+              rules: [{
+                required: true,
+                message: "请输入楼栋名称",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "所属区域",
+              prop: "residentialId",
+              slot: true,
+              type: "select",
+              search: true,
+              searchFilterable: true,
+              // cascaderItem: ['buildingId'],
+              dicUrl: "/api/cyzh-community/residential/select?size=100",
+              // dicFormatter:(res)=>{
+              //   return res.data.records;//返回字典的层级结构
+              // },
+              // dicFlag: false,
+              // filterable: true,
+              props: {
+                label: "name",
+                value: "id"
+              },
+              rules: [{
+                required: true,
+                message: "请选择所属区域",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "图片",
+              prop: "pic",
+              type: 'upload',
+              // dataType: 'string',
+              hide: true,
+              propsHttp: {
+                res: "data",
+                url: 'link'
+              },
+              listType: 'picture-img',
+              span: 24,
+              row: true,
+              // value: "/img/default/building.png",
+              action: "/api/blade-resource/oss/endpoint/put-file",
+              rules: [{
+                required: false,
+                message: "请上传封面图片",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "单元数",
+              prop: "unitCount",
+              display: false,
+              rules: [{
+                required: false,
+                message: "请输入",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "楼层数",
+              prop: "floorCount",
+              display: false,
+              rules: [{
+                required: false,
+                message: "请输入",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "房间数",
+              prop: "roomCount",
+              display: false,
+              rules: [{
+                required: false,
+                message: "请输入",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "总人口数",
+              prop: "userCount",
+              display: false,
+              hide: true,
+              rules: [{
+                required: false,
+                message: "请输入",
+                trigger: "blur"
+              }]
+            },
+          ]
+        },
+        data: []
+      };
+    },
+    computed: {
+      ...mapGetters(["permission"]),
+      permissionList() {
+        return {
+          addBtn: this.vaildData(this.permission.doctor_add, false),
+          viewBtn: this.vaildData(this.permission.doctor_view, false),
+          delBtn: this.vaildData(this.permission.doctor_delete, false),
+          editBtn: this.vaildData(this.permission.doctor_edit, false)
+        };
+      },
+      ids() {
+        let ids = [];
+        this.selectionList.forEach(ele => {
+          ids.push(ele.id);
+        });
+        return ids.join(",");
+      }
+    },
+    methods: {
+      showAdd() {
+        this.$refs.crud.rowAdd()
+      },
+      rowSave(row, done, loading) {
+        add(row).then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+          done();
+        }, error => {
+          loading();
+          window.console.log(error);
+        });
+      },
+      rowUpdate(row, index, done, loading) {
+        update(row).then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+          done();
+        }, error => {
+          loading();
+          console.log(error);
+        });
+      },
+      rowDel(row) {
+        this.$confirm("确定将选择数据删除?", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          })
+          .then(() => {
+            return remove(row.id);
+          })
+          .then(() => {
+            this.onLoad(this.page);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+          });
+      },
+      handleDelete() {
+        if (this.selectionList.length === 0) {
+          this.$message.warning("请选择至少一条数据");
+          return;
+        }
+        this.$confirm("确定将选择数据删除?", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          })
+          .then(() => {
+            return remove(this.ids);
+          })
+          .then(() => {
+            this.onLoad(this.page);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+            this.$refs.crud.toggleSelection();
+          });
+      },
+      beforeOpen(done, type) {
+        if (["edit", "view"].includes(type)) {
+          getDetail(this.form.id).then(res => {
+            this.form = res.data.data;
+          });
+        }
+        done();
+      },
+      searchReset() {
+        this.query = {};
+        this.onLoad(this.page);
+      },
+      searchChange(params, done) {
+        this.query = params;
+        this.page.currentPage = 1;
+        this.onLoad(this.page, params);
+        done();
+      },
+      selectionChange(list) {
+        this.selectionList = list;
+      },
+      selectionClear() {
+        this.selectionList = [];
+        this.$refs.crud.toggleSelection();
+      },
+      currentChange(currentPage) {
+        this.page.currentPage = currentPage;
+      },
+      sizeChange(pageSize) {
+        this.page.pageSize = pageSize;
+      },
+      refreshChange() {
+        this.onLoad(this.page, this.query);
+      },
+      onLoad(page, params = {}) {
+        this.loading = true;
+        this.query.residentialId = this.agencymng.residentialId
+        getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
+          const data = res.data.data;
+          this.page.total = data.total;
+          this.data = data.records;
+          this.loading = false;
+          this.selectionClear();
+          this.$emit('getList', this.data)
+        });
+      }
+    }
+  };
+</script>
+
+<style>
+
+
+</style>

+ 463 - 0
src/components/agency/form/floor.vue

@@ -0,0 +1,463 @@
+<template>
+  <basic-container style="width:100%;height:100%">
+    <avue-crud :option="option" :table-loading="loading" :data="data" :page.sync="page" :permission="permissionList"
+      :before-open="beforeOpen" v-model="form" ref="crud" @row-update="rowUpdate" @row-save="rowSave" @row-del="rowDel"
+      @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange"
+      @current-change="currentChange" @size-change="sizeChange" @refresh-change="refreshChange" @on-load="onLoad">
+      <template slot="menuLeft">
+        <el-button type="danger" size="small" icon="el-icon-delete" plain v-if="permission.doctor_delete"
+          @click="handleDelete">删 除
+        </el-button>
+      </template>
+    </avue-crud>
+  </basic-container>
+</template>
+
+<script>
+  import {
+    getList,
+    getDetail,
+    add,
+    update,
+    remove
+  } from "@/api/community/floor";
+  import {
+    mapGetters
+  } from "vuex";
+  import {
+    validatePhone
+  } from "@/util/validator.js";
+  let _this;
+  export default {
+    inject: ['agencymng'],
+    watch: {
+      agencymng: {
+        handler: (value) => {
+          _this.refreshChange()
+        },
+        deep: true
+      }
+    },
+    created() {
+      _this = this
+    },
+    data() {
+      return {
+        form: {},
+        query: {},
+        loading: true,
+        page: {
+          pageSize: 10,
+          currentPage: 1,
+          total: 0
+        },
+        selectionList: [],
+        option: {
+          dialogWidth: '46%',
+          searchMenuSpan: 5,
+          labelWidth: 120,
+          align: "center",
+          height: '500px',
+          calcHeight: 10,
+          tip: false,
+          searchShow: true,
+          searchMenuSpan: 6,
+          border: true,
+          index: false,
+          viewBtn: true,
+          selection: false,
+          menu: false,
+          searchShow: false,
+          dialogClickModal: false,
+          column: [{
+              label: "楼层名称",
+              width: 100,
+              prop: "name",
+              rules: [{
+                required: true,
+                message: "请输入楼层名称",
+                trigger: "blur"
+              }]
+            },
+            {
+              prop:'residentialName',
+              label:"所属区域"
+            },
+            {
+              label: "所属区域",
+              prop: "residentialId",
+              type: "select",
+              cascaderItem: ['buildingId'],
+              hide:true,
+              remote: true,
+              //回显的时候有问题,如果所选不在前十条内,下拉框只会显示id
+              dicUrl: "/api/cyzh-community/residential/list?size=900",
+              dicFormatter: (res) => {
+                return res.data.records; //返回字典的层级结构
+              },
+              props: {
+                label: "name",
+                value: "id"
+              },
+              searchFilterable: true,
+              search: true,
+              slot: true,
+              rules: [{
+                required: true,
+                message: "请选择所属区域",
+                trigger: "blur"
+              }]
+            },
+            {
+              prop:'buildingName',
+              label:'所属楼栋'
+            },
+            {
+              label: "所属楼栋",
+              prop: "buildingId",
+              // width: 100,
+              slot: true,
+              search: true,
+              hide:true,
+              type: "select",
+              // cascaderIndex:0,
+              cascaderItem: ['unitId'],
+              dicUrl: "/api/cyzh-community/building/list?size=100&residentialId={{key}}",
+              dicFormatter: (res) => {
+                return res.data.records; //返回字典的层级结构
+              },
+              filterable: true,
+              dicFlag: false,
+              props: {
+                label: "name",
+                value: "id"
+              },
+              rules: [{
+                required: true,
+                message: "请选择所属楼栋",
+                trigger: "blur"
+              }]
+            },
+            {
+              prop:'unitName',
+              label:'所属单元'
+            },
+            {
+              label: "所属单元",
+              prop: "unitId",
+              // width: 100,
+              search: true,
+              slot: true,
+              hide:true,
+              type: "select",
+              dicFlag: false,
+              // cascaderIndex: 1,
+              dicUrl: "/api/cyzh-community/unit/list?buildingId={{key}}",
+              dicFormatter: (res) => {
+                return res.data.records; //返回字典的层级结构
+              },
+              filterable: true,
+              props: {
+                label: "name",
+                value: "id"
+              },
+              rules: [{
+                required: true,
+                message: "请输入所属单元",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "负责人姓名",
+              prop: "personName",
+              hide: true,
+              labelWidth: 100,
+              rules: [{
+                required: false,
+                message: "请输入负责人姓名",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "负责人电话",
+              prop: "personTel",
+              labelWidth: 100,
+              hide: true,
+              rules: [{
+                required: false,
+                message: "请输入负责人电话",
+              }, {
+                validator: validatePhone,
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "建筑年代",
+              prop: "builtYear",
+              hide: true,
+              rules: [{
+                required: false,
+                message: "请输入建筑年代",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "产权性质",
+              prop: "propertyNature",
+              hide: true,
+              rules: [{
+                required: false,
+                message: "请输入产权性质",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "有无电梯",
+              prop: "includingElevator",
+              type: "select",
+              dicUrl: "/api/blade-system/dict-biz/dictionary?code=including_elevator",
+              props: {
+                label: "dictValue",
+                value: "dictKey",
+              },
+              dataType: "number",
+              hide: true,
+              rules: [{
+                required: false,
+                message: "请选择有无电梯",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "房间数量",
+              prop: "roomCount",
+              // width: 100,
+              display: false,
+              rules: [{
+                required: false,
+                message: "请输入房间数量",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "住户数量",
+              prop: "userNumber",
+              hide: true,
+              display: false,
+              rules: [{
+                required: false,
+                message: "请输入住户数量",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "序号",
+              prop: "serial",
+              hide: true,
+              display: false,
+              rules: [{
+                required: true,
+                message: "请输入序号",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "备注",
+              prop: "remark",
+              hide: true,
+              rules: [{
+                required: false,
+                message: "请输入备注",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "所属机构id(属于园区机构,则存园区机构ID;无园区机构,则存小区ID)",
+              prop: "orgPid",
+              hide: true,
+              display: false,
+              rules: [{
+                required: true,
+                message: "请输入所属机构id(属于园区机构,则存园区机构ID;无园区机构,则存小区ID)",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "所属机构名称(属于园区机构,则存园区机构名称;无园区机构,则存小区名称)",
+              prop: "orgPidName",
+              hide: true,
+              display: false,
+              rules: [{
+                required: true,
+                message: "请输入所属机构名称(属于园区机构,则存园区机构名称;无园区机构,则存小区名称)",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "根机构Id",
+              prop: "rootOrgId",
+              hide: true,
+              display: false,
+              rules: [{
+                required: true,
+                message: "请输入根机构Id",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "原数据的Id",
+              prop: "oldId",
+              hide: true,
+              display: false,
+              rules: [{
+                required: true,
+                message: "请输入原数据的Id",
+                trigger: "blur"
+              }]
+            },
+          ]
+        },
+        data: []
+      };
+    },
+    computed: {
+      ...mapGetters(["permission"]),
+      permissionList() {
+        return {
+          addBtn: this.vaildData(this.permission.doctor_add, false),
+          viewBtn: this.vaildData(this.permission.doctor_view, false),
+          delBtn: this.vaildData(this.permission.doctor_delete, false),
+          editBtn: this.vaildData(this.permission.doctor_edit, false)
+        };
+      },
+      ids() {
+        let ids = [];
+        this.selectionList.forEach(ele => {
+          ids.push(ele.id);
+        });
+        return ids.join(",");
+      }
+    },
+    methods: {
+      showAdd() {
+        this.$refs.crud.rowAdd()
+      },
+      rowSave(row, done, loading) {
+        add(row).then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+          done();
+        }, error => {
+          loading();
+          window.console.log(error);
+        });
+      },
+      rowUpdate(row, index, done, loading) {
+        update(row).then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+          done();
+        }, error => {
+          loading();
+          console.log(error);
+        });
+      },
+      rowDel(row) {
+        this.$confirm("确定将选择数据删除?", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          })
+          .then(() => {
+            return remove(row.id);
+          })
+          .then(() => {
+            this.onLoad(this.page);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+          });
+      },
+      handleDelete() {
+        if (this.selectionList.length === 0) {
+          this.$message.warning("请选择至少一条数据");
+          return;
+        }
+        this.$confirm("确定将选择数据删除?", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          })
+          .then(() => {
+            return remove(this.ids);
+          })
+          .then(() => {
+            this.onLoad(this.page);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+            this.$refs.crud.toggleSelection();
+          });
+      },
+      beforeOpen(done, type) {
+        if (["edit", "view"].includes(type)) {
+          getDetail(this.form.id).then(res => {
+            this.form = res.data.data;
+          });
+        }
+        done();
+      },
+      searchReset() {
+        this.query = {};
+        this.onLoad(this.page);
+      },
+      searchChange(params, done) {
+        this.query = params;
+        this.page.currentPage = 1;
+        this.onLoad(this.page, params);
+        done();
+      },
+      selectionChange(list) {
+        this.selectionList = list;
+      },
+      selectionClear() {
+        this.selectionList = [];
+        this.$refs.crud.toggleSelection();
+      },
+      currentChange(currentPage) {
+        this.page.currentPage = currentPage;
+      },
+      sizeChange(pageSize) {
+        this.page.pageSize = pageSize;
+      },
+      refreshChange() {
+        this.onLoad(this.page, this.query);
+      },
+      onLoad(page, params = {}) {
+        this.loading = true;
+        this.query.unitId = this.agencymng.unitId
+        getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
+          const data = res.data.data;
+          this.page.total = data.total;
+          this.data = data.records;
+          this.loading = false;
+          this.selectionClear();
+          this.$emit('getList', this.data)
+        });
+      }
+    }
+  };
+</script>
+
+<style>
+
+
+</style>

+ 444 - 0
src/components/agency/form/residential.vue

@@ -0,0 +1,444 @@
+<template>
+  <basic-container style="width:100%;height:100%">
+    <avue-crud :option="option" :table-loading="loading" :data="data" :page.sync="page" :permission="permissionList"
+      :before-open="beforeOpen" v-model="form" ref="crud" @row-update="rowUpdate" @row-save="rowSave" @row-del="rowDel"
+      @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange"
+      @current-change="currentChange" @size-change="sizeChange" @refresh-change="refreshChange" @on-load="onLoad">
+      <template slot="menuLeft">
+        <el-button type="danger" size="small" icon="el-icon-delete" plain v-if="permission.doctor_delete"
+          @click="handleDelete">删 除
+        </el-button>
+      </template>
+    </avue-crud>
+  </basic-container>
+</template>
+
+<script>
+  import {
+    getList,
+    getDetail,
+    add,
+    update,
+    remove
+  } from "@/api/community/residential";
+  import {
+    mapGetters
+  } from "vuex";
+  import {
+    validatePhone
+  } from "@/util/validator.js";
+  let _this;
+  export default {
+    inject: ['agencymng'],
+    watch: {
+      agencymng: {
+        handler: (value) => {
+          _this.refreshChange()
+        },
+        deep: true
+      }
+    },
+    created() {
+      _this = this
+    },
+    data() {
+      return {
+        pageChange: false,
+        form: {},
+        query: {},
+        loading: true,
+        page: {
+          pageSize: 10,
+          currentPage: 1,
+          total: 0
+        },
+        selectionList: [],
+        option: {
+          title: '测试',
+          dialogWidth: '46%',
+          searchMenuSpan: 5,
+          labelWidth: 120,
+          align: "center",
+          height: '500px',
+          calcHeight: 10,
+          tip: false,
+          searchShow: true,
+          searchMenuSpan: 6,
+          border: true,
+          index: false,
+          viewBtn: true,
+          selection: false,
+          menu: false,
+          searchShow: false,
+          dialogClickModal: false,
+          column: [{
+              label: "名称",
+              overHidden: true,
+              width: 150,
+              prop: "name",
+              // row: true,
+              search: true,
+              rules: [{
+                required: true,
+                message: "请输入名称",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: '',
+              prop: 'mapSelect',
+              // row: true,
+              // span: 20,
+              formslot: true,
+              hide: true,
+            },
+            {
+              label: "经度",
+              prop: "longitude",
+              width: 120,
+              hide: true,
+              rules: [{
+                required: false,
+                message: "请输入经度",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "纬度",
+              prop: "latitude",
+              width: 120,
+              hide: true,
+              rules: [{
+                required: false,
+                message: "请输入纬度",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "所属园区",
+              prop: "agencyId",
+              width: 150,
+              overHidden: true,
+              type: "select",
+              remote: true,
+              refresh: true,
+              searchFilterable: true,
+              filterable: true,
+              dicUrl: "/api/cyzh-community/agency/list?size=500&name={{key}}",
+              props: {
+                label: "name",
+                value: "id"
+              },
+              dicFormatter: (res) => {
+                return res.data.records;
+              },
+              rules: [{
+                required: true,
+                message: "请输入所属园区名称",
+                trigger: "blur"
+              }]
+
+            },
+
+            {
+              label: "详细地址",
+              prop: "address",
+              overHidden: true,
+            },
+            {
+              label: "楼栋数量",
+              prop: "buildingCount",
+              width: 100,
+              display: false,
+            },
+            {
+              label: "单元数量",
+              prop: "unitCount",
+              width: 100,
+              display: false,
+            },
+            {
+              label: "楼层数量",
+              prop: "floorCount",
+              width: 100,
+              display: false,
+            },
+            {
+              label: "房间数量",
+              prop: "roomCount",
+              width: 100,
+              display: false,
+            },
+            {
+              label: "住户数量",
+              prop: "userCount",
+              width: 100,
+              display: false,
+              hide: true,
+            },
+            {
+              label: "已录入人脸住户数",
+              prop: "userFaceCount",
+              hide: true,
+              width: 120,
+              display: false,
+            },
+            {
+              label: "所属物业",
+              labelWidth: 110,
+              hide: true,
+              display: false,
+              type: "select",
+              prop: "estateId",
+              dicUrl: "/api/cyzh-estate/company/list?current=1&size=50",
+              props: {
+                label: "name",
+                value: "id"
+              },
+              dicFormatter: (res) => {
+                return res.data.records
+              },
+              rules: [{
+                required: false,
+                message: "请选择所属物业",
+                trigger: "blur"
+              }, {
+                // validator: validatePhone,
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "物业名称",
+              prop: "estateName",
+              labelWidth: 110,
+              display: false,
+              hide: true,
+              rules: [{
+                required: true,
+                message: "请输入物业名称",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "物业电话",
+              display: false,
+              hide: true,
+              prop: "estatePhone",
+              labelWidth: 110,
+              rules: [{
+                required: true,
+                message: "请输入物业电话",
+                trigger: "blur"
+              }, {
+                validator: validatePhone,
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "负责人姓名",
+              prop: "personName",
+              labelWidth: 110,
+              rules: [{
+                required: false,
+                message: "请输入负责人姓名",
+                trigger: "blur"
+              }, {
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "负责人电话",
+              prop: "personPhone",
+              labelWidth: 110,
+              rules: [{
+                required: false,
+                message: "请输入负责人电话",
+                trigger: "blur"
+              }, {
+                validator: validatePhone,
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "图片",
+              prop: "pic",
+              type: 'upload',
+              hide: true,
+              propsHttp: {
+                res: "data",
+                url: 'link'
+              },
+              listType: 'picture-img',
+              span: 24,
+              row: true,
+              action: "/api/blade-resource/oss/endpoint/put-file",
+              display: true,
+              rules: [{
+                required: false,
+                message: "请输入封面图片",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "备注",
+              hide: true,
+              prop: "remark",
+              type: "textarea"
+            },
+            {
+              label: "创建时间",
+              hide: true,
+              width: 85,
+              prop: "createTime",
+              type: "datetime",
+              valueFormat: "yyyy-MM-dd HH:mm:ss",
+              display: false,
+            },
+          ]
+        },
+        data: []
+      };
+    },
+    computed: {
+      ...mapGetters(["permission"]),
+      permissionList() {
+        return {
+          addBtn: this.vaildData(this.permission.doctor_add, false),
+          viewBtn: this.vaildData(this.permission.doctor_view, false),
+          delBtn: this.vaildData(this.permission.doctor_delete, false),
+          editBtn: this.vaildData(this.permission.doctor_edit, false)
+        };
+      },
+      ids() {
+        let ids = [];
+        this.selectionList.forEach(ele => {
+          ids.push(ele.id);
+        });
+        return ids.join(",");
+      }
+    },
+    methods: {
+      showAdd() {
+        this.$refs.crud.rowAdd()
+      },
+      rowSave(row, done, loading) {
+        add(row).then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+          done();
+        }, error => {
+          loading();
+          window.console.log(error);
+        });
+      },
+      rowUpdate(row, index, done, loading) {
+        update(row).then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+          done();
+        }, error => {
+          loading();
+          console.log(error);
+        });
+      },
+      rowDel(row) {
+        this.$confirm("确定将选择数据删除?", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          })
+          .then(() => {
+            return remove(row.id);
+          })
+          .then(() => {
+            this.onLoad(this.page);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+          });
+      },
+      handleDelete() {
+        if (this.selectionList.length === 0) {
+          this.$message.warning("请选择至少一条数据");
+          return;
+        }
+        this.$confirm("确定将选择数据删除?", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          })
+          .then(() => {
+            return remove(this.ids);
+          })
+          .then(() => {
+            this.onLoad(this.page);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+            this.$refs.crud.toggleSelection();
+          });
+      },
+      beforeOpen(done, type) {
+        if (["edit", "view"].includes(type)) {
+          getDetail(this.form.id).then(res => {
+            this.form = res.data.data;
+          });
+        }
+        done();
+      },
+      searchReset() {
+        this.query = {};
+        this.onLoad(this.page);
+      },
+      searchChange(params, done) {
+        this.query = params;
+        this.page.currentPage = 1;
+        this.onLoad(this.page, params);
+        done();
+      },
+      selectionChange(list) {
+        this.selectionList = list;
+      },
+      selectionClear() {
+        this.selectionList = [];
+        this.$refs.crud.toggleSelection();
+      },
+      currentChange(currentPage) {
+        console.log(currentPage);
+        this.page.currentPage = currentPage;
+      },
+      sizeChange(pageSize) {
+        console.log(pageSize);
+        this.page.pageSize = pageSize;
+      },
+      refreshChange() {
+        this.onLoad(this.page, this.query);
+      },
+      onLoad(page, params = {}) {
+        this.loading = true;
+        this.query.agencyId = this.agencymng.agencyId
+        getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
+          const data = res.data.data;
+          this.page.total = data.total;
+          this.data = data.records;
+          this.loading = false;
+          this.selectionClear();
+          this.$emit('getList', this.data)
+        });
+      }
+    }
+  };
+</script>
+
+<style>
+
+
+</style>

+ 423 - 0
src/components/agency/form/room.vue

@@ -0,0 +1,423 @@
+<template>
+  <basic-container>
+    <avue-crud :option="option" :table-loading="loading" :data="data" :page="page" :permission="permissionList"
+      :before-open="beforeOpen" v-model="form" ref="crud" @row-update="rowUpdate" @row-save="rowSave" @row-del="rowDel"
+      @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange"
+      @current-change="currentChange" @size-change="sizeChange" @refresh-change="refreshChange">
+      <template slot="menuLeft">
+        <el-button type="danger" size="small" icon="el-icon-delete" plain v-if="permission.room_delete"
+          @click="handleDelete">删 除
+        </el-button>
+      </template>
+      <template slot="residentialId" slot-scope="scope">
+        <div>{{scope.row.residentialName}}</div>
+      </template>
+      <template slot="unitId" slot-scope="scope">
+        {{scope.row.unitName}}
+      </template>
+      <template slot="buildingId" slot-scope="scope">
+        {{scope.row.buildingName}}
+      </template>
+      <template slot="floorId" slot-scope="scope">
+        {{scope.row.floorName}}
+      </template>
+    </avue-crud>
+  </basic-container>
+</template>
+
+<script>
+  import {
+    deepClone
+  } from "@/util/util.js"
+  import {
+    getList,
+    getDetail,
+    add,
+    update,
+    remove,
+    getRoomList,
+    getRoomDetail
+  } from "@/api/community/room";
+  import {
+    mapGetters
+  } from "vuex";
+  export default {
+    inject: ['agencymng'],
+    data() {
+      return {
+        form: {},
+        query: {},
+        loading: true,
+        page: {
+          pageSize: 10,
+          currentPage: 1,
+          total: 0
+        },
+        selectionList: [],
+        option: {
+          height: '500px',
+          calcHeight: 10,
+          tip: false,
+          searchShow: false,
+          searchMenuSpan: 6,
+          border: true,
+          index: true,
+          viewBtn: true,
+          menuWidth: 350,
+          // delBtn: false,
+          selection: true,
+          dialogClickModal: false,
+          column: [{
+              label: "门牌号 ",
+              width: 100,
+              prop: "name",
+              search: true,
+              rules: [{
+                required: true,
+                message: "请输入门牌号-限制数字,单元楼下唯一  ",
+                trigger: "blur"
+              }]
+            }, {
+              label: "所属园区",
+              prop: "agencyId",
+              slot: true,
+              hide: true,
+              display: false,
+              type: "select",
+              // search: true,
+              dicUrl: "/api/cyzh-community/agency/list",
+              // cascaderItem: ['residentialId','unitId'],
+              props: {
+                label: "agencyName",
+                value: "id"
+              },
+              dicFormatter: (res) => {
+                return res.data.records;
+              },
+              rules: [{
+                required: true,
+                message: "请选择所属园区",
+                trigger: "blur"
+              }]
+            }, {
+              label: "所属区域",
+              prop: "residentialId",
+              slot: true,
+              type: "select",
+              search: true,
+              cascaderItem: ["buildingId"],
+              // dicUrl: "/grid/estate/getResidentialList",
+              remote: true,
+              //回显的时候有问题,如果所选不在前十条内,下拉框只会显示id
+              dicUrl: "/api/cyzh-community/residential/list?size=900&name={{key}}",
+              searchFilterable: true,
+              dicFormatter: (res) => {
+                return res.data.records; //返回字典的层级结构
+              },
+              // dicFlag: false,
+              props: {
+                label: "name",
+                value: "id"
+              },
+              rules: [{
+                required: true,
+                message: "请输入所属区域",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "所属楼栋",
+              prop: "buildingId",
+              // width: 150,
+              cascaderItem: ["unitId"],
+              slot: true,
+              type: "select",
+              search: true,
+              dicFlag: false,
+              filterable: true,
+              dicUrl: "/api/cyzh-community/building/list?size=100&residentialId={{key}}",
+              dicFormatter: (res) => {
+                return res.data.records;
+              },
+              props: {
+                label: "name",
+                value: "id"
+              },
+              rules: [{
+                required: true,
+                message: "请输入所属单元名称",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "所属单元",
+              prop: "unitId",
+              // width: 150,
+              slot: true,
+              type: "select",
+              search: true,
+              dicFlag: false,
+              cascaderItem: ["floorId"],
+              filterable: true,
+              dicUrl: "/api/cyzh-community/unit/list?buildingId={{key}}",
+              dicFormatter: (res) => {
+                return res.data.records;
+              },
+              props: {
+                label: "name",
+                value: "id"
+              },
+              rules: [{
+                required: true,
+                message: "请输入所属单元名称",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "所属楼层",
+              // width: 150,
+              prop: "floorId",
+              slot: true,
+              type: "select",
+              search: true,
+              dicFlag: false,
+              // cascaderIndex:1,
+              // dicUrl: "/grid/estate/getUnitList",
+              dicUrl: "/api/cyzh-community/floor/list?unitId={{key}}&size=900000",
+              dicFormatter: (res) => {
+                return res.data.records;
+              },
+              props: {
+                label: "name",
+                value: "id"
+              },
+              rules: [{
+                required: true,
+                message: "请输入所属单元名称",
+                trigger: "blur"
+              }]
+            },
+            // {
+            //   label: "房屋面积",
+            //   prop: "area",
+            //   hide: true,
+            // },
+            {
+              label: "入住用户数量",
+              prop: "userNumber",
+              hide: true,
+              display: false,
+            },
+            {
+              label: "户型",
+              prop: "houseType",
+              hide: true,
+              type: "select",
+              // search: true,
+              dicUrl: "/api/blade-system/dict-biz/dictionary?code=house_type",
+              props: {
+                label: "dictValue",
+                value: "dictKey"
+              },
+            },
+            // {
+            //   label: "楼层",
+            //   prop: "floor",
+            //   hide: true,
+            // },
+            {
+              label: "装饰",
+              prop: "ornament",
+              hide: true,
+            },
+            {
+              label: "房屋朝向",
+              prop: "orientation",
+              hide: true,
+            }, {
+              label: "序号",
+              prop: "serial",
+              value: 1,
+              hide: true,
+              display: false,
+            }, {
+              label: "备注",
+              prop: "remark",
+              hide: true,
+            },
+            {
+              label: "创建时间",
+              prop: "createTime",
+              hide: true,
+              type: "datetime",
+              valueFormat: "yyyy-MM-dd HH:mm:ss",
+              display: false,
+            },
+          ]
+        },
+        data: []
+      };
+    },
+    computed: {
+      ...mapGetters(["permission"]),
+      permissionList() {
+        return {
+          addBtn: this.vaildData(this.permission.room_add, false),
+          viewBtn: this.vaildData(this.permission.room_view, false),
+          delBtn: this.vaildData(this.permission.room_delete, false),
+          editBtn: this.vaildData(this.permission.room_edit, false)
+        };
+      },
+      ids() {
+        let ids = [];
+        this.selectionList.forEach(ele => {
+          ids.push(ele.id);
+        });
+        return ids.join(",");
+      }
+    },
+    mounted() {
+      let tenantType = localStorage.getItem("tenantType");
+      const agencyColumn = this.findObject(this.option.column, "agencyId");
+      const residentialColumn = this.findObject(this.option.column, "residentialId");
+      if (tenantType == 1) { //园区
+        agencyColumn.label = "所属园区";
+        residentialColumn.label = "所属区域";
+      } else { //园区
+        agencyColumn.label = "所属园区";
+        residentialColumn.label = "所属区域";
+      }
+    },
+    methods: {
+      rowSave(row, done, loading) {
+        row.userNumber = 0;
+        add(row).then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+          done();
+        }, error => {
+          loading();
+        });
+      },
+      rowUpdate(row, index, done, loading) {
+        // done()
+        update(row).then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+          done();
+        }, error => {
+          loading();
+        });
+      },
+      rowDel(row) {
+        if (row.userNumber > 0) {
+          this.$message.error("请先删除该房间的住户和其他数据")
+        }
+        this.$confirm("确定将选择数据删除?", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          })
+          .then(() => {
+            return remove(row.id);
+          })
+          .then(() => {
+            this.onLoad(this.page);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+          });
+      },
+      handleDelete() {
+        if (this.selectionList.length === 0) {
+          this.$message.warning("请选择至少一条数据");
+          return;
+        }
+        this.$confirm("确定将选择数据删除?", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          })
+          .then(() => {
+            return remove(this.ids);
+          })
+          .then(() => {
+            this.onLoad(this.page);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+            this.$refs.crud.toggleSelection();
+          });
+      },
+      beforeOpen(done, type) {
+        if (["edit", "view"].includes(type)) {
+          getDetail(this.form.id).then(res => {
+            this.form = res.data.data;
+          });
+        }
+        done();
+      },
+      searchReset() {
+        this.query = {};
+        this.onLoad(this.page);
+      },
+      searchChange(params, done) {
+        this.query = params;
+        this.page.currentPage = 1;
+        this.onLoad(this.page, params);
+        done();
+      },
+      selectionChange(list) {
+        this.selectionList = list;
+      },
+      selectionClear() {
+        this.selectionList = [];
+        this.$refs.crud.toggleSelection();
+      },
+      currentChange(currentPage) {
+        this.page.currentPage = currentPage;
+      },
+      sizeChange(pageSize) {
+        this.page.pageSize = pageSize;
+      },
+      refreshChange() {
+        this.onLoad(this.page, this.query);
+      },
+      getList(query) {
+        let id = query.id
+        let floorId = query.floorId
+        let params = {}
+        if (this.$isNotEmpty(id)) {
+          params.id = id
+        }
+        if (this.$isNotEmpty(floorId)) {
+          params.floorId = floorId
+        }
+        this.onLoad(this.page, params);
+      },
+      onLoad(page, params = {}) {
+        this.loading = true;
+        getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
+          const data = res.data.data;
+          this.page.total = data.total;
+          this.data = data.records;
+          this.loading = false;
+          this.selectionClear();
+          this.$emit('getList', this.data)
+        });
+
+      }
+    }
+  };
+</script>
+
+<style>
+</style>

+ 402 - 0
src/components/agency/form/unit.vue

@@ -0,0 +1,402 @@
+<template>
+  <basic-container style="width:100%;height:100%">
+    <avue-crud :option="option" :table-loading="loading" :data="data" :page.sync="page" :permission="permissionList"
+      :before-open="beforeOpen" v-model="form" ref="crud" @row-update="rowUpdate" @row-save="rowSave" @row-del="rowDel"
+      @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange"
+      @current-change="currentChange" @size-change="sizeChange" @refresh-change="refreshChange" @on-load="onLoad">
+      <template slot="menuLeft">
+        <el-button type="danger" size="small" icon="el-icon-delete" plain v-if="permission.doctor_delete"
+          @click="handleDelete">删 除
+        </el-button>
+      </template>
+    </avue-crud>
+  </basic-container>
+</template>
+
+<script>
+  import {
+    getList,
+    getDetail,
+    add,
+    update,
+    remove
+  } from "@/api/community/unit";
+  import {
+    mapGetters
+  } from "vuex";
+  import {
+    validatePhone
+  } from "@/util/validator.js";
+  let _this;
+  export default {
+    inject: ['agencymng'],
+    watch: {
+      agencymng: {
+        handler: (value) => {
+          _this.refreshChange()
+        },
+        deep: true
+      }
+    },
+    created() {
+      _this = this
+    },
+    data() {
+      return {
+        form: {},
+        query: {},
+        loading: true,
+        page: {
+          pageSize: 10,
+          currentPage: 1,
+          total: 0
+        },
+        selectionList: [],
+        option: {
+          dialogWidth: '46%',
+          searchMenuSpan: 5,
+          labelWidth: 120,
+          align: "center",
+          height: '500px',
+          calcHeight: 10,
+          tip: false,
+          searchShow: true,
+          searchMenuSpan: 6,
+          border: true,
+          index: false,
+          viewBtn: true,
+          selection: false,
+          menu: false,
+          searchShow: false,
+          dialogClickModal: false,
+          column: [{
+              label: "单元名称",
+              prop: "name",
+              search: true,
+              width: 100,
+              rules: [{
+                required: true,
+                message: "请输入单元名称",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "单元编号",
+              prop: "unitNumber",
+              display: false,
+              hide: true,
+            },
+            {
+              label: "单元楼类型",
+              prop: "type",
+              hide: true,
+              type: "select",
+              dataType: "number",
+              searchLabelWidth: 110,
+              labelWidth: 110,
+              dicUrl: "/api/blade-system/dict-biz/dictionary?code=unit_type",
+              props: {
+                label: "dictValue",
+                value: "dictKey"
+              },
+              rules: [{
+                required: false,
+                message: "请选择单元楼类型",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "所属区域",
+              prop: "residentialId",
+              slot: true,
+              type: "select",
+              search: true,
+              hide:true,
+              cascaderItem: ['buildingId'],
+              // remote: true,
+              //回显的时候有问题,如果所选不在前十条内,下拉框只会显示id
+              dicUrl: "/api/cyzh-community/residential/list?size=999",
+              dicFormatter: (res) => {
+                return res.data.records; //返回字典的层级结构
+              },
+              searchFilterable: true,
+              props: {
+                label: "name",
+                value: "id"
+              },
+              rules: [{
+                required: true,
+                message: "请选择所属区域",
+                trigger: "blur"
+              }]
+            },
+            {
+              prop:'residentialName',
+              label:"所属区域"
+            },
+            {
+              label:'所属楼栋',
+              prop:'buildingName'
+            },
+            {
+              label: "所属楼栋",
+              prop: "buildingId",
+              // width: 100,
+              slot: true,
+              type: "select",
+              search: true,
+              hide:true,
+              dicUrl: `/api/cyzh-community/building/list?residentialId={{key}}`,
+              dicFormatter: (res) => {
+                return res.data.records; //返回字典的层级结构
+              },
+              dicFlag: false,
+              searchFilterable: true,
+              props: {
+                label: "name",
+                value: "id"
+              },
+              rules: [{
+                required: true,
+                message: "请选择所属楼栋",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "负责人姓名",
+              prop: "personName",
+              hide: true,
+
+              rules: [{
+                required: false,
+                message: "请输入负责人姓名",
+                trigger: "blur"
+              }]
+            }, {
+              label: "负责人电话",
+              prop: "personTel",
+              labelWidth: 110,
+              hide: true,
+              rules: [{
+                required: false,
+                message: "请输入负责人电话",
+              }, {
+                validator: validatePhone,
+                trigger: "blur"
+              }]
+            }, {
+              label: "建筑年代",
+              prop: "builtYear",
+              hide: true,
+            }, {
+              label: "产权性质",
+              prop: "propertyNature",
+              hide: true,
+            }, {
+              label: "有无电梯",
+              prop: "includingElevator",
+              hide: true,
+            },
+            {
+              label: "图片",
+              prop: "pic",
+              type: 'upload',
+              dataType: 'string',
+              hide: true,
+              propsHttp: {
+                res: "data",
+                url: 'link'
+              },
+              listType: 'picture-img',
+              span: 24,
+              row: true,
+              action: "/api/blade-resource/oss/endpoint/put-file",
+              rules: [{
+                required: false,
+                message: "请上传封面图片",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "楼层数量",
+              prop: "floorCount",
+              display: false
+            },
+            {
+              label: "房间数量",
+              prop: "roomCount",
+              display: false
+            },
+            {
+              label: "住户数量",
+              prop: "userNumber",
+              display: false,
+              hide: true,
+            },
+            {
+              label: "序号",
+              prop: "serial",
+              hide: true,
+              display: false,
+              value: 1
+            },
+            {
+              label: "创建时间",
+              prop: "createTime",
+              type: "datetime",
+              hide: true,
+              valueFormat: "yyyy-MM-dd HH:mm:ss",
+              display: false
+            },
+            {
+              label: "备注",
+              prop: "remark",
+              hide: true,
+              type: "textarea"
+            },
+          ]
+        },
+        data: []
+      };
+    },
+    computed: {
+      ...mapGetters(["permission"]),
+      permissionList() {
+        return {
+          addBtn: this.vaildData(this.permission.doctor_add, false),
+          viewBtn: this.vaildData(this.permission.doctor_view, false),
+          delBtn: this.vaildData(this.permission.doctor_delete, false),
+          editBtn: this.vaildData(this.permission.doctor_edit, false)
+        };
+      },
+      ids() {
+        let ids = [];
+        this.selectionList.forEach(ele => {
+          ids.push(ele.id);
+        });
+        return ids.join(",");
+      }
+    },
+    methods: {
+      showAdd() {
+        this.$refs.crud.rowAdd()
+      },
+      rowSave(row, done, loading) {
+        add(row).then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+          done();
+        }, error => {
+          loading();
+          window.console.log(error);
+        });
+      },
+      rowUpdate(row, index, done, loading) {
+        update(row).then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+          done();
+        }, error => {
+          loading();
+          console.log(error);
+        });
+      },
+      rowDel(row) {
+        this.$confirm("确定将选择数据删除?", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          })
+          .then(() => {
+            return remove(row.id);
+          })
+          .then(() => {
+            this.onLoad(this.page);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+          });
+      },
+      handleDelete() {
+        if (this.selectionList.length === 0) {
+          this.$message.warning("请选择至少一条数据");
+          return;
+        }
+        this.$confirm("确定将选择数据删除?", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          })
+          .then(() => {
+            return remove(this.ids);
+          })
+          .then(() => {
+            this.onLoad(this.page);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+            this.$refs.crud.toggleSelection();
+          });
+      },
+      beforeOpen(done, type) {
+        if (["edit", "view"].includes(type)) {
+          getDetail(this.form.id).then(res => {
+            this.form = res.data.data;
+          });
+        }
+        done();
+      },
+      searchReset() {
+        this.query = {};
+        this.onLoad(this.page);
+      },
+      searchChange(params, done) {
+        this.query = params;
+        this.page.currentPage = 1;
+        this.onLoad(this.page, params);
+        done();
+      },
+      selectionChange(list) {
+        this.selectionList = list;
+      },
+      selectionClear() {
+        this.selectionList = [];
+        this.$refs.crud.toggleSelection();
+      },
+      currentChange(currentPage) {
+        this.page.currentPage = currentPage;
+      },
+      sizeChange(pageSize) {
+        this.page.pageSize = pageSize;
+      },
+      refreshChange() {
+        this.onLoad(this.page, this.query);
+      },
+      onLoad(page, params = {}) {
+        this.loading = true;
+        this.query.buildingId = this.agencymng.buildingId
+        getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
+          const data = res.data.data;
+          this.page.total = data.total;
+          this.data = data.records;
+          this.loading = false;
+          this.selectionClear();
+          this.$emit('getList',this.data)
+        });
+      }
+    }
+  };
+</script>
+
+<style>
+
+
+</style>

+ 192 - 0
src/components/map/trajectory.vue

@@ -0,0 +1,192 @@
+<template>
+  <div>
+    <button @click="carMove">启动</button>
+    <div id="container"></div>
+  </div>
+</template>
+
+<script>
+  import * as mapUtil from "./js/mapUtil.js"
+  let TMap,map,center;
+  export default {
+    name: 'trajectory',
+    data() {
+      return {
+        //移动路线坐标
+        path: [],
+      };
+    },
+    mounted() {
+      this.initMap()
+    },
+    methods: {
+      initData() {
+        //移动坐标
+        let carLatLngList = [{
+          lat: 39.98481500648338,
+          lng: 116.30571126937866
+        }, {
+          lat: 39.982266575222155,
+          lng: 116.30596876144409
+        }, {
+          lat: 39.982348784165886,
+          lng: 116.3111400604248
+        }, {
+          lat: 39.978813710266024,
+          lng: 116.31699800491333
+        }]
+        this.path = []
+        carLatLngList.forEach(item => {
+          this.path.push(new TMap.LatLng(item.lat, item.lng))
+        })
+
+        let endIndex = carLatLngList.length - 1
+        let centerLat = this.$digital.floatMul(this.$digital.floatAdd(carLatLngList[0].lat, carLatLngList[
+          endIndex].lat), 0.5)
+        let centerLng = this.$digital.floatMul(this.$digital.floatAdd(carLatLngList[0].lng, carLatLngList[
+          endIndex].lng), 0.5)
+          center = new TMap.LatLng(centerLat, centerLng)
+      },
+      async initMap() {
+        let scripts=['https://map.qq.com/api/gljs?libraries=geometry&v=1.exp']
+        TMap = await mapUtil.loadMap(scripts)
+        //初始化数据
+        this.initData()
+        //创建地图
+        this.createMap()
+        //创建路线
+        this.createPolylineLayer()
+        //创建小车
+        this.createMarker()
+      },
+      /**
+       * 创建地图
+       */
+      createMap() {
+        // 初始化地图
+        map = new TMap.Map('container', {
+          zoom: 15,
+          center,
+        });
+      },
+      /**
+       * 创建小车移动路线
+       */
+      createPolylineLayer() {
+        this.polylineLayer = new TMap.MultiPolyline({
+          map: map, // 绘制到目标地图
+          // 折线样式定义
+          styles: {
+            style_blue: new TMap.PolylineStyle({
+              color: '#3777FF', // 线填充色
+              width: 4, // 折线宽度
+              borderWidth: 2, // 边线宽度
+              borderColor: '#FFF', // 边线颜色
+              lineCap: 'round', // 线端头方式
+              eraseColor: 'rgba(190,188,188,1)',
+            }),
+          },
+          geometries: [{
+            id: 'erasePath',
+            styleId: 'style_blue',
+            paths: this.path,
+          }, ],
+        });
+      },
+      /**
+       * //创建小车
+       */
+      createMarker() {
+        this.marker = new TMap.MultiMarker({
+          map: map,
+          styles: {
+            'car-down': new TMap.MarkerStyle({
+              width: 40,
+              height: 40,
+              anchor: {
+                x: 20,
+                y: 20,
+              },
+              faceTo: 'map',
+              rotate: 180,
+              src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/car.png',
+            }),
+            start: new TMap.MarkerStyle({
+              width: 25,
+              height: 35,
+              anchor: {
+                x: 16,
+                y: 32
+              },
+              src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/start.png',
+            }),
+            end: new TMap.MarkerStyle({
+              width: 25,
+              height: 35,
+              anchor: {
+                x: 16,
+                y: 32
+              },
+              src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/end.png',
+            }),
+          },
+          geometries: [{
+              id: 'car',
+              styleId: 'car-down',
+              position: this.path[0],
+            },
+            {
+              id: 'start',
+              styleId: 'start',
+              position: this.path[0],
+            },
+            {
+              id: 'end',
+              styleId: 'end',
+              position: this.path[(this.path.length - 1)],
+            },
+          ],
+        });
+      },
+      /**
+       * 小车移动
+       */
+      carMove() {
+        this.marker.moveAlong({
+          car: {
+            path: this.path,
+            speed: 700,
+          },
+        }, {
+          autoRotation: true,
+        });
+        this.marker.on('moving', (e) => {
+          var passedLatLngs = e.car && e.car.passedLatLngs;
+          if (passedLatLngs) {
+            // 使用路线擦除接口 eraseTo, https://lbs.qq.com/webApi/javascriptGL/glDoc/glDocVector
+            this.polylineLayer.eraseTo(
+              'erasePath',
+              passedLatLngs.length - 1,
+              passedLatLngs[passedLatLngs.length - 1]
+            );
+          }
+        });
+      },
+    }
+  };
+</script>
+
+
+<style type="text/css" scoped>
+  html,
+  body {
+    height: 100%;
+    margin: 0px;
+    padding: 0px;
+  }
+
+  #container {
+    width: 100%;
+    height: 100%;
+  }
+</style>

+ 23 - 0
src/util/deepClone.js

@@ -0,0 +1,23 @@
+// 判断arr是否为一个数组,返回一个bool值
+function isArray (arr) {
+    return Object.prototype.toString.call(arr) === '[object Array]';
+}
+
+// 深度克隆
+function deepClone (obj) {
+	// 对常见的“非”值,直接返回原来值
+	if([null, undefined, NaN, false].includes(obj)) return obj;
+    if(typeof obj !== "object" && typeof obj !== 'function') {
+		//原始类型直接返回
+        return obj;
+    }
+    var o = isArray(obj) ? [] : {};
+    for(let i in obj) {
+        if(obj.hasOwnProperty(i)){
+            o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i];
+        }
+    }
+    return o;
+}
+
+export default deepClone;

+ 491 - 460
src/views/businessmng/agencymng/agency.vue

@@ -1,518 +1,549 @@
 <template>
   <basic-container>
 
-<!--卡片数据展示-->
+    <!--卡片数据展示-->
     <el-card style="margin-bottom: 20px">
-        <el-tabs type="border-card">
-          <el-tab-pane label="园区数据统计">
-            <div><avue-data-box :option="communityStatistics"></avue-data-box></div>
-          </el-tab-pane>
-        </el-tabs>
+      <el-tabs type="border-card">
+        <el-tab-pane label="园区数据统计">
+          <div>
+            <avue-data-box :option="communityStatistics"></avue-data-box>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
     </el-card>
 
     <avue-crud :option="option" :table-loading="loading" :data="data" :page="page" :permission="permissionList"
-               :before-open="beforeOpen" v-model="form" ref="crud" @row-update="rowUpdate" @row-save="rowSave" @row-del="rowDel"
-               @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange" @current-change="currentChange"
-               @size-change="sizeChange" @refresh-change="refreshChange" @on-load="onLoad">
+      :before-open="beforeOpen" v-model="form" ref="crud" @row-update="rowUpdate" @row-save="rowSave" @row-del="rowDel"
+      @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange"
+      @current-change="currentChange" @size-change="sizeChange" @refresh-change="refreshChange" @on-load="onLoad">
       <template slot="menuLeft">
-        <el-button type="danger" size="small" icon="el-icon-delete" plain v-if="permission.agency_delete" @click="handleDelete">删 除</el-button>
-<!--        <cy-excel-import :flag="1" file-name="园区信息导入模板" @success="onLoad(page)"></cy-excel-import>-->
+        <el-button type="danger" size="small" icon="el-icon-delete" plain v-if="permission.agency_delete"
+          @click="handleDelete">删 除</el-button>
+        <!--        <cy-excel-import :flag="1" file-name="园区信息导入模板" @success="onLoad(page)"></cy-excel-import>-->
       </template>
       <template slot="mapSelectForm" slot-scope="scope">
         <div>
           <!--          <input class="el-input&#45;&#45;small el-input__inner" placeholder="选择地址" @click="mapVisible = true">-->
           <el-button @click="mapVisible = true"> 选择地址</el-button>
-          <el-dialog :append-to-body="true" :close-on-click-modal="false" :modal-append-to-body="false" :visible.sync="mapVisible"
-                     title="编辑地址" width="80%">
-            <editPolygonMap v-if="mapVisible" :editForm.sync="scope.row" :region.sync="scope.row.address" :latitude.sync="scope.row.latitude" :longitude.sync="scope.row.longitude" :visible.sync="mapVisible"></editPolygonMap>
+          <el-dialog :append-to-body="true" :close-on-click-modal="false" :modal-append-to-body="false"
+            :visible.sync="mapVisible" title="编辑地址" width="80%">
+            <editPolygonMap v-if="mapVisible" :editForm.sync="scope.row" :region.sync="scope.row.address"
+              :latitude.sync="scope.row.latitude" :longitude.sync="scope.row.longitude" :visible.sync="mapVisible">
+            </editPolygonMap>
           </el-dialog>
         </div>
       </template>
+      <template slot-scope="scope" slot="menu">
+        <el-button type="text" size="small" icon="el-icon-edit" plain class="none-border"
+          @click.stop="agencymng(scope.row.id)">管理
+        </el-button>
+      </template>
     </avue-crud>
+
+    
+      <agencymng></agencymng>
+    
+
   </basic-container>
 </template>
 
 <script>
-import {
-  getList,
-  getDetail,
-  add,
-  update,
-  remove,
-  dataStat
-} from "@/api/community/agency.js";
-import {getCommunityList} from "../../../api/grid/index";
-import {
-  mapGetters
-} from "vuex";
-import {
-  validatePhone
-} from "@/util/validator"
-import CyExcelImport from "../../../components/excel/cy-excel-import"
-import editPolygonMap from "../../../components/residential/editPolygonMap.vue"
-import {getDetail as getRegDetail} from "@/api/base/region"
-export default {
-  components: {CyExcelImport,editPolygonMap},
-  data() {
-    return {
-      communityCount:{},
-      mapVisible:false,
-      areaData: [],
-      form: {},
-      query: {},
-      loading: true,
-      page: {
-        pageSize: 10,
-        currentPage: 1,
-        total: 0
-      },
-      //数据展示
-      communityStatistics:{
-        span:6,
-        data: [
-          {
-            title: '园区数量',
-            count: 0,
-            icon: 'el-icon-office-building',
-            color: 'rgb(49, 180, 141)',
-          },
-          {
-            title: '楼宇数量',
-            count: 0,
-            icon: 'el-icon-school',
-            color: 'rgb(56, 161, 242)',
-          },
-          {
-            title: '企业数量',
-            count: 0,
-            icon: 'el-icon-s-home',
-            color: 'rgb(117, 56, 199)',
-          },
-          {
-            title: '人员数量',
-            count: 0,
-            icon: 'el-icon-user-solid',
-            color: 'rgb(143,119,0)',
-          },
-        ]
-      },
+  import agencymng from "@/components/agency/agencymng.vue"
+  import {
+    getList,
+    getDetail,
+    add,
+    update,
+    remove,
+    dataStat
+  } from "@/api/community/agency.js";
+  import {
+    getCommunityList
+  } from "../../../api/grid/index";
+  import {
+    mapGetters
+  } from "vuex";
+  import {
+    validatePhone
+  } from "@/util/validator"
+  import CyExcelImport from "../../../components/excel/cy-excel-import"
+  import editPolygonMap from "../../../components/residential/editPolygonMap.vue"
+  import {
+    getDetail as getRegDetail
+  } from "@/api/base/region"
+  export default {
+    components: {
+      CyExcelImport,
+      editPolygonMap,
+      agencymng
+    },
+    data() {
+      return {
+        agencymngShow:false,
 
-      selectionList: [],
-      option: {
-        height: 'auto',
-        // calcHeight: 60,
-        tip: false,
-        searchShow: true,
-        searchMenuSpan: 6,
-        border: true,
-        index: true,
-        viewBtn: true,
-        selection: true,
-        dialogClickModal: false,
-        menuWidth:350,
-        column: [
-          {
-          label: "名称",
-          prop: "name",
-          search: true,
-          width: 160,
-          overHidden: true,
-          rules: [{
-            required: true,
-            message: "请输入名称",
-            trigger: "blur"
-          }]
+        communityCount: {},
+        mapVisible: false,
+        areaData: [],
+        form: {},
+        query: {},
+        loading: true,
+        page: {
+          pageSize: 10,
+          currentPage: 1,
+          total: 0
         },
-          {
-            label:'',
-            prop:'mapSelect',
-            viewDisplay: false,
-            formslot: true,
-            hide: true,
-          },
-          {
-            label: "经度",
-            prop: "longitude",
-            width: 120,
-            hide: true,
-            rules: [{
-              required: false,
-              message: "请输入经度",
-              trigger: "blur"
-            }]
-          },
-          {
-            label: "纬度",
-            prop: "latitude",
-            width: 120,
-            hide: true,
-            rules: [{
-              required: false,
-              message: "请输入纬度",
-              trigger: "blur"
-            }]
-          },
-          {
-            label: "所属省",
-            prop: "regionProvince",
-            type: "select",
-            width: 150,
-            dicUrl: "/api/blade-system/region/lazy-tree?parentCode=000000",
-            cascaderItem:["regionCity"],
-            props:{
-              label:"title",
-              value: "id"
+        //数据展示
+        communityStatistics: {
+          span: 6,
+          data: [{
+              title: '园区数量',
+              count: 0,
+              icon: 'el-icon-office-building',
+              color: 'rgb(49, 180, 141)',
+            },
+            {
+              title: '楼宇数量',
+              count: 0,
+              icon: 'el-icon-school',
+              color: 'rgb(56, 161, 242)',
+            },
+            {
+              title: '企业数量',
+              count: 0,
+              icon: 'el-icon-s-home',
+              color: 'rgb(117, 56, 199)',
             },
-            rules: [{
-              required: true,
-              message: "请选择所属省份",
-              trigger: "blur"
-            }]
-          },
-          {
-            label: "所属市",
-            prop: "regionCity",
-            type: "select",
-            width: 150,
-            dicFlag: true,
-            cascaderItem: ["regionArea"],
-            dicUrl: `/api/blade-system/region/lazy-tree?parentCode={{key}}`,
+            {
+              title: '人员数量',
+              count: 0,
+              icon: 'el-icon-user-solid',
+              color: 'rgb(143,119,0)',
+            },
+          ]
+        },
 
-            props:{
-              label: "title",
-              value: "id"
+        selectionList: [],
+        option: {
+          height: 'auto',
+          // calcHeight: 60,
+          tip: false,
+          searchShow: true,
+          searchMenuSpan: 6,
+          border: true,
+          index: true,
+          viewBtn: true,
+          selection: true,
+          dialogClickModal: false,
+          menuWidth: 350,
+          column: [{
+              label: "名称",
+              prop: "name",
+              search: true,
+              width: 160,
+              overHidden: true,
+              rules: [{
+                required: true,
+                message: "请输入名称",
+                trigger: "blur"
+              }]
             },
-            rules: [{
-              required: false,
-              message: "请选择所属市",
-              trigger: "blur"
-            }]
-          },
-          {
-            label: "所属区",
-            prop: "regionArea",
-            type: "select",
-            width: 150,
-            cascaderItem: ["regionStreet"],
-            dicUrl:  `/api/blade-system/region/lazy-tree?parentCode={{key}}`,
-            props: {
-              label: "title",
-              value: "id"
+            {
+              label: '',
+              prop: 'mapSelect',
+              viewDisplay: false,
+              formslot: true,
+              hide: true,
             },
-            rules: [{
-              required: false,
-              message: "请选择所属区",
-              trigger: "blur"
-            }]
-          },
-          {
-            label: "所属街道",
-            prop: "regionStreet",
-            type:"select",
+            {
+              label: "经度",
+              prop: "longitude",
+              width: 120,
+              hide: true,
+              rules: [{
+                required: false,
+                message: "请输入经度",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "纬度",
+              prop: "latitude",
+              width: 120,
+              hide: true,
+              rules: [{
+                required: false,
+                message: "请输入纬度",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "所属省",
+              prop: "regionProvince",
+              type: "select",
+              width: 150,
+              dicUrl: "/api/blade-system/region/lazy-tree?parentCode=000000",
+              cascaderItem: ["regionCity"],
+              props: {
+                label: "title",
+                value: "id"
+              },
+              rules: [{
+                required: true,
+                message: "请选择所属省份",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "所属市",
+              prop: "regionCity",
+              type: "select",
+              width: 150,
+              dicFlag: true,
+              cascaderItem: ["regionArea"],
+              dicUrl: `/api/blade-system/region/lazy-tree?parentCode={{key}}`,
 
-            width: 150,
-            dicUrl: `/api/blade-system/region/lazy-tree?parentCode={{key}}`,
-            props: {
-              label: "title",
-              value: "id"
+              props: {
+                label: "title",
+                value: "id"
+              },
+              rules: [{
+                required: false,
+                message: "请选择所属市",
+                trigger: "blur"
+              }]
             },
+            {
+              label: "所属区",
+              prop: "regionArea",
+              type: "select",
+              width: 150,
+              cascaderItem: ["regionStreet"],
+              dicUrl: `/api/blade-system/region/lazy-tree?parentCode={{key}}`,
+              props: {
+                label: "title",
+                value: "id"
+              },
+              rules: [{
+                required: false,
+                message: "请选择所属区",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "所属街道",
+              prop: "regionStreet",
+              type: "select",
+
+              width: 150,
+              dicUrl: `/api/blade-system/region/lazy-tree?parentCode={{key}}`,
+              props: {
+                label: "title",
+                value: "id"
+              },
 
-            rules: [{
-              required: true,
-              message: "请选择所属街道",
-              trigger: "blur"
-            }]
-          },
-          {
-            label: "详细地址",
-            search: true,
-            prop: "address",
-            type: "textarea",
-            maxRows: 2,
-            // width: 300,
-            overHidden: true,
-            rules: [{
-              required: false,
-              message: "请输入详细地址",
-              trigger: "blur"
-            }]
-          },
-          {
-            label: "负责人名称",
-            prop: "personName",
-            width: 210,
-            labelWidth: 100,
-            rules: [{
-              required: false,
-              message: "请输入负责人名称",
-              trigger: "blur"
-            }]
-          },
-          {
-            label: "联系方式",
-            prop: "personPhone",
-            width: 120,
-            rules: [{
-              required: false,
-              message: "请输入负责人联系方式",
-              trigger: "blur"
-            }, {
-              validator: validatePhone,
-              trigger: "blur"
-            }],
-          },
-          {
-            label: "背景图",
-            prop: "pic",
-            type: 'upload',
-            hide: true,
-            propsHttp: {
-              res: "data",
-              url: 'link'
+              rules: [{
+                required: true,
+                message: "请选择所属街道",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "详细地址",
+              search: true,
+              prop: "address",
+              type: "textarea",
+              maxRows: 2,
+              // width: 300,
+              overHidden: true,
+              rules: [{
+                required: false,
+                message: "请输入详细地址",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "负责人名称",
+              prop: "personName",
+              width: 210,
+              labelWidth: 100,
+              rules: [{
+                required: false,
+                message: "请输入负责人名称",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "联系方式",
+              prop: "personPhone",
+              width: 120,
+              rules: [{
+                required: false,
+                message: "请输入负责人联系方式",
+                trigger: "blur"
+              }, {
+                validator: validatePhone,
+                trigger: "blur"
+              }],
+            },
+            {
+              label: "背景图",
+              prop: "pic",
+              type: 'upload',
+              hide: true,
+              propsHttp: {
+                res: "data",
+                url: 'link'
+              },
+              listType: 'picture-img',
+              span: 24,
+              row: true,
+              action: "/api/blade-resource/oss/endpoint/put-file",
+              display: true,
+              tip: "上传图片不能超过500K",
+              rules: [{
+                required: false,
+                message: "请上传封面图片",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "小区数量",
+              prop: "residentialCount",
+              display: false,
+              hide: true,
+            },
+            {
+              label: "楼栋数量",
+              prop: "buildingCount",
+              hide: true,
+              display: false,
+            },
+            {
+              label: "单元数量",
+              prop: "unitCount",
+              hide: true,
+              display: false,
+            },
+            {
+              label: "楼层数量",
+              prop: "floorCount",
+              hide: true,
+              display: false,
+            },
+            {
+              label: "房间数量",
+              prop: "roomCount",
+              hide: true,
+              display: false,
+            },
+            {
+              label: "人员数量",
+              prop: "personCount",
+              hide: true,
+              display: false,
             },
-            listType: 'picture-img',
-            span: 24,
-            row: true,
-            action: "/api/blade-resource/oss/endpoint/put-file",
-            display: true,
-            tip:"上传图片不能超过500K",
-            rules: [{
-              required: false,
-              message: "请上传封面图片",
-              trigger: "blur"
-            }]
-          },
-          {
-            label: "小区数量",
-            prop: "residentialCount",
-            display: false,
-            hide: true,
-          },
-          {
-            label: "楼栋数量",
-            prop: "buildingCount",
-            hide: true,
-            display: false,
-          },
-          {
-            label: "单元数量",
-            prop: "unitCount",
-            hide: true,
-            display: false,
-          },
-          {
-            label: "楼层数量",
-            prop: "floorCount",
-            hide: true,
-            display: false,
-          },
-          {
-            label: "房间数量",
-            prop: "roomCount",
-            hide: true,
-            display: false,
-          },
-          {
-            label: "人员数量",
-            prop: "personCount",
-            hide: true,
-            display: false,
-          },
 
-          {
-            label: "备注",
-            prop: "remark",
-            hide: true,
-          },
-        ]
-      },
-      data: []
-    };
-  },
-  computed: {
-    ...mapGetters(["permission"]),
-    permissionList() {
-      return {
-        addBtn: this.vaildData(this.permission.agencymng_add, false),
-        viewBtn: this.vaildData(this.permission.agencymng_view, false),
-        delBtn: this.vaildData(this.permission.agencymng_delete, false),
-        editBtn: this.vaildData(this.permission.agencymng_edit, false)
+            {
+              label: "备注",
+              prop: "remark",
+              hide: true,
+            },
+          ]
+        },
+        data: []
       };
     },
-    ids() {
-      let ids = [];
-      this.selectionList.forEach(ele => {
-        ids.push(ele.id);
-      });
-      return ids.join(",");
+    computed: {
+      ...mapGetters(["permission"]),
+      permissionList() {
+        return {
+          addBtn: this.vaildData(this.permission.agencymng_add, false),
+          viewBtn: this.vaildData(this.permission.agencymng_view, false),
+          delBtn: this.vaildData(this.permission.agencymng_delete, false),
+          editBtn: this.vaildData(this.permission.agencymng_edit, false)
+        };
+      },
+      ids() {
+        let ids = [];
+        this.selectionList.forEach(ele => {
+          ids.push(ele.id);
+        });
+        return ids.join(",");
+      },
     },
-  },
-  watch: {
-    'form.address': {
-      handler: function(value) {
-        if (!value){
-          return
-        }else{
-          var _this = this
-          AMap.plugin('AMap.Geocoder', function() {
-            var geocoder = new AMap.Geocoder({})
-            let lnglat = [_this.form.longitude,_this.form.latitude]
-            geocoder.getAddress(lnglat, function(status, result) {
-              if (status === 'complete'&&result.regeocode&&result.regeocode.addressComponent.township) {
-                let parentCode = result.regeocode.addressComponent.adcode
-                let name = result.regeocode.addressComponent.township
-                getRegDetail({"name":name,"regionLevel":"4","parentCode":parentCode}).then((res)=>{
-                  let data = res.data.data
-                  let obj = {}
-                  obj['regionProvince'] = data.provinceCode
-                  obj['regionCity']  = data.cityCode
-                  obj['regionArea'] = data.districtCode
-                  obj['regionStreet'] = data.code
-                  _this.form = obj
-                })
-              }
+    watch: {
+      'form.address': {
+        handler: function(value) {
+          if (!value) {
+            return
+          } else {
+            var _this = this
+            AMap.plugin('AMap.Geocoder', function() {
+              var geocoder = new AMap.Geocoder({})
+              let lnglat = [_this.form.longitude, _this.form.latitude]
+              geocoder.getAddress(lnglat, function(status, result) {
+                if (status === 'complete' && result.regeocode && result.regeocode.addressComponent.township) {
+                  let parentCode = result.regeocode.addressComponent.adcode
+                  let name = result.regeocode.addressComponent.township
+                  getRegDetail({
+                    "name": name,
+                    "regionLevel": "4",
+                    "parentCode": parentCode
+                  }).then((res) => {
+                    let data = res.data.data
+                    let obj = {}
+                    obj['regionProvince'] = data.provinceCode
+                    obj['regionCity'] = data.cityCode
+                    obj['regionArea'] = data.districtCode
+                    obj['regionStreet'] = data.code
+                    _this.form = obj
+                  })
+                }
+              })
             })
-          })
-        }
+          }
+        },
       },
+      'form.mapSelect': {
+        handler: function(value) {
+          if (!value) {
+            return
+          } else {
+            this.form.longitude = this.form.mapSelect.longitude;
+            this.form.latitude = this.form.mapSelect.latitude;
+            this.form.address = this.form.mapSelect.formattedAddress;
+          }
+        },
+      }
     },
-    'form.mapSelect': {
-      handler: function(value) {
-        if (!value){
-          return
-        }else{
-          this.form.longitude = this.form.mapSelect.longitude;
-          this.form.latitude = this.form.mapSelect.latitude;
-          this.form.address = this.form.mapSelect.formattedAddress;
-        }
+    methods: {
+      agencymng(id) {
+
       },
-    }
-  },
-  methods: {
-    rowSave(row, done, loading) {
-      row.residentialCount = 0;
-      row.unitCount = 0;
-      row.roomCount = 0;
-      row.personCount = 0;
-      row.carCount = 0;
-      add(row).then(() => {
-        this.onLoad(this.page);
-        this.$message({
-          type: "success",
-          message: "操作成功!"
-        });
-        done();
-      }, error => {
-        loading();
-        window.console.log(error);
-      });
-    },
-    rowUpdate(row, index, done, loading) {
-      update(row).then(() => {
-        this.onLoad(this.page);
-        this.$message({
-          type: "success",
-          message: "操作成功!"
-        });
-        done();
-      }, error => {
-        loading();
-        console.log(error);
-      });
-    },
-    rowDel(row) {
-      this.$confirm("确定将选择数据删除?", {
-        confirmButtonText: "确定",
-        cancelButtonText: "取消",
-        type: "warning"
-      })
-        .then(() => {
-          return remove(row.id);
-        })
-        .then(() => {
+      rowSave(row, done, loading) {
+        row.residentialCount = 0;
+        row.unitCount = 0;
+        row.roomCount = 0;
+        row.personCount = 0;
+        row.carCount = 0;
+        add(row).then(() => {
           this.onLoad(this.page);
           this.$message({
             type: "success",
             message: "操作成功!"
           });
+          done();
+        }, error => {
+          loading();
+          window.console.log(error);
         });
-    },
-    handleDelete() {
-      if (this.selectionList.length === 0) {
-        this.$message.warning("请选择至少一条数据");
-        return;
-      }
-      this.$confirm("确定将选择数据删除?", {
-        confirmButtonText: "确定",
-        cancelButtonText: "取消",
-        type: "warning"
-      })
-        .then(() => {
-          return remove(this.ids);
-        })
-        .then(() => {
+      },
+      rowUpdate(row, index, done, loading) {
+        update(row).then(() => {
           this.onLoad(this.page);
           this.$message({
             type: "success",
             message: "操作成功!"
           });
-          this.$refs.crud.toggleSelection();
+          done();
+        }, error => {
+          loading();
+          console.log(error);
         });
-    },
-    beforeOpen(done, type) {
+      },
+      rowDel(row) {
+        this.$confirm("确定将选择数据删除?", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          })
+          .then(() => {
+            return remove(row.id);
+          })
+          .then(() => {
+            this.onLoad(this.page);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+          });
+      },
+      handleDelete() {
+        if (this.selectionList.length === 0) {
+          this.$message.warning("请选择至少一条数据");
+          return;
+        }
+        this.$confirm("确定将选择数据删除?", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          })
+          .then(() => {
+            return remove(this.ids);
+          })
+          .then(() => {
+            this.onLoad(this.page);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+            this.$refs.crud.toggleSelection();
+          });
+      },
+      beforeOpen(done, type) {
 
-      if (["edit", "view"].includes(type)) {
-        getDetail(this.form.id).then(res => {
-          this.form = res.data.data;
+        if (["edit", "view"].includes(type)) {
+          getDetail(this.form.id).then(res => {
+            this.form = res.data.data;
+          });
+        }
+        done();
+      },
+      searchReset() {
+        this.query = {};
+        this.onLoad(this.page);
+      },
+      searchChange(params, done) {
+        this.query = params;
+        this.page.currentPage = 1;
+        this.onLoad(this.page, params);
+        done();
+      },
+      selectionChange(list) {
+        this.selectionList = list;
+      },
+      selectionClear() {
+        this.selectionList = [];
+        this.$refs.crud.toggleSelection();
+      },
+      currentChange(currentPage) {
+        this.page.currentPage = currentPage;
+      },
+      sizeChange(pageSize) {
+        this.page.pageSize = pageSize;
+      },
+      refreshChange() {
+        this.onLoad(this.page, this.query);
+      },
+      onLoad(page, params = {}) {
+        dataStat().then(res => {
+          this.communityCount = res.data.data;
+          this.communityStatistics.data[0].count = this.communityCount.agencyCount;
+          this.communityStatistics.data[1].count = this.communityCount.buildingCount;
+          this.communityStatistics.data[2].count = this.communityCount.enterpriseCount;
+          this.communityStatistics.data[3].count = this.communityCount.staffCount;
+        });
+        this.loading = true;
+        getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
+          const data = res.data.data;
+          this.page.total = data.total;
+          this.data = data.records;
+          this.loading = false;
+          this.selectionClear();
         });
       }
-      done();
-    },
-    searchReset() {
-      this.query = {};
-      this.onLoad(this.page);
-    },
-    searchChange(params, done) {
-      this.query = params;
-      this.page.currentPage = 1;
-      this.onLoad(this.page, params);
-      done();
-    },
-    selectionChange(list) {
-      this.selectionList = list;
-    },
-    selectionClear() {
-      this.selectionList = [];
-      this.$refs.crud.toggleSelection();
-    },
-    currentChange(currentPage) {
-      this.page.currentPage = currentPage;
-    },
-    sizeChange(pageSize) {
-      this.page.pageSize = pageSize;
-    },
-    refreshChange() {
-      this.onLoad(this.page, this.query);
-    },
-    onLoad(page, params = {}) {
-      dataStat().then(res=>{
-        this.communityCount = res.data.data;
-        this.communityStatistics.data[0].count = this.communityCount.agencyCount;
-        this.communityStatistics.data[1].count = this.communityCount.buildingCount;
-        this.communityStatistics.data[2].count = this.communityCount.enterpriseCount;
-        this.communityStatistics.data[3].count = this.communityCount.staffCount;
-      });
-      this.loading = true;
-      getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
-        const data = res.data.data;
-        this.page.total = data.total;
-        this.data = data.records;
-        this.loading = false;
-        this.selectionClear();
-      });
     }
-  }
-};
+  };
 </script>
 
 <style>

+ 546 - 0
src/views/community/agency - 副本.vue

@@ -0,0 +1,546 @@
+<template>
+  <basic-container>
+<!--    卡片-->
+<!--    <el-container>-->
+<!--      <el-main>-->
+<!--        <template>-->
+<!--          <el-carousel :interval="5000" height="200px">-->
+<!--            <el-carousel-item>-->
+<!--              <el-container>-->
+<!--                <el-header style="background-color: rgb(29,67,58);height: 65px">-->
+<!--                  <div class="titleLabel">-->
+<!--                    <el-row :gutter="40">-->
+<!--                      <div>-->
+<!--                        <el-col :span="20"><div class="titleText">{{communityCount.agencyCount}}</div></el-col>-->
+<!--                        <el-col :span="4"><div class="titleCount">{{communityCount.buildingCount}}</div></el-col>-->
+<!--                      </div>-->
+<!--                    </el-row>-->
+<!--                  </div>-->
+<!--                </el-header>-->
+<!--                <el-main>-->
+<!--                  <div style="margin-left: 100px">-->
+<!--                    <avue-data-display :option="dataShow(item)"></avue-data-display>-->
+<!--                  </div>-->
+<!--                </el-main>-->
+<!--              </el-container>-->
+<!--            </el-carousel-item>-->
+<!--          </el-carousel>-->
+<!--        </template>-->
+<!--      </el-main>-->
+<!--    </el-container>-->
+
+<!--卡片数据展示-->
+    <el-card style="margin-bottom: 20px">
+        <el-tabs type="border-card">
+          <el-tab-pane label="园区数据统计">
+            <div><avue-data-box :option="communityStatistics"></avue-data-box></div>
+          </el-tab-pane>
+        </el-tabs>
+    </el-card>
+
+    <avue-crud :option="option" :table-loading="loading" :data="data" :page="page" :permission="permissionList"
+               :before-open="beforeOpen" v-model="form" ref="crud" @row-update="rowUpdate" @row-save="rowSave" @row-del="rowDel"
+               @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange" @current-change="currentChange"
+               @size-change="sizeChange" @refresh-change="refreshChange" @on-load="onLoad">
+      <template slot="menuLeft">
+        <el-button type="danger" size="small" icon="el-icon-delete" plain v-if="permission.agency_delete" @click="handleDelete">删 除</el-button>
+        <cy-excel-import :flag="1" file-name="园区信息导入模板" @success="onLoad(page)"></cy-excel-import>
+      </template>
+      <template slot="mapSelectForm" slot-scope="scope">
+        <div>
+          <!--          <input class="el-input&#45;&#45;small el-input__inner" placeholder="选择地址" @click="mapVisible = true">-->
+          <el-button @click="mapVisible = true"> 选择地址</el-button>
+          <el-dialog :append-to-body="true" :close-on-click-modal="false" :modal-append-to-body="false" :visible.sync="mapVisible"
+                     title="编辑地址" width="80%">
+            <editPolygonMap v-if="mapVisible" :editForm.sync="scope.row" :region.sync="scope.row.address" :latitude.sync="scope.row.latitude" :longitude.sync="scope.row.longitude" :visible.sync="mapVisible"></editPolygonMap>
+          </el-dialog>
+        </div>
+      </template>
+    </avue-crud>
+  </basic-container>
+</template>
+
+<script>
+import {
+  getList,
+  getDetail,
+  add,
+  update,
+  remove
+} from "@/api/community/agency.js";
+import {getCommunityList} from "../../api/grid/index";
+import {
+  mapGetters
+} from "vuex";
+import {
+  validatePhone
+} from "@/util/validator"
+import CyExcelImport from "../../components/excel/cy-excel-import"
+import editPolygonMap from "../../components/residential/editPolygonMap.vue"
+import {getDetail as getRegDetail} from "@/api/base/region"
+export default {
+  components: {CyExcelImport,editPolygonMap},
+  data() {
+    return {
+      communityCount:{},
+      mapVisible:false,
+      areaData: [],
+      form: {},
+      query: {},
+      loading: true,
+      page: {
+        pageSize: 10,
+        currentPage: 1,
+        total: 0
+      },
+      //数据展示
+      communityStatistics:{
+        span:6,
+        data: [
+          {
+            title: '园区数量',
+            count: 0,
+            icon: 'el-icon-office-building',
+            color: 'rgb(49, 180, 141)',
+          },
+          {
+            title: '区域数量',
+            count: 0,
+            icon: 'el-icon-school',
+            color: 'rgb(56, 161, 242)',
+          },
+          {
+            title: '楼宇数量',
+            count: 0,
+            icon: 'el-icon-s-home',
+            color: 'rgb(117, 56, 199)',
+          },
+          {
+            title: '住户数量',
+            count: 0,
+            icon: 'el-icon-user-solid',
+            color: 'rgb(143,119,0)',
+          },
+        ]
+      },
+
+      selectionList: [],
+      option: {
+        height: 'auto',
+        // calcHeight: 60,
+        tip: false,
+        searchShow: true,
+        searchMenuSpan: 6,
+        border: true,
+        index: true,
+        viewBtn: true,
+        selection: true,
+        dialogClickModal: false,
+        menuWidth:350,
+        column: [{
+          label: "名称",
+          prop: "name",
+          search: true,
+          width: 160,
+          overHidden: true,
+          rules: [{
+            required: true,
+            message: "请输入名称",
+            trigger: "blur"
+          }]
+        },
+          {
+            label:'',
+            prop:'mapSelect',
+            viewDisplay: false,
+            formslot: true,
+            hide: true,
+          },
+          {
+            label: "经度",
+            prop: "longitude",
+            width: 120,
+            hide: true,
+            rules: [{
+              required: false,
+              message: "请输入经度",
+              trigger: "blur"
+            }]
+          },
+          {
+            label: "纬度",
+            prop: "latitude",
+            width: 120,
+            hide: true,
+            rules: [{
+              required: false,
+              message: "请输入纬度",
+              trigger: "blur"
+            }]
+          },
+          {
+            label: "所属省",
+            prop: "regionProvince",
+            type: "select",
+            width: 150,
+            dicUrl: "/api/blade-system/region/lazy-tree?parentCode=000000",
+            cascaderItem:["regionCity"],
+            props:{
+              label:"title",
+              value: "id"
+            },
+            rules: [{
+              required: true,
+              message: "请选择所属省份",
+              trigger: "blur"
+            }]
+          },
+          {
+            label: "所属市",
+            prop: "regionCity",
+            type: "select",
+            width: 150,
+            dicFlag: true,
+            cascaderItem: ["regionArea"],
+            dicUrl: `/api/blade-system/region/lazy-tree?parentCode={{key}}`,
+
+            props:{
+              label: "title",
+              value: "id"
+            },
+            rules: [{
+              required: false,
+              message: "请选择所属市",
+              trigger: "blur"
+            }]
+          },
+          {
+            label: "所属区",
+            prop: "regionArea",
+            type: "select",
+            width: 150,
+            cascaderItem: ["regionStreet"],
+            dicUrl:  `/api/blade-system/region/lazy-tree?parentCode={{key}}`,
+            props: {
+              label: "title",
+              value: "id"
+            },
+            rules: [{
+              required: false,
+              message: "请选择所属区",
+              trigger: "blur"
+            }]
+          },
+          {
+            label: "所属街道",
+            prop: "regionStreet",
+            type:"select",
+
+            width: 150,
+            dicUrl: `/api/blade-system/region/lazy-tree?parentCode={{key}}`,
+            props: {
+              label: "title",
+              value: "id"
+            },
+
+            rules: [{
+              required: true,
+              message: "请选择所属街道",
+              trigger: "blur"
+            }]
+          },
+          {
+            label: "详细地址",
+            search: true,
+            prop: "address",
+            type: "textarea",
+            maxRows: 2,
+            // width: 300,
+            overHidden: true,
+            rules: [{
+              required: false,
+              message: "请输入详细地址",
+              trigger: "blur"
+            }]
+          },
+          {
+            label: "负责人名称",
+            prop: "personName",
+            width: 210,
+            labelWidth: 100,
+            rules: [{
+              required: false,
+              message: "请输入负责人名称",
+              trigger: "blur"
+            }]
+          },
+          {
+            label: "联系方式",
+            prop: "personPhone",
+            width: 120,
+            rules: [{
+              required: false,
+              message: "请输入负责人联系方式",
+              trigger: "blur"
+            }, {
+              validator: validatePhone,
+              trigger: "blur"
+            }],
+          },
+          {
+            label: "背景图",
+            prop: "pic",
+            type: 'upload',
+            hide: true,
+            propsHttp: {
+              res: "data",
+              url: 'link'
+            },
+            listType: 'picture-img',
+            span: 24,
+            row: true,
+            action: "/api/blade-resource/oss/endpoint/put-file",
+            display: true,
+            tip:"上传图片不能超过500K",
+            rules: [{
+              required: false,
+              message: "请上传封面图片",
+              trigger: "blur"
+            }]
+          },
+          {
+            label: "小区数量",
+            prop: "residentialCount",
+            display: false,
+            hide: true,
+          },
+          {
+            label: "楼栋数量",
+            prop: "buildingCount",
+            hide: true,
+            display: false,
+          },
+          {
+            label: "单元数量",
+            prop: "unitCount",
+            hide: true,
+            display: false,
+          },
+          {
+            label: "楼层数量",
+            prop: "floorCount",
+            hide: true,
+            display: false,
+          },
+          {
+            label: "房间数量",
+            prop: "roomCount",
+            hide: true,
+            display: false,
+          },
+          {
+            label: "人员数量",
+            prop: "personCount",
+            hide: true,
+            display: false,
+          },
+
+          {
+            label: "备注",
+            prop: "remark",
+            hide: true,
+          },
+        ]
+      },
+      data: []
+    };
+  },
+  computed: {
+    ...mapGetters(["permission"]),
+    permissionList() {
+      return {
+        addBtn: this.vaildData(this.permission.agency_add, false),
+        viewBtn: this.vaildData(this.permission.agency_view, false),
+        delBtn: this.vaildData(this.permission.agency_delete, false),
+        editBtn: this.vaildData(this.permission.agency_edit, false)
+      };
+    },
+    ids() {
+      let ids = [];
+      this.selectionList.forEach(ele => {
+        ids.push(ele.id);
+      });
+      return ids.join(",");
+    },
+  },
+  watch: {
+    'form.address': {
+      handler: function(value) {
+        if (!value){
+          return
+        }else{
+          var _this = this
+          AMap.plugin('AMap.Geocoder', function() {
+            var geocoder = new AMap.Geocoder({})
+            let lnglat = [_this.form.longitude,_this.form.latitude]
+            geocoder.getAddress(lnglat, function(status, result) {
+              if (status === 'complete'&&result.regeocode&&result.regeocode.addressComponent.township) {
+                let parentCode = result.regeocode.addressComponent.adcode
+                let name = result.regeocode.addressComponent.township
+                getRegDetail({"name":name,"regionLevel":"4","parentCode":parentCode}).then((res)=>{
+                  let data = res.data.data
+                  let obj = {}
+                  obj['regionProvince'] = data.provinceCode
+                  obj['regionCity']  = data.cityCode
+                  obj['regionArea'] = data.districtCode
+                  obj['regionStreet'] = data.code
+                  _this.form = obj
+                })
+              }
+            })
+          })
+        }
+      },
+    },
+    'form.mapSelect': {
+      handler: function(value) {
+        if (!value){
+          return
+        }else{
+          this.form.longitude = this.form.mapSelect.longitude;
+          this.form.latitude = this.form.mapSelect.latitude;
+          this.form.address = this.form.mapSelect.formattedAddress;
+        }
+      },
+    }
+  },
+  methods: {
+    rowSave(row, done, loading) {
+      row.residentialCount = 0;
+      row.unitCount = 0;
+      row.roomCount = 0;
+      row.personCount = 0;
+      row.carCount = 0;
+      add(row).then(() => {
+        this.onLoad(this.page);
+        this.$message({
+          type: "success",
+          message: "操作成功!"
+        });
+        done();
+      }, error => {
+        loading();
+        window.console.log(error);
+      });
+    },
+    rowUpdate(row, index, done, loading) {
+      update(row).then(() => {
+        this.onLoad(this.page);
+        this.$message({
+          type: "success",
+          message: "操作成功!"
+        });
+        done();
+      }, error => {
+        loading();
+        console.log(error);
+      });
+    },
+    rowDel(row) {
+      this.$confirm("确定将选择数据删除?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      })
+        .then(() => {
+          return remove(row.id);
+        })
+        .then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+        });
+    },
+    handleDelete() {
+      if (this.selectionList.length === 0) {
+        this.$message.warning("请选择至少一条数据");
+        return;
+      }
+      this.$confirm("确定将选择数据删除?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      })
+        .then(() => {
+          return remove(this.ids);
+        })
+        .then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+          this.$refs.crud.toggleSelection();
+        });
+    },
+    beforeOpen(done, type) {
+
+      if (["edit", "view"].includes(type)) {
+        getDetail(this.form.id).then(res => {
+          this.form = res.data.data;
+        });
+      }
+      done();
+    },
+    searchReset() {
+      this.query = {};
+      this.onLoad(this.page);
+    },
+    searchChange(params, done) {
+      this.query = params;
+      this.page.currentPage = 1;
+      this.onLoad(this.page, params);
+      done();
+    },
+    selectionChange(list) {
+      this.selectionList = list;
+    },
+    selectionClear() {
+      this.selectionList = [];
+      this.$refs.crud.toggleSelection();
+    },
+    currentChange(currentPage) {
+      this.page.currentPage = currentPage;
+    },
+    sizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+    },
+    refreshChange() {
+      this.onLoad(this.page, this.query);
+    },
+    onLoad(page, params = {}) {
+      getCommunityList('/640000').then(res=>{
+        this.communityCount = res.data.data;
+        console.log(this.communityCount,"打印communityCount");
+        this.communityStatistics.data[0].count = this.communityCount.agencyCount;
+        this.communityStatistics.data[1].count = this.communityCount.residentialCount;
+        this.communityStatistics.data[2].count = this.communityCount.buildingCount;
+        this.communityStatistics.data[3].count = this.communityCount.userCount;
+      });
+      this.loading = true;
+      getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
+        const data = res.data.data;
+        this.page.total = data.total;
+        this.data = data.records;
+        this.loading = false;
+        this.selectionClear();
+      });
+    }
+  }
+};
+</script>
+
+<style>
+</style>

+ 2 - 11
src/views/community/room.vue

@@ -64,7 +64,8 @@ export default {
         height:'auto',
         calcHeight: 60,
         tip: false,
-        searchShow: true,
+        searchBtn:false,
+        searchShow: false,
         searchMenuSpan: 6,
         border: true,
         index: true,
@@ -74,16 +75,6 @@ export default {
         selection: true,
         dialogClickModal: false,
         column: [
-          // {
-          //   label: "房间名称",
-          //   prop: "name",
-          //   search: true,
-          //   rules: [{
-          //     required: true,
-          //     message: "请输入房间名称",
-          //     trigger: "blur"
-          //   }]
-          // },
           {
             label: "门牌号 ",
             width: 100,

+ 89 - 0
src/views/dashboard/smartoperationcenter/smartoperationcenter - 副本.vue

@@ -0,0 +1,89 @@
+<template>
+  <div class="body">
+    <el-row>
+      <el-col :span="18">
+        <div style="box-sizing: border-box;margin: 0.625rem;margin-top: 0;">
+
+          <grid-list></grid-list>
+
+          <agency-info></agency-info>
+
+          <div class="my-layout">
+            <div class="layout">
+              <access-records></access-records>
+            </div>
+            <div class="layout">
+              <device></device>
+            </div>
+          </div>
+
+          <div class="my-layout">
+            <div class="layout">
+              <air-quality></air-quality>
+            </div>
+            <div class="layout">
+              <energy></energy>
+            </div>
+          </div>
+
+        </div>
+      </el-col>
+      <el-col :span="6">
+        <work-order></work-order>
+      </el-col>
+    </el-row>
+
+    <div style="height: 1.25rem;"></div>
+  </div>
+</template>
+
+<script>
+  import agencyInfo from "./comps/agency_info.vue"
+  import gridList from "./comps/grid_list.vue"
+  import workOrder from './comps/work_order.vue'
+  import accessRecords from './comps/access_records.vue'
+  import device from './comps/device.vue'
+  import airQuality from './comps/air_quality.vue'
+  import energy from './comps/energy.vue'
+  export default {
+    components: {
+      agencyInfo,
+      gridList,
+      workOrder,
+      accessRecords,
+      device,
+      airQuality,
+      energy
+    },
+    data() {
+      return {
+
+      };
+    }
+  };
+</script>
+
+<style>
+  .avue-main {
+    background-color: #F5F5F5 !important;
+  }
+</style>
+
+<style lang="scss" scoped>
+  .body {
+    box-sizing: border-box;
+    background-color: #F5F5F5;
+    height: 100%;
+  }
+
+  .my-layout {
+    margin-top: 0.625rem;
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+
+    .layout {
+      width: calc(50% - 5px);
+    }
+  }
+</style>

+ 23 - 105
src/views/dashboard/smartoperationcenter/smartoperationcenter.vue

@@ -1,115 +1,33 @@
 <template>
-  <div class="full">
-    <divide></divide>
-  </div>
+  <basic-container style="justify-content: center;">
+    <button @click="open">打开</button>
+    <agencymng ref="agencymng"></agencymng>
+  </basic-container>
 </template>
 
 <script>
-  import divide from "@/components/map/divide.vue"
-  export default {
-    components: {
-      divide
-    },
-    data() {
-      return {
-
-      };
+import agencymng from "@/components/agency/agencymng.vue"
+export default {
+  components:{
+    agencymng
+  },
+  data() {
+    return {
+
+    };
+  },
+  methods:{
+    open(){
+      let item = {
+        id: '1321081130731597825',
+        name: '阅海万家社区'
+      }
+      this.$refs.agencymng.showDialog(item)
     }
-  };
-</script>
-
-<style lang="scss" scoped>
-
-</style>
-
-
-<!-- <template>
-  <div class="body">
-    <el-row>
-      <el-col :span="18">
-        <div style="box-sizing: border-box;margin: 0.625rem;margin-top: 0;">
-
-          <grid-list></grid-list>
-
-          <agency-info></agency-info>
-
-          <div class="my-layout">
-            <div class="layout">
-              <access-records></access-records>
-            </div>
-            <div class="layout">
-              <device></device>
-            </div>
-          </div>
-
-          <div class="my-layout">
-            <div class="layout">
-              <air-quality></air-quality>
-            </div>
-            <div class="layout">
-              <energy></energy>
-            </div>
-          </div>
-
-        </div>
-      </el-col>
-      <el-col :span="6">
-        <work-order></work-order>
-      </el-col>
-    </el-row>
-
-    <div style="height: 1.25rem;"></div>
-  </div>
-</template>
-
-<script>
-  import agencyInfo from "./comps/agency_info.vue"
-  import gridList from "./comps/grid_list.vue"
-  import workOrder from './comps/work_order.vue'
-  import accessRecords from './comps/access_records.vue'
-  import device from './comps/device.vue'
-  import airQuality from './comps/air_quality.vue'
-  import energy from './comps/energy.vue'
-  export default {
-    components: {
-      agencyInfo,
-      gridList,
-      workOrder,
-      accessRecords,
-      device,
-      airQuality,
-      energy
-    },
-    data() {
-      return {
-
-      };
-    }
-  };
-</script>
-
-<style>
-  .avue-main {
-    background-color: #F5F5F5 !important;
   }
-</style>
+};
+</script>
 
 <style lang="scss" scoped>
-  .body {
-    box-sizing: border-box;
-    background-color: #F5F5F5;
-    height: 100%;
-  }
 
-  .my-layout {
-    margin-top: 0.625rem;
-    display: flex;
-    width: 100%;
-    justify-content: space-between;
-
-    .layout {
-      width: calc(50% - 5px);
-    }
-  }
 </style>
- -->

+ 7 - 0
src/views/wel/index.vue

@@ -100,6 +100,13 @@
         },
       }
     },
+    created() {
+      let list=[5,4,3,2,1]
+      let level=5
+      let len=list.length
+      list.splice(0,(len-level))
+      console.log(list);
+    },
     methods: {
 
     }