Bladeren bron

pc app人员分布

lihongxiao 2 jaren geleden
bovenliggende
commit
c98bf685e7

+ 1 - 1
config/dev.env.js

@@ -21,8 +21,8 @@ module.exports = merge(prodEnv, {
   // BASE_URL: '"http:///192.168.0.55:8080/"',//蔡雅茹
   CONSOLE_BASE_URL: '"http://localhost:8080/"', //控制台测试服务器
   // CONSOLE_BASE_URL: '"https://test.baoxianzhanggui.com/console-api"' //控制台正式服务器
-
   APP_BASE_URL: '"https://pre.baoxianzhanggui.com/web-api"',    // app打包上传地址
+  SOCKET_Url: '"ws://192.168.0.52:8080/"',
 
 })
 

+ 1 - 0
config/pre.env.js

@@ -9,5 +9,6 @@ module.exports = merge(prodEnv, {
   // BASE_URL: '"http:///192.168.0.103:8080/web-api"',//测试服务器
   CONSOLE_BASE_URL: '"https://pre.baoxianzhanggui.com/console-api"', //控制台测试服务器
   APP_BASE_URL: '"https://pre.baoxianzhanggui.com/web-api"',    // app打包上传地址
+  SOCKET_Url: '"wss://pre.baoxianzhanggui.com/web-api/websocket"',
 
 })

+ 1 - 0
config/prod.env.js

@@ -5,6 +5,7 @@ module.exports = {
   BASE_URL: '"https://sxzgkj.baoxianzhanggui.com/web-api"',
   CONSOLE_BASE_URL: '"https://sxzgkj.baoxianzhanggui.com/console-api"', //控制台测试服务器
   APP_BASE_URL: '"https://pre.baoxianzhanggui.com/web-api"',    // app打包上传地址
+  SOCKET_Url: '"wss://sxzgkj.baoxianzhanggui.com/web-api/websocket"',
 
 
 }

+ 4 - 1
config/test.env.js

@@ -9,5 +9,8 @@ module.exports = merge(prodEnv, {
   BASE_URL: '"https://test.baoxianzhanggui.com/web-api"',//测试服务器
   // BASE_URL: '"http://192.168.0.115:8080"',
   APP_BASE_URL: '"https://test.baoxianzhanggui.com/web-api"',    // app打包上传地址
-  CONSOLE_BASE_URL: '"https://test.baoxianzhanggui.com/console-api"' //控制台测试服务器
+  CONSOLE_BASE_URL: '"https://test.baoxianzhanggui.com/console-api"', //控制台测试服务器
+  SOCKET_Url: '"ws://test.baoxianzhanggui.com/web-api/"',
+
+
 })

+ 2 - 2
package-lock.json

@@ -2688,7 +2688,7 @@
     },
     "crypto-js": {
       "version": "4.2.0",
-      "resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.2.0.tgz",
+      "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
       "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
     },
     "css-color-names": {
@@ -3062,7 +3062,7 @@
     },
     "decimal.js": {
       "version": "10.4.3",
-      "resolved": "https://registry.npmmirror.com/decimal.js/-/decimal.js-10.4.3.tgz",
+      "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
       "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA=="
     },
     "decode-uri-component": {

+ 23 - 0
src/http/moudules/user.js

@@ -606,3 +606,26 @@ export const queryGeographyInfo = (data) => {
     data
   })
 }
+export const ipAddrLocations = (data) => {
+  return axios({
+    url: '/sys/ipAddr/locations',
+    method: 'post',
+    data
+  })
+}
+
+
+export const ipAddrGetPcAddress = (params) => {
+  return axios({
+    url: '/sys/ipAddr/getPcAddress',
+    method: 'get',
+    params
+  })
+}
+export const getGeographyPosition = (params) => {
+  return axios({
+    url: '/geography/getGeographyPosition',
+    method: 'get',
+    params
+  })
+}

+ 112 - 0
src/utils/websocket.js

@@ -0,0 +1,112 @@
+import { Message } from 'element-ui'
+// import { getToken } from '@/utils/authToken' // 与后端的协商,websocket请求需要带上token参数
+let websock = null
+let messageCallback = null
+let errorCallback = null
+let wsUrl = process.env.SOCKET_Url
+let tryTime = 0
+ 
+// 接收ws后端返回的数据
+function websocketonmessage (e) { 
+  messageCallback(JSON.parse(e.data))
+}
+ 
+/**
+ * 发起websocket连接
+ * @param {Object} agentData 需要向后台传递的参数数据
+ */
+function websocketSend (agentData) {
+  // 加延迟是为了尽量让ws连接状态变为OPEN   
+  setTimeout(() => { 
+    // 添加状态判断,当为OPEN时,发送消息
+    if (websock.readyState === websock.OPEN) { // websock.OPEN = 1 
+      // 发给后端的数据需要字符串化
+      websock.send(JSON.stringify(agentData))
+    }
+    if (websock.readyState === websock.CLOSED) { // websock.CLOSED = 3 
+      console.log('websock.readyState=3')
+      Message.error('ws连接异常,请稍候重试')
+      errorCallback()
+    }
+  }, 500)
+}
+ 
+// 关闭ws连接
+function websocketclose (e) {  
+  // e.code === 1000  表示正常关闭。 无论为何目的而创建, 该链接都已成功完成任务。
+  // e.code !== 1000  表示非正常关闭。
+  if (e && e.code !== 1000) {
+    Message.error('ws连接异常,请稍候重试')
+    errorCallback()
+    // // 如果需要设置异常重连则可替换为下面的代码,自行进行测试
+    // if (tryTime < 10) {
+    //   setTimeout(function() {
+    //    websock = null
+    //    tryTime++
+    //    initWebSocket()
+    //    console.log(`第${tryTime}次重连`)
+    //  }, 3 * 1000)
+    //} else {
+    //  Message.error('重连失败!请稍后重试')
+    //}
+  }
+}
+// 建立ws连接
+function websocketOpen (e) {
+  // console.log('ws连接成功')
+}
+ 
+// 初始化weosocket
+function initWebSocket () { 
+  if (typeof (WebSocket) === 'undefined') {
+    Message.error('您的浏览器不支持WebSocket,无法获取数据')
+    return false
+  }
+  
+  // const token = Cookies.get('token')
+  // // ws请求完整地址
+  // const requstWsUrl = wsUrl + '?' + token
+  // websock = new WebSocket(requstWsUrl)
+  websock = new WebSocket(wsUrl)
+ 
+  websock.onmessage = function (e) {
+    websocketonmessage(e)
+  } 
+  websock.onopen = function () {
+    websocketOpen()
+  }
+  websock.onerror = function () {
+    Message.error('ws连接异常,请稍候重试')
+    errorCallback()
+  }
+  websock.onclose = function (e) {
+    websocketclose(e)
+  } 
+}
+ 
+/**
+ * 发起websocket请求函数
+ * @param {string} url ws连接地址
+ * @param {Object} agentData 传给后台的参数
+ * @param {function} successCallback 接收到ws数据,对数据进行处理的回调函数
+ * @param {function} errCallback ws连接错误的回调函数
+ */
+export function sendWebsocket (url, agentData, successCallback, errCallback) { 
+
+  wsUrl+=url
+  initWebSocket()
+  messageCallback = successCallback
+  errorCallback = errCallback
+  websocketSend(agentData)
+}
+ 
+/**
+ * 关闭websocket函数
+ */
+export function closeWebsocket () {
+  if (websock) {
+    websock.close() // 关闭websocket
+    websock.onclose() // 关闭websocket
+  }
+}
+ 

+ 2 - 0
src/views/Core/PersonalPanel.vue

@@ -75,6 +75,7 @@ import Psdreset from "@/views/Psdreset/Psdreset"
 import Recruiting from "@/views/Sys/Recruiting"
 import MessagePanel from "@/views/Core/MessagePanel"
 import TemplateForm from "@/components/TemplateForm/index"
+import { closeWebsocket  } from '@/utils/websocket.js'
 
 export default {
   name: "qrCode",
@@ -227,6 +228,7 @@ export default {
       })
         .then(() => {
           localStorage.clear()
+          closeWebsocket()
           sessionStorage.removeItem("user")
           this.deleteCookie("token")
           this.deleteCookie("user")

+ 17 - 2
src/views/Login.vue

@@ -158,6 +158,8 @@ import LangSelector from "@/components/LangSelector";
 import { login } from "@/api/user";
 import CryptoJS from "crypto-js";
 // import { getSysList } from "../http/moudules/sys";
+
+import { sendWebsocket,closeWebsocket  } from '@/utils/websocket.js'
 import {
   getUserIP,
   getUserLocation,
@@ -229,6 +231,7 @@ export default {
       }
     },
     login(formName) {
+      
       // let token = CryptoJS.AES.encrypt(
       //   "2856c49f-7b34-4e83-b3c8-2c37dba7cb3b",
       //   "token"
@@ -304,10 +307,22 @@ export default {
                     token;
                   // alert(res.data);
                 } else {
+                  this.getUser();
                   Cookies.set("token", res.data); // 放置token到Cookie
-                  this.submitLocation();
+                  // this.submitLocation();
                   this.getDictItems();
-                  this.getUser();
+                  setTimeout(()=>{
+                    let userId=sessionStorage.getItem("user")
+                    let data={
+                    ...this.addressInfo,
+                    userId,
+                    systemType:this.systemType
+                  }
+                  // sendWebsocket(`ws://192.168.0.52:8080//pcWebsocket/${userId}`,data)
+                  sendWebsocket(`/pcWebsocket/${userId}`,data)
+                  },1000)
+                  
+
                 }
               }
               this.loading = false;

+ 390 - 81
src/views/PeopleManage/PcLoginRecord.vue

@@ -19,6 +19,8 @@
           :value="option.code"></el-option>
       </el-select>
       <el-button size="small" type="primary" @click="onSearch">搜索</el-button>
+      <!-- <el-button size="small" type="primary" @click="onCircular">圆形定位</el-button> -->
+      <!-- <el-button size="small" type="primary" @click="map.remove(circle)">删除定位</el-button> -->
     </div>
     <div class="source-window">
       <div>
@@ -37,70 +39,95 @@
         </el-switch>
       </div>
     </div>
-    <div v-if="infoWindowVisible" class="info-window">
+    <div v-if="infoWindowVisible" class="infohis-window" >
       <p class="close flex j-s">
-        <span>详情内容</span>
+        <span>历史记录</span>
         <span style="color: #c3c3c3;font-size:18px" @click="infoWindowVisible = false"> ×</span>
       </p>
-      <el-table :data="tableData" border style="width: 100%; height: 50vh; overflow: auto;margin-bottom:40px"
+      <el-table :data="tableData" border style="width: 100%;  overflow: auto;"
         :header-cell-style="{
           background: '#F2F7FC',
           fontWeight: '700',
           color: '#606266',
         }">
-        <el-table-column prop="userId" label="工号" width="170">
+        <el-table-column prop="userId" label="工号" width="150">
         </el-table-column>
-        <el-table-column prop="userName" label="姓名" width="100">
+        <el-table-column prop="userName" label="姓名" width="80">
         </el-table-column>
         <el-table-column prop="address" label="地址">
         </el-table-column>
       </el-table>
       <div class="bottomFixed">
         <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pageNum"
-          :page-sizes="[10, 20, 30, 50, 100]" :page-size="pageSize" layout="total, sizes, prev, pager, next"
+          :page-sizes="[5,10, 20, 30, 50, 100]" :page-size="pageSize" layout="total, sizes, prev, pager, next"
           :total="totalSum">
         </el-pagination>
       </div>
     </div>
     <div class="personnel-window ">
       <p class="close flex j-s ">
-        <span>人员分布</span>
-        <span style="color: #3865E9 ; cursor: pointer; font-size: 14px;" @click="isCollapse = !isCollapse">{{
-          isCollapse ? '收起' : '展开' }} </span>
+        <!-- <span>人员分布</span> -->
+        <el-tabs style="position: relative;width: 100%;" v-model="activeName" @tab-click="handHistory">
+          <el-tab-pane label="人员分布" name="1"></el-tab-pane>
+          <el-tab-pane label="历史在线人数" name="2"></el-tab-pane>
+        </el-tabs>
+        <span style="color: #3865E9 ; cursor: pointer; font-size: 14px;position: absolute;line-height: 40px;
+    right: 30px;" @click="isCollapse = !isCollapse">{{
+      isCollapse ? '收起' : '展开' }} </span>
       </p>
-      <div class="info-title"><i></i>人员数量概览</div>
-      <div style="padding: 10px 0;" class="flex j-s">
-        <div v-for="(item, index) in overviewOption" :key="index"
-          :class="currentIndex === index ? 'overview after-img' : 'overview '" @click="checkPrice(index)">
-          <span>{{ item.active }}</span>
-          <span>{{ item.name }}</span>
+      <div v-show="activeName == 1">
+        <div class="flex j-s">
+          <div class="info-title"><i></i>人员数量概览</div>
+          <div class="info-online"><i></i>在线人数:{{ onlineData }}</div>
+        </div>
+        <div style="padding: 10px 0;" class="flex j-s">
+          <div v-for="(item, index) in overviewOption" :key="index"
+            :class="currentIndex === index ? 'overview after-img' : 'overview '" @click="checkPrice(index)">
+            <span>{{ item.active }}</span>
+            <span>{{ item.name }}</span>
+          </div>
         </div>
+        <div v-show="isCollapse" class="info-title"><i></i>区域人员概览</div>
+        <el-table v-show="isCollapse" :data="overviewData" border
+          style="width: 100%; max-height: 50vh; overflow: auto;margin:15px 0" :header-cell-style="{
+            background: '#F7F7F9',
+            fontWeight: '700',
+            color: '#000',
+          }">
+          <el-table-column type="index" align="center" width="50" label="序号">
+            <template slot-scope="scope">
+              <img v-if="scope.$index == 0" src="../../assets/序号1.png" />
+              <img v-else-if="scope.$index == 1" src="../../assets/序号2.png" />
+              <img v-else-if="scope.$index == 2" src="../../assets/序号3.png" />
+              <span v-else style="text-decoration-line: underline;">{{ scope.$index + 1 }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="districtName" align="center" label="区域">
+          </el-table-column>
+          <el-table-column prop="number" align="center" label="人数">
+          </el-table-column>
+          <div slot="empty" class="empty">
+            <img src="../../assets/暂无数据.png" />
+            <div class="txt">暂无数据哦</div>
+          </div>
+        </el-table>
       </div>
-      <div class="info-title"><i></i>区域人员概览</div>
-
-      <el-table v-if="isCollapse" :data="overviewData" border
-        style="width: 100%; max-height: 50vh; overflow: auto;margin:15px 0" :header-cell-style="{
-          background: '#F7F7F9',
-          fontWeight: '700',
-          color: '#000',
-        }">
-        <el-table-column type="index" align="center" width="50" label="序号">
-          <template slot-scope="scope">
-            <img v-if="scope.$index == 0" src="../../assets/序号1.png" />
-            <img v-else-if="scope.$index == 1" src="../../assets/序号2.png" />
-            <img v-else-if="scope.$index == 2" src="../../assets/序号3.png" />
-            <span v-else style="text-decoration-line: underline;">{{ scope.$index + 1 }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column prop="districtName" align="center" label="区域">
-        </el-table-column>
-        <el-table-column prop="number" align="center" label="人数">
-        </el-table-column>
-        <div slot="empty" class="empty">
-          <img src="../../assets/暂无数据.png" />
-          <div class="txt">暂无数据哦</div>
+      <div v-show="activeName == 2">
+        <div style="margin-bottom: 10px;">
+          <span style="color: #262626;font-weight: 700;font-size: 14px;">时间筛选 </span>
+          <el-date-picker size="small" @change="historyDateFun"  v-model="historyDate" type="date" placeholder="选择日期" format="yyyy 年 MM 月 dd 日"
+            value-format="yyyy-MM-dd">
+          </el-date-picker>
         </div>
-      </el-table>
+        <div class="flex j-s">
+          <div class="info-title"><i></i>历史在线人数统计</div>
+          <div class="info-online"><i></i>在线总人数:{{ onlineHisData }}</div>
+        </div>
+        <div id="echarts_box" v-show="isCollapse" style="width: 460px;height:300px;"></div>
+
+      </div>
+
+
     </div>
     <div v-if="personnelVisible" class="info-window">
       <p class="close flex j-s">
@@ -133,6 +160,18 @@
             {{ scope.row.source == '1' ? '渠道' : '代理' }}
           </template>
         </el-table-column>
+        <el-table-column
+          label="操作">
+          <template slot-scope="scope">
+            <el-button
+            style="color:#3865E9 "
+              @click.native.prevent="historicRecords(scope.row)"
+              type="text"
+              size="small">
+              历史记录
+            </el-button>
+          </template>
+        </el-table-column>
         <div slot="empty" class="empty">
           <img src="../../assets/暂无数据.png" />
           <div class="txt">暂无数据哦</div>
@@ -144,17 +183,27 @@
         </el-pagination>
       </div>
     </div>
+    <div class="info-window input-card" v-if="circle">
+      <el-button size="small" round @click="circleEditor.open()" style="margin-bottom: 5px">开始编辑</el-button>
+      <el-button size="small" round @click="circleEditor.close()" style="margin-left:0">结束编辑</el-button>
+
+    </div>
   </div>
 </template>
 
 <script>
+import echarts from 'echarts';
 import yongchengData from '../../assets/js/yongchengData';
 import AMapLoader from "@amap/amap-jsapi-loader";
+window._AMapSecurityConfig = {
+  securityJsCode: 'd62687dd438cfadd859bbab66d8e41a2',		//安全密钥
+}
+var myChart;
 export default {
   data() {
     return {
       pageNum: 1, //当前页面
-      pageSize: 10, //每页显示条数
+      pageSize: 5, //每页显示条数
       totalSum: 0, //全部的数据条数
       tableData: [],
       marker: null,
@@ -194,10 +243,21 @@ export default {
       personnelData: [],
       personnelTotalSize: 0,
       personnelPageNum: 1,
-      position: []
+      position: [],
+      location: ["112.34988", "37.827066"],
+      circleEditor: null,
+      circle: null,
+      activeName: '1',
+      historyDate: '',
+      onlineData:'',
+      onlineHisData:'',
+      radius:'100000',
+      markers: [],
+
     };
   },
   mounted() {
+    myChart = echarts.init(document.getElementById('echarts_box'))
     this.initMap();
   },
   created() {
@@ -205,11 +265,6 @@ export default {
     this.queryPcNum()
 
     //标注文字上的点击事件
-    // window.handleDetail = id => {
-    //   this.rowId = id;
-    //   this.detail();
-    // };
-
     window.personnelclick = () => {
       this.personnelVisible = true;
     };
@@ -219,6 +274,87 @@ export default {
     this.map.destroy();
   },
   methods: {
+    historicRecords(row){
+      this.rowId=row.userId
+      this.detail()
+    },
+    handHistory(tab, event){
+      if(tab.name=='2'){
+        this.queryAnalysis();
+      }
+    },
+    historyDateFun(val){
+      this.queryAnalysis({dates:val});
+    },
+    queryAnalysis(param) {
+      this.$api.user.ipAddrGetPcAddress(param).then((res) => {
+      	if (res.code == 200) {
+          this.onlineHisData=res.data.onlineNum
+      		this.formatAnalysisDate(res.data.list)
+      	}
+        else{
+          this.$message.error(res.msg)
+        }
+      })
+    },
+    formatAnalysisDate(data) {
+      const dateList = data.map(function (item) {
+        return item.time.split(" ")[1]+':00'
+      });
+      const valueList = data.map(function (item) {
+        return item.countNum;
+      });
+
+      let option = {
+        visualMap:  {
+      show: false,
+      type: 'continuous',
+      seriesIndex: 0,
+      min: 0,
+      max: 400
+    },
+     
+        tooltip: {
+          trigger: 'axis'
+        },
+        xAxis:{
+            data: dateList,
+            axisLine: {
+                lineStyle: {
+                    color: "#86909C ",
+                }
+            }
+          },
+        yAxis: {
+          name: "人数", //命名
+          axisLine: {
+                lineStyle: {
+                  color: "#86909C ",
+                }
+            }
+        },
+        series:  [{
+          type: 'line',
+          showSymbol: false,
+          data: valueList,
+          lineStyle: {
+            color: {
+              type: 'linear',
+                x: 0,
+                y: 0,
+                x2: 0,
+                y2: 1,
+                colorStops: [
+                  {offset: 0, color: '#3865E9'},
+                    {offset: 1, color: '#A6D2F3'}, 
+                ],
+            }
+        }
+        }],
+      }
+      myChart.setOption(option)
+
+    },
     morelFun() {
       this.$api.user
         .queryPcAddressInfo({ lng: this.position[0], lat: this.position[1], pageSize: 5, pageNum: this.personnelPageNum })
@@ -233,12 +369,120 @@ export default {
       this.currentIndex = index
       this.queryRegion(index == 0 ? null : index)
     },
+    onCircular() {
+      // 创建圆形编辑器对象
+      let _this = this
+      _this.map.on('click', e => {
+        let longitude = e.lnglat.lng
+        let latitude = e.lnglat.lat
+        if (_this.circle) {
+          _this.map.remove(_this.circle)
+        }
+ 
+
+        _this.circle = new AMap.Circle({
+          center: [longitude, latitude],
+          radius: this.radius, //半径
+          borderWeight: 2,
+          strokeColor: "#68B7FF",
+          strokeOpacity: 1,
+          strokeWeight: 6,
+          strokeOpacity: 0.2,
+          fillOpacity: 0.4,
+          // strokeStyle: 'dashed',
+          strokeStyle: 'solid',
+          strokeDasharray: [10, 10],
+          // 线样式还支持 'dashed'
+          // fillColor: '#1791fc',
+          fillColor: '#68B7FF',
+          zIndex: 50,
+        })
+
+        // circle.setMap(null)
+
+        _this.circle.setMap(_this.map)
+        // 缩放地图到合适的视野级别
+        _this.map.setFitView([_this.circle])
+
+        _this.onCircularFun({ latitude, longitude, radius: _this.radius })
+        _this.circleEditor = new AMap.CircleEditor(_this.map, _this.circle)
+        _this.circleEditor.on('move', function (event) {
+          _this.onCircularFun({ latitude: event.lnglat.lat, longitude: event.lnglat.lng, radius: _this.radius })
+
+        })
+        _this.circleEditor.on('adjust', function (event) {
+          _this.radius=event.radius
+          _this.onCircularFun({ latitude: event.lnglat.lat, longitude: event.lnglat.lng, radius: event.radius })
+
+        })
+
+        _this.circleEditor.on('end', function (event) {
+          console.log('触发事件: end', event)
+          // event.target 即为编辑后的圆形对象
+        })
+
+      })
+  
+  // 将点标记添加到地图map上
+    },
+   
+    async onCircularFun(data) {
+      let _this = this;
+          //  // 首先创建 AMap.Icon 实例:
+          //  var icon = new AMap.Icon({
+          //   size: new AMap.Size(40, 40), // 图标尺寸
+          //   image: '../../assets/Frame(2).png',
+          //   imageOffset: new AMap.Pixel(0, 0), // 图像相对展示区域的偏移量,适于雪碧图等
+          //   imageSize: new AMap.Size(40, 40), // 根据所设置的大小拉伸或压缩图片
+          // });
+          // // 将 Icon 实例添加到 marker 上:
+          // var marker = new AMap.Marker({
+          //   position: new AMap.LngLat(data.longitude, data.latitude),// icon在地图上显示的位置,数组内对应经纬度
+          //   offset: new AMap.Pixel(-20, -36),//设置icon在地上的偏移量
+          //   icon: icon, // 添加 Icon 实例
+          //   zoom: 13, //缩放等级
+          // });
+          // _this.map.add(marker);
+          // this.addMarker(data)
+      let res = await _this.$api.user.ipAddrLocations(data)
+      _this.map.on("load", () => {
+            if (res.code == 200) {
+              if (res.data && res.data.length > 0) {
+                //处理后台返回要用到的数据
+                // _this.positionData = res.data.data
+                _this.positionData = res.data.map(item => ({
+                  userName: item.userName,
+                  id: item.id,
+                  userId: item.userId,
+                  address: item.address,
+                  leaderName: item.leaderName,
+                  // onlineImg: item.status ? "Frame-1(2).png" : "Frame(2).png",
+                  onlineImg: "Frame-1(2).png",
+                  operationTime: item.operationTime,
+                  source: item.source,
+                  // status: item.status ? "在线" : "离线",
+                  positionArr: [item.longitude, item.latitude]
+                }));
+                _this.mapPoint();
+              }
+              else {
+                _this.positionData=[]
+                _this.loading = false; //地图加载完成
+              }
+            } else {
+              _this.$message.error(res.msg)
+              _this.loading = false;
+            }
+
+        });
+
+    },
     queryPcNum() {
       this.$api.user
         .ipAddrQueryPcNum(this.province)
         .then(res => {
           if (res.code == 200) {
-            // this.overviewForm = res.data;
+            this.onlineData = res.data.onlineNum
             this.overviewOption[0].active = res.data.allNum
             this.overviewOption[1].active = res.data.channelNum
             this.overviewOption[2].active = res.data.proxyNum
@@ -259,13 +503,39 @@ export default {
       this.currentIndex = 0
       this.queryRegion()
       this.queryPcNum()
-      this.initMap();
+      const geocoder = new AMap.Geocoder({
+        radius: 1000,
+        extensions: 'all'
+      })
+      let address = ''
+      if (this.province.province) {
+        address = this.province.province
+        if (this.province.city) {
+          address = this.province.province + this.province.city
+          if (this.province.district) {
+            address = this.province.province + this.province.city + this.province.district
+          }
+        }
+      }
+
+      geocoder.getLocation(address ? address : '山西省', (status, result) => {
+        if (status === 'complete' && result.info === 'OK') {
+          this.location = [
+            result.geocodes[0].location.lng + "",
+            result.geocodes[0].location.lat + ""
+          ]
+          this.initMap();
+        }
+      })
+
     },
     provinceChange(val) {
+      this.cityClear()
       this.province.province = this.provinceOption.find(e => e.code == val).name
       this.cityOption = this.provinceOption.find(e => e.code == val).sub
     },
     cityChange(val) {
+      this.districtClear()
       this.province.city = this.cityOption.find(e => e.code == val).name
       this.districtOption = this.cityOption.find(e => e.code == val).sub
     },
@@ -351,26 +621,30 @@ export default {
       this.personnelPageNum = val;
       this.morelFun();
     },
+
+    addMarker(data) {
+      // 清除其他icon
+      if (this.marker) {
+        this.marker.setMap(null)
+        this.marker = null
+      }
+      // 重新渲染icon
+      this.marker = new AMap.Marker({
+        // icon: '//a.amap.com/jsapi_demos/static/demo-c: this.pointenter/icons/po: this.pointi-marker-default.png',
+        icon: '../../assets/Frame(2).png',
+        position:new AMap.LngLat(data.longitude, data.latitude),
+        offset: new AMap.Pixel(-13, -30) //icon中心点的偏移量
+      })
+      this.marker.setMap(this.map) //设置icon
+    },
     initMap() {
       var _this = this;
       // https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png
       AMapLoader.load({
         key: "262c17c813cdaab1bf93bfeb9873a6c8", // 申请好的Web端开发者Key,首次调用 load 时必填
         version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
-        plugins: ["AMap.Geocoder"] // 需要使用的的插件列表,如比例尺'AMap.Scale'等
+        plugins: ["AMap.Geocoder", 'AMap.Marker', 'AMap.CircleEditor',] // 需要使用的的插件列表,如比例尺'AMap.Scale'等
       }).then(AMap => {
-        // AMap.plugin('AMap.Geocoder', function() {
-        //   var geocoder = new AMap.Geocoder({
-        //     // city 指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
-        //     city: '010'
-        //   })
-
-        //   geocoder.getLocation('北京市海淀区苏州街', function(status, result) {
-        //     if (status === 'complete' && result.info === 'OK') {
-        //       // result中对应详细地理坐标信息
-        //     }
-        //   })
-        // })
 
         _this.map = new AMap.Map("containerMap", {
           //设置地图容器id
@@ -378,7 +652,8 @@ export default {
           zoom: 8, //初始化地图级别
           expandZoomRange: true, //支持可以扩展最大缩放级别
           // center: ['116.441504', '40.031386'], //初始化地图中心点位置
-          center: ["112.34988", "37.827066"],
+          center: this.location,
+          resizeEnable: true,
           // mapStyle: 'amap://styles/blue',
           mapStyle: "amap://styles/normal" //地图样式,彩色
         });
@@ -393,10 +668,12 @@ export default {
                   id: item.id,
                   userId: item.userId,
                   address: item.address,
+                  leaderName: item.leaderName,
                   // onlineImg: item.status ? "Frame-1(2).png" : "Frame(2).png",
                   onlineImg: "Frame-1(2).png",
                   operationTime: item.operationTime,
                   source: item.source,
+                  status: item.status ? "#1CE247" : "#B2B2B2",
                   // status: item.status ? "在线" : "离线",
                   positionArr: [item.longitude, item.latitude]
                 }));
@@ -410,7 +687,9 @@ export default {
               _this.loading = false;
             }
           });
+
         });
+
       });
       //放大/缩小的工具条----地图右下角的 + 和 - 按钮
       // _this.map.plugin(["AMap.ToolBar"], function () {
@@ -427,7 +706,7 @@ export default {
     },
 
     mapPoint() {
-      var _this = this;
+      let _this = this;
       /* 1.创建 LabelMarker,
       2.创建 LabelsLayer,将已创建的 LabelMarker 添加到 LabelsLayer 上
       3. 将 LabelsLayer 添加到地图实例 */
@@ -457,24 +736,14 @@ export default {
             : '<div style="width:14px;height:14px;background: #00C2FF;border-radius: 50%;border: 1px solid #FFFFFF;"></div>',
           // icon: require("@/assets/" + position[i].onlineImg)
         });
-        // normalMarker.content =
-        //   '<div style="font-weight: 700;padding:20px 20px 6px 20px">员工姓名:' +
-        //   position[i].userName +
-        //   "</div>" +
-        //   '<div  style="padding:6px 20px">员工工号:' +
-        //   position[i].userId +
-        //   "</div>" +
-        //   "</div>" +
-        //   '<div style="padding:6px 20px 20px 20px">地址:' +
-        //   position[i].address +
-        //   "</div>" +
-        //   '<div style="height: 32px;line-height:30px;text-align: center;background: rgba(218,59,15,0.15);color: #DA3B0F;cursor:pointer;" onclick="handleDetail(\'' +
-        //   position[i].userId +
-        //   "')\">查看详情</div>";
         normalMarker.content =
           `
-        <div style="font-weight: 700;border-bottom: 1px solid rgba(255, 255, 255, 0.85); padding: 5px 0 8px 0;"> ${position[i].source == 1 ? "渠道姓名:" : "代理人姓名:"} ${position[i].userName}</div>
+        <div  style="font-weight: 700;border-bottom: 1px solid rgba(255, 255, 255, 0.85); padding: 5px 0 8px 0;"> 
+            <i style="display: inline-block;margin-right:5px;width: 8px;height: 8px;border-radius: 50%;background-color:${position[i].status}"></i>
+            <span>${position[i].source == 1 ? "渠道姓名:" : "代理人姓名:"} ${position[i].userName}</span>
+        </div>
         <div style="padding: 8px 0 5px 0;">${position[i].source == 1 ? "渠道工号:" : "代理人工号:"}${position[i].userId}</div>
+        <div >管理人名称: ${position[i].leaderName}</div>
         <div >地址: ${position[i].address}</div>
         <div >登录时间: ${position[i].operationTime}</div>
         `
@@ -490,13 +759,13 @@ export default {
       this.position = e.target._position
       // _this.morelFun()
       this.$api.user
-        .queryPcAddressInfo({ lng: e.target._position[0], lat: e.target._position[1], pageSize: 5, pageNum: this.personnelPageNum })
+        .queryPcAddressInfo({ lng: e.target._position[0], lat: e.target._position[1], source: this.source,pageSize: 5, pageNum: this.personnelPageNum })
         .then(res => {
           if (res.code == 200) {
             this.personnelTotalSize = res.data.totalSize
             this.personnelData = res.data.content
             let content = e.target.content
-            content= _this.personnelTotalSize==1?content:content+ `<div style="font-weight: 700;display: flex; justify-content: space-between;align-items: center;"> 
+            content =  e.target.content + `<div style="font-weight: 700;display: flex; justify-content: space-between;align-items: center;"> 
           <span>共${_this.personnelTotalSize}人信息</span>
            <div style="background: linear-gradient( 270deg, #225FFE 0%, #23CAFF 100%);padding:4px 8px;color:#fff;border-radius: 4px 4px 4px 4px;" onclick="personnelclick()">查看更多</div>
           </div>`
@@ -574,7 +843,16 @@ export default {
   width: 30vw;
   box-shadow: 0px 5px 10px #ddd;
 }
-
+.infohis-window{
+  position: absolute;
+  top: 0;
+  right: 0;
+  z-index: 100;
+  background-color: white;
+  padding: 10px;
+  width: 25vw;
+  box-shadow: 0px 5px 10px #ddd;
+}
 .personnel-window {
   position: fixed;
   bottom: 10px;
@@ -615,6 +893,19 @@ export default {
 }
 
 /deep/ {
+  .el-button--primary{
+    background: #3355FF !important;
+    border-color: #3355FF !important;
+  }
+  .el-tabs__item:hover,
+  .el-tabs__item.is-active {
+    color: #3865E9;
+  }
+
+  .el-tabs__active-bar {
+    background-color: #3865E9;
+  }
+
   .el-table__empty-text {
     line-height: 35px;
   }
@@ -680,5 +971,23 @@ export default {
   .txt {
     padding: 15px 0;
   }
+
+  .input-card {
+    width: 85px;
+    display: flex;
+    flex-direction: column;
+  }
+  .info-online{
+    font-size: 14px;
+    line-height: 30px;
+  i {
+    display: inline-block;
+    width: 8px;
+    height: 8px;
+    background: #1CE247;
+    border-radius: 50%;
+    margin-right: 10px;
+  }
+  }
 }
 </style>

+ 265 - 74
src/views/PeopleManage/UserMap.vue

@@ -2,31 +2,6 @@
   <div>
     <div id="container" style="width: 100%; height: 87vh" v-loading="loading" element-loading-text="数据量较大,正在为您加载......"
       element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)"></div>
-    <div v-if="infoWindowVisible" class="info-window">
-      <p class="close flex j-s">
-        <span>详情内容</span>
-        <span style="color: #c3c3c3;font-size:18px" @click="infoWindowVisible = false"> ×</span>
-      </p>
-      <el-table :data="tableData" border style="width: 100%; height: 50vh; overflow: auto;margin-bottom:40px"
-        :header-cell-style="{
-          background: '#F2F7FC',
-          fontWeight: '700',
-          color: '#606266',
-        }">
-        <el-table-column prop="userId" label="工号" width="170">
-        </el-table-column>
-        <el-table-column prop="userName" label="姓名" width="100">
-        </el-table-column>
-        <el-table-column prop="address" label="地址">
-        </el-table-column>
-      </el-table>
-      <div class="bottomFixed">
-        <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pageNum"
-          :page-sizes="[10, 20, 30, 50, 100]" :page-size="pageSize" layout="total, sizes, prev, pager, next"
-          :total="totalSum">
-        </el-pagination>
-      </div>
-    </div>
     <div class="province-window">
       <el-select size="small" v-model="provinceName" clearable placeholder="请选择省" @change="provinceChange" @clear="provinceClear">
         <el-option v-for="(option, index) in provinceOption" :key="index" :label="option.name"
@@ -64,44 +39,96 @@
         </el-switch>
       </div>
     </div>
+    <div v-if="infoWindowVisible" class="infohis-window" >
+      <p class="close flex j-s">
+        <span>历史记录</span>
+        <span style="color: #c3c3c3;font-size:18px" @click="infoWindowVisible = false"> ×</span>
+      </p>
+      <el-table :data="tableData" border style="width: 100%;  overflow: auto;"
+        :header-cell-style="{
+          background: '#F2F7FC',
+          fontWeight: '700',
+          color: '#606266',
+        }">
+        <el-table-column prop="userId" label="工号" width="150">
+        </el-table-column>
+        <el-table-column prop="userName" label="姓名" width="80">
+        </el-table-column>
+        <el-table-column prop="address" label="地址">
+        </el-table-column>
+      </el-table>
+      <div class="bottomFixed">
+        <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pageNum"
+          :page-sizes="[5,10, 20, 30, 50, 100]" :page-size="pageSize" layout="total, sizes, prev, pager, next"
+          :total="totalSum">
+        </el-pagination>
+      </div>
+    </div>
     <div class="personnel-window ">
       <p class="close flex j-s ">
-        <span>人员分布</span>
-        <span style="color: #3865E9 ; cursor: pointer; font-size: 14px;" @click="isCollapse = !isCollapse">{{
-          isCollapse ? '收起' : '展开' }} </span>
+        <!-- <span>人员分布</span> -->
+        <el-tabs style="position: relative;width: 100%;" v-model="activeName" @tab-click="handHistory">
+          <el-tab-pane label="人员分布" name="1"></el-tab-pane>
+          <el-tab-pane label="历史在线人数" name="2"></el-tab-pane>
+        </el-tabs>
+        <span style="color: #3865E9 ; cursor: pointer; font-size: 14px;position: absolute;line-height: 40px;
+    right: 30px;" @click="isCollapse = !isCollapse">{{
+      isCollapse ? '收起' : '展开' }} </span>
       </p>
-      <div class="info-title"><i></i>人员数量概览</div>
-      <div style="padding: 10px 0;" class="flex j-s">
-        <div v-for="(item, index) in overviewOption" :key="index"
-          :class="currentIndex === index ? 'overview after-img' : 'overview '" @click="checkPrice(index)">
-          <span>{{ item.active }}</span>
-          <span>{{ item.name }}</span>
+      <div v-show="activeName == 1">
+        <div class="flex j-s">
+          <div class="info-title"><i></i>人员数量概览</div>
+          <div class="info-online"><i></i>在线人数:{{ onlineData }}</div>
+        </div>
+        <div style="padding: 10px 0;" class="flex j-s">
+          <div v-for="(item, index) in overviewOption" :key="index"
+            :class="currentIndex === index ? 'overview after-img' : 'overview '" @click="checkPrice(index)">
+            <span>{{ item.active }}</span>
+            <span>{{ item.name }}</span>
+          </div>
         </div>
+        <div v-show="isCollapse" class="info-title"><i></i>区域人员概览</div>
+        <el-table v-show="isCollapse" :data="overviewData" border
+          style="width: 100%; max-height: 50vh; overflow: auto;margin:15px 0" :header-cell-style="{
+            background: '#F7F7F9',
+            fontWeight: '700',
+            color: '#000',
+          }">
+          <el-table-column type="index" align="center" width="50" label="序号">
+            <template slot-scope="scope">
+              <img v-if="scope.$index == 0" src="../../assets/序号1.png" />
+              <img v-else-if="scope.$index == 1" src="../../assets/序号2.png" />
+              <img v-else-if="scope.$index == 2" src="../../assets/序号3.png" />
+              <span v-else style="text-decoration-line: underline;">{{ scope.$index + 1 }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="districtName" align="center" label="区域">
+          </el-table-column>
+          <el-table-column prop="number" align="center" label="人数">
+          </el-table-column>
+          <div slot="empty" class="empty">
+            <img src="../../assets/暂无数据.png" />
+            <div class="txt">暂无数据哦</div>
+          </div>
+        </el-table>
       </div>
-      <div class="info-title"><i></i>区域人员概览</div>
-
-      <el-table v-if="isCollapse" :data="overviewData" border style="width: 100%;margin: 10px 0px;" :header-cell-style="{
-        background: '#F7F7F9',
-        fontWeight: '700',
-        color: '#000',
-      }">
-      <el-table-column type="index" align="center" width="50" label="序号">
-          <template slot-scope="scope">
-            <img v-if="scope.$index == 0" src="../../assets/序号1.png" />
-            <img v-else-if="scope.$index == 1" src="../../assets/序号2.png" />
-            <img v-else-if="scope.$index == 2" src="../../assets/序号3.png" />
-            <span v-else style="text-decoration-line: underline;">{{ scope.$index + 1 }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column prop="districtName" align="center" label="区域">
-        </el-table-column>
-        <el-table-column prop="number" align="center" label="人数">
-        </el-table-column>
-        <div slot="empty" class="empty">
-          <img src="../../assets/暂无数据.png"/>
-          <div class="txt">暂无数据哦</div>
+      <div v-show="activeName == 2">
+        <div style="margin-bottom: 10px;">
+          <span style="color: #262626;font-weight: 700;font-size: 14px;">时间筛选 </span>
+          <el-date-picker size="small" @change="historyDateFun"  v-model="historyDate" type="date" placeholder="选择日期" format="yyyy 年 MM 月 dd 日"
+            value-format="yyyy-MM-dd">
+          </el-date-picker>
+        </div>
+        <div class="flex j-s">
+          <div class="info-title"><i></i>历史在线人数统计</div>
+          <div class="info-online"><i></i>在线总人数:{{ onlineHisData }}</div>
+        </div>
+        <div id="echarts_box" v-show="isCollapse" style="width: 460px;height:300px;"></div>
+        <!-- <div v-if="isCollapse &&onlineHisData==0" class="empty" style="text-align: center;">
+            <img src="../../assets/暂无数据.png" />
+            <div class="txt">暂无数据哦</div>
+          </div> -->
       </div>
-      </el-table>
     </div>
     <div v-if="personnelVisible" class="info-window">
       <p class="close flex j-s">
@@ -121,19 +148,33 @@
             <span v-else style="text-decoration-line: underline;">{{ scope.$index + 1 }}</span>
           </template>
         </el-table-column>
-        <el-table-column prop="userName" label="姓名" width="100">
+        <el-table-column prop="userName" label="姓名" >
+        </el-table-column>
+        <el-table-column prop="id" label="工号">
         </el-table-column>
-        <el-table-column prop="userId" label="工号">
+        <el-table-column prop="leaderName" label="管理人">
         </el-table-column>
         <el-table-column prop="address" label="地址">
         </el-table-column>
-        <el-table-column prop="operationTime" label="登录时间">
+        <el-table-column prop="createTime" label="登录时间">
         </el-table-column>
         <el-table-column prop="source" label="分类">
           <template slot-scope="scope">
             {{ scope.row.source == '1' ? '渠道' : '代理' }}
           </template>
         </el-table-column>
+        <el-table-column
+          label="操作">
+          <template slot-scope="scope">
+            <el-button
+            style="color:#3865E9 "
+              @click.native.prevent="historicRecords(scope.row)"
+              type="text"
+              size="small">
+              历史记录
+            </el-button>
+          </template>
+        </el-table-column>
         <div slot="empty" class="empty">
           <img src="../../assets/暂无数据.png" />
           <div class="txt">暂无数据哦</div>
@@ -149,13 +190,18 @@
 </template>
 
 <script>
+import echarts from 'echarts';
 import yongchengData from '../../assets/js/yongchengData';
 import AMapLoader from "@amap/amap-jsapi-loader";
+window._AMapSecurityConfig = {
+  securityJsCode: 'd62687dd438cfadd859bbab66d8e41a2',		//安全密钥
+}
+var myChart;
 export default {
   data() {
     return {
       pageNum: 1, //当前页面
-      pageSize: 10, //每页显示条数
+      pageSize: 5, //每页显示条数
       totalSum: 0, //全部的数据条数
       tableData: [],
       marker: null,
@@ -195,20 +241,24 @@ export default {
       personnelData: [],
       personnelTotalSize: 0,
       personnelPageNum: 1,
-      position: []
+      position: [],
+      location: ["112.34988", "37.827066"],
+      circleEditor: null,
+      circle: null,
+      activeName: '1',
+      historyDate: '',
+      onlineData:'',
+      onlineHisData:'',
     };
   },
   mounted() {
+    myChart = echarts.init(document.getElementById('echarts_box'))
     this.initMap();
   },
   created() {
     this.queryRegion()
     this.queryPcNum()
     //标注文字上的点击事件
-    // window.handleDetail = id => {
-    //   this.rowId = id;
-    //   this.detail();
-    // };
     window.personnelclick = () => {
       this.personnelVisible = true;
     };
@@ -218,6 +268,85 @@ export default {
     this.map.destroy();
   },
   methods: {
+    historicRecords(row){
+      this.rowId=row.id
+      this.detail()
+    },
+    handHistory(tab, event){
+      if(tab.name=='2'){
+        this.queryAnalysis();
+      }
+    },
+    historyDateFun(val){
+      this.queryAnalysis({dates:val});
+    },
+    queryAnalysis(param) {
+      this.$api.user.getGeographyPosition(param).then((res) => {
+      	if (res.code == 200) {
+          this.onlineHisData=res.data.onlineNum
+      		this.formatAnalysisDate(res.data.list)
+      	}
+        else{
+          this.$message.error(res.msg)
+        }
+      })
+    },
+    formatAnalysisDate(data) {
+      const dateList = data.map(function (item) {
+        return item.time.split(" ")[1]+':00'
+      });
+      const valueList = data.map(function (item) {
+        return item.countNum;
+      });
+
+      let option = {
+        visualMap:  {
+      show: false,
+      type: 'continuous',
+      seriesIndex: 0,
+      min: 0,
+      max: 400
+    },
+        tooltip: {
+          trigger: 'axis'
+        },
+        xAxis:{
+            data: dateList,
+            axisLine: {
+                lineStyle: {
+                    color: "#86909C ",
+                }
+            }
+          },
+        yAxis: {
+          name: "人数", //命名
+          axisLine: {
+                lineStyle: {
+                  color: "#86909C ",
+                }
+            }
+        },
+        series:  [{
+          type: 'line',
+          showSymbol: false,
+          data: valueList,
+          lineStyle: {
+            color: {
+              type: 'linear',
+                x: 0,
+                y: 0,
+                x2: 0,
+                y2: 1,
+                colorStops: [
+                  {offset: 0, color: '#3865E9'},
+                    {offset: 1, color: '#A6D2F3'}, 
+                ],
+            }
+        }
+        }],
+      }
+      myChart.setOption(option)
+    },
     handlePersonnelChange(val) {
       this.personnelPageNum = val;
       this.morelFun();
@@ -241,7 +370,7 @@ export default {
         .geographyQueryPcNum(this.province)
         .then(res => {
           if (res.code == 200) {
-            this.overviewForm = res.data;
+            this.onlineData = res.data.onlineNum
             this.overviewOption[0].active = res.data.allNum
             this.overviewOption[1].active = res.data.channelNum
             this.overviewOption[2].active = res.data.proxyNum
@@ -261,7 +390,30 @@ export default {
       this.currentIndex=0
       this.queryRegion()
       this.queryPcNum()
-      this.initMap();
+      const geocoder = new AMap.Geocoder({
+        radius: 1000,
+        extensions: 'all'
+      })
+      let address = ''
+      if (this.province.province) {
+        address = this.province.province
+        if (this.province.city) {
+          address = this.province.province + this.province.city
+          if (this.province.district) {
+            address = this.province.province + this.province.city + this.province.district
+          }
+        }
+      }
+
+      geocoder.getLocation(address ? address : '山西省', (status, result) => {
+        if (status === 'complete' && result.info === 'OK') {
+          this.location = [
+            result.geocodes[0].location.lng + "",
+            result.geocodes[0].location.lat + ""
+          ]
+          this.initMap();
+        }
+      })
     },
     provinceChange(val) {
       this.province.province = this.provinceOption.find(e => e.code == val).name
@@ -349,6 +501,7 @@ export default {
       this.pageNum = val;
       this.detail();
     },
+    
     initMap() {
       var _this = this;
       // https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png
@@ -385,6 +538,7 @@ export default {
                   createTime: item.createTime,
                   deptName: item.deptName,
                   source: item.source,
+                  leaderName: item.leaderName,
                   positionArr: [item.longitude, item.latitude]
                 }));
                 _this.mapPoint();
@@ -460,6 +614,7 @@ export default {
         </div>
         <div style="padding: 8px 0 5px 0;">${position[i].source == 1 ? "渠道工号:" : "代理人工号:"}${position[i].id}</div>
         <div >所属机构:${position[i].deptName}</div>
+        <div >管理人名称: ${position[i].leaderName}</div>
         <div >地址: ${position[i].address}</div>
         <div >登录时间: ${position[i].createTime}</div>
         `
@@ -513,7 +668,7 @@ export default {
             this.personnelTotalSize = res.data.totalSize
             this.personnelData = res.data.content
             let content = e.target.content
-            content= _this.personnelTotalSize==1?content:content+ `<div style="font-weight: 700;display: flex; justify-content: space-between;align-items: center;"> 
+            content=  e.target.content+ `<div style="font-weight: 700;display: flex; justify-content: space-between;align-items: center;"> 
           <span>共${_this.personnelTotalSize}人信息</span>
            <div style="background: linear-gradient( 270deg, #225FFE 0%, #23CAFF 100%);padding:4px 8px;color:#fff;border-radius: 4px 4px 4px 4px;" onclick="personnelclick()">查看更多</div>
           </div>`
@@ -623,10 +778,19 @@ export default {
   z-index: 100;
   background-color: white;
   padding: 10px;
-  width: 30vw;
+  width: 32vw;
+  box-shadow: 0px 5px 10px #ddd;
+}
+.infohis-window{
+  position: absolute;
+  top: 0;
+  right: 0;
+  z-index: 100;
+  background-color: white;
+  padding: 10px;
+  width: 25vw;
   box-shadow: 0px 5px 10px #ddd;
 }
-
 .personnel-window {
   position: fixed;
   bottom: 10px;
@@ -639,9 +803,7 @@ export default {
 }
 
 .bottomFixed {
-  height: 50px;
-  position: absolute;
-  bottom: 0;
+  text-align: right;
   width: 100%;
   background: #fff;
   margin-top: 10px;
@@ -669,6 +831,18 @@ export default {
 }
 
 /deep/ {
+  .el-button--primary{
+    background: #3355FF !important;
+    border-color: #3355FF !important;
+  }
+  .el-tabs__item:hover,
+  .el-tabs__item.is-active {
+    color: #3865E9;
+  }
+
+  .el-tabs__active-bar {
+    background-color: #3865E9;
+  }
   .el-table__empty-text{
     line-height: 35px;
   }
@@ -732,5 +906,22 @@ export default {
   .txt{
     padding: 15px 0;
   }
+  .input-card {
+    width: 85px;
+    display: flex;
+    flex-direction: column;
+  }
+  .info-online{
+    font-size: 14px;
+    line-height: 30px;
+    i {
+      display: inline-block;
+      width: 8px;
+      height: 8px;
+      background: #1CE247;
+      border-radius: 50%;
+      margin-right: 10px;
+    }
+  }
 }
 </style>