huangmp 4 vuotta sitten
vanhempi
commit
db466c771c
29 muutettua tiedostoa jossa 1765 lisäystä ja 714 poistoa
  1. BIN
      public/img/icon/buxing.png
  2. BIN
      public/img/icon/demo.jpg
  3. BIN
      public/img/icon/xingzou.png
  4. 0 0
      src/components/map/device-map/comps/device-list.vue
  5. 0 0
      src/components/map/device-map/comps/door-device-form.vue
  6. 0 0
      src/components/map/device-map/comps/video-device-form.vue
  7. 6 6
      src/components/map/device-map/device-map.vue
  8. 0 0
      src/components/map/mapUtil.js
  9. 2 2
      src/components/map/search.vue
  10. 252 0
      src/components/map/trajectory-map/comps/accessRecords.vue
  11. 331 0
      src/components/map/trajectory-map/comps/accessRecordsCrud.vue
  12. 77 0
      src/components/map/trajectory-map/comps/accessRecordsDetail.vue
  13. 408 0
      src/components/map/trajectory-map/comps/map-show.vue
  14. 46 0
      src/components/map/trajectory-map/trajectory-map.vue
  15. 0 192
      src/components/map/trajectory.vue
  16. 98 88
      src/components/residential/editPolygonMap.vue
  17. 3 0
      src/main.js
  18. 1 1
      src/page/index/index.vue
  19. 11 6
      src/page/login/index.vue
  20. 4 4
      src/page/login/userlogin.vue
  21. 0 4
      src/styles/common.scss
  22. 13 15
      src/views/accesscontrolmng/device.vue
  23. 1 1
      src/views/dashboard/onefaceaccess/comps/person-detail.vue
  24. 2 2
      src/views/dashboard/onefaceaccess/comps/resident.vue
  25. 1 1
      src/views/dashboard/onefaceaccess/comps/strange.vue
  26. 15 9
      src/views/dashboard/smartsecurity/comps/control.vue
  27. 98 383
      src/views/smartaccess/facetrajectory.vue
  28. 379 0
      src/views/smartaccess/form/facetrajectory-crud.vue
  29. 17 0
      src/views/wel/index.vue

BIN
public/img/icon/buxing.png


BIN
public/img/icon/demo.jpg


BIN
public/img/icon/xingzou.png


+ 0 - 0
src/components/map/comps/device-list.vue → src/components/map/device-map/comps/device-list.vue


+ 0 - 0
src/components/map/comps/door-device-form.vue → src/components/map/device-map/comps/door-device-form.vue


+ 0 - 0
src/components/map/comps/video-device-form.vue → src/components/map/device-map/comps/video-device-form.vue


+ 6 - 6
src/components/map/divide.vue → src/components/map/device-map/device-map.vue

@@ -8,7 +8,7 @@
         <el-select @change="setSuggestion" :clearable="true" @clear="clear" v-model="value" style="width:100%"
           filterable remote reserve-keyword placeholder="请输入设备名称关键词" :remote-method="getSuggestions" :loading="loading">
           <el-option v-for="(item,index) in suggestionList" :key="index" :label="item.name" :value="item">
-            <span style="float: left">{{ item.name }}</span>
+            <span style="float: left">{{item.name}}</span>
             <el-tooltip class="item" effect="dark" :content="item.address" placement="top-start">
               <span style="float: right; color: #8492a6; font-size: 13px;">{{textCut(item.address)}}</span>
             </el-tooltip>
@@ -77,12 +77,13 @@
   import {
     deepClone
   } from '@/util/util.js'
-  import * as mapUtil from "./js/mapUtil.js"
+  import * as mapUtil from "@/components/map/mapUtil.js"
 
   let _this = this
   let TMap, map, markers, editor, geocoder;
   let infoWindow; //窗口
   export default {
+    name:"设备地图",
     components: {
       deviceList,
       doorDeviceForm,
@@ -199,9 +200,9 @@
         }
 
         let res;
-        if (this.activeIndex==0) {
-           res = await getDoordeviceList(1, 10, params)
-        }else if (this.activeIndex==1) {
+        if (this.activeIndex == 0) {
+          res = await getDoordeviceList(1, 10, params)
+        } else if (this.activeIndex == 1) {
           res = await getGbdevicechannelList(1, 10, params)
         }
         let data = res.data.data
@@ -577,7 +578,6 @@
        * 更新标记集合
        */
       updateGeometries(styleId = 'marker') {
-        console.log('updateGeometries');
         //更新标点坐标
         if (this.$isEmpty(this.coordinates)) {
           markers.setGeometries([])

+ 0 - 0
src/components/map/js/mapUtil.js → src/components/map/mapUtil.js


+ 2 - 2
src/components/map/search.vue

@@ -30,8 +30,8 @@
 </template>
 
 <script>
-  import deviceList from "./comps/device-list.vue"
-  import * as mapUtil from "./js/mapUtil.js"
+  import deviceList from "./device-map/comps/device-list.vue"
+  import * as mapUtil from "./mapUtil.js"
   var TMap, map, markers;
   var editor; // 编辑器
   export default {

+ 252 - 0
src/components/map/trajectory-map/comps/accessRecords.vue

@@ -0,0 +1,252 @@
+<template>
+  <div class="animate__animated animate__faster animate__fadeInRight" style="position: relative;top: -2.6rem;box-sizing: border-box;">
+    <div style="position: absolute;right: 20px;bottom: -1.5rem;z-index: 999;" v-if="page.pages>1">
+      <el-pagination background small layout="prev, pager, next" :current-page="page.current" :page-count="page.pages"
+        @current-change="currentChange">
+      </el-pagination>
+    </div>
+    <more title="人员轨迹" @more="more"></more>
+    <template v-if="$isNotEmpty(list)">
+      <div @click="showDetail(item)" class="card-box" style="cursor: pointer;" v-for="(item,index) in list"
+        :key="item.id" :style="{marginTop:index==0?'0':''}">
+        <div class="left center">
+          <div class="left-data">
+            <div>
+              {{item.userName}}
+              <el-tag size="mini" type="danger">{{userType(item.userType)}}</el-tag>
+            </div>
+            <div>
+              相似度:
+              <span>{{similarity(item.recgScore)}}</span>
+            </div>
+            <div style="margin-top: 0.2rem;">
+              设备名称:{{ellipsis(item.deviceName,14)}}
+            </div>
+            <div style="margin-top: 0.2rem;">开门时间:{{item.createTime}}</div>
+          </div>
+        </div>
+        <div class="right center">
+          <div class="face">
+
+            <el-image @click.stop="" style="width: 5rem; height: 5rem" fit="cover" :src="item.faceUrl"
+              :preview-src-list="[item.faceUrl]">
+            </el-image>
+
+            <div class="center">
+              <img src="/img/safe/vs.png" style="width: 1.25rem;height: 1.25rem;padding: 0 1.25rem;">
+            </div>
+
+            <el-image @click.stop="" style="width: 5rem; height: 5rem" fit="cover" :src="item.originalFaceUrl"
+              :preview-src-list="[item.originalFaceUrl]">
+            </el-image>
+          </div>
+          <div class="func">
+            <div @click.stop="todayList(item)" class="trajectory"><img src="/img/safe/xdgz.png"><span>当天轨迹</span></div>
+          </div>
+        </div>
+      </div>
+    </template>
+
+    <avue-empty v-else style="margin-top: 150px;"></avue-empty>
+
+    <accessRecordsDetail ref="accessRecordsDetail"></accessRecordsDetail>
+  </div>
+</template>
+
+<script>
+  import accessRecordsDetail from "./accessRecordsDetail.vue"
+  // 门禁
+  import more from "@/components/more.vue"
+  import {
+    getList
+  } from "@/api/estate/accessrecord.js"
+  import dateTime from "@/util/dateTime.js"
+  let _markers
+  export default {
+    name: '',
+    components: {
+      more,
+      accessRecordsDetail
+    },
+    inject:['changeTabs'],
+    data() {
+      return {
+        timer: null,
+        list: [],
+        query: {},
+        page: {
+          current: 1,
+          size: 5,
+          total: 0,
+          pages: 0
+        },
+      };
+    },
+    computed: {
+      similarity() {
+        return data => {
+          if (data == -1 || this.$isEmpty(data)) {
+            return '暂无'
+          }
+          return data + '%'
+        }
+      },
+      userType() {
+        return data => {
+          if (data == 'ZH_') {
+            return '住户'
+          }
+          if (data == 'FK_') {
+            return '访客'
+          }
+          if (data == 'FWY_') {
+            return '服务人员'
+          }
+          return '未知'
+        }
+      },
+      ellipsis() {
+        return (data, len) => {
+          if (!data) return '';
+          if (data.length > len) {
+            return data.slice(0, len - 1) + '...'
+          } else {
+            return data
+          }
+        }
+      }
+    },
+    created() {
+      this.$EventBus.$on('search', (params) => {
+        console.log("params", params);
+        this.getList(params)
+      })
+      this.init()
+    },
+    beforeDestroy() {
+      this.$EventBus.$off('search')
+    },
+    methods: {
+      more(){
+        this.changeTabs('facetrajectoryCrud')
+      },
+      init() {
+        this.getList()
+      },
+      showDetail(item) {
+        this.$refs.accessRecordsDetail.show(item)
+      },
+      todayList(item) {
+        let params = {
+          userId: item.userId,
+          openType: 1,
+          queryDate: dateTime.format(new Date(item.createTime), 'YYYY-mm-dd')
+        }
+        getList(1, 500, params).then(res => {
+          let data = {
+            type: 1, //0分页触发,轨迹触发
+            list: res.data.data.records
+          }
+          this.$EventBus.$emit('accessRecordsData', data)
+        })
+      },
+      getList(params = {}) {
+        this.query.openType = 1
+        if (this.$isNotEmpty(params)) {
+          this.page.current = 1
+          this.query = Object.assign(params, this.query)
+        }
+        getList(this.page.current, this.page.size, this.query).then(res => {
+          let data = res.data.data
+          this.list = data.records
+          this.page.pages = data.pages
+          this.page.total = data.total;
+          let accessRecordsData = {
+            type: 0, //0分页触发,轨迹触发
+            list: this.list
+          }
+          this.$EventBus.$emit('accessRecordsData', accessRecordsData)
+        })
+      },
+      currentChange(current) {
+        this.page.current = current
+        this.getList()
+      },
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .trajectory {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    cursor: pointer;
+
+    img {
+      width: 1rem;
+      height: 1rem;
+      margin-right: 0.25rem;
+    }
+
+  }
+
+  .card-box:hover {
+    border: 1px solid #e1e1e1;
+  }
+
+
+
+  .card-box {
+    margin-top: 0.7rem;
+    padding: 15px 0;
+    background-color: #f5f5f5;
+    border: 1px solid #f5f5f5;
+    display: flex;
+    justify-content: space-between;
+
+    .left {
+      color: #333333;
+      font-size: 0.85rem;
+      width: 45%;
+      display: flex;
+      flex-direction: column;
+
+      .left-data {
+        div:first-child {
+          font-weight: 800;
+          font-size: 1rem;
+          padding-bottom: 1rem;
+        }
+      }
+    }
+
+    .right {
+      width: 55%;
+      display: flex;
+      flex-direction: column;
+
+      .face {
+        display: flex;
+
+        img {
+          width: 5rem;
+          height: 5rem;
+        }
+      }
+
+      .func {
+        color: #3B8FF4;
+        font-size: 0.875rem;
+        display: flex;
+        padding-top: 0.8rem;
+
+        div:first-child {
+          padding-right: 0.625rem;
+        }
+      }
+    }
+  }
+
+
+</style>

+ 331 - 0
src/components/map/trajectory-map/comps/accessRecordsCrud.vue

@@ -0,0 +1,331 @@
+<template>
+  <el-dialog title="抓拍记录" :visible.sync="dialogTableVisible" :append-to-body="true" :modal-append-to-body="true"
+    :destroy-on-close="true" width="65%">
+    <basic-container>
+      <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">
+      </avue-crud>
+    </basic-container>
+  </el-dialog>
+</template>
+
+<script>
+  import {
+    getList,
+    getDetail,
+    add,
+    update,
+    remove,
+    getAccessCount
+  } from "@/api/estate/accessrecord";
+  import {
+    mapGetters
+  } from "vuex";
+
+  export default {
+    props: ['userName'],
+    data() {
+      return {
+        dialogTableVisible: false,
+        form: {},
+        query: {},
+        loading: true,
+        page: {
+          pageSize: 10,
+          currentPage: 1,
+          total: 0
+        },
+        selectionList: [],
+        option: {
+          align: 'center',
+          height: 'auto',
+          tip: false,
+          searchShow: true,
+          searchMenuSpan: 6,
+          border: true,
+          index: false,
+          addBtn: false,
+          delBtn: false,
+          editBtn: false,
+          viewBtn: true,
+          selection: false,
+          dialogClickModal: false,
+          menu: false,
+          column: [{
+              label: "用户姓名",
+              prop: "userName",
+              width: 80,
+              rules: [{
+                required: true,
+                message: "请输入用户姓名",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "人脸",
+              prop: "faceUrl",
+              type: 'upload',
+              width: 100,
+              listType: 'picture-img',
+              propsHttp: {
+                res: "data",
+                url: "link"
+              },
+              tip: '只能生产jpg/png图片,且不超过500kb',
+              action: "/api/blade-resource/oss/endpoint/put-file",
+              rules: [{
+                required: true,
+                message: "请输入人脸",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "开门方式",
+              prop: "openType",
+              width: 90,
+              type: "select",
+              dicData: [{
+                label: '刷脸开门',
+                value: 1
+              }, {
+                label: '远程开门',
+                value: 2
+              }],
+            },
+            {
+              label: "体温(℃)",
+              prop: "temperature",
+              width: 80,
+              rules: [{
+                required: true,
+                message: "请输入体温",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "用户类型",
+              prop: "userType",
+              type: "select",
+              editDisplay: false,
+              width: 90,
+              addDisplay: false,
+              dicData: [{
+                  label: "住户",
+                  value: 'ZH_'
+                }, {
+                  label: "企业员工",
+                  value: 'QYYG_'
+                },
+                {
+                  label: "服务人员",
+                  value: 'FWY_'
+                },
+                {
+                  label: "访客",
+                  value: 'FK_'
+                },
+                {
+                  label: "管理员",
+                  value: 'ADMIN_'
+                }
+              ]
+            },
+            {
+              label: "所属园区",
+              prop: "agencyName",
+            },
+            {
+              label: "所属区域",
+              prop: "residentialName",
+            },
+            {
+              label: "设备编码",
+              prop: "deviceId",
+              hide: true,
+              rules: [{
+                required: true,
+                message: "请输入设备唯一标识",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "设备名称",
+              prop: "deviceName",
+            },
+            {
+              label: "设备地址",
+              prop: "deviceAddress",
+            },
+            {
+              label: "设备mac码",
+              prop: "deviceMac",
+              hide: true,
+              rules: [{
+                required: true,
+                message: "请输入设备mac码",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "开门时间",
+              prop: "openTime",
+              rules: [{
+                required: true,
+                message: "请输入开门时间",
+                trigger: "blur"
+              }]
+            },
+          ]
+        },
+        data: []
+      };
+    },
+    computed: {
+      ...mapGetters(["permission"]),
+      permissionList() {
+        return {
+          addBtn: this.vaildData(this.permission.accessrecord_add, false),
+          viewBtn: this.vaildData(this.permission.accessrecord_view, false),
+          delBtn: this.vaildData(this.permission.accessrecord_delete, false),
+          editBtn: this.vaildData(this.permission.accessrecord_edit, false)
+        };
+      },
+      ids() {
+        let ids = [];
+        this.selectionList.forEach(ele => {
+          ids.push(ele.id);
+        });
+        return ids.join(",");
+      }
+    },
+    watch: {
+      userName() {
+        console.log(o);
+      }
+    },
+    methods: {
+      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);
+      },
+      search(params) {
+        this.onLoad(this.page, params);
+      },
+      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);
+      },
+      show(page, params = {}) {
+        this.dialogTableVisible = true
+        this.onLoad(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();
+        });
+      }
+    }
+  };
+</script>
+
+<style>
+
+</style>

+ 77 - 0
src/components/map/trajectory-map/comps/accessRecordsDetail.vue

@@ -0,0 +1,77 @@
+<template>
+  <div>
+    <el-dialog title="详情" :visible.sync="dialogVisible" :append-to-body="true" :modal-append-to-body="true" width="51%">
+      <e-desc :data='info' margin='-10px 2px 10px' label-width='100px'>
+        <e-desc-item label="抓拍照片" :span="1">
+          <template slot="content">
+            <el-image style="width: 100px; height: 100px;margin-left: -15px;" :src="info.faceUrl"
+              :preview-src-list="[info.faceUrl]" fit="cover" :z-index="99999"></el-image>
+          </template>
+        </e-desc-item>
+        <e-desc-item label="对比照片" :span="1">
+          <template slot="content">
+            <el-image style="width: 100px; height: 100px;margin-left: -15px;" :src="info.originalFaceUrl"
+              :preview-src-list="[info.originalFaceUrl]" fit="cover" :z-index="99999"></el-image>
+          </template>
+        </e-desc-item>
+        <e-desc-item label="人员姓名">{{info.userName}}</e-desc-item>
+        <e-desc-item label="人员编号">{{info.userId}}</e-desc-item>
+        <e-desc-item label="抓拍温度">
+          <template slot="content">
+            <span v-if="info.temperature">{{ info.temperature }}℃</span>
+          </template>
+        </e-desc-item>
+        <e-desc-item label="开门方式">
+          <template slot="content">
+            <div v-if="info.openType==2">小程序一键开门</div>
+            <div v-else>刷脸开门</div>
+          </template>
+        </e-desc-item>
+        <e-desc-item label="开门时间" v-if="info.openTime">{{ info.openTime }}</e-desc-item>
+        <e-desc-item label="抓拍时间" v-if="info.createTime">{{ info.createTime }}</e-desc-item>
+        <e-desc-item label="相似度">
+          {{similarity(info.recgScore)}}
+        </e-desc-item>
+        <e-desc-item label="进/出">{{ info.isOut?'进':'出' }}</e-desc-item>
+        <e-desc-item label="设备名称">{{ info.deviceName }}</e-desc-item>
+        <e-desc-item label="所在社区">{{ info.agencyName }}</e-desc-item>
+        <e-desc-item label="所在小区">{{ info.residentialName }}</e-desc-item>
+        <e-desc-item label="所在企业" v-if="info.enterpriseName">{{ info.enterpriseName }}</e-desc-item>
+        <e-desc-item label="设备地址">{{ info.deviceAddress }}</e-desc-item>
+      </e-desc>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import EDesc from '@/components/desc/e-desc.vue'
+  import EDescItem from '@/components/desc/e-desc-item.vue'
+  export default {
+    components: {
+      EDesc,
+      EDescItem
+    },
+    computed:{
+      similarity() {
+        return data => {
+          if (data == -1 || this.$isEmpty(data)) {
+            return '0%'
+          }
+          return data + '%'
+        }
+      }
+    },
+    data() {
+      return {
+        dialogVisible: false,
+        info: {}
+      }
+    },
+    methods: {
+      show(data) {
+        this.info = data
+        this.dialogVisible = true
+      }
+    }
+  }
+</script>

+ 408 - 0
src/components/map/trajectory-map/comps/map-show.vue

@@ -0,0 +1,408 @@
+<template>
+  <div class="animate__animated animate__faster animate__zoomIn">
+    <div style="position: relative;">
+      <!-- 地图 -->
+      <div id="trajectoryMap"></div>
+      <div class="search-body">
+        <el-date-picker align="center" value-format="yyyy-MM-dd" v-model="search.queryDate" type="date"
+          placeholder="选择日期">
+        </el-date-picker>
+        <el-input v-model="search.userName" clearable placeholder="请输入人员姓名" style="width: 200px;">
+        </el-input>
+        <div class="btn" style="background-color: #3B8FF4;" @click="$EventBus.$emit('search',search)">
+          <i class="el-icon-search"></i>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+  import {
+    deepClone
+  } from "@/util/util.js"
+  import {
+    getDetail as getAgencyDetail
+  } from "@/api/community/agency.js"
+  import {
+    getList as getAccessRecordsList
+  } from "@/api/estate/accessrecord.js"
+  import * as mapUtil from "../../mapUtil.js"
+  import more from "@/components/more.vue"
+  import dateTime from "@/util/dateTime.js"
+  let TMap, center, markers;
+  export default {
+    components: {
+      more,
+    },
+    data() {
+      return {
+        map: null,
+        //当前通行记录的坐标点集合
+        LatLngList: [],
+        search: {
+          userName: '',
+          queryDate: ''
+        },
+        //路径
+        path: [],
+      };
+    },
+    mounted() {
+      this.loading = true
+      this.$EventBus.$on('accessRecordsData', (data) => {
+        //擦除折线
+        if (this.polylineLayer) {
+          this.polylineLayer.remove('erasePath')
+        }
+        this.initLatLngList(data.list)
+        if (!this.map) {
+          //未初始化地图
+          this.initMap()
+        } else {
+          console.log("更新");
+          //更新标记点
+          this.updateGeometries()
+        }
+        //轨迹触发
+        if (data.type == 1) {
+          //初始化线路坐标
+          this.initPath()
+          //轨迹,画线路
+          this.createPolylineLayer()
+          //创建小车
+          this.updateCarGeometries()
+          //启动小车
+          this.carMove()
+        }
+      })
+    },
+    beforeDestroy() {
+      this.$EventBus.$off('accessRecordsData')
+    },
+    methods: {
+      clear() {
+        this.getSuggestions()
+      },
+      initLatLngList(list) {
+        this.LatLngList = []
+        if (this.$isEmpty(list)) {
+          return
+        }
+        let originalLatLngList = list.map(item => {
+          return {
+            deviceName: item.deviceName,
+            lat: item.latitude,
+            lng: item.longitude
+          }
+        })
+        for (var i = 0; i < originalLatLngList.length; i++) {
+          let item = originalLatLngList[i]
+          if (this.$isEmpty(item.lat) || this.$isEmpty(item.lng)) {
+            continue
+          }
+          if (!this.LatLngList.some(e => JSON.stringify(e) == JSON.stringify(item))) {
+            this.LatLngList.push(item)
+          }
+        }
+      },
+      initPath() {
+        //移动坐标
+        let carLatLngList = this.LatLngList.reverse()
+        this.path = []
+        carLatLngList.forEach(item => {
+          let obj = new TMap.LatLng(item.lat, item.lng)
+          obj.content = item.deviceName
+          this.path.push(obj)
+        })
+      },
+      /**
+       * 通过设备坐标点获取中心坐标
+       * 或者通过社区经纬度获取中心坐标
+       */
+      async getCenter() {
+        if (this.$isNotEmpty(this.LatLngList)) {
+          let arr = mapUtil.getPointsCenter(this.LatLngList, "lat", "lng")
+          center = this.createCenterObj(arr)
+        }
+        if (this.$isEmpty(center)) {
+          let data = (await getAgencyDetail()).data.data
+          if (this.$isEmpty(data.latitude) || this.$isEmpty(data.longitude)) {
+            this.$message.error('该社区未初始化坐标点')
+            return
+          }
+          let lat = parseFloat(data.latitude).toFixed(6)
+          let lng = parseFloat(data.longitude).toFixed(6)
+          center = new TMap.LatLng(lat, lng)
+        }
+      },
+      /**
+       * @param {Object} data [lat,lng]
+       */
+      createCenterObj(data) {
+        let center = {};
+        try {
+          center = new TMap.LatLng(...data)
+        } catch (e) {
+          console.error(e, "创建中心坐标错误")
+        }
+        return center
+      },
+      async initMap() {
+        let scripts = ['https://map.qq.com/api/gljs?libraries=geometry&v=1.exp']
+        TMap = await mapUtil.loadMap(scripts)
+        //初始化数据
+        await this.getCenter()
+        //创建地图
+        this.createMap()
+        //创建标点
+        this.createMarker()
+      },
+      /**
+       * 创建地图
+       */
+      createMap() {
+        // 初始化地图
+        this.map = new TMap.Map('trajectoryMap', {
+          zoom: 17,
+          pitch: 30,
+          center,
+        });
+        this.map.on("click", (evt) => {
+          let lat = evt.latLng.getLat().toFixed(6);
+          let lng = evt.latLng.getLng().toFixed(6);
+        })
+      },
+      /**
+       * 创建小车移动路线
+       */
+      createPolylineLayer() {
+        this.polylineLayer = new TMap.MultiPolyline({
+          map: this.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() {
+        markers = new TMap.MultiMarker({
+          map: this.map,
+          styles: {
+            "marker": new TMap.MarkerStyle({
+              "width": 30,
+              "height": 30,
+              "anchor": {
+                x: 16,
+                y: 32
+              },
+              "src": '/img/device/door-device.png',
+              "color": '#333', // 标注点文本颜色
+              "size": 14, // 标注点文本文字大小
+              "direction": 'bottom', // 标注点文本文字相对于标注点图片的方位
+              "offset": {
+                x: 0,
+                y: 8
+              }, // 标注点文本文字基于direction方位的偏移属性
+              "strokeColor": '#fff', // 标注点文本描边颜色
+              "strokeWidth": 2, // 标注点文本描边宽度
+            }),
+            'car-down': new TMap.MarkerStyle({
+              width: 40,
+              height: 40,
+              anchor: {
+                x: 16,
+                y: 32,
+              },
+              // faceTo: 'map',
+              // rotate: 20,
+              src: '/img/icon/xingzou.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',
+              color: '#333', // 标注点文本颜色
+              size: 14, // 标注点文本文字大小
+              direction: 'bottom', // 标注点文本文字相对于标注点图片的方位
+              offset: {
+                x: 0,
+                y: 8
+              }, // 标注点文本文字基于direction方位的偏移属性
+              strokeColor: '#fff', // 标注点文本描边颜色
+              strokeWidth: 2, // 标注点文本描边宽度
+            }),
+            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',
+              color: '#333', // 标注点文本颜色
+              size: 14, // 标注点文本文字大小
+              direction: 'bottom', // 标注点文本文字相对于标注点图片的方位
+              offset: {
+                x: 0,
+                y: 8
+              }, // 标注点文本文字基于direction方位的偏移属性
+              strokeColor: '#fff', // 标注点文本描边颜色
+              strokeWidth: 2, // 标注点文本描边宽度
+            }),
+          },
+          geometries: []
+        });
+        this.updateGeometries()
+      },
+      updateCarGeometries() {
+        if (this.$isEmpty(this.path)) {
+          return
+        }
+        let firstPath = this.path[0]
+        let lastPath = this.path[this.path.length - 1]
+        let geometries = [{
+            id: 'car',
+            styleId: 'car-down',
+            position: firstPath,
+          },
+          {
+            id: 'start',
+            styleId: 'start',
+            content: firstPath.content,
+            position: firstPath,
+          },
+          {
+            id: 'end',
+            styleId: 'end',
+            content: lastPath.content,
+            position: lastPath,
+          },
+        ]
+        markers.setGeometries(geometries);
+      },
+      /**
+       * 更新标记集合
+       */
+      updateGeometries(styleId = 'marker') {
+        //更新标点坐标
+        if (this.$isEmpty(this.LatLngList)) {
+          markers.setGeometries([])
+          return
+        }
+        let geometries = this.LatLngList.map((item) => {
+          return {
+            id: item.id,
+            styleId,
+            content: item.deviceName,
+            position: new TMap.LatLng(item.lat, item.lng),
+            properties: item,
+          }
+        })
+        markers.setGeometries(geometries);
+      },
+      /**
+       * 小车移动
+       */
+      carMove() {
+        markers.moveAlong({
+          car: {
+            path: this.path,
+            speed: 600,
+          },
+        }, {
+          autoRotation: true,
+        });
+        markers.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 lang="scss" scoped>
+  html,
+  body {
+    height: 100%;
+    margin: 0px;
+    padding: 0px;
+  }
+
+  #trajectoryMap {
+    width: 100%;
+    height: 50rem;
+  }
+
+  .search-body {
+    position: absolute;
+    z-index: 9999;
+    width: 400px;
+    top: 1.25rem;
+    left: 1.25rem;
+    width: 35%;
+    height: 2.5rem;
+    line-height: 2.5rem;
+    background-color: #FFFFFF;
+    display: flex;
+
+    .btn {
+      cursor: pointer;
+      color: #FFFFFF;
+      font-size: 0.6rem;
+      width: 3.6rem;
+      text-align: center;
+      border-radius: 0 4px 4px 0;
+    }
+
+    .btn:active {
+      transform: scale(1.05);
+    }
+  }
+
+  /deep/ .el-input__inner {
+    border-radius: 0 !important;
+  }
+
+  /deep/ .el-input__inner:hover {
+    border: none;
+  }
+
+  .center {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  }
+
+  .img {
+    width: 100%;
+    height: 50rem;
+  }
+</style>

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

@@ -0,0 +1,46 @@
+<template>
+  <div class="page">
+    <div class="container">
+      <mapShow class="container-left"></mapShow>
+      <accessRecords class="container-right"></accessRecords>
+    </div>
+  </div>
+</template>
+
+<script>
+  import mapShow from "./comps/map-show.vue"
+  import accessRecords from "./comps/accessRecords.vue"
+  export default {
+    name: "轨迹地图",
+    components: {
+      mapShow,
+      accessRecords
+    },
+    data() {
+      return {
+
+      };
+    },
+    methods: {
+
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .page {
+    box-sizing: border-box;
+    background-color: #FFFFFF;
+    padding-bottom: 1.25rem;
+  }
+  .container {
+    display: flex;
+    .container-left {
+      width: 70%;
+    }
+    .container-right {
+      width: 30%;
+      padding: 0.5rem 1rem 1rem;
+    }
+  }
+</style>

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

@@ -1,192 +0,0 @@
-<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>

+ 98 - 88
src/components/residential/editPolygonMap.vue

@@ -6,28 +6,32 @@
       <button class="el-button" @click="closeEdit" style="margin-bottom: 5px">编辑完成</button>
       <button class="el-button" @click="getPath" style="margin-bottom: 5px">保存</button>
     </div>
-    <div id="container"  style="height: 600px;display: block;position: relative;margin-top: 10px;">
+    <div id="container" style="height: 600px;display: block;position: relative;margin-top: 10px;">
       <div id="panel" style="position: absolute;top: 0;bottom:0;right: 0;width: 300px;overflow: auto;z-index: 9;"></div>
     </div>
   </div>
 </template>
 <script>
+  import {
+    getDetail as getAgencyDetail
+  } from "@/api/community/agency.js"
   export default {
     data() {
       return {
-        location:{
+        location: {
           latitude: "39.994257",
           longitude: "116.471354",
         },
-        map:null,
-        polyEditor:null,
-        marker:null,
-        polygonPath:[],
-        address:'',
+        map: null,
+        polyEditor: null,
+        marker: null,
+        polygonPath: [],
+        address: '',
       }
     },
-    props:['editForm', 'longitude', 'latitude', 'region'],
-    mounted() {
+    props: ['editForm', 'longitude', 'latitude', 'region'],
+    async mounted() {
+      await this.getLatLng()
       let data = this.editForm
       let longitude = this.longitude;
       let latitude = this.latitude;
@@ -36,7 +40,7 @@
           this.location.longitude = longitude;
           this.location.latitude = latitude;
         }
-        if(data.boundaryPath!==""&&data.boundaryPath!==null&&data.boundaryPath!==undefined){
+        if (data.boundaryPath !== "" && data.boundaryPath !== null && data.boundaryPath !== undefined) {
           this.polygonPath = JSON.parse(data.boundaryPath)
         }
       }
@@ -45,8 +49,13 @@
       this.initPolygon()
       this.initSearch()
     },
-    methods:{
-      initMap(){
+    methods: {
+      async getLatLng() {
+        let data = (await getAgencyDetail()).data.data
+        this.location.longitude = data.longitude;
+        this.location.latitude = data.latitude;
+      },
+      initMap() {
         var _this = this
         this.map = new AMap.Map('container', {
           resizeEnable: true, //是否监控地图容器尺寸变化
@@ -59,9 +68,9 @@
           _this.setMark(_this.location)
         });
       },
-      setMark(data){
+      setMark(data) {
         var _this = this
-        if(this.marker){
+        if (this.marker) {
           this.map.remove(this.marker);
         }
         AMap.plugin('AMap.Geocoder', function() {
@@ -69,50 +78,51 @@
           var lnglat = [data.longitude, data.latitude]
           geocoder.getAddress(lnglat, function(status, result) {
             if (status === 'complete' && result.info === 'OK') {
-                // result为对应的地理位置详细信息
-                let address = result.regeocode.formattedAddress
-                _this.marker = new AMap.Marker({
-                  position: new AMap.LngLat(data.longitude, data.latitude), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
-                });
-                _this.marker.setLabel({
-                    direction:'center top',
-                    offset: new AMap.Pixel(10, 0),  //设置文本标注偏移量
-                    content: address, //设置文本标注内容
-                });
-                _this.address = address
-                _this.map.add(_this.marker);
+              // result为对应的地理位置详细信息
+              let address = result.regeocode.formattedAddress
+              _this.marker = new AMap.Marker({
+                position: new AMap.LngLat(data.longitude, data
+                  .latitude), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
+              });
+              _this.marker.setLabel({
+                direction: 'center top',
+                offset: new AMap.Pixel(10, 0), //设置文本标注偏移量
+                content: address, //设置文本标注内容
+              });
+              _this.address = address
+              _this.map.add(_this.marker);
             }
           })
         })
 
       },
-      initSearch(){
-          var _this = this
-          //输入提示
-          var autoOptions = {
-              input: "tipinput"
-          };
-          AMap.plugin(['AMap.PlaceSearch','AMap.AutoComplete'], function(){
-              var auto = new AMap.AutoComplete(autoOptions);
-              var placeSearch = new AMap.PlaceSearch({
-                  pageSize: 5, // 单页显示结果条数
-                  pageIndex: 1, // 页码
-                  map: _this.map, // 展现结果的地图实例
-                  panel: "panel", // 结果列表将在此容器中进行展示。
-                  autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
-              });  //构造地点查询类
-              auto.on("select", select);//注册监听,当选中某条记录时会触发
-              function select(e) {
-                  placeSearch.setCity(e.poi.adcode);
-                  placeSearch.search(e.poi.name);  //关键字查询查询
-              }
-          });
+      initSearch() {
+        var _this = this
+        //输入提示
+        var autoOptions = {
+          input: "tipinput"
+        };
+        AMap.plugin(['AMap.PlaceSearch', 'AMap.AutoComplete'], function() {
+          var auto = new AMap.AutoComplete(autoOptions);
+          var placeSearch = new AMap.PlaceSearch({
+            pageSize: 5, // 单页显示结果条数
+            pageIndex: 1, // 页码
+            map: _this.map, // 展现结果的地图实例
+            panel: "panel", // 结果列表将在此容器中进行展示。
+            autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
+          }); //构造地点查询类
+          auto.on("select", select); //注册监听,当选中某条记录时会触发
+          function select(e) {
+            placeSearch.setCity(e.poi.adcode);
+            placeSearch.search(e.poi.name); //关键字查询查询
+          }
+        });
       },
-      initPolygon(){
+      initPolygon() {
         var _this = this;
         this.polyEditor = new AMap.PolygonEditor(this.map);
         this.setPolygon(this.polygonPath)
-        this.polyEditor.on('add', function (data) {
+        this.polyEditor.on('add', function(data) {
           var polygon = data.target;
           _this.polyEditor.addAdsorbPolygons(polygon);
           // polygon.on('click', (res) => {
@@ -122,64 +132,64 @@
           // })
         })
       },
-      setPolygon(data){
-        if(data.length<1)return
+      setPolygon(data) {
+        if (data.length < 1) return
         var _this = this
-            let polygon = new AMap.Polygon({
-              path: data,
-              fillColor: '#ccebc5',
-              strokeOpacity: 1,
-              fillOpacity: 0.5,
-              strokeColor: '#2b8cbe',
-              strokeWeight: 1,
-              strokeStyle: 'dashed',
-              strokeDasharray: [5, 5],
-            });
-            polygon.on('mouseover', () => {
-              polygon.setOptions({
-                fillOpacity: 0.7,
-                fillColor: '#7bccc4'
-              })
-            })
-            polygon.on('mouseout', () => {
-              polygon.setOptions({
-                fillOpacity: 0.5,
-                fillColor: '#ccebc5'
-              })
-            })
-            polygon.on('click', () => {
-              this.polyEditor.open();
-            })
-            this.map.add(polygon);
-            this.map.setFitView();
-            _this.polyEditor.setTarget(polygon)
+        let polygon = new AMap.Polygon({
+          path: data,
+          fillColor: '#ccebc5',
+          strokeOpacity: 1,
+          fillOpacity: 0.5,
+          strokeColor: '#2b8cbe',
+          strokeWeight: 1,
+          strokeStyle: 'dashed',
+          strokeDasharray: [5, 5],
+        });
+        polygon.on('mouseover', () => {
+          polygon.setOptions({
+            fillOpacity: 0.7,
+            fillColor: '#7bccc4'
+          })
+        })
+        polygon.on('mouseout', () => {
+          polygon.setOptions({
+            fillOpacity: 0.5,
+            fillColor: '#ccebc5'
+          })
+        })
+        polygon.on('click', () => {
+          this.polyEditor.open();
+        })
+        this.map.add(polygon);
+        this.map.setFitView();
+        _this.polyEditor.setTarget(polygon)
       },
       createPolygon() {
         this.polyEditor.close();
         this.polyEditor.setTarget();
         this.polyEditor.open();
       },
-      startEdit(){
+      startEdit() {
         this.polyEditor.open();
       },
-      closeEdit(){
+      closeEdit() {
         this.polyEditor.close();
       },
-      getPath(){
+      getPath() {
         let target = this.polyEditor.getTarget()
         let path = ""
-        if(target){
+        if (target) {
           path = target._opts.path
         }
-        if(path!==""&&path!==null&&path!==undefined){
+        if (path !== "" && path !== null && path !== undefined) {
           path = JSON.stringify(path)
         }
         this.region = this.address;
         this.latitude = this.location['latitude']
         this.longitude = this.location['longitude']
-        if(this.editForm != "{}"){
-           this.editForm.boundaryPath = path
-           this.$emit('update:editForm', this.editForm)
+        if (this.editForm != "{}") {
+          this.editForm.boundaryPath = path
+          this.$emit('update:editForm', this.editForm)
         }
 
         this.$emit('update:region', this.region);
@@ -194,7 +204,7 @@
 </script>
 
 <style>
-  .amap-sug-result{
+  .amap-sug-result {
     z-index: 999999999;
     background-color: #fff;
     color: #000;

+ 3 - 0
src/main.js

@@ -34,6 +34,9 @@ require('echarts');
 Vue.prototype.$datavAlert = alert;
 
 
+
+
+Vue.prototype.$EventBus = new Vue();
 //缓存
 import simpleCache from "@/util/cache.js"
 Vue.prototype.$cache = simpleCache

+ 1 - 1
src/page/index/index.vue

@@ -23,7 +23,7 @@
         </div>
 
         <!-- 主体视图层 -->
-        <div class="animate__animated animate__fadeInUpBig" style="height:100%;overflow-y:auto;overflow-x:hidden;"
+        <div style="height:100%;overflow-y:auto;overflow-x:hidden;"
           :style="menuIndex == 0 ?'height: calc(100vh - 10rem);':''" id="avue-view" v-show="!isSearch">
           <keep-alive>
             <router-view class="avue-view" v-if="$route.meta.keepAlive" />

+ 11 - 6
src/page/login/index.vue

@@ -1,12 +1,11 @@
 <template>
   <div class="login-container" ref="login" @keyup.enter.native="handleLogin">
     <indexbg />
-    <div class="login-border" style="">
-      <div style="position: relative;">
-        <div style="position: absolute;left: 1.875rem;bottom: 0rem;width: 30%;display: flex;flex-direction: column;">
-          <userLogin></userLogin>
-        </div>
-        <img src="/img/icon/login.gif" style="width: 100%;height: 100%;"/>
+    <div class="login-border" style="box-sizing: border-box">
+      <div style="background-image: url(/img/icon/login.gif);width: 100%;height: 100%;position: relative;" class="bg-img">
+          <div style="position: absolute;left: 1.875rem;bottom: -1.25rem;width: 30%;">
+            <userLogin></userLogin>
+          </div>
       </div>
     </div>
     <foot />
@@ -111,4 +110,10 @@
 
 <style lang="scss">
   @import "@/styles/login.scss";
+
+  .bg-img {
+    background-size: cover;
+    background-position: center;
+    background-repeat: no-repeat;
+  }
 </style>

+ 4 - 4
src/page/login/userlogin.vue

@@ -1,11 +1,11 @@
 <template>
-  <div>
+  <div style="position: relative;">
     <el-form class="login-form" status-icon :rules="loginRules" ref="loginForm" :model="loginForm" label-width="0">
       <el-form-item>
         <div>
-          <i class="login-title" style="font-size: 1.5rem;position: relative;bottom: -0.8rem;">CY-SMART</i>
+          <i class="login-title" style="font-size: 1.6rem;">CY-SMART</i>
           <br />
-          <i class="login-title" style="font-size: 1.3rem;position: relative;bottom: -0.4rem;">智慧社区大数据平台</i>
+          <i class="login-title" style="font-size: 1.3rem;">智慧社区大数据平台</i>
         </div>
       </el-form-item>
       <el-form-item v-if="tenantMode" prop="tenantId">
@@ -69,7 +69,7 @@
   import {
     getTenantTypeByTenantId
   } from "@/api/system/tenanttype"
-  
+
   import {setStore} from "@/util/store.js"
 
   export default {

+ 0 - 4
src/styles/common.scss

@@ -24,10 +24,6 @@
 @import url(./avue.scss);
 
 
-
-
-
-
 a{
   text-decoration: none;
   color:#333;

+ 13 - 15
src/views/accesscontrolmng/device.vue

@@ -1,54 +1,52 @@
 <template>
   <div class="page">
     <div class="tabs">
-      <div class="tabs_item center" @click="activeIndex=index" :class="activeIndex==index?'tabs_active':''"
-           v-for="(item,index) in tabList" :key="index">
+      <div class="tabs_item center" @click="compsName=item.compsName"
+        :class="compsName==item.compsName?'tabs_active':''" v-for="(item,index) in tabList" :key="index">
         <i class="tabs_icon " :class="item.icon"></i>
         <span class="tabs_label">{{item.label}}</span>
       </div>
     </div>
     <div class="content" style="height: calc(100% - 40px)">
-      <divide v-if="activeIndex==0"></divide>
-      <door-device v-if="activeIndex==1"></door-device>
-      <video-manage v-if="activeIndex==2"></video-manage>
+      <keep-alive>
+        <component :is="compsName"></component>
+      </keep-alive>
     </div>
   </div>
 </template>
 <script>
-  import divide from "../../components/map/divide";
+  import deviceMap from "@/components/map/device-map/device-map.vue";
   import doorDevice from "./comps/door-device.vue";
   import videoManage from "../videoapply/comp/videomanage";
 
   export default {
     components: {
-      divide, doorDevice, videoManage
+      deviceMap,
+      doorDevice,
+      videoManage
     },
     data() {
       return {
+        compsName: 'deviceMap',
         activeIndex: 0,
         tabList: [{
           icon: 'el-icon-setting',
           label: '设备管理',
+          compsName: 'deviceMap',
           prop: 'device',
         }, {
           icon: 'el-icon-lock',
           label: '门禁设备',
+          compsName: 'doorDevice',
           prop: 'door',
         }, {
           icon: 'el-icon-video-camera',
           label: '监控设备',
+          compsName: 'videoManage',
           prop: 'video',
         }]
       }
     },
-    created() {
-      this.activeItem = this.option.column[0];
-    },
-    methods: {
-      handleChange(column) {
-        this.activeItem = column
-      }
-    }
   }
 </script>
 

+ 1 - 1
src/views/dashboard/onefaceaccess/comps/person-detail.vue

@@ -4,7 +4,7 @@
       <e-desc :data='info' margin='-10px 2px 10px' label-width='100px'>
         <e-desc-item label="抓拍照片" :span="3">
           <template slot="content">
-            <el-image style="width: 100px; height: 100px" :src="info.faceUrl" :preview-src-list="[info.faceUrl]"
+            <el-image style="width: 100px; height: 100px;margin-left: -15px;" :src="info.faceUrl" :preview-src-list="[info.faceUrl]"
               fit="cover" :z-index="99999"></el-image>
           </template>
         </e-desc-item>

+ 2 - 2
src/views/dashboard/onefaceaccess/comps/resident.vue

@@ -3,8 +3,8 @@
     <more title="常住人员" reload @reload="reload"></more>
 
     <div style="position: relative" v-if="$isNotEmpty(list)">
-      <div style="position: absolute;right: 10px;bottom: -10px;z-index: 999;" v-show="!loading">
-        <el-pagination @current-change="currentChange" small layout="prev, pager, next" :page-count="page.pages">
+      <div style="position: absolute;right: -5px;bottom: -13px;z-index: 999;" v-show="!loading">
+        <el-pagination background @current-change="currentChange" small layout="prev, pager, next" :page-count="page.pages">
         </el-pagination>
       </div>
 

+ 1 - 1
src/views/dashboard/onefaceaccess/comps/strange.vue

@@ -4,7 +4,7 @@
 
     <div style="position: relative;" v-if="$isNotEmpty(list)">
       <div style="position: absolute;right: 10px;bottom: -10px;z-index: 999;" v-show="!loading">
-        <el-pagination @current-change="currentChange" small layout="prev, pager, next" :page-count="page.pages">
+        <el-pagination background @current-change="currentChange" small layout="prev, pager, next" :page-count="page.pages">
         </el-pagination>
       </div>
 

+ 15 - 9
src/views/dashboard/smartsecurity/comps/control.vue

@@ -19,10 +19,14 @@
         </div>
       </div>
 
-      <div class="container-right animate__animated animate__faster animate__fadeInRight">
-        <more title="今日布控预警"></more>
+      <div class="container-right animate__animated animate__faster animate__fadeInRight" style="position: relative;">
+        <div style="position: absolute;right: 10px;bottom: -10px;z-index: 999;">
+          <el-pagination small layout="prev, pager, next" :page-count="page.pages">
+          </el-pagination>
+        </div>
 
-        <div class="card-box" style="margin-top: 0.975rem" v-for="(item,index) in 5" :key="index">
+        <more title="今日布控预警"></more>
+        <div class="card-box" v-for="(item,index) in 5" :key="index" :style="{marginTop:index==0?'1rem':''}">
           <div class="left center">
             <div class="left-data">
               <div>张**</div>
@@ -38,7 +42,6 @@
                 :preview-src-list="['/img/test/face.png']">
               </el-image>
 
-
               <div class="center">
                 <img src="/img/safe/vs.png" style="width: 1.25rem;height: 1.25rem;padding: 0 1.25rem;">
               </div>
@@ -70,7 +73,12 @@
     },
     data() {
       return {
-
+        page: {
+          current: 1,
+          size: 6,
+          total: 0,
+          pages: 0
+        },
       };
     },
     methods: {
@@ -144,8 +152,8 @@
   }
 
   .card-box {
-    margin-top: 1.25rem;
-    padding: 18px 0;
+    margin-top: 0.7rem;
+    padding: 16px 0;
     background-color: #f5f5f5;
     display: flex;
     justify-content: space-between;
@@ -193,7 +201,5 @@
         }
       }
     }
-
-
   }
 </style>

+ 98 - 383
src/views/smartaccess/facetrajectory.vue

@@ -1,396 +1,111 @@
 <template>
-  <basic-container>
-<!--    卡片数据展示-->
-    <el-card style="margin-bottom: 20px">
-<!--      <template slot="header">-->
-<!--        出入统计数据-->
-        <el-tabs type="border-card">
-          <el-tab-pane label="数据统计"><avue-data-box :option="AccessRecord"></avue-data-box></el-tab-pane>
-<!--          <el-tab-pane label="本周数据"><avue-data-icon :option="weekAccessRecord"></avue-data-icon></el-tab-pane>-->
-<!--          <el-tab-pane label="本月数据"><avue-data-icon :option="monthAccessRecord"></avue-data-icon></el-tab-pane>-->
-<!--          <el-tab-pane label="今年数据"><avue-data-icon :option="yearAccessRecord"></avue-data-icon></el-tab-pane>-->
-        </el-tabs>
-<!--      </template>-->
-    </el-card>
-
-
-    <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">
-    </avue-crud>
-  </basic-container>
+  <div class="page" style="height: 55.5rem;">
+    <div class="tabs">
+      <div class="tabs_item center" @click="compsName=item.compsName"
+        :class="compsName==item.compsName?'tabs_active':''" v-for="(item,index) in tabList" :key="index">
+        <i class="tabs_icon " :class="item.icon"></i>
+        <span class="tabs_label">{{item.label}}</span>
+      </div>
+    </div>
+    <div class="content" style="height: calc(90% - 40px)">
+      <keep-alive>
+        <component :is="compsName"></component>
+      </keep-alive>
+    </div>
+  </div>
 </template>
-
 <script>
-  import {getList, getDetail, add, update, remove, getAccessCount} from "@/api/estate/accessrecord";
-  import {mapGetters} from "vuex";
-
   export default {
-    data() {
-      return {
-        //今年数据
-        AccessRecord:{
-          span:6,
-          data: [
-            {
-              title: '今日数据',
-              count: 0,
-              icon: 'el-icon-user-solid',
-              color: 'rgb(49, 180, 141)',
-            },
-            {
-              title: '本周数据',
-              count: 0,
-              icon: 'el-icon-user-solid',
-              color: 'rgb(56, 161, 242)',
-            },
-            {
-              title: '本月数据',
-              count: 0,
-              icon: 'el-icon-user-solid',
-              color: 'rgb(117, 56, 199)',
-            },
-            {
-              title: '今年数据',
-              count: 0,
-              icon: 'el-icon-user-solid',
-              color: 'rgb(143,119,0)',
-            },
-          ]
-        },
-        enterpriseColumn: {
-          label: "所属企业",
-          prop: "enterpriseId",
-          type: "select",
-          search: true,
-          width:200,
-          filterable: true,
-          dicUrl: "/api/cyzh-enterprise/enterprise/list?size=9999",
-          props:{
-            label:"enterpriseName",
-            value:"id"
-          },
-          dicFormatter: (res)=>{
-            return res.data.records;
-          },
-          searchFilterable: true,
-        },
-        form: {},
-        query: {},
-        loading: true,
-        page: {
-          pageSize: 10,
-          currentPage: 1,
-          total: 0
-        },
-        selectionList: [],
-        option: {
-          height:'auto',
-          // calcHeight: 30,
-          tip: false,
-          searchShow: true,
-          searchMenuSpan: 6,
-          border: true,
-          index: true,
-          addBtn: false,
-          delBtn: false,
-          editBtn: false,
-          viewBtn: true,
-          selection: true,
-          dialogClickModal: false,
-          column: [
-            {
-              label: "用户姓名",
-              prop: "userName",
-              width:80,
-              rules: [{
-                required: true,
-                message: "请输入用户姓名",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "人脸",
-              prop: "faceUrl",
-              type:'upload',
-              width:100,
-              listType: 'picture-img',
-              propsHttp: {
-                res: "data",
-                url: "link"
-              },
-              tip: '只能生产jpg/png图片,且不超过500kb',
-              action: "/api/blade-resource/oss/endpoint/put-file",
-              rules: [{
-                required: true,
-                message: "请输入人脸",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "开门方式",
-              prop: "openType",
-              type:"select",
-              dicData:[
-                {
-                  label:'刷脸开门',
-                  value:1
-                },{
-                  label:'远程开门',
-                  value:2
-                }
-              ],
-            },
-            {
-              label: "体温(℃)",
-              prop: "temperature",
-              width:80,
-              rules: [{
-                required: true,
-                message: "请输入体温",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "用户类型",
-              prop: "userType",
-              type: "select",
-              value: 4,
-              editDisplay: false,
-              addDisplay: false,
-              dicData:[
-                {
-                  label: "企业员工",
-                  value: 2
-                },
-                {
-                  label: "服务人员",
-                  value: 3
-                },
-                {
-                  label: "访客",
-                  value: 4
-                },
-                {
-                  label: "管理员",
-                  value: 5
-                }]
-            },
-            {
-              label: "所属园区",
-              prop: "agencyName",
-            },
-            {
-              label: "所属区域",
-              prop: "residentialName",
-            },
-            {
-              label: "设备编码",
-              prop: "deviceId",
-              hide:true,
-              rules: [{
-                required: true,
-                message: "请输入设备唯一标识",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "设备名称",
-              prop: "deviceName",
-            },
-            {
-              label: "设备mac码",
-              prop: "deviceMac",
-              hide:true,
-              rules: [{
-                required: true,
-                message: "请输入设备mac码",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "开门时间",
-              prop: "openTime",
-              rules: [{
-                required: true,
-                message: "请输入开门时间",
-                trigger: "blur"
-              }]
-            },
-          ]
-        },
-        data: []
-      };
+    components: {
+      trajectoryMap:()=>import('@/components/map/trajectory-map/trajectory-map.vue'),
+      facetrajectoryCrud:()=>import('./form/facetrajectory-crud.vue')
     },
-    computed: {
-      ...mapGetters(["permission"]),
-      permissionList() {
-        return {
-          addBtn: this.vaildData(this.permission.accessrecord_add, false),
-          viewBtn: this.vaildData(this.permission.accessrecord_view, false),
-          delBtn: this.vaildData(this.permission.accessrecord_delete, false),
-          editBtn: this.vaildData(this.permission.accessrecord_edit, false)
-        };
-      },
-      ids() {
-        let ids = [];
-        this.selectionList.forEach(ele => {
-          ids.push(ele.id);
-        });
-        return ids.join(",");
+    provide() {
+      return {
+        'changeTabs': this.changeTabs,
       }
     },
-    created() {
-      const tenantType = localStorage.getItem("tenantType");
-      let agencyNameProp = this.findObject(this.option.column,"agencyName");
-      let residentialNameProp = this.findObject(this.option.column,"residentialName");
-      if (tenantType == 0){
-        //园区
-        agencyNameProp.label="所属园区";
-        residentialNameProp.label="所属区域";
-      }else if (tenantType == 1){
-        //园区
-        agencyNameProp.label = "所属园区";
-        this.option.column.splice(5,0,this.enterpriseColumn)
-        residentialNameProp.label="所属区域";
+    data() {
+      return {
+        compsName: 'trajectoryMap',
+        tabList: [{
+          icon: 'el-icon-place',
+          label: '轨迹地图',
+          compsName: 'trajectoryMap',
+        }, {
+          icon: 'el-icon-user',
+          label: '人员轨迹',
+          compsName: 'facetrajectoryCrud',
+        }]
       }
     },
-    methods: {
-      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 = {}) {
-        params.userType = 4;
-        this.loading = true;
-        getAccessCount().then(res=>{
-          console.log(res,"打印res")
-          this.AccessRecord.data[0].count = res.data.dayCount;
-          this.AccessRecord.data[1].count = res.data.weekCount;
-          this.AccessRecord.data[2].count = res.data.monthCount;
-          this.AccessRecord.data[3].count = res.data.yearCount;
-        });
-        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();
-        });
+    methods:{
+      changeTabs(name){
+        this.compsName=name
       }
-    }
-  };
+    },
+  }
 </script>
 
-<style>
+<style lang="scss" scoped>
+  * {
+    box-sizing: border-box;
+  }
+
+  .page {
+    background-color: #fff;
+    width: 100%;
+  }
+
+  /deep/ #avue-view {
+    margin-top: -10px !important;
+  }
+
+  .center {
+    display: flex;
+    justify-content: center;
+    align-content: center;
+  }
+
+  .content {
+    width: 100%;
+    height: 100%
+  }
+
+  .tabs {
+    display: flex;
+    justify-content: start;
+    align-content: center;
+    padding-left: 20px;
+    height: 40px;
+  }
+
+  .tabs_item {
+    margin-right: 40px;
+    cursor: pointer;
+    color: #303133;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  }
+
+  .tabs_item:hover {
+    color: #409EFF;
+  }
+
+  .tabs_label {
+    margin-left: 4px;
+    font-size: 14px;
+  }
+
+  .tabs_icon {
+    font-size: 14px;
+
+  }
+
+  .tabs_active {
+    color: #409EFF;
+    font-weight: 800;
+    border-bottom: 1px solid #409EFF
+  }
 </style>

+ 379 - 0
src/views/smartaccess/form/facetrajectory-crud.vue

@@ -0,0 +1,379 @@
+<template>
+  <basic-container class="animate__animated animate__faster animate__zoomIn">
+    <!--    卡片数据展示-->
+    <el-card style="margin-bottom: 20px">
+      <el-tabs type="border-card">
+        <el-tab-pane label="数据统计">
+          <avue-data-box :option="AccessRecord"></avue-data-box>
+        </el-tab-pane>
+      </el-tabs>
+    </el-card>
+    <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">
+    </avue-crud>
+  </basic-container>
+</template>
+
+<script>
+  import {
+    getList,
+    getDetail,
+    add,
+    update,
+    remove,
+    getAccessCount
+  } from "@/api/estate/accessrecord";
+  import {
+    mapGetters
+  } from "vuex";
+
+  export default {
+    data() {
+      return {
+        //今年数据
+        AccessRecord: {
+          span: 6,
+          data: [{
+              title: '今日数据',
+              count: 0,
+              icon: 'el-icon-user-solid',
+              color: 'rgb(49, 180, 141)',
+            },
+            {
+              title: '本周数据',
+              count: 0,
+              icon: 'el-icon-user-solid',
+              color: 'rgb(56, 161, 242)',
+            },
+            {
+              title: '本月数据',
+              count: 0,
+              icon: 'el-icon-user-solid',
+              color: 'rgb(117, 56, 199)',
+            },
+            {
+              title: '今年数据',
+              count: 0,
+              icon: 'el-icon-user-solid',
+              color: 'rgb(143,119,0)',
+            },
+          ]
+        },
+        enterpriseColumn: {
+          label: "所属企业",
+          prop: "enterpriseId",
+          type: "select",
+          search: true,
+          width: 200,
+          filterable: true,
+          dicUrl: "/api/cyzh-enterprise/enterprise/list?size=9999",
+          props: {
+            label: "enterpriseName",
+            value: "id"
+          },
+          dicFormatter: (res) => {
+            return res.data.records;
+          },
+          searchFilterable: true,
+        },
+        form: {},
+        query: {},
+        loading: true,
+        page: {
+          pageSize: 10,
+          currentPage: 1,
+          total: 0
+        },
+        selectionList: [],
+        option: {
+          height: 'auto',
+          // calcHeight: 30,
+          tip: false,
+          searchShow: true,
+          searchMenuSpan: 6,
+          border: true,
+          index: true,
+          addBtn: false,
+          delBtn: false,
+          editBtn: false,
+          viewBtn: true,
+          selection: true,
+          dialogClickModal: false,
+          column: [{
+              label: "用户姓名",
+              prop: "userName",
+              width: 80,
+              rules: [{
+                required: true,
+                message: "请输入用户姓名",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "人脸",
+              prop: "faceUrl",
+              type: 'upload',
+              width: 100,
+              listType: 'picture-img',
+              propsHttp: {
+                res: "data",
+                url: "link"
+              },
+              tip: '只能生产jpg/png图片,且不超过500kb',
+              action: "/api/blade-resource/oss/endpoint/put-file",
+              rules: [{
+                required: true,
+                message: "请输入人脸",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "开门方式",
+              prop: "openType",
+              type: "select",
+              dicData: [{
+                label: '刷脸开门',
+                value: 1
+              }, {
+                label: '远程开门',
+                value: 2
+              }],
+            },
+            {
+              label: "体温(℃)",
+              prop: "temperature",
+              width: 80,
+              rules: [{
+                required: true,
+                message: "请输入体温",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "用户类型",
+              prop: "userType",
+              type: "select",
+              value: 4,
+              editDisplay: false,
+              addDisplay: false,
+              dicData: [{
+                  label: "企业员工",
+                  value: 2
+                },
+                {
+                  label: "服务人员",
+                  value: 3
+                },
+                {
+                  label: "访客",
+                  value: 4
+                },
+                {
+                  label: "管理员",
+                  value: 5
+                }
+              ]
+            },
+            {
+              label: "所属园区",
+              prop: "agencyName",
+            },
+            {
+              label: "所属区域",
+              prop: "residentialName",
+            },
+            {
+              label: "设备编码",
+              prop: "deviceId",
+              hide: true,
+              rules: [{
+                required: true,
+                message: "请输入设备唯一标识",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "设备名称",
+              prop: "deviceName",
+            },
+            {
+              label: "设备mac码",
+              prop: "deviceMac",
+              hide: true,
+              rules: [{
+                required: true,
+                message: "请输入设备mac码",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "开门时间",
+              prop: "openTime",
+              rules: [{
+                required: true,
+                message: "请输入开门时间",
+                trigger: "blur"
+              }]
+            },
+          ]
+        },
+        data: []
+      };
+    },
+    computed: {
+      ...mapGetters(["permission"]),
+      permissionList() {
+        return {
+          addBtn: this.vaildData(this.permission.accessrecord_add, false),
+          viewBtn: this.vaildData(this.permission.accessrecord_view, false),
+          delBtn: this.vaildData(this.permission.accessrecord_delete, false),
+          editBtn: this.vaildData(this.permission.accessrecord_edit, false)
+        };
+      },
+      ids() {
+        let ids = [];
+        this.selectionList.forEach(ele => {
+          ids.push(ele.id);
+        });
+        return ids.join(",");
+      }
+    },
+    created() {
+      const tenantType = localStorage.getItem("tenantType");
+      let agencyNameProp = this.findObject(this.option.column, "agencyName");
+      let residentialNameProp = this.findObject(this.option.column, "residentialName");
+      if (tenantType == 0) {
+        //园区
+        agencyNameProp.label = "所属园区";
+        residentialNameProp.label = "所属区域";
+      } else if (tenantType == 1) {
+        //园区
+        agencyNameProp.label = "所属园区";
+        this.option.column.splice(5, 0, this.enterpriseColumn)
+        residentialNameProp.label = "所属区域";
+      }
+    },
+    methods: {
+      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;
+        getAccessCount().then(res => {
+          this.AccessRecord.data[0].count = res.data.dayCount;
+          this.AccessRecord.data[1].count = res.data.weekCount;
+          this.AccessRecord.data[2].count = res.data.monthCount;
+          this.AccessRecord.data[3].count = res.data.yearCount;
+        });
+        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>

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

@@ -102,6 +102,23 @@
     },
     methods: {
 
+    },
+    created() {
+      this.demo()
+    },
+    methods:{
+      demo(){
+       
+      },
+      test1(){
+        console.log('test1');
+      },
+      test2(){
+        console.log('test2');
+      },
+      test3(){
+        console.log('test3');
+      }
     }
   }
 </script>