Ver código fonte

扫楼日志

zhulizhen 6 anos atrás
pai
commit
cf324a29b2

+ 1 - 0
index.html

@@ -4,6 +4,7 @@
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width,initial-scale=1.0" />
     <title>sagacloud-admin</title>
+    <link src='//at.alicdn.com/t/font_1112731_cpdyeyhpqk.css'>
   </head>
   <body>
     <div id="app"></div>

Diferenças do arquivo suprimidas por serem muito extensas
+ 951 - 0
src/components/scan/buildFamily.vue


+ 49 - 0
src/components/scan/input.vue

@@ -0,0 +1,49 @@
+<template>
+  <div class="build_input">
+        <i class="iconfont icon-sousuo"></i>
+        <input type="text" v-model="value" :placeholder="placeholder" @keyup.enter="search">
+    </div>
+</template>
+
+<script>
+export default {
+    props: [ 'placeholder'],
+    data(){
+        return{
+            value: ''
+        }
+    },
+    methods: {
+        search(){
+            this.$emit("search",this.value)
+        },
+    },
+}
+</script>
+
+<style lang="less" scoped>
+.build_input{
+    display: inline-block;
+    width: 23rem;
+    height: 2rem;
+    font-size: 1.4rem;
+    position: relative;
+    input{
+        width: 100%;
+        height: 100%;
+        padding-left: 2rem;
+        font-size: .8rem;
+        box-sizing: border-box;
+    }
+    .icon-sousuo{
+        position: absolute;
+        width: 2rem;
+        height: 2rem;
+        left: 0;
+        top: 3px;
+        bottom: 0;
+        line-height: 2rem;
+        text-align: center;
+    }
+}
+</style>

+ 155 - 0
src/components/scan/selectTime.vue

@@ -0,0 +1,155 @@
+<template>
+  <div class="select_time">
+    <span
+      v-for="item in timeArr"
+      @click="checkTime(item)"
+      class="bar"
+      :class="item == activeClass ? 'active' : ''"
+    >{{item}}</span>
+    <span @click="doCheck" :class="'自定义' == activeClass ? 'active' : ''">
+      自定义
+      <i v-show="valDate.length">{{valDate[0]}} ~ {{valDate[1]}}</i>
+      <div v-show="isShow" class="picker_view">
+        <i>扫楼时间:</i>
+        <el-date-picker
+          v-model="value"
+          type="daterange"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          @change="getDate"
+        ></el-date-picker>
+      </div>
+    </span>
+    <div class="masked" v-if="isShow" @click="isShow = !isShow"></div>
+  </div>
+</template>
+
+<script>
+export default {
+  props: ['timeArr'],
+  data() {
+    return {
+      activeClass: '今天',
+      value: '',
+      isShow: false,
+      valDate: []
+    }
+  },
+  methods: {
+    getNowFormatDate(str) {
+      var date = new Date(str);
+      var seperator1 = "-";
+      var seperator2 = ":";
+      var month = date.getMonth() + 1;
+      var strDate = date.getDate();
+      if (month >= 1 && month <= 9) {
+        month = "0" + month;
+      }
+      if (strDate >= 0 && strDate <= 9) {
+        strDate = "0" + strDate;
+      }
+      let minutes = date.getMinutes() > 9 ? date.getMinutes() : "0" + date.getMinutes()
+      let hour = date.getHours() > 9 ? date.getHours() : "0" + date.getHours()
+      let seconds = date.getSeconds() > 9 ? date.getSeconds() : "0" + date.getSeconds()
+      var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate
+        + " " + hour + seperator2 + minutes
+        + seperator2 + seconds;
+      return currentdate;
+    },
+    checkTime(val) {
+      // 控制active显示
+      this.activeClass = val
+      let nowdate = new Date().setHours(0, 0, 0, 0)
+      let oldDate = ''
+      let oneDay = new Date()
+      this.valDate = []
+      switch (val) {
+        case '一个月内':
+          oldDate = new Date(new Date().setMonth(new Date().getMonth() - 1)).setHours(0, 0, 0, 0)
+          this.$emit('checkTime', [this.getNowFormatDate(oldDate), this.getNowFormatDate(new Date(oneDay))])
+          break;
+        case '一周内':
+          oldDate = new Date(nowdate - 7 * 24 * 3600 * 1000)
+          this.$emit('checkTime', [this.getNowFormatDate(oldDate), this.getNowFormatDate(new Date(oneDay))])
+          break;
+        case '近三天':
+          oldDate = new Date(nowdate - 3 * 24 * 3600 * 1000)
+          this.$emit('checkTime', [this.getNowFormatDate(oldDate), this.getNowFormatDate(new Date(oneDay))])
+          break;
+        case '昨天':
+          oldDate = new Date(nowdate - 24 * 3600 * 1000)
+          this.$emit('checkTime', [this.getNowFormatDate(oldDate), this.getNowFormatDate(new Date(nowdate))])
+          break;
+        case '今天':
+          oldDate = new Date(nowdate);
+          this.$emit('checkTime', [this.getNowFormatDate(oldDate), this.getNowFormatDate(new Date())])
+          break;
+        default:
+      }
+    },
+    doCheck() {
+      this.isShow = true
+    },
+    getDate() {
+      if (this.value == '' || this.value) {
+        this.$emit('checkTime', [this.getNowFormatDate(this.value[0]), this.getNowFormatDate(this.value[1])])
+        this.valDate[0] = this.getNowFormatDate(this.value[0]).split(' ')[0]
+        this.valDate[1] = this.getNowFormatDate(this.value[1]).split(' ')[0]
+        this.isShow = false
+        this.activeClass = '自定义'
+      } else {
+        this.isShow = false
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.select_time {
+  font-size: 0.8rem;
+  display: inline-block;
+  margin-left: 2rem;
+  span {
+    cursor: pointer;
+    position: relative;
+    &.active {
+      color: #409eff;
+    }
+    .picker_view {
+      position: absolute;
+      width: 30rem;
+      bottom: -3rem;
+      left: -23rem;
+      height: 3rem;
+      padding-top: 0.5rem;
+      box-sizing: border-box;
+      z-index: 999;
+      background-color: rgba(255, 255, 255, 1);
+      padding-left: 1rem;
+      padding-right: 2rem;
+      border: 0.01rem solid #eee;
+      z-index: 2001;
+      i {
+        color: #000;
+      }
+    }
+  }
+  .bar::after {
+    content: "|";
+    margin-right: 0.2rem;
+    margin-left: 0.2rem;
+    color: #000;
+  }
+  .masked {
+    position: fixed;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    opacity: 0;
+    z-index: 2;
+  }
+}
+</style>

+ 2 - 1
src/router/sagacloud.js

@@ -14,6 +14,7 @@ import collectsetting from "@/views/project_setting/collection_setting"
 
 /** 扫楼数据整理 */
 import buildAssets from "@/views/data_admin/buildAssets"
+import buildLog from "@/views/data_admin/buildLog"
 
 export default [
     { path: '/auth', name: 'Auth', component: Auth },
@@ -125,7 +126,7 @@ export default [
             { path: 'data', name: 'Dasboard', component: Dasboard },
             { path: 'plan', name: 'Dasboard', component: Dasboard },
             { path: 'abnormalprop', name: 'buildAssets', component: buildAssets },
-            { path: 'log', name: 'Dasboard', component: Dasboard },
+            { path: 'log', name: 'buildLog', component: buildLog },
             { path: 'appuser', name: 'Dasboard', component: Dasboard },
         ]
     },

+ 464 - 0
src/views/data_admin/buildLog/index.vue

@@ -0,0 +1,464 @@
+<!--
+  revit扫楼日志
+ -->
+<template>
+    <div id="build_log">
+        <div class="search_header">
+            <build-input :placeholder="placeholder" @search="search"></build-input>
+            <em @click="showDic" class="dong_dic">
+                <i class="iconfont icon-wenti"></i>
+                <i style="font-size:12px;">动作说明</i>
+            </em>
+            <build-time :timeArr="timeArr" @checkTime="checkTime"></build-time>
+            <div class="derived_btn" @click="downExcel">
+                <i class="iconfont icon-excelwenjian"></i>
+                <i class="excel">导出到Excel</i>
+            </div>
+            <div class="derived_btn" @click="refresh">
+                <i class="iconfont icon-shuaxin"></i>
+                <i class="excel">刷新</i>
+            </div>
+        </div>
+        <div class="log_view" v-loading="loading">
+            <div id="log"></div>
+            <div v-if="noData" class="no_data">暂无数据</div>
+        </div>
+        <div class="log_page">
+            <el-pagination
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page.sync="currentPage"
+                :page-sizes="pageSizeArr"
+                :page-size="pageSize"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="pageCount"
+            ></el-pagination>
+        </div>
+        <el-dialog class="log_dialog" title="动作说明" :visible.sync="dic">
+            <dl>二维码</dl>
+            <dt>查询设备资产</dt>
+            <dt>查询点位标签</dt>
+            <dl>信标</dl>
+            <dt>创建信标</dt>
+            <dt>批量删除信标</dt>
+            <dt>查询信标</dt>
+            <dt>批量更新信标</dt>
+            <dl>建筑</dl>
+            <dt>下载建筑信息</dt>
+            <dt>根据建筑ID获得楼层信息</dt>
+            <dt>根据项目ID获得建筑列表</dt>
+            <dl>扫楼用户</dl>
+            <dt>扫楼用户切换项目</dt>
+            <dt>创建扫楼用户</dt>
+            <dt>删除扫楼用户</dt>
+            <dt>扫楼用户登录</dt>
+            <dt>查询扫楼用户</dt>
+            <dt>批量更新扫楼用户</dt>
+            <dt>扫楼用户获得验证码</dt>
+            <dl>扫楼用户日志</dl>
+            <dt>导出扫楼用户日志</dt>
+            <dt>查看扫楼用户日志</dt>
+            <dl>数据字典</dl>
+            <dt>查看所有设备族</dt>
+            <dt>设备族信息点</dt>
+            <dl>模板</dl>
+            <dt>打印标签模板</dt>
+            <dl>点位标签</dl>
+            <dt>创建点位标签</dt>
+            <dt>批量删除点位标签</dt>
+            <dt>查询点位标签</dt>
+            <dt>批量更新扫楼用户</dt>
+            <dl>设备资产</dl>
+            <dt>创建设备资产</dt>
+            <dt>批量删除设备资产</dt>
+            <dt>异常设备资产</dt>
+            <dt>设备族列表</dt>
+            <dt>按标签分组查询修改信息</dt>
+            <dt>查询设备资产</dt>
+            <dt>查询设备资产(专供revit)</dt>
+            <dt>批量更新设备资产</dt>
+            <dl>项目</dl>
+            <dt>登记项目(在扫楼app中登录项目信息)</dt>
+            <dt>查询项目信息</dt>
+            <dt>更新项目信息</dt>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import buildInput from '@/components/scan/input'
+import buildTime from '@/components/scan/selectTime'
+
+
+import {
+    getBuildLog,//获取日志
+    dowmloadLog//下载日志
+} from '@/api/scan/request'
+
+import axios from 'axios'
+  import {
+        mapGetters,
+        mapActions
+    } from "vuex"
+
+export default {
+    components: {
+        'build-input': buildInput,
+        'build-time': buildTime
+    },
+    data() {
+        return {
+            placeholder: '请输入操作人、动作、对象id、等关键字搜索',
+            timeArr: ['一个月内', '一周内', '近三天', '昨天', '今天'],
+            checkTimeArr: [],
+            myHot: '',
+            filter: '',
+            pageNum: 1,
+            pageSize: 10,
+            logData: [],
+            resrtData: [],
+            pageSizeArr: [10, 30, 50, 100, 150, 200],
+            pageCount: 0,
+            currentPage: 1,
+            noData: false,//有无数据
+            // ProjId: this.$store.state.projectId,//url获取项目id this.$route.query.projId
+            // UserId: this.$route.query.userId,//url获取用户id this.$route.query.userId
+            loading: false,
+            dic: false,
+        }
+    },
+    created() {
+        this.checkTimeArr = [this.getNowFormatDate(new Date().setHours(0, 0, 0, 0)), this.getNowFormatDate(new Date())]
+        this.getLogData()
+    },
+    mounted() {
+    },
+    computed: {
+          ...mapGetters("project", [
+              "projectId",
+              "datasourceId",
+              "protocolType"
+          ])
+      },
+    methods: {
+        showDic() {
+            this.dic = true
+        },
+        //下载excel
+        downExcel() {
+            let param = {
+                'startTime': this.checkTimeArr[0],
+                'endTime': this.checkTimeArr[1],
+                'filter': this.filter,
+                "ProjId": this.projectId,
+                "UserId": this.datasourceId,
+                "Comming": "revit",
+            }
+            axios({
+                method: 'post',
+                url: 'api/ScanBuilding/service/user_log/export',
+                data: param,
+                responseType: 'blob'
+            })
+                .then(function (res) {
+                    var blob = new Blob([res.data], {
+                        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
+                    });
+                    var fileName = res.headers['content-disposition'];
+                    if (fileName)
+                        fileName = fileName.substring(fileName.indexOf('=') + 1);
+                    if ('download' in document.createElement('a')) { // 非IE下载
+                        const elink = document.createElement('a')
+                        elink.download = fileName
+                        elink.style.display = 'none'
+                        elink.href = URL.createObjectURL(blob)
+                        document.body.appendChild(elink)
+                        elink.click()
+                        URL.revokeObjectURL(elink.href) // 释放URL 对象
+                        document.body.removeChild(elink)
+                    } else { // IE10+下载
+                        navigator.msSaveBlob(blob, fileName)
+                    }
+                })
+                .catch(function (err) {
+                    console.dirxml(err);
+                })
+        },
+
+        //选择一页个数
+        handleSizeChange(val) {
+            this.loading = true
+            if (this.myHot) {
+                this.myHot.destroy()
+                this.myHot = ''
+            }
+            this.pageSize = val
+            this.getLogData()
+        },
+
+        //选择页数
+        handleCurrentChange(val) {
+            this.loading = true
+            if (this.myHot) {
+                this.myHot.destroy()
+                this.myHot = ''
+            }
+            this.pageNum = val
+            this.getLogData()
+        },
+
+        //刷新
+        refresh() {
+            this.loading = true
+            if (this.myHot) {
+                this.myHot.destroy()
+                this.myHot = ''
+            }
+            this.pageNum = this.currentPage = 1
+            this.getLogData()
+        },
+
+        //搜索
+        search(val) {
+            this.loading = true
+            if (this.myHot) {
+                this.myHot.destroy()
+                this.myHot = ''
+            }
+            this.filter = val
+            this.pageNum = this.currentPage = 1
+            this.getLogData()
+        },
+
+        //选择时间
+        checkTime(val) {
+            this.loading = true
+            if (this.myHot) {
+                this.myHot.destroy()
+                this.myHot = ''
+            }
+            this.pageNum = this.currentPage = 1
+            this.checkTimeArr = val
+            this.getLogData()
+        },
+
+        //获取log数据
+        getLogData() {
+            let param = {
+                'startTime': this.checkTimeArr[0],
+                'endTime': this.checkTimeArr[1],
+                'filter': this.filter,
+                'pageNum': this.pageNum,
+                'pageSize': this.pageSize,
+                "ProjId": this.projectId,
+                "UserId": this.datasourceId
+            }
+            getBuildLog(
+                param
+            ).then(
+                result => {
+                    this.logData = result.data.LogList
+                    this.pageCount = result.data.Count
+                    this.loading = false
+                    if (this.pageCount) {
+                        this.noData = false
+                        if (this.myHot) {
+                            this.myHot.loadData(this.delArr(this.logData))
+                        } else {
+                            this.populateHot()
+                        }
+                    } else {
+                        if (this.myHot) {
+                            this.myHot.destroy()
+                            this.myHot = ''
+                        }
+                        this.noData = true
+                    }
+                }
+            )
+        },
+
+        mouseOver(event, coords, TD) {
+            if (coords.col == 6) {
+                TD.setAttribute('title', this.resrtData[coords.row])
+            }
+        },
+
+        //处理操作说明
+        delArr(arr) {
+            if (arr.length) {
+                let newArr = this.deepCopy(arr).map(
+                    (item, index) => {
+                        this.resrtData[index] = item.Note
+                        let noteArr = item.Note.split('\n')
+                        if (noteArr.length > 2) {
+                            item.Note = noteArr[0] + '\n' + noteArr[1] + '\n ...'
+                        }
+                        return item
+                    }
+                )
+                return newArr
+            }
+        },
+
+        //生成实例
+        populateHot() {
+            var container1 = document.getElementById('log')
+            var options = {
+                data: this.delArr(this.logData),
+                colHeaders: ['时间', '来源', '操作人', '手机', '动作', '对象id', '操作说明'],
+                manualColumnResize: true,
+                manualColumnMove: true,
+                stretchH: 'last',
+                readOnly: true,
+                columns: [
+                    {
+                        data: 'CreateTime',
+                    },
+                    {
+                        data: 'Comming',
+                    },
+                    {
+                        data: 'UserName',
+                    },
+                    {
+                        data: 'Phone',
+                    },
+                    {
+                        data: 'Action',
+                    },
+                    {
+                        data: 'projectId'
+                    },
+                    {
+                        data: 'Note',
+                    }
+                ],
+                afterOnCellMouseOver: this.mouseOver
+            }
+            this.myHot = new Handsontable(container1, options)
+            // this.getTd()
+            document.getElementById('hot-display-license-info').style.display = 'none'
+        },
+
+        //处理时间
+        getNowFormatDate(str) {
+            var date = new Date(str);
+            var seperator1 = "-";
+            var seperator2 = ":";
+            var month = date.getMonth() + 1;
+            var strDate = date.getDate();
+            if (month >= 1 && month <= 9) {
+                month = "0" + month;
+            }
+            if (strDate >= 0 && strDate <= 9) {
+                strDate = "0" + strDate;
+            }
+            var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate
+                + " " + date.getHours() + seperator2 + date.getMinutes()
+                + seperator2 + date.getSeconds();
+            return currentdate;
+        },
+
+        //工具函数浅复制深拷贝,防止共用存储空间
+        deepCopy(obj) {
+            var out = [], i = 0, len = obj.length;
+            for (; i < len; i++) {
+                if (obj[i] instanceof Array) {
+                    out[i] = deepcopy(obj[i]);
+                }
+                else out[i] = obj[i];
+            }
+            return out;
+        },
+
+        //字符处理,将\n转换成<br/>
+        changeBr(str) {
+            return str.replace(/\n/g, "<br/>")
+        }
+    }
+}
+</script>
+
+<style lang="less" scoped>
+#app {
+  min-width: 1098px;
+  min-height: 767px;
+  position: relative;
+  overflow-x: auto;
+}
+#build_log {
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+  box-sizing: border-box;
+  dl {
+    font-size: 20px;
+    font-weight: 600;
+  }
+  dt {
+    margin-left: 20px;
+    line-height: 25px;
+  }
+  .search_header {
+    min-width: 1098px;
+    padding-top: 0.4rem;
+    padding-left: 1rem;
+    padding-right: 1rem;
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    height: 3rem;
+    margin-bottom: 1rem;
+    z-index: 999;
+    background-color: #fff;
+    .dong_dic {
+      cursor: pointer;
+    }
+    .derived_btn {
+      width: 6rem;
+      border: 1px solid #777;
+      text-align: center;
+      font-size: 0.6rem;
+      height: 1.6rem;
+      line-height: 1.6rem;
+      cursor: pointer;
+      background-color: #ccc;
+      border-radius: 0.1rem;
+      float: right;
+      margin-right: 1rem;
+      margin-top: 0.2rem;
+      .icon-excelwenjian {
+        font-size: 1rem;
+        margin-bottom: -0.1rem;
+      }
+      .excel {
+        font-size: 12px;
+        display: inline-block;
+        line-height: 1.4rem;
+      }
+    }
+  }
+  .log_view {
+    position: absolute;
+    left: 0;
+    padding-left: 1rem;
+    padding-right: 1rem;
+    top: 3rem;
+    bottom: 3rem;
+    right: 0;
+    overflow-y: auto;
+    box-sizing: border-box;
+  }
+  .log_page {
+    position: fixed;
+    bottom: 0;
+    width: 100%;
+    left: 0;
+    right: 0;
+    height: 3rem;
+    background-color: #fff;
+  }
+}
+</style>