上饶市警务平台后台管理前端
guanqb
2023-02-28 2e41623f7fd7fd4f01b08cda81012edc9c573d91
Merge branch 'master' of http://192.168.0.105:10010/r/srs-police-web
24 files modified
12 files added
7286 ■■■■■ changed files
package-lock.json 41 ●●●●● patch | view | raw | blame | history
package.json 1 ●●●● patch | view | raw | blame | history
src/App.vue 37 ●●●● patch | view | raw | blame | history
src/api/houseStatistic/houseStatistic.js 50 ●●●●● patch | view | raw | blame | history
src/api/policePost/policePost.js 62 ●●●●● patch | view | raw | blame | history
src/api/realEstate/realEstate.js 50 ●●●●● patch | view | raw | blame | history
src/api/security/security.js 42 ●●●●● patch | view | raw | blame | history
src/api/system/dept.js 8 ●●●●● patch | view | raw | blame | history
src/api/villagePersonInfo/villagePersonInfo.js 50 ●●●●● patch | view | raw | blame | history
src/components/map/dcMap.vue 168 ●●●●● patch | view | raw | blame | history
src/components/map/dcSearchMap.vue 192 ●●●●● patch | view | raw | blame | history
src/components/map/mapBox.vue 171 ●●●●● patch | view | raw | blame | history
src/components/map/searchMap.vue 139 ●●●●● patch | view | raw | blame | history
src/components/map/searchMapBox.vue 360 ●●●●● patch | view | raw | blame | history
src/main.js 150 ●●●● patch | view | raw | blame | history
src/option/user/info.js 38 ●●●● patch | view | raw | blame | history
src/page/index/top/index.vue 2 ●●● patch | view | raw | blame | history
src/page/login/userlogin.vue 4 ●●●● patch | view | raw | blame | history
src/permission.js 278 ●●●● patch | view | raw | blame | history
src/store/modules/user.js 566 ●●●● patch | view | raw | blame | history
src/styles/element-ui.scss 1 ●●●● patch | view | raw | blame | history
src/util/store.js 1 ●●●● patch | view | raw | blame | history
src/views/community/community.vue 14 ●●●●● patch | view | raw | blame | history
src/views/houseStatistic/houseStatistic.vue 361 ●●●●● patch | view | raw | blame | history
src/views/policePost/policePost.vue 323 ●●●●● patch | view | raw | blame | history
src/views/policeman/policeman.vue 500 ●●●●● patch | view | raw | blame | history
src/views/range/range.vue 9 ●●●●● patch | view | raw | blame | history
src/views/realEstate/realEstate.vue 392 ●●●●● patch | view | raw | blame | history
src/views/scheduling/scheduling.vue 594 ●●●●● patch | view | raw | blame | history
src/views/security/security.vue 325 ●●●●● patch | view | raw | blame | history
src/views/securityManage/securityManage.vue 10 ●●●●● patch | view | raw | blame | history
src/views/securityManageCar/securityManageCar.vue 10 ●●●●● patch | view | raw | blame | history
src/views/system/dept.vue 10 ●●●●● patch | view | raw | blame | history
src/views/system/user.vue 1958 ●●●● patch | view | raw | blame | history
src/views/villagePersonInfo/villagePersonInfo.vue 354 ●●●●● patch | view | raw | blame | history
vue.config.js 15 ●●●●● patch | view | raw | blame | history
package-lock.json
@@ -2495,6 +2495,16 @@
      "dev": true,
      "optional": true
    },
    "bindings": {
      "version": "1.5.0",
      "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
      "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
      "dev": true,
      "optional": true,
      "requires": {
        "file-uri-to-path": "1.0.0"
      }
    },
    "bluebird": {
      "version": "3.7.2",
      "resolved": "https://registry.npmmirror.com/bluebird/-/bluebird-3.7.2.tgz",
@@ -4684,6 +4694,15 @@
        "safer-buffer": "^2.1.0"
      }
    },
    "echarts": {
      "version": "5.4.1",
      "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.4.1.tgz",
      "integrity": "sha512-9ltS3M2JB0w2EhcYjCdmtrJ+6haZcW6acBolMGIuf01Hql1yrIV01L1aRj7jsaaIULJslEP9Z3vKlEmnJaWJVQ==",
      "requires": {
        "tslib": "2.3.0",
        "zrender": "5.4.1"
      }
    },
    "ee-first": {
      "version": "1.1.1",
      "resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz",
@@ -5572,6 +5591,13 @@
          }
        }
      }
    },
    "file-uri-to-path": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
      "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
      "dev": true,
      "optional": true
    },
    "filesize": {
      "version": "3.6.1",
@@ -12711,6 +12737,11 @@
      "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==",
      "dev": true
    },
    "tslib": {
      "version": "2.3.0",
      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
    },
    "tty-browserify": {
      "version": "0.0.0",
      "resolved": "https://registry.npmmirror.com/tty-browserify/-/tty-browserify-0.0.0.tgz",
@@ -13367,6 +13398,7 @@
          "dev": true,
          "optional": true,
          "requires": {
            "bindings": "^1.5.0",
            "nan": "^2.12.1"
          }
        },
@@ -13693,6 +13725,7 @@
          "dev": true,
          "optional": true,
          "requires": {
            "bindings": "^1.5.0",
            "nan": "^2.12.1"
          }
        },
@@ -14218,6 +14251,14 @@
          "dev": true
        }
      }
    },
    "zrender": {
      "version": "5.4.1",
      "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.4.1.tgz",
      "integrity": "sha512-M4Z05BHWtajY2241EmMPHglDQAJ1UyHQcYsxDNzD9XLSkPDqMq4bB28v9Pb4mvHnVQ0GxyTklZ/69xCFP6RXBA==",
      "requires": {
        "tslib": "2.3.0"
      }
    }
  }
}
package.json
@@ -18,6 +18,7 @@
    "babel-polyfill": "^6.26.0",
    "classlist-polyfill": "^1.2.0",
    "crypto-js": "^4.0.0",
    "echarts": "^5.4.1",
    "element-ui": "^2.15.6",
    "js-base64": "^2.5.1",
    "js-cookie": "^2.2.0",
src/App.vue
@@ -1,30 +1,29 @@
<template>
  <div id="app">
    <router-view />
  </div>
    <div id="app">
        <router-view />
    </div>
</template>
<script>
export default {
  name: "app",
  data() {
    return {};
  },
  watch: {},
  created() {
  },
  methods: {},
  computed: {}
};
    name: "app",
    data () {
        return {}
    },
    watch: {},
    created () { },
    methods: {},
    computed: {}
}
</script>
<style lang="scss">
#app {
  width: 100%;
  height: 100%;
  overflow: hidden;
    width: 100%;
    height: 100%;
    overflow: hidden;
}
.avue--detail .el-col{
  margin-bottom: 0;
.avue--detail .el-col {
    margin-bottom: 0;
}
</style>
src/api/houseStatistic/houseStatistic.js
New file
@@ -0,0 +1,50 @@
import request from '@/router/axios';
export const getList = (current, size, params) => {
  return request({
    url: '/api/houseStatistic/houseStatistic/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    }
  })
}
export const getDetail = (id) => {
  return request({
    url: '/api/houseStatistic/houseStatistic/detail',
    method: 'get',
    params: {
      id
    }
  })
}
export const remove = (ids) => {
  return request({
    url: '/api/houseStatistic/houseStatistic/remove',
    method: 'post',
    params: {
      ids,
    }
  })
}
export const add = (row) => {
  return request({
    url: '/api/houseStatistic/houseStatistic/submit',
    method: 'post',
    data: row
  })
}
export const update = (row) => {
  return request({
    url: '/api/houseStatistic/houseStatistic/submit',
    method: 'post',
    data: row
  })
}
src/api/policePost/policePost.js
New file
@@ -0,0 +1,62 @@
import request from '@/router/axios';
export const getList = (current, size, params) => {
  return request({
    url: '/api/policePost/policePost/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    }
  })
}
export const getPage = (current, size, params) => {
  return request({
    url: '/api/policePost/policePost/page',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    }
  })
}
export const getDetail = (id) => {
  return request({
    url: '/api/policePost/policePost/detail',
    method: 'get',
    params: {
      id
    }
  })
}
export const remove = (ids) => {
  return request({
    url: '/api/policePost/policePost/remove',
    method: 'post',
    params: {
      ids,
    }
  })
}
export const add = (row) => {
  return request({
    url: '/api/policePost/policePost/submit',
    method: 'post',
    data: row
  })
}
export const update = (row) => {
  return request({
    url: '/api/policePost/policePost/submit',
    method: 'post',
    data: row
  })
}
src/api/realEstate/realEstate.js
New file
@@ -0,0 +1,50 @@
import request from '@/router/axios';
export const getList = (current, size, params) => {
  return request({
    url: '/api/realEstate/realEstate/list',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    }
  })
}
export const getDetail = (id) => {
  return request({
    url: '/api/realEstate/realEstate/detail',
    method: 'get',
    params: {
      id
    }
  })
}
export const remove = (ids) => {
  return request({
    url: '/api/realEstate/realEstate/remove',
    method: 'post',
    params: {
      ids,
    }
  })
}
export const add = (row) => {
  return request({
    url: '/api/realEstate/realEstate/submit',
    method: 'post',
    data: row
  })
}
export const update = (row) => {
  return request({
    url: '/api/realEstate/realEstate/submit',
    method: 'post',
    data: row
  })
}
src/api/security/security.js
@@ -67,3 +67,45 @@
  })
}
//http://192.168.0.112:18080/sf3d/area/getAoiByPt?lng=117.9471794&lat=28.4474852&height=0&tolerance=10&adcode=361102
export const getAoiByPt = (row) =>{
  return request({
    url:'http://192.168.0.112:18080/sf3d/area/getAoiByPt',
    method:'get',
    data:row
  })
}
//192.168.0.112:9091/zhs/bs/search?ak=ebf48ecaa1fd436fa3d40c4600aa051f&region=361100&query=公安局&ids=61743e28bbf11700e9fc4ef03dd8bea9
export const searchByQuery  = (ak, region, query, ids) => {
  return request({
    url: '/bsapi/zhs/bs/search',
    method: 'get',
    params: {
      ak,
      region,
      query,
      ids
    }
  })
}
//http://{IP}:{PORT}/zhs/bs/search?ak=***&query= 万 达 商 场
// &region=440300&region_type=circle&page_size=3&page_num=1&infos=1&radius=500&location=113.841901,22.628249
export const searchByLonLat  = (ak, query,region,region_type,page_size,page_num,infos,radius,location) => {
  return request({
    url: '/bsapi/zhs/bs/search',
    method: 'get',
    params: {
      ak,
      query,
      region,
      region_type,
      page_size,
      page_num,
      infos,
      radius,
      location
    }
  })
}
src/api/system/dept.js
@@ -79,3 +79,11 @@
  })
}
export const getPoliceStationTree = (params) => {
  return request({
    url: '/api/blade-system/dept/getPoliceStationTree',
    method: 'get',
    params: params
  })
}
src/api/villagePersonInfo/villagePersonInfo.js
New file
@@ -0,0 +1,50 @@
import request from '@/router/axios';
export const getPage = (current, size, params) => {
  return request({
    url: '/api/villagePersonInfo/villagePersonInfo/page',
    method: 'get',
    params: {
      ...params,
      current,
      size,
    }
  })
}
export const getDetail = (id) => {
  return request({
    url: '/api/villagePersonInfo/villagePersonInfo/detail',
    method: 'get',
    params: {
      id
    }
  })
}
export const remove = (ids) => {
  return request({
    url: '/api/villagePersonInfo/villagePersonInfo/remove',
    method: 'post',
    params: {
      ids,
    }
  })
}
export const add = (row) => {
  return request({
    url: '/api/villagePersonInfo/villagePersonInfo/submit',
    method: 'post',
    data: row
  })
}
export const update = (row) => {
  return request({
    url: '/api/villagePersonInfo/villagePersonInfo/submit',
    method: 'post',
    data: row
  })
}
src/components/map/dcMap.vue
New file
@@ -0,0 +1,168 @@
<template>
    <div>
        <div id="viewer-container" :style="{ height: isDetail ? '95vh' : '40vh', width: '100%' }"></div>
        <div style="position: absolute;right:45%;top:-1%;z-index: 999999">
            <p style="margin-top: 10px" v-if="!isDetail">
                <el-button type="primary" size="small" @click="draw('polygon')">绘制区域</el-button>
                <el-button size="small" @click="clearDraw">重置</el-button>
            </p>
        </div>
    </div>
</template>
<script>
export default {
    name: "dcMap",
    props: ['isDetail', 'range'],
    data () {
        return {
            polygonLayer: null,
            polyLineLayer: null,
            polygon: null,
            polyLine: null,
            //绘制工具
            plotTool: null,
            coordinates: []
        }
    },
    created () {
    },
    mounted () {
        let self = this
        global.DC.ready(() => {
            initViewer()
        })
        function initViewer () {
            //配置viewer
            global.viewer = new global.DC.Viewer('viewer-container', {
                contextOptions: {
                    webgl: {
                        alpha: true,
                        stencil: true,
                        preserveDrawingBuffer: true
                    }
                },
                sceneMode: 2
            })
            //加载地图
            //   global.viewer.imageryLayers.addImageryProvider(
            //     new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
            //       url: 'https://webmap-tile.sf-express.com/MapTileService/rt?fetchtype=static&x={x}&y={y}&z={z}&project=sfmap&pic_size=256&pic_type=png8&data_name=361100&data_format=merged-dat&data_type=normal',
            //       format: 'image/jpeg',
            //       show: true,
            //       maximumLevel: 18
            //     })
            //   )
            global.viewer.imageryLayers.addImageryProvider(
                new global.DC.Namespace.Cesium.WebMapTileServiceImageryProvider({
                    url: "http://10.141.11.8:8090/MapTileService/wmts?STORETYPE=merged-dat&PROJECTION=4326",
                    layer: "wmts_4326_361100",
                    style: "default",
                    format: "image/png",
                    tileMatrixSetID: "c",
                    tileMatrixLabels: new Array(18).fill(0).map((v, i) => i + 1),
                    tilingScheme: new global.DC.Namespace.Cesium.GeographicTilingScheme(),
                })
            )
            //添加图层
            self.polygonLayer = new global.DC.VectorLayer('polygonLayer')
            global.viewer.addLayer(self.polygonLayer)
            //添加图层
            self.polyLineLayer = new global.DC.VectorLayer('polyLineLayer')
            global.viewer.addLayer(self.polyLineLayer)
            self.plotTool = new global.DC.Plot(global.viewer)
            //初始化定位
            global.viewer.camera.setView({
                // Cesium的坐标是以地心为原点,一向指向南美洲,一向指向亚洲,一向指向北极州
                // fromDegrees()方法,将经纬度和高程转换为世界坐标
                destination: global.DC.Namespace.Cesium.Cartesian3.fromDegrees(
                    //设置坐标为上饶市信州区
                    117.966460, 28.431002, 5000.0
                ),
                orientation: {
                    // 指向
                    heading: global.DC.Namespace.Cesium.Math.toRadians(0, 0),
                    // 视角
                    pitch: global.DC.Namespace.Cesium.Math.toRadians(-90),
                    roll: 0.0
                }
            })
        }
        if (this.isDetail) {
            this.showPolyLine(this.range)
        }
    },
    methods: {
        //开始绘画
        draw (type) {
            if (this.polygon) {
                this.clearDraw()
            }
            this.plotTool && this.plotTool.draw(type, overlay => {
                if (overlay) {
                    this.polygonLayer.addOverlay(overlay)
                    overlay.positions.forEach(e => {
                        this.coordinates.push([e.lng, e.lat])
                    })
                    let toData = this.doData(this.coordinates)
                    this.$emit('toData', toData)
                }
            })
        },
        //重置
        clearDraw () {
            this.polygonLayer.clear()
        },
        //转换成数据库数据
        doData (val) {
            let str = "LINESTRING("
            for (let k = 0; k < val.length; k++) {
                str += `${val[k][0]} ${val[k][1]}`
                if (k != val.length - 1) {
                    str += ","
                }
            }
            str = str + "," + `${val[0][0]} ${val[0][1]}`
            str += ")"
            // console.log(str)
            return '\'' + str + '\''
        },
        //回显多边形
        showPolygon (positions) {
            let viewer = global.viewer
            positions = positions.replaceAll(",", ";").replaceAll(" ", ",")
            this.polygon = new global.DC.Polygon(positions)
            this.polygon.setStyle({
                material: global.DC.Color.RED
            })
            this.polygonLayer.addOverlay(this.polygon)
            viewer.flyTo(this.polygonLayer)
        },
        //回显线
        showPolyLine (positions) {
            let viewer = global.viewer
            positions = positions.replaceAll(",", ";").replaceAll(" ", ",")
            this.polyLine = new global.DC.Polyline(positions)
            this.polyLine.setStyle({
                material: global.DC.Color.RED
            })
            this.polyLineLayer.addOverlay(this.polyLine)
            viewer.flyTo(this.polyLineLayer)
        }
    }
}
</script>
<style scoped>
</style>
src/components/map/dcSearchMap.vue
New file
@@ -0,0 +1,192 @@
<template>
    <div>
        <div id="search-viewer-container" style="height: 50vh; width: 100%"></div>
    </div>
</template>
<script>
let pointLayer = null
export default {
    name: "dcSearchMap",
    props: ['isDetail', 'point'],
    data() {
        return {
            currentPoint: null,
            //绘制工具
            plotTool: null,
            coordinates: []
        }
    },
    created() {
    },
    mounted() {
    },
    methods: {
        init() {
            let self = this
            if (global.searchViewer != null) {
                global.searchViewer = null
            }
            global.DC.ready(() => {
                initViewer()
            })
            function initViewer() {
                //配置viewer
                global.searchViewer = new global.DC.Viewer('search-viewer-container', {
                    contextOptions: {
                        webgl: {
                            alpha: true,
                            stencil: true,
                            preserveDrawingBuffer: true
                        }
                    },
                    sceneMode: 2
                })
                //加载地图
                // global.searchViewer.imageryLayers.addImageryProvider(
                //     new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
                //         url: 'https://webmap-tile.sf-express.com/MapTileService/rt?fetchtype=static&x={x}&y={y}&z={z}&project=sfmap&pic_size=256&pic_type=png8&data_name=361100&data_format=merged-dat&data_type=normal',
                //         format: 'image/jpeg',
                //         show: true,
                //         maximumLevel: 18
                //     })
                // )
                global.searchViewer.imageryLayers.addImageryProvider(
                    new global.DC.Namespace.Cesium.WebMapTileServiceImageryProvider({
                        url: "http://10.141.11.8:8090/MapTileService/wmts?STORETYPE=merged-dat&PROJECTION=4326",
                        layer: "wmts_4326_361100",
                        style: "default",
                        format: "image/png",
                        tileMatrixSetID: "c",
                        tileMatrixLabels: new Array(18).fill(0).map((v, i) => i + 1),
                        tilingScheme: new global.DC.Namespace.Cesium.GeographicTilingScheme(),
                    })
                )
                //添加图层
                pointLayer = new global.DC.VectorLayer('polygonLayer')
                global.searchViewer.addLayer(pointLayer)
                self.plotTool = new global.DC.Plot(global.searchViewer, {
                    icon_center: "/img/dwicon.jpeg", // 自定义的中心点图标
                    icon_anchor: "/img/dwicon.jpeg", //自定义的锚点图标
                    icon_midAnchor: "/img/dwicon.jpeg", //自定义的中心锚点图标
                    icon_size: [12, 12],//自定义的中心锚点大小
                    clampToModel: false // 点位是否获取模型表面坐标
                })
                //初始化定位
                global.searchViewer.camera.setView({
                    // Cesium的坐标是以地心为原点,一向指向南美洲,一向指向亚洲,一向指向北极州
                    // fromDegrees()方法,将经纬度和高程转换为世界坐标
                    destination: global.DC.Namespace.Cesium.Cartesian3.fromDegrees(
                        //设置坐标为上饶市信州区
                        117.966460, 28.431002, 5000.0
                    ),
                    orientation: {
                        // 指向
                        heading: global.DC.Namespace.Cesium.Math.toRadians(0, 0),
                        // 视角
                        pitch: global.DC.Namespace.Cesium.Math.toRadians(-90),
                        roll: 0.0
                    }
                })
            }
            this.showPoint(this.point)
            this.draw()
        },
        //开始绘画
        draw() {
            const self = this
            if (this.polygon) {
                this.clearDraw()
            }
            //鼠标左键事件
            let leftClick = function (event) {
                if (self.currentPoint) {
                    pointLayer.removeOverlay(self.currentPoint)
                    self.currentPoint = null
                }
                let point = new global.DC.Billboard(new global.DC.Position(event.wgs84SurfacePosition.lng, event.wgs84SurfacePosition.lat), 'img/dwicon.jpeg')
                // point.setStyle({
                //     pixelSize: 10,
                //     color: global.DC.Color.RED, //颜色
                //     outlineColor: global.DC.Color.WHITE, //边框颜色
                //     outlineWidth: 2, //边框大小,
                // })
                self.currentPoint = point
                pointLayer.addOverlay(point)
                let pointLonLat = [event.wgs84SurfacePosition.lng, event.wgs84SurfacePosition.lat]
                self.$emit("getMapData", pointLonLat)
            }
            //添加鼠标左键事件
            global.searchViewer.on(global.DC.MouseEventType.LEFT_DOWN, leftClick)
        },
        //重置
        clearDraw() {
            this.polygonLayer.clear()
        },
        //转换成数据库数据
        doData(val) {
            let str = "LINESTRING("
            for (let k = 0; k < val.length; k++) {
                str += `${val[k][0]} ${val[k][1]}`
                if (k != val.length - 1) {
                    str += ","
                }
            }
            str = str + "," + `${val[0][0]} ${val[0][1]}`
            str += ")"
            // console.log(str)
            return '\'' + str + '\''
        },
        //回显点
        showPoint(positions) {
            let viewer = global.searchViewer
            if (positions) {
                let pointData = ""
                let pointArray = []
                pointData = positions.match(/\(([^)]*)\)/)
                pointArray = pointData[1].split(" ")
                let position = new global.DC.Position(pointArray[0], pointArray[1])
                let point = new global.DC.Billboard(position, 'img/dwicon.jpeg')
                // point.setStyle({
                //     pixelSize: 10,
                //     color: global.DC.Color.RED, //颜色
                //     outlineColor: global.DC.Color.WHITE, //边框颜色
                //     outlineWidth: 2, //边框大小,
                // })
                this.currentPoint = point
                pointLayer.addOverlay(point)
                viewer.flyTo(pointLayer)
            }
        },
        setView(points) {
            if (points) {
                let position = new global.DC.Position(Number(points.lng), Number(points.lat), 2000, 0, -90, 0)
                let point = new global.DC.Billboard(position, 'img/dwicon.jpeg')
                this.currentPoint = point
                pointLayer.clear()
                pointLayer.addOverlay(point)
                global.searchViewer.flyToPosition(
                    new global.DC.Position(Number(points.lng), Number(points.lat), 2000, 0, -90, 0)
                )
            }
        }
    }
}
</script>
<style scoped></style>
src/components/map/mapBox.vue
@@ -1,10 +1,10 @@
<template>
  <div>
    <div id='map' :style="{height:isDetail?'90vh':'40vh',width:'100%'}">
    <div id='map' :style="{ height: isDetail ? '90vh' : '40vh', width: '100%' }" ref="MapContent">
      <div style="position: absolute;right:40%;top:-1%;z-index: 999999">
        <p style="margin-top: 10px" v-if="!isDetail">
          <el-button type="primary" size="small" @click="point()">绘制路线</el-button>
          <el-button  size="small" @click="clearDraw()">重置</el-button>
          <el-button type="primary" size="small" @click="point()">绘制区域</el-button>
          <el-button size="small" @click="clearDraw()">重置</el-button>
        </p>
      </div>
      <!--画线后的提示-->
@@ -21,18 +21,18 @@
import VectorSource from 'ol/source/Vector'
import Cluster from 'ol/source/Cluster'
import {Vector as VectorLayer, Tile as TileLayer} from 'ol/layer'
import LineString from "ol/geom/LineString";
import Point from 'ol/geom/Point';
import Icon from 'ol/style/Icon';
import LineString from "ol/geom/LineString"
import Point from 'ol/geom/Point'
import Icon from 'ol/style/Icon'
import {Style, Fill as StyleFill, Stroke as StyleStroke, Text as StyleText, Circle as StyleCircle} from 'ol/style'
import {Circle as GeomCircle, Point as GeomPoint, LineString as GeomLineString, Polygon as GeomPolygon} from 'ol/geom'
import Draw from 'ol/interaction/Draw'
import XYZ from "ol/source/XYZ";
import XYZ from "ol/source/XYZ"
import 'ol/ol.css'
export default {
  name: 'mapBox',
  props:['routeRange','isDetail'],
  props: ['routeRange', 'isDetail', "searchMap"],
  data() {
    return {
      map: null,
@@ -44,15 +44,16 @@
      draw: null,
      drawLayer: null,
      lineVector: null,
      pointVector:null,
      pointVector: null,
      polygonVector: null,
      coordinates: [],// 保存绘画坐标地址   [[115.90490549080435, 28.746101718722358],[115.93151300423209, 28.741123538790717]]
      toData: null,// 保存数据库格式坐标地址
      showTip:false,
      showTip: false,
      tipPosition: {//提示的位置
        w: 200,
        h: 10,
      },
      tipTitle:null
      tipTitle: null
    }
  },
  methods: {
@@ -72,7 +73,7 @@
        ],
        view: new View({
          // 设置中心点,默认南昌,用于规划南昌市的路线
          center: [115.9032747077233, 28.67433116990186],
          center: [117.951478782, 28.447896798],
          projection: 'EPSG:4326',
          // 设置缩放倍数
          zoom: 13,
@@ -80,6 +81,7 @@
          maxZoom: 19
        })
      })
      _this.lineVector = new VectorLayer({
        //layer所对应的source
        source: new VectorSource({
@@ -92,8 +94,15 @@
          wrapX: false // 禁止横向无限重复(底图渲染的时候会横向无限重复),设置了这个属性,可以让绘制的图形不跟随底图横向无限重复
        }),
      })
      _this.polygonVector = new VectorLayer({
        //layer所对应的source
        source: new VectorSource({
          wrapX: false // 禁止横向无限重复(底图渲染的时候会横向无限重复),设置了这个属性,可以让绘制的图形不跟随底图横向无限重复
        }),
      })
      _this.map.addLayer(_this.lineVector)
      _this.map.addLayer(_this.pointVector)
      _this.map.addLayer(_this.polygonVector)
      //在地图上回显线或点
      _this.startAdd(_this.routeRange)
    },
@@ -116,41 +125,41 @@
      // toData = 'LINESTRING(115.90505364627936 28.740342332731327,115.9119724729309 28.74040302419318,115.90766337913915 28.73566909016844)'
      if (toData) {
        // 将数据库点坐标数据转换
        let entityData = "";
        let entityArr = [];
        entityData = toData.match(/\(([^)]*)\)/);
        let entityData = ""
        let entityArr = []
        entityData = toData.match(/\(([^)]*)\)/)
        if (entityData && entityData != "") {
          entityData = entityData[1].split(",");
          entityData = entityData[1].split(",")
          for (let j = 0; j < entityData.length; j++) {
            entityArr.push([
              Number(entityData[j].split(" ")[0]),
              Number(entityData[j].split(" ")[1]),
            ]);
            ])
          }
        }
        // let lineCoords = [[115.90490549080435, 28.746101718722358],[115.93151300423209, 28.741123538790717],[115.90696542732779, 28.73408542233564],[115.90696542732779, 28.73408542233564]]
        let lineCoords = entityArr
        let view = this.map.getView();
        let view = this.map.getView()
        view.setCenter([
          lineCoords[Math.ceil(lineCoords.length / 2)][0],
          lineCoords[Math.ceil(lineCoords.length / 2)][1],
        ]);
        view.setZoom(14.5);
        ])
        view.setZoom(14.5)
        let feature_LineString = new Feature({
          geometry: new LineString(lineCoords),
        });
        feature_LineString.setStyle(this.styleFunction());// 设置样式
        this.lineVector.getSource().addFeature(feature_LineString);
        })
        feature_LineString.setStyle(this.styleFunction())// 设置样式
        this.lineVector.getSource().addFeature(feature_LineString)
      }
    },
    // 添加点
    addPoint(pointLonLat){
    addPoint(pointLonLat) {
      // pointLonLat = POINT(115.87531914674 28.8603307485585)
      if (pointLonLat){
      if (pointLonLat) {
        let pointData = ""
        let pointArray = []
        pointData = pointLonLat.match(/\(([^)]*)\)/);
        pointData = pointLonLat.match(/\(([^)]*)\)/)
        pointArray = pointData[1].split(" ")
        //设置点
        let feature_Point = new Feature({
@@ -164,53 +173,63 @@
            // imgSize: [250,320],
            scale: 0.2
          }),
        });
        feature_Point.setStyle(style);
        this.pointVector.getSource().addFeature(feature_Point);
        let center = [Number(pointArray[0]), Number(pointArray[1])];
        let view = this.map.getView();
        view.setZoom(16);
        })
        feature_Point.setStyle(style)
        this.pointVector.getSource().addFeature(feature_Point)
        let center = [Number(pointArray[0]), Number(pointArray[1])]
        let view = this.map.getView()
        view.setZoom(16)
        view.animate({
          center: center,
          duration: 5,
        });
        })
      }
    },
    // 将点坐标集合转换为数据库数据
    doData(val) {
      let str = "LINESTRING(";
      let str = "LINESTRING("
      for (let k = 0; k < val.length; k++) {
        str += `${val[k][0]} ${val[k][1]}`;
        str += `${val[k][0]} ${val[k][1]}`
        if (k != val.length - 1) {
          str += ",";
          str += ","
        }
      }
      str += ")";
      str = str + "," + `${val[0][0]} ${val[0][1]}`
      str += ")"
      // console.log(str)
      return '\''+str+'\'';
      return '\'' + str + '\''
    },
    // 开始绘制
    point() {
      let _this = this
      _this.coordinates = []
      _this.map.removeInteraction(_this.draw)
      _this.lineVector.getSource().clear()
      _this.polygonVector.getSource().clear()
      //提示
      if(!_this.showTip){
      if (!_this.showTip) {
        _this.showTip = true
      }
      _this.tipTitle = "单击左键或者右键开始绘画"
      //提示器
      $("#map").off("mousemove").mousemove(function (e) {
        _this.setTipPosition(e.offsetX, e.offsetY, 5, 5);
      })
      $("#map").off("mousedown").mousedown(function () {
      function mapMousemove(e) {
        _this.setTipPosition(e.offsetX, e.offsetY, 5, 5)
      }
      this.$refs.MapContent.addEventListener('mousemove', mapMousemove)
      // this.$refs.MapContent.removeEventListener('mousemove', mapMousemove)
      function mapMousedown() {
        _this.tipTitle = "可继续,或选择最终位置双击结束绘画"
      })
      }
      this.$refs.MapContent.addEventListener('mousedown', mapMousedown)
      // this.$refs.MapContent.removeEventListener('mousedown', mapMousedown)
      _this.draw = new Draw({
        source: _this.lineVector.getSource(),
        type: 'LineString',
        source: _this.polygonVector.getSource(),
        type: 'Polygon',
        style: new Style({
          stroke: new StyleStroke({
            color: "red",
@@ -227,16 +246,17 @@
      // 结束事件
      _this.draw.on('drawend', function () {
        _this.map.removeInteraction(_this.draw);
        _this.lineVector.setStyle(_this.styleFunction())// 路线画好之后的样式
        _this.map.removeInteraction(_this.draw)
        _this.polygonVector.setStyle(_this.styleFunction())// 路线画好之后的样式
        // 将点坐标集合转换为数据库数据
        let toData = _this.doData(_this.coordinates)
        // 传值给父组件
        _this.$emit('toData',toData)
        _this.$emit('toData', toData)
        //隐藏提示
        _this.tipTitle = null;
        _this.tipTitle = null
        _this.showTip = false
      })
    },
    // 设置统一控制点击事件,需要画图方式在此处切换
    handleClick(point) {
@@ -263,7 +283,7 @@
      this.linePoints.push(point)
      let featureLine = new Feature({
        geometry: new GeomLineString(this.linePoints),
      });
      })
      // 添加线的样式
      let lineStyle = new Style({
@@ -274,8 +294,8 @@
          color: 'rgba(255, 0, 0)',
          width: 4,
        }),
      });
      featureLine.setStyle(lineStyle);
      })
      featureLine.setStyle(lineStyle)
      let source = new VectorSource()
      source.addFeature(featureLine)
@@ -299,7 +319,7 @@
      let feature = new Feature({
        geometry: new GeomPolygon([this.polygonPoints]),
        attributes: null
      });
      })
      // 添加线的样式
      let lineStyle = new Style({
        fill: new StyleFill({
@@ -309,9 +329,9 @@
          color: 'rgba(255, 0, 0)',
          width: 4,
        }),
      });
      feature.setStyle(lineStyle);
      let source = new VectorSource();
      })
      feature.setStyle(lineStyle)
      let source = new VectorSource()
      source.addFeature(feature)
      let vectorLayer = new VectorLayer({
        source: source
@@ -320,12 +340,12 @@
    },
    // 设置聚合点
    addMarker() {
      let source = new VectorSource();
      let source = new VectorSource()
      // 随机创建200个要素,后台点位取出后按此格式处理
      for (let i = 1; i <= 200; i++) {
        let coordinates = [115.90 + Math.random() * 0.05, 28.64 + Math.random() * 0.05];
        let feature = new Feature(new GeomPoint(coordinates));
        source.addFeature(feature);
        let coordinates = [115.90 + Math.random() * 0.05, 28.64 + Math.random() * 0.05]
        let feature = new Feature(new GeomPoint(coordinates))
        source.addFeature(feature)
      }
      // 聚合
@@ -337,7 +357,7 @@
      let clusters = new VectorLayer({
        source: clusterSource,
        style: function (feature) {
          let size = feature.get('features').length;
          let size = feature.get('features').length
          let style = new Style({
            image: new StyleCircle({
              radius: 20,
@@ -355,20 +375,23 @@
              })
            })
          })
          return style;
          return style
        }
      });
      })
      this.map.addLayer(clusters)
    },
    // 重置图层
    clearDraw(){
    clearDraw() {
      let _this = this
      _this.coordinates = []
      _this.map.removeInteraction(_this.draw)
      _this.lineVector.getSource().clear()
      _this.showTip = false
      _this.tipTitle = null
      // 传值给父组件
      _this.$emit('toData', "")
    },
    // 获取新的 layer 图层对象
    getLayer() {
@@ -394,14 +417,16 @@
    // 设置提示位置
    setTipPosition(x, y, n, m) {
      let _this = this
      _this.tipPosition.w = x + n;
      _this.tipPosition.h = y + m;
      _this.tipPosition.w = x + n
      _this.tipPosition.h = y + m
    },
    startAdd(routeRange){
      if (routeRange.startsWith("LINESTRING")){
        this.addLineDraw(routeRange)
      }else {
        this.addPoint(routeRange)
    startAdd(routeRange) {
      if (routeRange) {
        if (routeRange.startsWith("LINESTRING")) {
          this.addLineDraw(routeRange)
        } else if (routeRange.startsWith("POINT")) {
          this.addPoint(routeRange)
        }
      }
    }
  },
src/components/map/searchMap.vue
New file
@@ -0,0 +1,139 @@
<template>
  <div class="basic-container">
    <div class="search-line">
      <el-select
        class="search-input"
        v-model="queryString"
        filterable
        remote
        reserve-keyword
        placeholder="请输入关键词"
        :remote-method="remoteMethod"
        :loading="loading"
        @change="selectChange">
        <el-option
          v-for="item in searchList"
          :key="item.uid"
          :label="item.address"
          :value="JSON.stringify(item)">
        </el-option>
      </el-select>
      <!--      <el-button class="search-button" @click="getAddressByQuery">查询</el-button>-->
    </div>
    <!--    <search-map-box ref="OpenLayersMap" @getMapData="getMapData" :route-range="point" :is-detail="true"></search-map-box>-->
    <dc-search-map ref="dcSearchMap" @getMapData="getMapData" :point="point"></dc-search-map>
  </div>
</template>
<script>
import SearchMapBox from "@/components/map/searchMapBox";
import {getAoiByPt, search, searchByLonLat, searchByQuery} from "@/api/security/security";
import data from "@/views/util/data";
import DcSearchMap from "@/components/map/dcSearchMap";
export default {
  name: "searchMap",
  components: {DcSearchMap, SearchMapBox},
  props: ['pointLonLat'],
  data() {
    return {
      ak: "ebf48ecaa1fd436fa3d40c4600aa051f",
      region: "361100",
      longitude: "",
      latitude: "",
      queryString: "",
      point: "",
      searchList: [],
      loading: false,
    }
  },
  watch: {
    longitude: {
      handler(newVal) {
        if (newVal) {
          this.getAddressByLonLat()
        }
      }
    }
  },
  created() {
    this.point = this.pointLonLat
  },
  mounted() {
    this.$refs.dcSearchMap.init()
  },
  methods: {
    getMapData(data) {
      this.longitude = data[0]
      this.latitude = data[1]
      this.$emit("getLonLat", data)
    },
    remoteMethod(data) {
      this.queryString = data
      this.getAddressByQuery()
    },
    getAddressByQuery() {
      let ak = this.ak
      let region = this.region
      let query = this.queryString
      searchByQuery(ak, region, query).then(res => {
        let dataList = res.data.result
        this.searchList = dataList
      })
    },
    getAddressByLonLat() {
      let ak = this.ak
      let query = ""
      let region = this.region
      let region_type = "circle"
      let page_size = "1"
      let page_num = "1"
      let infos = 1
      let radius = 100
      let location = this.longitude + " " + this.latitude
      searchByLonLat(ak, query, region, region_type, page_size, page_num, infos, radius, location).then(res => {
        let data = res.data.result[0]
        if(data!=undefined){
          this.queryString = data.address
          this.$emit("getAddress", this.queryString)
          let point = [data.location.lng,data.location.lat]
          this.$emit("getLonLat", point)
          //清空
          this.searchList = []
          //触发搜索
          this.getAddressByQuery()
        }else{
          this.queryString = [];
          //清空
          this.searchList = []
          this.$emit("getAddress", '')
          this.$emit("getLonLat", ['',''])
        }
      })
    },
    selectChange(data) {
      let selectData = JSON.parse(data)
      this.$emit("getLonLat", [selectData.location.lng, selectData.location.lat])
      this.$emit("getAddress", selectData.address)
      this.$refs.dcSearchMap.setView(selectData.location)
    }
  }
}
</script>
<style scoped>
.search-line {
  display: flex;
  width: 1286px;
}
.search-input {
  margin-bottom: 2%;
  width: 100%;
}
</style>
src/components/map/searchMapBox.vue
New file
@@ -0,0 +1,360 @@
<template>
  <div>
    <div id='searchMap' style="height: 50vh; width: 100%" ref="MapContent">
    </div>
  </div>
</template>
<script>
import {Feature, Map, View} from "ol";
import {Tile as TileLayer, Vector as VectorLayer} from "ol/layer";
import XYZ from "ol/source/XYZ";
import VectorSource from "ol/source/Vector";
import {Circle as StyleCircle, Fill as StyleFill, Stroke as StyleStroke, Style, Text as StyleText} from "ol/style";
import Point from "ol/geom/Point";
import Icon from "ol/style/Icon";
import Draw from "ol/interaction/Draw";
import {Circle as GeomCircle, LineString as GeomLineString, Point as GeomPoint, Polygon as GeomPolygon} from "ol/geom";
import Cluster from "ol/source/Cluster";
export default {
  name: "searchMapBox",
  props: ['routeRange'],
  data() {
    return {
      map: null,
      points: [],
      featurePoint:null,
      // 线条点数组
      linePoints: [],
      // 多边形数组
      polygonPoints: [],
      draw: null,
      drawLayer: null,
      pointVector: null,
      coordinates: [],// 保存绘画坐标地址   [[115.90490549080435, 28.746101718722358],[115.93151300423209, 28.741123538790717]]
      toData: null,// 保存数据库格式坐标地址
      showTip: false,
      tipTitle: null
    }
  },
  methods: {
    createMap() {
      let _this = this
      //初始化地图
      _this.map = new Map({
        target: 'searchMap',
        layers: [
          new TileLayer({
            source: new XYZ({
              url: "https://webmap-tile.sf-express.com/MapTileService/rt?fetchtype=static&x={x}&y={y}&z={z}&project=sfmap&pic_size=256&pic_type=png8&data_name=361100&data_format=merged-dat&data_type=normal", // 行政区划
            })
          }),
        ],
        view: new View({
          // 设置中心点
          //117.951478782, 28.447896798, 5000
          center: [117.951478782, 28.447896798],
          projection: 'EPSG:4326',
          // 设置缩放倍数
          zoom: 13,
          minZoom: 8,
          maxZoom: 19
        })
      })
      _this.pointVector = new VectorLayer({
        //layer所对应的source
        source: new VectorSource({
          wrapX: false // 禁止横向无限重复(底图渲染的时候会横向无限重复),设置了这个属性,可以让绘制的图形不跟随底图横向无限重复
        }),
        style: new Style({
          image: new Icon({
            src: "/img/dwicon.jpeg",
            anchor: [0.48, 1],
            // imgSize: [250,320],
            scale: 0.13
          }),
        })
      })
      _this.map.addLayer(_this.pointVector)
      // 在地图上回显线或点
      if (this.routeRange) {
        _this.startAdd(_this.routeRange)
      }
      this.point()
    },
    // 绘画之后的样式
    styleFunction() {
      // 绘画之后的样式
      let styles = [
        new Style({
          fill: new StyleFill({color: "rgba(255, 255, 255, 0.2)"}),
          stroke: new StyleStroke({
            color: 'rgb(252, 94, 32)',
            width: 5
          })
        })
      ]
      return styles
    },
    // 添加点
    addPoint(pointLonLat) {
      // pointLonLat = POINT(115.87531914674 28.8603307485585)
      if (pointLonLat) {
        let pointData = ""
        let pointArray = []
        pointData = pointLonLat.match(/\(([^)]*)\)/)
        pointArray = pointData[1].split(" ")
        //设置点
        let feature_Point = new Feature({
          geometry: new Point([Number(pointArray[0]), Number(pointArray[1])])
        })
        //点样式
        let style = new Style({
          image: new Icon({
            src: "/img/dwicon.jpeg",
            anchor: [0.48, 1],
            // imgSize: [250,320],
            scale: 0.13
          }),
        })
        this.featurePoint = feature_Point
        feature_Point.setStyle(style)
        this.pointVector.getSource().addFeature(feature_Point)
        let center = [Number(pointArray[0]), Number(pointArray[1])]
        let view = this.map.getView()
        view.setZoom(16)
        view.animate({
          center: center,
          duration: 5,
        })
      }
    },
    // 将点坐标集合转换为数据库数据
    doData(val) {
      let str = "LINESTRING("
      for (let k = 0; k < val.length; k++) {
        str += `${val[k][0]} ${val[k][1]}`
        if (k != val.length - 1) {
          str += ","
        }
      }
      str = str + "," + `${val[0][0]} ${val[0][1]}`
      str += ")"
      // console.log(str)
      return '\'' + str + '\''
    },
    // 开始绘制
    point() {
      let _this = this
      _this.coordinates = []
      _this.map.removeInteraction(_this.draw)
      // _this.pointVector.getSource().clear()
      _this.draw = new Draw({
        source: _this.pointVector.getSource(),
        type: 'Point',
      })
      _this.map.addInteraction(_this.draw)
      // 点击事件
      _this.map.on('click', function (e) {
        if (_this.featurePoint != null){
          _this.pointVector.getSource().removeFeature(_this.featurePoint)
        }
        if (_this.coordinates.length > 0) {
          let featureArray = _this.pointVector.getSource().getFeatures()
          for (let i = 0; i < featureArray.length -1; i++) {
            _this.pointVector.getSource().removeFeature(featureArray[i])
          }
          _this.coordinates = []
        }
        // 将点坐标保存集合
        _this.coordinates.push(e.coordinate)
        _this.$emit("getMapData", _this.coordinates)
      })
    },
    // 设置统一控制点击事件,需要画图方式在此处切换
    handleClick(point) {
      // 绘制连线
      this.drawLineString(point)
      // 绘制点
      // this.drawPoint(point)
      // 绘制圆形
      // this.drawCircle(point)
      // 绘制多边形
      // this.drawPolygon(point)
    },
    // 绘制点位
    drawPoint(center) {
      let vectorLayer = this.getLayer()
      let point = new GeomPoint(center)
      let feature = new Feature(point)
      vectorLayer.getSource().addFeature(feature)
      this.map.addLayer(vectorLayer)
    },
    // 绘制连线
    drawLineString(point) {
      this.linePoints.push(point)
      let featureLine = new Feature({
        geometry: new GeomLineString(this.linePoints),
      })
      // 添加线的样式
      let lineStyle = new Style({
        fill: new StyleFill({
          color: 'rgba(1, 210, 241, 0.1)'
        }),
        stroke: new StyleStroke({
          color: 'rgba(255, 0, 0)',
          width: 4,
        }),
      })
      featureLine.setStyle(lineStyle)
      let source = new VectorSource()
      source.addFeature(featureLine)
      let layer = new VectorLayer()
      layer.setSource(source)
      this.map.addLayer(layer)
    },
    // 绘制区域圆形
    drawCircle(center) {
      let vectorLayer = this.getLayer()
      // 设置半径
      let circle = new GeomCircle(center, 0.003)// 新建圆对象
      let feature = new Feature(circle)// 新建Feature对象 并将circle传入
      vectorLayer.getSource().addFeature(feature)// 将Feature对象填入图层源
      this.map.addLayer(vectorLayer) // 将图层添至地图对象
    },
    // 画多边形
    drawPolygon(point) {
      this.polygonPoints.push(point)
      let feature = new Feature({
        geometry: new GeomPolygon([this.polygonPoints]),
        attributes: null
      })
      // 添加线的样式
      let lineStyle = new Style({
        fill: new StyleFill({
          color: 'rgba(1, 210, 241, 0.1)'
        }),
        stroke: new StyleStroke({
          color: 'rgba(255, 0, 0)',
          width: 4,
        }),
      })
      feature.setStyle(lineStyle)
      let source = new VectorSource()
      source.addFeature(feature)
      let vectorLayer = new VectorLayer({
        source: source
      })
      this.map.addLayer(vectorLayer)
    },
    // 设置聚合点
    addMarker() {
      let source = new VectorSource()
      // 随机创建200个要素,后台点位取出后按此格式处理
      for (let i = 1; i <= 200; i++) {
        let coordinates = [115.90 + Math.random() * 0.05, 28.64 + Math.random() * 0.05]
        let feature = new Feature(new GeomPoint(coordinates))
        source.addFeature(feature)
      }
      // 聚合
      let clusterSource = new Cluster({
        source: source,
        distance: 50
      })
      let clusters = new VectorLayer({
        source: clusterSource,
        style: function (feature) {
          let size = feature.get('features').length
          let style = new Style({
            image: new StyleCircle({
              radius: 20,
              stroke: new StyleStroke({
                color: 'white'
              }),
              fill: new StyleFill({
                color: '#AAD3DF'
              })
            }),
            text: new StyleText({
              text: size.toString(),
              fill: new StyleFill({
                color: 'black'
              })
            })
          })
          return style
        }
      })
      this.map.addLayer(clusters)
    },
    // 重置图层
    clearDraw() {
      let _this = this
      _this.coordinates = []
      _this.map.removeInteraction(_this.draw)
      _this.pointVector.getSource().clear()
      // 传值给父组件
      _this.$emit('toData', "")
    },
    // 获取新的 layer 图层对象
    getLayer() {
      return new VectorLayer({
        source: new VectorSource({
          features: ''
        }),
        // 设置样式,但不完全兼容
        // style: function (feature) {
        //   let style = new Style({
        //     stroke: new StyleStroke({
        //       color: '#E80000',
        //       width: 2
        //     }),
        //     fill: new StyleFill({
        //       color: 'rgba(0,0,0,0)'
        //     })
        //   })
        //   return style
        // }
      })
    },
    startAdd(routeRange) {
      if (routeRange.startsWith("POINT")) {
        this.addPoint(routeRange)
      }
    },
    setView(point){
      let view = this.map.getView()
      let center = [point.lng,point.lat]
      view.setZoom(20)
      view.animate({
        center: center,
        duration: 5,
      })
    }
  },
  mounted() {
    this.createMap()
  }
}
</script>
<style scoped>
</style>
src/main.js
@@ -1,90 +1,102 @@
import Vue from 'vue';
import axios from './router/axios';
import VueAxios from 'vue-axios';
import App from './App';
import router from './router/router';
import './permission'; // 权限
import './error'; // 日志
import './cache';//页面缓存
import store from './store';
/*
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2023-02-06 10:34:02
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2023-02-07 10:39:07
 * @FilePath: \srs-police-web\src\main.js
 * @Description:
 *
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
 */
import Vue from 'vue'
import axios from './router/axios'
import VueAxios from 'vue-axios'
import App from './App'
import router from './router/router'
import './permission' // 权限
import './error' // 日志
import './cache'//页面缓存
import store from './store'
import { loadStyle } from './util/util'
import * as urls from '@/config/env';
import Element from 'element-ui';
import * as urls from '@/config/env'
import Element from 'element-ui'
import {
  iconfontUrl,
  iconfontVersion
} from '@/config/env';
import i18n from './lang'; // Internationalization
import './styles/common.scss';
import basicBlock from './components/basic-block/main';
import basicContainer from './components/basic-container/main';
import thirdRegister from './components/third-register/main';
import flowDesign from './components/flow-design/main';
import avueUeditor from 'avue-plugin-ueditor';
import website from '@/config/website';
import crudCommon from '@/mixins/crud';
    iconfontUrl,
    iconfontVersion
} from '@/config/env'
import i18n from './lang' // Internationalization
import './styles/common.scss'
import basicBlock from './components/basic-block/main'
import basicContainer from './components/basic-container/main'
import thirdRegister from './components/third-register/main'
import flowDesign from './components/flow-design/main'
import avueUeditor from 'avue-plugin-ueditor'
import website from '@/config/website'
import crudCommon from '@/mixins/crud'
// 业务组件
import tenantPackage from './views/system/tenantpackage';
import tenantPackage from './views/system/tenantpackage'
import * as echarts from 'echarts'
Vue.prototype.$echarts = echarts
import DC from '@dvgis/dc-sdk/dist/dc.base.min' //基础包
import DcCore from '@dvgis/dc-sdk/dist/dc.core.min' //核心包
import DcChart from '@dvgis/dc-sdk/dist/dc.chart.min' //chart包
import DcMapv from '@dvgis/dc-sdk/dist/dc.mapv.min' //mapv包
import DcS3M from '@dvgis/dc-sdk/dist/dc.s3m.min' //s3m包
import '@dvgis/dc-sdk/dist/dc.core.min.css' // 主要样式
global.DC = DC // 将DC提升到全局变量,方便在工程中直接使用
global.viewer = null // 将viewer提升到全局变量,方便在工程中直接使用
global.searchViewer = null // 将viewer提升到全局变量,方便在工程中直接使用
global.echarts = echarts // 将DC提升到全局变量,方便在工程中直接使用
DC.use(DcCore) // 安装DC核心库
DC.use(DcChart) // 安装DC图标库,使用前确保echarts为全局函数
DC.use(DcMapv) // 安装Mapv库
DC.use(DcS3M) // 安装DcS3M库
// 注册全局crud驱动
window.$crudCommon = crudCommon;
window.$crudCommon = crudCommon
// 加载Vue拓展
Vue.use(router);
Vue.use(VueAxios, axios);
Vue.use(router)
Vue.use(VueAxios, axios)
Vue.use(Element, {
  i18n: (key, value) => i18n.t(key, value)
});
    i18n: (key, value) => i18n.t(key, value)
})
Vue.use(window.AVUE, {
  size: 'small',
  tableSize: 'small',
  calcHeight: 65,
  i18n: (key, value) => i18n.t(key, value)
});
    size: 'small',
    tableSize: 'small',
    calcHeight: 65,
    i18n: (key, value) => i18n.t(key, value)
})
// 注册全局容器
Vue.component('basicContainer', basicContainer);
Vue.component('basicBlock', basicBlock);
Vue.component('thirdRegister', thirdRegister);
Vue.component('avueUeditor', avueUeditor);
Vue.component('flowDesign', flowDesign);
Vue.component('tenantPackage', tenantPackage);
Vue.component('basicContainer', basicContainer)
Vue.component('basicBlock', basicBlock)
Vue.component('thirdRegister', thirdRegister)
Vue.component('avueUeditor', avueUeditor)
Vue.component('flowDesign', flowDesign)
Vue.component('tenantPackage', tenantPackage)
// 加载相关url地址
Object.keys(urls).forEach(key => {
  Vue.prototype[key] = urls[key];
});
    Vue.prototype[key] = urls[key]
})
// 加载NutFlow
Vue.use(window.WfDesignBase);
Vue.use(window.WfDesignBase)
// 加载website
Vue.prototype.website = website;
Vue.prototype.website = website
// 动态加载阿里云字体库
iconfontVersion.forEach(ele => {
  loadStyle(iconfontUrl.replace('$key', ele));
});
    loadStyle(iconfontUrl.replace('$key', ele))
})
Vue.config.productionTip = false;
//import Cookies from 'js-cookie'
// 携带token跳转页面设置
//const tokenLength = window.location.href.indexOf('=');
//if(tokenLength>0){
//  //取“=”之后的token
 // let z = window.location.href.substring(tokenLength + 1)
 // // 把token存进B系统
 // let obj = {
 //   dataType: typeof (z),
 //   content: z,
 //   datetime: new Date().getTime()
 // }
 // window.localStorage.setItem('saber-token', JSON.stringify(obj));
 // Cookies.set('saber-access-token', z)
//}
Vue.config.productionTip = false
new Vue({
  router,
  store,
  i18n,
  render: h => h(App)
}).$mount('#app');
    router,
    store,
    i18n,
    render: h => h(App)
}).$mount('#app')
src/option/user/info.js
@@ -5,24 +5,26 @@
    {
      label: '个人信息',
      prop: 'info',
      column: [{
        label: '头像',
        type: 'upload',
        listType: 'picture-img',
        propsHttp: {
          res: 'data',
          url: 'link',
        },
        canvasOption: {
          text: ' ',
          ratio: 0.1
        },
        action: '/api/blade-resource/oss/endpoint/put-file',
        tip: '只能上传jpg/png用户头像,且不超过500kb',
        span: 12,
        row: true,
        prop: 'avatar'
      }, {
      column: [
      //   {
      //   label: '头像',
      //   type: 'upload',
      //   listType: 'picture-img',
      //   propsHttp: {
      //     res: 'data',
      //     url: 'link',
      //   },
      //   canvasOption: {
      //     text: ' ',
      //     ratio: 0.1
      //   },
      //   action: '/api/blade-resource/oss/endpoint/put-file',
      //   tip: '只能上传jpg/png用户头像,且不超过500kb',
      //   span: 12,
      //   row: true,
      //   prop: 'avatar'
      // },
      {
        label: '姓名',
        span: 12,
        row: true,
src/page/index/top/index.vue
@@ -83,7 +83,7 @@
        </div>
      </el-tooltip>
      <img class="top-bar__img"
           :src="userInfo.avatar">
           src="/icon.png">
      <el-dropdown>
        <span class="el-dropdown-link">
          {{userInfo.userName}}
src/page/login/userlogin.vue
@@ -88,9 +88,9 @@
          //角色ID
          roleId: "",
          //用户名
          username: "admin",
          username: "",
          //密码
          password: "admin",
          password: "",
          //账号类型
          type: "account",
          //验证码的值
src/permission.js
@@ -2,9 +2,9 @@
 * 全站权限配置
 *
 */
import md5 from 'js-md5'
import request from '@/router/axios';
import { Message } from 'element-ui'
// import md5 from 'js-md5'
// import request from '@/router/axios'
// import { Message } from 'element-ui'
import router from './router/router'
import store from './store'
@@ -12,144 +12,150 @@
import { getToken } from '@/util/auth'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
NProgress.configure({ showSpinner: false });
const lockPage = store.getters.website.lockPage; //锁屏页
NProgress.configure({ showSpinner: false })
const lockPage = store.getters.website.lockPage //锁屏页
router.beforeEach((to, from, next) => {
  var tag = false;
  // if (to.fullPath.indexOf("token") > 0) {
  //   tag = true;
  // }
  const meta = to.meta || {};
  const isMenu = meta.menu === undefined ? to.query.menu : meta.menu;
  store.commit('SET_IS_MENU', isMenu === undefined);
  if (getToken()) {
    if (store.getters.isLock && to.path !== lockPage) { //如果系统激活锁屏,全部跳转到锁屏页
      next({ path: lockPage })
    } else if (to.path === '/login') { //如果登录成功访问登录页跳转到主页
      next({ path: '/' })
    } else {
      //如果用户信息为空则获取用户信息,获取用户信息失败,跳转到登录页
      // if (store.getters.token.length === 0 && tag==false) {
        if (store.getters.token.length === 0) {
        store.dispatch('FedLogOut').then(() => {
          next({ path: '/login' })
        })
      } else {
        const value = to.query.src || to.fullPath;
        const label = to.query.name || to.name;
        const meta = to.meta || router.$avueRouter.meta || {};
        const i18n = to.query.i18n;
        if (to.query.target) {
          window.open(value)
        } else if (meta.isTab !== false && !validatenull(value) && !validatenull(label)) {
       // } else if (meta.isTab !== false && !validatenull(value) && !validatenull(label) && tag==false) {
          store.commit('ADD_TAG', {
            label: label,
            value: value,
            params: to.params,
            query: to.query,
            meta: (() => {
              if (!i18n) {
                return meta
              }
              return {
                i18n: i18n
              }
            })(),
            group: router.$avueRouter.group || []
          });
        }
        next()
      }
    let hrefIdx = window.location.href.indexOf('token=') // url中是否携带token
    var tag = false
    if (to.fullPath.indexOf("token") > 0) {
        tag = true
    }
  } else {
    //判断是否需要认证,没有登录访问去登录页
    if (meta.isAuth === false) {
      next()
    } else {
      console.log(to.path,66666)
      if (to.path == '/security/security') {
        // console.log('进入首页-----')
        var a = to.query.securitySupervisionSystem;
        if (a == undefined || typeof a != "string") {
          // console.log("无securitySupervisionSystem参数  跳回登入");
          next('/login');
          next('/login');
          return;
        }
        // console.log("有securitySupervisionSystem参数");
        try {
          // console.log("判断securitySupervisionSystem是否能被JSOn解码");
          var obj = JSON.parse(a);
          if (typeof obj == "object" && obj && obj.tokenMY == '987654321S') {
            debugger
            var data = {
              tenantId: obj.data.dip,
              username: obj.data.rese,
              password: md5(obj.data.sap),
              grant_type: 'password',
              scope: 'all',
              type: 'account'
            };
            request({
              url: '/api/blade-auth/oauth/token',
              method: 'post',
              headers: {
                'Authorization': 'Basic c2FiZXI6c2FiZXJfc2VjcmV0',
                "Tenant-Id": "000000"
              },
              params: data
            }).then(res => {
              const data = res.data;
              if (data.error_description) {
                // console.log("登入失败");
                Message({
                  message: data.error_description,
                  type: 'error'
    const meta = to.meta || {}
    const isMenu = meta.menu === undefined ? to.query.menu : meta.menu
    store.commit('SET_IS_MENU', isMenu === undefined)
    if (hrefIdx > -1) {
        let token = window.location.href.slice(hrefIdx + 6)
        store.commit('SET_TOKEN', token)
    }
    if (getToken()) {
        if (store.getters.isLock && to.path !== lockPage) { //如果系统激活锁屏,全部跳转到锁屏页
            next({ path: lockPage })
        } else if (to.path === '/login') { //如果登录成功访问登录页跳转到主页
            next({ path: '/' })
        } else {
            //如果用户信息为空则获取用户信息,获取用户信息失败,跳转到登录页
            if (store.getters.token.length === 0 && tag == false) {
                // if (store.getters.token.length === 0) {
                store.dispatch('FedLogOut').then(() => {
                    next({ path: '/login' })
                })
                next('/login');
                next('/login');
                return;
              } else {
                // console.log("登入成功");
                store.commit('SET_TOKEN', data.access_token);
                store.commit('SET_REFRESH_TOKEN', data.refresh_token);
                store.commit('SET_TENANT_ID', data.tenant_id);
                store.commit('SET_USER_INFO', data);
                store.commit('DEL_ALL_TAG');
                store.commit('CLEAR_LOCK');
                next(to.path);
                return;
              }
            })
            return;
          } else {
            // console.log("成功解码 不是对象");
            next('/login');
            next('/login');
            return;
          }
        } catch {
          // console.log('不是Json对象 跳回登入');
          next('/login');
          next('/login');
          return;
            } else {
                const value = to.query.src || to.fullPath
                const label = to.query.name || to.name
                const meta = to.meta || router.$avueRouter.meta || {}
                const i18n = to.query.i18n
                if (to.query.target) {
                    window.open(value)
                    // } else if (meta.isTab !== false && !validatenull(value) && !validatenull(label)) {
                } else if (meta.isTab !== false && !validatenull(value) && !validatenull(label) && tag == false) {
                    store.commit('ADD_TAG', {
                        label: label,
                        value: value,
                        params: to.params,
                        query: to.query,
                        meta: (() => {
                            if (!i18n) {
                                return meta
                            }
                            return {
                                i18n: i18n
                            }
                        })(),
                        group: router.$avueRouter.group || []
                    })
                }
                next()
            }
        }
      }
      next('/login')
    } else {
        //判断是否需要认证,没有登录访问去登录页
        if (meta.isAuth === false) {
            next()
        } else {
            // console.log(to.path, 66666)
            // if (to.path == '/security/security') {
            //     // console.log('进入首页-----')
            //     var a = to.query.securitySupervisionSystem
            //     if (a == undefined || typeof a != "string") {
            //         // console.log("无securitySupervisionSystem参数  跳回登入");
            //         next('/login')
            //         next('/login')
            //         return
            //     }
            //     // console.log("有securitySupervisionSystem参数");
            //     try {
            //         // console.log("判断securitySupervisionSystem是否能被JSOn解码");
            //         var obj = JSON.parse(a)
            //         if (typeof obj == "object" && obj && obj.tokenMY == '987654321S') {
            //             debugger
            //             var data = {
            //                 tenantId: obj.data.dip,
            //                 username: obj.data.rese,
            //                 password: md5(obj.data.sap),
            //                 grant_type: 'password',
            //                 scope: 'all',
            //                 type: 'account'
            //             }
            //             request({
            //                 url: '/api/blade-auth/oauth/token',
            //                 method: 'post',
            //                 headers: {
            //                     'Authorization': 'Basic c2FiZXI6c2FiZXJfc2VjcmV0',
            //                     "Tenant-Id": "000000"
            //                 },
            //                 params: data
            //             }).then(res => {
            //                 const data = res.data
            //                 if (data.error_description) {
            //                     // console.log("登入失败");
            //                     Message({
            //                         message: data.error_description,
            //                         type: 'error'
            //                     })
            //                     next('/login')
            //                     next('/login')
            //                     return
            //                 } else {
            //                     // console.log("登入成功");
            //                     store.commit('SET_TOKEN', data.access_token)
            //                     store.commit('SET_REFRESH_TOKEN', data.refresh_token)
            //                     store.commit('SET_TENANT_ID', data.tenant_id)
            //                     store.commit('SET_USER_INFO', data)
            //                     store.commit('DEL_ALL_TAG')
            //                     store.commit('CLEAR_LOCK')
            //                     next(to.path)
            //                     return
            //                 }
            //             })
            //             return
            //         } else {
            //             // console.log("成功解码 不是对象");
            //             next('/login')
            //             return
            //         }
            //     } catch {
            //         // console.log('不是Json对象 跳回登入');
            //         next('/login')
            //         return
            //     }
            // }
            next('/login')
        }
    }
  }
})
router.afterEach(() => {
  NProgress.done();
  let title = store.getters.tag.label;
  let i18n = store.getters.tag.meta.i18n;
  title = router.$avueRouter.generateTitle(title, i18n);
  //判断登录页的情况
  if (router.history.current.fullPath === "/login") {
    title = "登录";
  }
  //根据当前的标签也获取label的值动态设置浏览器标题
  router.$avueRouter.setTitle(title);
});
    NProgress.done()
    let title = store.getters.tag.label
    let i18n = store.getters.tag.meta.i18n
    title = router.$avueRouter.generateTitle(title, i18n)
    //判断登录页的情况
    if (router.history.current.fullPath === "/login") {
        title = "登录"
    }
    //根据当前的标签也获取label的值动态设置浏览器标题
    router.$avueRouter.setTitle(title)
})
src/store/modules/user.js
@@ -1,301 +1,301 @@
import {setToken, setRefreshToken, removeToken, removeRefreshToken} from '@/util/auth'
import {Message} from 'element-ui'
import {setStore, getStore} from '@/util/store'
import {isURL, validatenull} from '@/util/validate'
import {deepClone} from '@/util/util'
import { setToken, setRefreshToken, removeToken, removeRefreshToken } from '@/util/auth'
import { Message } from 'element-ui'
import { setStore, getStore } from '@/util/store'
import { isURL, validatenull } from '@/util/validate'
import { deepClone } from '@/util/util'
import website from '@/config/website'
import {loginByUsername, loginBySocial, loginBySso, getUserInfo, logout, refreshToken, getButtons} from '@/api/user'
import {getTopMenu, getRoutes} from '@/api/system/menu'
import { loginByUsername, loginBySocial, loginBySso, getUserInfo, logout, refreshToken, getButtons } from '@/api/user'
import { getTopMenu, getRoutes } from '@/api/system/menu'
import md5 from 'js-md5'
function addPath(ele, first) {
  const menu = website.menu;
  const propsConfig = menu.props;
  const propsDefault = {
    label: propsConfig.label || 'name',
    path: propsConfig.path || 'path',
    icon: propsConfig.icon || 'icon',
    children: propsConfig.children || 'children'
  }
  const icon = ele[propsDefault.icon];
  ele[propsDefault.icon] = validatenull(icon) ? menu.iconDefault : icon;
  const isChild = ele[propsDefault.children] && ele[propsDefault.children].length !== 0;
  if (!isChild) ele[propsDefault.children] = [];
  if (!isChild && first && !isURL(ele[propsDefault.path])) {
    ele[propsDefault.path] = ele[propsDefault.path] + '/index'
  } else {
    ele[propsDefault.children].forEach(child => {
      addPath(child);
    })
  }
function addPath (ele, first) {
    const menu = website.menu
    const propsConfig = menu.props
    const propsDefault = {
        label: propsConfig.label || 'name',
        path: propsConfig.path || 'path',
        icon: propsConfig.icon || 'icon',
        children: propsConfig.children || 'children'
    }
    const icon = ele[propsDefault.icon]
    ele[propsDefault.icon] = validatenull(icon) ? menu.iconDefault : icon
    const isChild = ele[propsDefault.children] && ele[propsDefault.children].length !== 0
    if (!isChild) ele[propsDefault.children] = []
    if (!isChild && first && !isURL(ele[propsDefault.path])) {
        ele[propsDefault.path] = ele[propsDefault.path] + '/index'
    } else {
        ele[propsDefault.children].forEach(child => {
            addPath(child)
        })
    }
}
const user = {
  state: {
    tenantId: getStore({name: 'tenantId'}) || '',
    userInfo: getStore({name: 'userInfo'}) || [],
    permission: getStore({name: 'permission'}) || {},
    roles: [],
    menuId: {},
    menu: getStore({name: 'menu'}) || [],
    menuAll: getStore({name: 'menuAll'}) || [],
    token: getStore({name: 'token'}) || '',
    refreshToken: getStore({name: 'refreshToken'}) || '',
  },
  actions: {
    //根据用户名登录
    LoginByUsername({commit}, userInfo) {
      return new Promise((resolve, reject) => {
        loginByUsername(userInfo.tenantId, userInfo.deptId, userInfo.roleId, userInfo.username, md5(userInfo.password), userInfo.type, userInfo.key, userInfo.code).then(res => {
          const data = res.data;
          if (data.error_description) {
            Message({
              message: data.error_description,
              type: 'error'
    state: {
        tenantId: getStore({ name: 'tenantId' }) || '',
        userInfo: getStore({ name: 'userInfo' }) || [],
        permission: getStore({ name: 'permission' }) || {},
        roles: [],
        menuId: {},
        menu: getStore({ name: 'menu' }) || [],
        menuAll: getStore({ name: 'menuAll' }) || [],
        token: getStore({ name: 'token' }) || '',
        refreshToken: getStore({ name: 'refreshToken' }) || '',
    },
    actions: {
        //根据用户名登录
        LoginByUsername ({ commit }, userInfo) {
            return new Promise((resolve, reject) => {
                loginByUsername(userInfo.tenantId, userInfo.deptId, userInfo.roleId, userInfo.username, md5(userInfo.password), userInfo.type, userInfo.key, userInfo.code).then(res => {
                    const data = res.data
                    if (data.error_description) {
                        Message({
                            message: data.error_description,
                            type: 'error'
                        })
                    } else {
                        commit('SET_TOKEN', data.access_token)
                        commit('SET_REFRESH_TOKEN', data.refresh_token)
                        commit('SET_TENANT_ID', data.tenant_id)
                        commit('SET_USER_INFO', data)
                        commit('DEL_ALL_TAG')
                        commit('CLEAR_LOCK')
                    }
                    resolve()
                }).catch(error => {
                    reject(error)
                })
            })
          } else {
            commit('SET_TOKEN', data.access_token);
            commit('SET_REFRESH_TOKEN', data.refresh_token);
            commit('SET_TENANT_ID', data.tenant_id);
            commit('SET_USER_INFO', data);
            commit('DEL_ALL_TAG');
            commit('CLEAR_LOCK');
          }
          resolve();
        }).catch(error => {
          reject(error);
        })
      })
    },
    //根据手机号登录
    LoginByPhone({commit}, userInfo) {
      return new Promise((resolve) => {
        loginByUsername(userInfo.phone, userInfo.code).then(res => {
          const data = res.data.data;
          commit('SET_TOKEN', data);
          commit('DEL_ALL_TAG');
          commit('CLEAR_LOCK');
          resolve();
        })
      })
    },
    //根据第三方信息登录
    LoginBySocial({commit}, userInfo) {
      return new Promise((resolve) => {
        loginBySocial(userInfo.tenantId, userInfo.source, userInfo.code, userInfo.state).then(res => {
          const data = res.data;
          if (data.error_description) {
            Message({
              message: data.error_description,
              type: 'error'
        },
        //根据手机号登录
        LoginByPhone ({ commit }, userInfo) {
            return new Promise((resolve) => {
                loginByUsername(userInfo.phone, userInfo.code).then(res => {
                    const data = res.data.data
                    commit('SET_TOKEN', data)
                    commit('DEL_ALL_TAG')
                    commit('CLEAR_LOCK')
                    resolve()
                })
            })
          } else {
            commit('SET_TOKEN', data.access_token);
            commit('SET_REFRESH_TOKEN', data.refresh_token);
            commit('SET_USER_INFO', data);
            commit('SET_TENANT_ID', data.tenant_id);
            commit('DEL_ALL_TAG');
            commit('CLEAR_LOCK');
          }
          resolve();
        })
      })
    },
    //根据单点信息登录
    LoginBySso({commit}, userInfo) {
      return new Promise((resolve) => {
        loginBySso(userInfo.state, userInfo.code).then(res => {
          const data = res.data;
          if (data.error_description) {
            Message({
              message: data.error_description,
              type: 'error'
        },
        //根据第三方信息登录
        LoginBySocial ({ commit }, userInfo) {
            return new Promise((resolve) => {
                loginBySocial(userInfo.tenantId, userInfo.source, userInfo.code, userInfo.state).then(res => {
                    const data = res.data
                    if (data.error_description) {
                        Message({
                            message: data.error_description,
                            type: 'error'
                        })
                    } else {
                        commit('SET_TOKEN', data.access_token)
                        commit('SET_REFRESH_TOKEN', data.refresh_token)
                        commit('SET_USER_INFO', data)
                        commit('SET_TENANT_ID', data.tenant_id)
                        commit('DEL_ALL_TAG')
                        commit('CLEAR_LOCK')
                    }
                    resolve()
                })
            })
          } else {
            commit('SET_TOKEN', data.access_token);
            commit('SET_REFRESH_TOKEN', data.refresh_token);
            commit('SET_USER_INFO', data);
            commit('SET_TENANT_ID', data.tenant_id);
            commit('DEL_ALL_TAG');
            commit('CLEAR_LOCK');
          }
          resolve();
        })
      })
        },
        //根据单点信息登录
        LoginBySso ({ commit }, userInfo) {
            return new Promise((resolve) => {
                loginBySso(userInfo.state, userInfo.code).then(res => {
                    const data = res.data
                    if (data.error_description) {
                        Message({
                            message: data.error_description,
                            type: 'error'
                        })
                    } else {
                        commit('SET_TOKEN', data.access_token)
                        commit('SET_REFRESH_TOKEN', data.refresh_token)
                        commit('SET_USER_INFO', data)
                        commit('SET_TENANT_ID', data.tenant_id)
                        commit('DEL_ALL_TAG')
                        commit('CLEAR_LOCK')
                    }
                    resolve()
                })
            })
        },
        //获取用户信息
        GetUserInfo ({ commit }) {
            return new Promise((resolve, reject) => {
                getUserInfo().then((res) => {
                    const data = res.data.data
                    commit('SET_ROLES', data.roles)
                    resolve(data)
                }).catch(err => {
                    reject(err)
                })
            })
        },
        //刷新token
        refreshToken ({ state, commit }, userInfo) {
            window.console.log('handle refresh token')
            return new Promise((resolve, reject) => {
                refreshToken(state.refreshToken, state.tenantId,
                    !validatenull(userInfo) ? userInfo.deptId : state.userInfo.dept_id,
                    !validatenull(userInfo) ? userInfo.roleId : state.userInfo.role_id
                ).then(res => {
                    const data = res.data
                    commit('SET_TOKEN', data.access_token)
                    commit('SET_REFRESH_TOKEN', data.refresh_token)
                    commit('SET_USER_INFO', data)
                    resolve()
                }).catch(error => {
                    reject(error)
                })
            })
        },
        // 登出
        LogOut ({ commit }) {
            return new Promise((resolve, reject) => {
                logout().then(() => {
                    commit('SET_TOKEN', '')
                    commit('SET_MENU', [])
                    commit('SET_MENU_ALL_NULL', [])
                    commit('SET_ROLES', [])
                    commit('SET_TAG_LIST', [])
                    commit('DEL_ALL_TAG')
                    commit('CLEAR_LOCK')
                    removeToken()
                    removeRefreshToken()
                    resolve()
                }).catch(error => {
                    reject(error)
                })
            })
        },
        //注销session
        FedLogOut ({ commit }) {
            return new Promise(resolve => {
                commit('SET_TOKEN', '')
                commit('SET_MENU_ALL_NULL', [])
                commit('SET_MENU', [])
                commit('SET_ROLES', [])
                commit('SET_TAG_LIST', [])
                commit('DEL_ALL_TAG')
                commit('CLEAR_LOCK')
                removeToken()
                removeRefreshToken()
                resolve()
            })
        },
        //获取顶部菜单
        GetTopMenu () {
            return new Promise(resolve => {
                getTopMenu().then((res) => {
                    const data = res.data.data || []
                    resolve(data)
                })
            })
        },
        //获取系统菜单
        GetMenu ({ commit, dispatch }, topMenuId) {
            return new Promise(resolve => {
                getRoutes(topMenuId).then((res) => {
                    const data = res.data.data
                    let menu = deepClone(data)
                    menu.forEach(ele => {
                        addPath(ele, true)
                    })
                    commit('SET_MENU_ALL', menu)
                    commit('SET_MENU', menu)
                    dispatch('GetButtons')
                    resolve(menu)
                })
            })
        },
        //获取系统按钮
        GetButtons ({ commit }) {
            return new Promise((resolve) => {
                getButtons().then(res => {
                    const data = res.data.data
                    commit('SET_PERMISSION', data)
                    resolve()
                })
            })
        },
    },
    //获取用户信息
    GetUserInfo({commit}) {
      return new Promise((resolve, reject) => {
        getUserInfo().then((res) => {
          const data = res.data.data;
          commit('SET_ROLES', data.roles);
          resolve(data);
        }).catch(err => {
          reject(err);
        })
      })
    },
    //刷新token
    refreshToken({state, commit}, userInfo) {
      window.console.log('handle refresh token');
      return new Promise((resolve, reject) => {
        refreshToken(state.refreshToken, state.tenantId,
          !validatenull(userInfo) ? userInfo.deptId : state.userInfo.dept_id,
          !validatenull(userInfo) ? userInfo.roleId : state.userInfo.role_id
        ).then(res => {
          const data = res.data;
          commit('SET_TOKEN', data.access_token);
          commit('SET_REFRESH_TOKEN', data.refresh_token);
          commit('SET_USER_INFO', data);
          resolve();
        }).catch(error => {
          reject(error)
        })
      })
    },
    // 登出
    LogOut({commit}) {
      return new Promise((resolve, reject) => {
        logout().then(() => {
          commit('SET_TOKEN', '');
          commit('SET_MENU', []);
          commit('SET_MENU_ALL_NULL', []);
          commit('SET_ROLES', []);
          commit('SET_TAG_LIST', []);
          commit('DEL_ALL_TAG');
          commit('CLEAR_LOCK');
          removeToken();
          removeRefreshToken();
          resolve();
        }).catch(error => {
          reject(error)
        })
      })
    },
    //注销session
    FedLogOut({commit}) {
      return new Promise(resolve => {
        commit('SET_TOKEN', '');
        commit('SET_MENU_ALL_NULL', []);
        commit('SET_MENU', []);
        commit('SET_ROLES', []);
        commit('SET_TAG_LIST', []);
        commit('DEL_ALL_TAG');
        commit('CLEAR_LOCK');
        removeToken();
        removeRefreshToken();
        resolve();
      })
    },
    //获取顶部菜单
    GetTopMenu() {
      return new Promise(resolve => {
        getTopMenu().then((res) => {
          const data = res.data.data || [];
          resolve(data)
        })
      })
    },
    //获取系统菜单
    GetMenu({commit, dispatch}, topMenuId) {
      return new Promise(resolve => {
        getRoutes(topMenuId).then((res) => {
          const data = res.data.data
          let menu = deepClone(data);
          menu.forEach(ele => {
            addPath(ele, true);
          });
          commit('SET_MENU_ALL', menu)
          commit('SET_MENU', menu)
          dispatch('GetButtons');
          resolve(menu)
        })
      })
    },
    //获取系统按钮
    GetButtons({commit}) {
      return new Promise((resolve) => {
        getButtons().then(res => {
          const data = res.data.data;
          commit('SET_PERMISSION', data);
          resolve();
        })
      })
    },
  },
  mutations: {
    SET_TOKEN: (state, token) => {
      setToken(token);
      state.token = token;
      setStore({name: 'token', content: state.token})
    },
    SET_MENU_ID(state, menuId) {
      state.menuId = menuId;
    },
    SET_MENU_ALL: (state, menuAll) => {
      let menu = state.menuAll;
      menuAll.forEach(ele => {
        if (!menu.find(item => item.label === ele.label && item.path === ele.path)) {
          menu.push(ele);
        }
      })
      state.menuAll = menu
      setStore({ name: 'menuAll', content: state.menuAll })
    },
    SET_MENU_ALL_NULL: (state) => {
      state.menuAll = []
      setStore({ name: 'menuAll', content: state.menuAll })
    },
    SET_MENU: (state, menu) => {
      state.menu = menu
      setStore({ name: 'menu', content: state.menu })
    },
    SET_REFRESH_TOKEN: (state, refreshToken) => {
      setRefreshToken(refreshToken)
      state.refreshToken = refreshToken;
      setStore({name: 'refreshToken', content: state.refreshToken})
    },
    SET_TENANT_ID: (state, tenantId) => {
      state.tenantId = tenantId;
      setStore({name: 'tenantId', content: state.tenantId})
    },
    SET_USER_INFO: (state, userInfo) => {
      if (validatenull(userInfo.avatar)) {
        userInfo.avatar = "/img/bg/img-logo.png";
      }
      state.userInfo = userInfo;
      setStore({name: 'userInfo', content: state.userInfo})
    },
    SET_ROLES: (state, roles) => {
      state.roles = roles;
    },
    SET_PERMISSION: (state, permission) => {
      let result = [];
      function getCode(list) {
        list.forEach(ele => {
          if (typeof (ele) === 'object') {
            const chiildren = ele.children;
            const code = ele.code;
            if (chiildren) {
              getCode(chiildren)
            } else {
              result.push(code);
    mutations: {
        SET_TOKEN: (state, token) => {
            setToken(token)
            state.token = token
            setStore({ name: 'token', content: state.token })
        },
        SET_MENU_ID (state, menuId) {
            state.menuId = menuId
        },
        SET_MENU_ALL: (state, menuAll) => {
            let menu = state.menuAll
            menuAll.forEach(ele => {
                if (!menu.find(item => item.label === ele.label && item.path === ele.path)) {
                    menu.push(ele)
                }
            })
            state.menuAll = menu
            setStore({ name: 'menuAll', content: state.menuAll })
        },
        SET_MENU_ALL_NULL: (state) => {
            state.menuAll = []
            setStore({ name: 'menuAll', content: state.menuAll })
        },
        SET_MENU: (state, menu) => {
            state.menu = menu
            setStore({ name: 'menu', content: state.menu })
        },
        SET_REFRESH_TOKEN: (state, refreshToken) => {
            setRefreshToken(refreshToken)
            state.refreshToken = refreshToken
            setStore({ name: 'refreshToken', content: state.refreshToken })
        },
        SET_TENANT_ID: (state, tenantId) => {
            state.tenantId = tenantId
            setStore({ name: 'tenantId', content: state.tenantId })
        },
        SET_USER_INFO: (state, userInfo) => {
            if (validatenull(userInfo.avatar)) {
                userInfo.avatar = "/img/bg/img-logo.png"
            }
          }
        })
      }
            state.userInfo = userInfo
            setStore({ name: 'userInfo', content: state.userInfo })
        },
        SET_ROLES: (state, roles) => {
            state.roles = roles
        },
        SET_PERMISSION: (state, permission) => {
            let result = []
      getCode(permission);
      state.permission = {};
      result.forEach(ele => {
        state.permission[ele] = true;
      });
      setStore({name: 'permission', content: state.permission})
            function getCode (list) {
                list.forEach(ele => {
                    if (typeof (ele) === 'object') {
                        const chiildren = ele.children
                        const code = ele.code
                        if (chiildren) {
                            getCode(chiildren)
                        } else {
                            result.push(code)
                        }
                    }
                })
            }
            getCode(permission)
            state.permission = {}
            result.forEach(ele => {
                state.permission[ele] = true
            })
            setStore({ name: 'permission', content: state.permission })
        }
    }
  }
}
export default user
src/styles/element-ui.scss
@@ -265,6 +265,7 @@
//多行输入
.el-textarea__inner {
  background-color: $inputB1 !important;
  color: #fff !important;
}
// 数字type input
src/util/store.js
@@ -55,7 +55,6 @@
    } else if (obj.dataType == 'object') {
        content = obj.content;
    }
    console.log(content,9999)
    return content;
}
/**
src/views/community/community.vue
@@ -18,7 +18,7 @@
               @size-change="sizeChange"
               @refresh-change="refreshChange"
               @on-load="onLoad">
      <template slot="menuLeft">
      <!-- <template slot="menuLeft">
        <el-button
                   size="small"
                   icon="el-icon-delete"
@@ -26,7 +26,7 @@
                   v-if="permission.community_delete"
                   @click="handleDelete">删 除
        </el-button>
      </template>
      </template> -->
    </avue-crud>
  </basic-container>
</template>
@@ -56,7 +56,11 @@
          border: true,
          index: true,
          viewBtn: true,
          selection: true,
          addBtn: false,
          editBtn: false,
          delBtn: false,
          // selection: true,
          menu:false,
          dialogClickModal: false,
          column: [
            {
@@ -208,7 +212,6 @@
    },
    methods: {
      rowSave(row, done, loading) {
        console.log(row,22222)
        add(row).then(() => {
          this.onLoad(this.page);
          this.$message({
@@ -222,7 +225,6 @@
        });
      },
      rowUpdate(row, index, done, loading) {
        console.log(row,22222)
        update(row).then(() => {
          this.onLoad(this.page);
          this.$message({
@@ -277,7 +279,7 @@
      beforeOpen(done, type) {
        if (["edit", "view"].includes(type)) {
          getDetails(this.form.id).then(res => {
            this.form = res.data.data;
              this.form = res.data.data;
          });
        }
        done();
src/views/houseStatistic/houseStatistic.vue
New file
@@ -0,0 +1,361 @@
<template>
  <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"
               @on-load="onLoad">
      <template slot="menuLeft">
        <el-button type="success"
                   size="small"
                   plain
                   icon="el-icon-upload2"
                   @click="handleImport">导入
        </el-button>
        <el-button type="danger"
                   size="small"
                   icon="el-icon-delete"
                   plain
                   v-if="permission.houseStatistic_delete"
                   @click="handleDelete">删 除
        </el-button>
      </template>
    </avue-crud>
    <el-dialog title="房屋数据导入"
               append-to-body
               :visible.sync="excelBox"
               width="555px">
      <avue-form :option="excelOption" v-model="excelForm" :upload-after="uploadAfter">
        <template slot="excelTemplate">
          <el-button type="primary" @click="handleTemplate">
            点击下载<i class="el-icon-download el-icon--right"></i>
          </el-button>
        </template>
      </avue-form>
    </el-dialog>
  </basic-container>
</template>
<script>
  import {getList, getDetail, add, update, remove} from "@/api/houseStatistic/houseStatistic";
  import {mapGetters} from "vuex";
  import {exportBlob} from "@/api/common";
  import {getToken} from "@/util/auth";
  import {downloadXls} from "@/util/util";
  export default {
    data() {
      return {
        form: {},
        query: {},
        loading: true,
        page: {
          pageSize: 10,
          currentPage: 1,
          total: 0
        },
        selectionList: [],
        excelBox: false,
        excelForm: {},
        excelOption: {
          submitBtn: false,
          emptyBtn: false,
          column: [
            {
              label: '模板上传',
              prop: 'excelFile',
              type: 'upload',
              drag: true,
              loadText: '模板上传中,请稍等',
              span: 24,
              propsHttp: {
                res: 'data'
              },
              tip: '请上传 .xls,.xlsx 标准格式文件',
              action: "/api/houseStatistic/houseStatistic/import-house-statistic"
            },
            {
              label: "数据覆盖",
              prop: "isCovered",
              type: "switch",
              align: "center",
              width: 80,
              dicData: [
                {
                  label: "否",
                  value: 0
                },
                {
                  label: "是",
                  value: 1
                }
              ],
              value: 0,
              slot: true,
              rules: [
                {
                  required: true,
                  message: "请选择是否覆盖",
                  trigger: "blur"
                }
              ]
            },
            {
              label: '模板下载',
              prop: 'excelTemplate',
              formslot: true,
              span: 24,
            }
          ]
        },
        option: {
          height:'auto',
          calcHeight: 30,
          tip: false,
          searchShow: true,
          searchMenuSpan: 6,
          border: true,
          index: true,
          viewBtn: true,
          selection: true,
          dialogClickModal: false,
          //隐藏操作栏
          menu:false,
          column: [
            {
              label: "主键",
              prop: "id",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
              hide: true,
            },
            {
              label: "派出所id",
              prop: "policeStationId",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
              hide: true,
            },
            {
              label: "派出所名称",
              prop: "policeStationName",
              type: "input",
              search:true,
              searchLabelWidth:110,
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
            },
            {
              label: "房屋类型id",
              prop: "type",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
              hide: true,
            },
            {
              label: "房屋类型名称",
              prop: "typeName",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
            },
            {
              label: "房屋数量",
              prop: "num",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
            },
            {
              label: "创建时间",
              prop: "createTime",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
              hide: true,
            },
          ]
        },
        data: []
      };
    },
    computed: {
      ...mapGetters(["permission"]),
      permissionList() {
        return {
          addBtn: this.vaildData(this.permission.houseStatistic_add, false),
          viewBtn: this.vaildData(this.permission.houseStatistic_view, false),
          delBtn: this.vaildData(this.permission.houseStatistic_delete, false),
          editBtn: this.vaildData(this.permission.houseStatistic_edit, false)
        };
      },
      ids() {
        let ids = [];
        this.selectionList.forEach(ele => {
          ids.push(ele.id);
        });
        return ids.join(",");
      }
    },
    watch: {
      'excelForm.isCovered'() {
        if (this.excelForm.isCovered !== '') {
          const column = this.findObject(this.excelOption.column, "excelFile");
          column.action = `/api/houseStatistic/houseStatistic/import-house-statistic?isCovered=${this.excelForm.isCovered}`;
        }
      }
    },
    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;
        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();
        });
      },
      //下面为导入操作
      handleImport() {
        this.excelBox = true;
      },
      uploadAfter(res, done, loading, column) {
        window.console.log(column);
        this.excelBox = false;
        this.refreshChange();
        done();
      },
      handleTemplate() {
        exportBlob(`/api/houseStatistic/houseStatistic/export-template?${this.website.tokenHeader}=${getToken()}`).then(res => {
          downloadXls(res.data, "房屋统计数据模板.xlsx");
        })
      },
    }
  };
</script>
<style>
</style>
src/views/policePost/policePost.vue
New file
@@ -0,0 +1,323 @@
<template>
  <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"
               @on-load="onLoad">
      <template slot="menuLeft">
        <el-button type="danger"
                   size="small"
                   icon="el-icon-delete"
                   plain
                   v-if="permission.policePost_delete"
                   @click="handleDelete">删 除
        </el-button>
      </template>
    </avue-crud>
  </basic-container>
</template>
<script>
  import {getPage, getDetail, add, update, remove} from "@/api/policePost/policePost";
  import {mapGetters} from "vuex";
  export default {
    data() {
      return {
        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,
          viewBtn: true,
          selection: true,
          dialogClickModal: false,
          menuWidth:250,
          column: [
            {
              label: "主键",
              prop: "id",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
              hide: true,
            },
            {
              label: "警务站名称",
              labelWidth:100,
              prop: "name",
              type: "input",
              search: true,
              searchLabelWidth:120,
              rules: [{
                required: true,
                message: "请输入警务站名称",
                trigger: "blur"
              }]
            },
            {
              label: "单位编号",
              prop: "unitCode",
              type: "input",
              search: true,
              rules: [{
                required: true,
                message: "请选输入单位编号",
                trigger: "blur"
              }]
            },
            {
              label: "关联派出所",
              labelWidth:100,
              prop: "policeStationId",
              type: "tree",
              multiple:true,
              dicUrl: "api/blade-system/dept/lazy-list",
              props:{
                label:'deptName',
                value:'id',
                children:'children'
              },
              leafOnly:"false",
              defaultExpandAll:true,
              // checkStrictly:true,
              // search: true,
              searchSpan:6,
              searchLabelWidth:120,
              rules: [{
                required: true,
                message: "请选择关联派出所",
                trigger: "blur"
              }]
            },
            {
              label: "创建人",
              prop: "createUser",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
              hide: true,
            },
            {
              label: "创建部门",
              prop: "createDept",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
              hide: true,
            },
            {
              label: "创建时间",
              prop: "createTime",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
              hide: true,
            },
            {
              label: "修改人",
              prop: "updateUser",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
              hide: true,
            },
            {
              label: "修改时间",
              prop: "updateTime",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
              hide: true,
            },
            {
              label: "状态",
              prop: "status",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
              hide: true,
            },
            {
              label: "是否已删除",
              prop: "isDeleted",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
              hide: true,
            },
          ]
        },
        data: []
      };
    },
    computed: {
      ...mapGetters(["permission"]),
      permissionList() {
        return {
          addBtn: this.vaildData(this.permission.policePost_add, false),
          viewBtn: this.vaildData(this.permission.policePost_view, false),
          delBtn: this.vaildData(this.permission.policePost_delete, false),
          editBtn: this.vaildData(this.permission.policePost_edit, false)
        };
      },
      ids() {
        let ids = [];
        this.selectionList.forEach(ele => {
          ids.push(ele.id);
        });
        return ids.join(",");
      }
    },
    methods: {
      rowSave(row, done, loading) {
        row.policeStationId = row.policeStationId.toString()
        add(row).then(() => {
          this.onLoad(this.page);
          this.$message({
            type: "success",
            message: "操作成功!"
          });
          done();
        }, error => {
          loading();
          window.console.log(error);
        });
      },
      rowUpdate(row, index, done, loading) {
        row.policeStationId = row.policeStationId.toString()
        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;
        getPage(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>
src/views/policeman/policeman.vue
@@ -1,241 +1,309 @@
<template>
  <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"
               @on-load="onLoad">
    <avue-crud :option="option" :table-loading="loading" :data="data" :page.sync="page" :permission="permissionList"
      :before-open="beforeOpen" v-model="form" ref="crud" @row-update="rowUpdate" @row-save="rowSave" @row-del="rowDel"
      @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange"
      @current-change="currentChange" @size-change="sizeChange" @refresh-change="refreshChange" @on-load="onLoad">
      <template slot="menuLeft">
        <el-button
                   size="small"
                   icon="el-icon-delete"
                   plain
                   v-if="permission.policeman_delete"
                   @click="handleDelete">删 除
        <el-button size="small" icon="el-icon-delete" plain v-if="permission.policeman_delete" @click="handleDelete">删 除
        </el-button>
        <el-button type="success" size="small" plain icon="el-icon-upload2" @click="handleImport">导入
        </el-button>
      </template>
    </avue-crud>
    <el-dialog title="数据导入" append-to-body :visible.sync="excelBox" width="555px">
      <avue-form :option="excelOption" v-model="excelForm" :upload-after="uploadAfter">
        <template slot="excelTemplate">
          <el-button type="primary" @click="handleTemplate">
            点击下载<i class="el-icon-download el-icon--right"></i>
          </el-button>
        </template>
      </avue-form>
    </el-dialog>
  </basic-container>
</template>
<script>
  import {getPage, getDetail, add, update, remove} from "@/api/policeman/policeman";
  import {mapGetters} from "vuex";
import { getPage, getDetail, add, update, remove } from "@/api/policeman/policeman";
import { mapGetters } from "vuex";
import { exportBlob } from "@/api/common";
import { downloadXls } from "@/util/util";
import { getToken } from "@/util/auth";
  export default {
    data() {
      return {
        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,
          viewBtn: true,
          selection: true,
          dialogClickModal: false,
          column: [
            {
              label: "警员名称",
              prop: "name",
              search: true,
              rules: [{
                required: true,
                message: "请输入警员名称",
                trigger: "blur"
              }]
export default {
  data() {
    return {
      form: {},
      query: {},
      loading: true,
      page: {
        pageSize: 10,
        currentPage: 1,
        total: 0
      },
      selectionList: [],
      excelBox: false,
      excelForm: {},
      excelOption: {
        submitBtn: false,
        emptyBtn: false,
        column: [
          {
            label: '模板上传',
            prop: 'excelFile',
            type: 'upload',
            drag: true,
            loadText: '模板上传中,请稍等',
            span: 24,
            propsHttp: {
              res: 'data'
            },
            {
              label: "警员编号",
              prop: "serialNumber",
            },
            {
              label: "联系方式",
              prop: "contact",
            },
            {
              label: "所属单位",
              prop: "deptId",
              type: "tree",
              dicUrl: "api/blade-system/dept/lazy-list",
              props:{
                label:'deptName',
                value:'id',
                children:'children'
            tip: '请上传 .xls,.xlsx 标准格式文件',
            action: "/api/policeman/policeman/import-policeman"
          },
          {
            label: "数据覆盖",
            prop: "isCovered",
            type: "switch",
            align: "center",
            width: 80,
            dicData: [
              {
                label: "否",
                value: 0
              },
              search: true,
              searchSpan:4,
              rules: [{
              {
                label: "是",
                value: 1
              }
            ],
            value: 0,
            slot: true,
            rules: [
              {
                required: true,
                message: "请选择所属单位",
                message: "请选择是否覆盖",
                trigger: "blur"
              }]
            },
          ]
        },
        data: []
              }
            ]
          },
          {
            label: '模板下载',
            prop: 'excelTemplate',
            formslot: true,
            span: 24,
          }
        ]
      },
      option: {
        height: 'auto',
        calcHeight: 30,
        tip: false,
        searchShow: true,
        searchMenuSpan: 6,
        border: true,
        index: true,
        viewBtn: true,
        addBtn: false,
        editBtn: false,
        selection: true,
        dialogClickModal: false,
        column: [
          {
            label: "警员名称",
            prop: "name",
            search: true,
            searchSpan: 4,
            rules: [{
              required: true,
              message: "请输入警员名称",
              trigger: "blur"
            }]
          },
          {
            label: "警员编号",
            prop: "serialNumber",
          },
          {
            label: "联系方式",
            prop: "contact",
          },
          {
            label: "单位编号",
            prop: "deptCode",
            search: true,
            searchSpan: 4,
          },
          {
            label: "单位名称",
            prop: "deptName",
            search: true,
            searchSpan: 4,
          },
        ]
      },
      data: []
    };
  },
  computed: {
    ...mapGetters(["userInfo", "permission"]),
    permissionList() {
      return {
        addBtn: this.vaildData(this.permission.policeman_add, false),
        viewBtn: this.vaildData(this.permission.policeman_view, false),
        delBtn: this.vaildData(this.permission.policeman_delete, false),
        editBtn: this.vaildData(this.permission.policeman_edit, false)
      };
    },
    computed: {
      ...mapGetters(["userInfo","permission"]),
      permissionList() {
        return {
          addBtn: this.vaildData(this.permission.policeman_add, false),
          viewBtn: this.vaildData(this.permission.policeman_view, false),
          delBtn: this.vaildData(this.permission.policeman_delete, false),
          editBtn: this.vaildData(this.permission.policeman_edit, false)
        };
      },
      ids() {
        let ids = [];
        this.selectionList.forEach(ele => {
          ids.push(ele.id);
        });
        return ids.join(",");
    ids() {
      let ids = [];
      this.selectionList.forEach(ele => {
        ids.push(ele.id);
      });
      return ids.join(",");
    }
  },
  watch: {
    'excelForm.isCovered'() {
      if (this.excelForm.isCovered !== '') {
        const column = this.findObject(this.excelOption.column, "excelFile");
        column.action = `/api/policeman/policeman/import-policeman?isCovered=${this.excelForm.isCovered}`;
      }
    },
    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 = {};
  },
  methods: {
    rowSave(row, done, loading) {
      add(row).then(() => {
        this.onLoad(this.page);
      },
      searchChange(params, done) {
        this.query = params;
        this.page.currentPage = 1;
        this.onLoad(this.page, params);
        this.$message({
          type: "success",
          message: "操作成功!"
        });
        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;
        if (this.userInfo.role_name != "admin" && this.userInfo.role_name != "administrator"){
          params["jurisdiction"] = this.userInfo.dept_id;
        }
        getPage(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();
      }, 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;
      if (this.userInfo.role_name != "admin" && this.userInfo.role_name != "administrator") {
        params["jurisdiction"] = this.userInfo.dept_id;
      }
      getPage(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();
      });
    },
    //下面为导入操作
    handleImport() {
      this.excelBox = true;
    },
    uploadAfter(res, done, loading, column) {
      window.console.log(column);
      this.excelBox = false;
      this.refreshChange();
      done();
    },
    handleTemplate() {
      exportBlob(`/api/policeman/policeman/export-template?${this.website.tokenHeader}=${getToken()}`).then(res => {
        downloadXls(res.data, "警员信息数据模板.xlsx");
      })
    },
  }
};
</script>
<style>
</style>
<style></style>
src/views/range/range.vue
@@ -29,7 +29,7 @@
      </template>
      <template slot-scope="{type,size,row,index}" slot="menu">
        <el-button icon="el-icon-view" :size="size" :type="type"  @click="handleDetail(row)">地 图</el-button>
        <el-button icon="el-icon-edit" v-if="permission.range_edit" :size="size" :type="type" @click="$refs.crud.rowEdit(row,index)">编 辑</el-button>
        <!-- <el-button icon="el-icon-edit" v-if="permission.range_edit" :size="size" :type="type" @click="$refs.crud.rowEdit(row,index)">编 辑</el-button> -->
        <el-button icon="el-icon-delete" v-if="permission.range_delete" :size="size" :type="type" @click="$refs.crud.rowDel(row,index)">删 除</el-button>
      </template>
    </avue-crud>
@@ -41,7 +41,8 @@
      size="60%"
      direction="rtl"
      :before-close="handleClose">
      <map-box v-if="isDetail" :is-detail="isDetail" :route-range="routeRange"></map-box>
<!--      <map-box v-if="isDetail" :is-detail="isDetail" :route-range="routeRange"></map-box>-->
      <dc-map ref="dcMap" v-if="isDetail" :is-detail="isDetail" :range="routeRange"></dc-map>
    </el-drawer>
  </basic-container>
</template>
@@ -50,9 +51,10 @@
  import {getList, getDetail, add, update, remove} from "@/api/range/range";
  import {mapGetters} from "vuex";
  import MapBox from "@/components/map/mapBox";
  import DcMap from "@/components/map/dcMap";
  export default {
    components: {MapBox},
    components: {DcMap, MapBox},
    data() {
      return {
        form: {},
@@ -77,6 +79,7 @@
          viewBtn: false,
          delBtn: false,
          editBtn: false,
          addBtn: false,
          selection: true,
          excelBtn: true,
          dialogClickModal: false,
src/views/realEstate/realEstate.vue
New file
@@ -0,0 +1,392 @@
<template>
  <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"
               @on-load="onLoad">
      <template slot="menuLeft">
        <el-button type="success"
                   size="small"
                   plain
                   icon="el-icon-upload2"
                   @click="handleImport">导入
        </el-button>
        <el-button type="danger"
                   size="small"
                   icon="el-icon-delete"
                   plain
                   v-if="permission.realEstate_delete"
                   @click="handleDelete">删 除
        </el-button>
      </template>
    </avue-crud>
    <el-dialog title="楼盘数据导入"
               append-to-body
               :visible.sync="excelBox"
               width="555px">
      <avue-form :option="excelOption" v-model="excelForm" :upload-after="uploadAfter">
        <template slot="excelTemplate">
          <el-button type="primary" @click="handleTemplate">
            点击下载<i class="el-icon-download el-icon--right"></i>
          </el-button>
        </template>
      </avue-form>
    </el-dialog>
  </basic-container>
</template>
<script>
  import {getList, getDetail, add, update, remove} from "@/api/realEstate/realEstate";
  import {mapGetters} from "vuex";
  import {exportBlob} from "@/api/common";
  import {getToken} from "@/util/auth";
  import {downloadXls} from "@/util/util";
  export default {
    data() {
      return {
        form: {},
        query: {},
        loading: true,
        page: {
          pageSize: 10,
          currentPage: 1,
          total: 0
        },
        selectionList: [],
        excelBox: false,
        excelForm: {},
        excelOption: {
          submitBtn: false,
          emptyBtn: false,
          column: [
            {
              label: '模板上传',
              prop: 'excelFile',
              type: 'upload',
              drag: true,
              loadText: '模板上传中,请稍等',
              span: 24,
              propsHttp: {
                res: 'data'
              },
              tip: '请上传 .xls,.xlsx 标准格式文件',
              action: "/api/realEstate/realEstate/import-realEstate"
            },
            {
              label: "数据覆盖",
              prop: "isCovered",
              type: "switch",
              align: "center",
              width: 80,
              dicData: [
                {
                  label: "否",
                  value: 0
                },
                {
                  label: "是",
                  value: 1
                }
              ],
              value: 0,
              slot: true,
              rules: [
                {
                  required: true,
                  message: "请选择是否覆盖",
                  trigger: "blur"
                }
              ]
            },
            {
              label: '模板下载',
              prop: 'excelTemplate',
              formslot: true,
              span: 24,
            }
          ]
        },
        option: {
          height:'auto',
          calcHeight: 30,
          tip: false,
          searchShow: true,
          searchMenuSpan: 6,
          border: true,
          index: true,
          viewBtn: true,
          selection: true,
          dialogClickModal: false,
          menu:false,
          column: [
            {
              label: "主键",
              prop: "id",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
              hide: true,
            },
            {
              label: "区",
              prop: "county",
              type: "input",
            },
            {
              label: "类型",
              prop: "type",
              type: "input",
            },
            {
              label: "小区名称",
              prop: "aoi",
              search:true,
              type: "input",
            },
            {
              label: "楼栋",
              prop: "building",
              type: "input",
            },
            {
              label: "地址",
              prop: "address",
              type: "input",
            },
            {
              label: "aoi-id",
              prop: "aoiId",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
            },
            {
              label: "楼栋id",
              prop: "buildingId",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
              hide: true,
            },
            {
              label: "x2000",
              prop: "x2000",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
            },
            {
              label: "y2000",
              prop: "y2000",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
            },
            {
              label: "bgId",
              prop: "bgId",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
            },
            {
              label: "创建时间",
              prop: "createTime",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
            },
            {
              label: "md5Id",
              prop: "md5Id",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
            },
          ]
        },
        data: []
      };
    },
    computed: {
      ...mapGetters(["permission"]),
      permissionList() {
        return {
          addBtn: this.vaildData(this.permission.realEstate_add, false),
          viewBtn: this.vaildData(this.permission.realEstate_view, false),
          delBtn: this.vaildData(this.permission.realEstate_delete, false),
          editBtn: this.vaildData(this.permission.realEstate_edit, false)
        };
      },
      ids() {
        let ids = [];
        this.selectionList.forEach(ele => {
          ids.push(ele.id);
        });
        return ids.join(",");
      }
    },
    watch: {
      'excelForm.isCovered'() {
        if (this.excelForm.isCovered !== '') {
          const column = this.findObject(this.excelOption.column, "excelFile");
          column.action = `/api/realEstate/realEstate/import-realEstate?isCovered=${this.excelForm.isCovered}`;
        }
      }
    },
    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;
        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();
        });
      },
      //下面为导入操作
      handleImport() {
        this.excelBox = true;
      },
      uploadAfter(res, done, loading, column) {
        window.console.log(column);
        this.excelBox = false;
        this.refreshChange();
        done();
      },
      handleTemplate() {
        exportBlob(`/api/realEstate/realEstate/export-template?${this.website.tokenHeader}=${getToken()}`).then(res => {
          downloadXls(res.data, "楼盘统计数据模板.xlsx");
        })
      },
    }
  };
</script>
<style>
</style>
src/views/scheduling/scheduling.vue
@@ -1,283 +1,351 @@
<template>
  <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"
               @on-load="onLoad">
    <avue-crud :option="option" :table-loading="loading" :data="data" :page.sync="page" :permission="permissionList"
      :before-open="beforeOpen" v-model="form" ref="crud" @row-update="rowUpdate" @row-save="rowSave" @row-del="rowDel"
      @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange"
      @current-change="currentChange" @size-change="sizeChange" @refresh-change="refreshChange" @on-load="onLoad">
      <template slot="menuLeft">
        <el-button
                   size="small"
                   icon="el-icon-delete"
                   plain
                   v-if="permission.scheduling_delete"
                   @click="handleDelete">删 除
        <el-button size="small" icon="el-icon-delete" plain v-if="permission.scheduling_delete" @click="handleDelete">删 除
        </el-button>
        <el-button type="success" size="small" plain icon="el-icon-upload2" @click="handleImport">导入
        </el-button>
      </template>
    </avue-crud>
    <el-dialog title="数据导入" append-to-body :visible.sync="excelBox" width="555px">
      <avue-form :option="excelOption" v-model="excelForm" :upload-after="uploadAfter">
        <template slot="excelTemplate">
          <el-button type="primary" @click="handleTemplate">
            点击下载<i class="el-icon-download el-icon--right"></i>
          </el-button>
        </template>
      </avue-form>
    </el-dialog>
  </basic-container>
</template>
<script>
  import {getList, getDetail, add, update, remove, getPliceman} from "@/api/scheduling/scheduling";
  import {mapGetters} from "vuex";
import { getList, getDetail, add, update, remove, getPliceman } from "@/api/scheduling/scheduling";
import { mapGetters } from "vuex";
import { exportBlob } from "@/api/common";
import { downloadXls } from "@/util/util";
import { getToken } from "@/util/auth";
  export default {
    data() {
      return {
        form: {},
        query: {},
        loading: true,
        page: {
          pageSize: 10,
          currentPage: 1,
          total: 0
        },
        selectionList: [],
        option: {
          height: 'auto',
          calcHeight: 30,
          dialogWidth: 950,
          tip: false,
          searchShow: true,
          searchMenuSpan: 6,
          border: true,
          index: true,
          viewBtn: true,
          selection: true,
          excelBtn: true,
          dialogClickModal: false,
          column: [
            {
              label: "值班员",
              prop: "person",
              search:true,
              type: "select",
              dicUrl: "/api/policeman/policeman/all",
              props: {
                label: "name",
                value: "id"
export default {
  data() {
    return {
      form: {},
      query: {},
      loading: true,
      page: {
        pageSize: 10,
        currentPage: 1,
        total: 0
      },
      selectionList: [],
      excelBox: false,
      excelForm: {},
      excelOption: {
        submitBtn: false,
        emptyBtn: false,
        column: [
          {
            label: '模板上传',
            prop: 'excelFile',
            type: 'upload',
            drag: true,
            loadText: '模板上传中,请稍等',
            span: 24,
            propsHttp: {
              res: 'data'
            },
            tip: '请上传 .xls,.xlsx 标准格式文件',
            action: "/api/scheduling/scheduling/import-scheduling"
          },
          {
            label: "数据覆盖",
            prop: "isCovered",
            type: "switch",
            align: "center",
            width: 80,
            dicData: [
              {
                label: "否",
                value: 0
              },
              {
                label: "是",
                value: 1
              }
            },
            {
              label: "联系方式",
              prop: "contact",
            },
            {
              label: "值班岗位",
              prop: "station",
              row: true,
              span: 24
            },
            {
              label: "值班时间",
              prop: "startTime",
              type: "datetime",
              defaultTime: '00:00:00',
              format: "yyyy-MM-dd",
              valueFormat: "yyyy-MM-dd HH:mm:ss",
              rules: [{
            ],
            value: 0,
            slot: true,
            rules: [
              {
                required: true,
                message: "请选择值班时间",
                message: "请选择是否覆盖",
                trigger: "blur"
              }],
            },
            {
              label: "带班领导",
              prop: "leads",
              type: "select",
              dicUrl: "/api/policeman/policeman/all",
              props: {
                label: "name",
                value: "id"
              }
            },
            {
              label: "联系方式",
              prop: "leadContact",
            },
          ]
        },
        data: [],
        policemanList: []
            ]
          },
          {
            label: '模板下载',
            prop: 'excelTemplate',
            formslot: true,
            span: 24,
          }
        ]
      },
      option: {
        height: 'auto',
        calcHeight: 30,
        dialogWidth: 950,
        tip: false,
        searchShow: true,
        searchMenuSpan: 6,
        border: true,
        index: true,
        viewBtn: true,
        addBtn: false,
        editBtn: false,
        selection: true,
        excelBtn: true,
        dialogClickModal: false,
        column: [
          {
            label: "值班单位",
            prop: "dept",
            row: true,
            span: 24
          },
          {
            label: "值班日期",
            prop: "day",
            type: "date",
            format: "yyyy-MM-dd",
            valueFormat: "yyyy-MM-dd",
            rules: [{
              required: true,
              message: "请选择值班日期",
              trigger: "blur"
            }],
          },
          {
            label: "值班员",
            prop: "person",
            search: true,
          },
          {
            label: "联系方式",
            prop: "contact",
          },
          {
            label: "值班类型",
            prop: "type",
          },
          {
            label: "带班领导",
            prop: "leads",
            type: "select",
            dicUrl: "/api/policeman/policeman/all",
            props: {
              label: "name",
              value: "id"
            }
          },
          {
            label: "联系方式",
            prop: "leadContact",
          },
        ]
      },
      data: [],
      policemanList: []
    };
  },
  computed: {
    ...mapGetters(["permission"]),
    permissionList() {
      return {
        addBtn: this.vaildData(this.permission.scheduling_add, false),
        viewBtn: this.vaildData(this.permission.scheduling_view, false),
        delBtn: this.vaildData(this.permission.scheduling_delete, false),
        editBtn: this.vaildData(this.permission.scheduling_edit, false)
      };
    },
    computed: {
      ...mapGetters(["permission"]),
      permissionList() {
        return {
          addBtn: this.vaildData(this.permission.scheduling_add, false),
          viewBtn: this.vaildData(this.permission.scheduling_view, false),
          delBtn: this.vaildData(this.permission.scheduling_delete, false),
          editBtn: this.vaildData(this.permission.scheduling_edit, false)
        };
      },
      ids() {
        let ids = [];
        this.selectionList.forEach(ele => {
          ids.push(ele.id);
        });
        return ids.join(",");
      }
    },
    watch: {
      'form.person': {
        handler(res) {
          this.policemanList.forEach(e => {
            if (res == e.id) {
              this.form.contact = e.contact
            }
          })
        }
      },
      'form.leads': {
        handler(res) {
          this.policemanList.forEach(e => {
            if (res == e.id) {
              this.form.leadContact = e.contact
            }
          })
        }
      },
    },
    created() {
      this.getPolicemanAll();
    },
    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;
        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();
        });
      },
      getPolicemanAll() {
        getPliceman().then(res => {
          this.policemanList = res.data.data
          const securityIdColumn = this.findObject(this.option.column, "person")
          securityIdColumn.dicData = this.policemanList
          const securityIdColumns = this.findObject(this.option.column, "leads")
          securityIdColumns.dicData = this.policemanList
        })
      }
    ids() {
      let ids = [];
      this.selectionList.forEach(ele => {
        ids.push(ele.id);
      });
      return ids.join(",");
    }
  };
  },
  watch: {
    'form.person': {
      handler(res) {
        this.policemanList.forEach(e => {
          if (res == e.id) {
            this.form.contact = e.contact
          }
        })
      }
    },
    'form.leads': {
      handler(res) {
        this.policemanList.forEach(e => {
          if (res == e.id) {
            this.form.leadContact = e.contact
          }
        })
      }
    },
    'excelForm.isCovered'() {
      if (this.excelForm.isCovered !== '') {
        const column = this.findObject(this.excelOption.column, "excelFile");
        column.action = `/api/scheduling/scheduling/import-scheduling?isCovered=${this.excelForm.isCovered}`;
      }
    },
  },
  created() {
    this.getPolicemanAll();
  },
  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;
      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();
      });
    },
    getPolicemanAll() {
      getPliceman().then(res => {
        this.policemanList = res.data.data
        const securityIdColumn = this.findObject(this.option.column, "person")
        securityIdColumn.dicData = this.policemanList
        const securityIdColumns = this.findObject(this.option.column, "leads")
        securityIdColumns.dicData = this.policemanList
      })
    },
    //下面为导入操作
    handleImport() {
      this.excelBox = true;
    },
    uploadAfter(res, done, loading, column) {
      window.console.log(column);
      this.excelBox = false;
      this.refreshChange();
      done();
    },
    handleTemplate() {
      exportBlob(`/api/scheduling/scheduling/export-template?${this.website.tokenHeader}=${getToken()}`).then(res => {
        downloadXls(res.data, "值班信息数据模板.xlsx");
      })
    },
  }
};
</script>
<style>
</style>
<style></style>
src/views/security/security.vue
@@ -1,17 +1,28 @@
<template>
  <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" @on-load="onLoad">
               :before-open="beforeOpen" v-model="form" ref="crud" @row-update="rowUpdate" @row-save="rowSave"
               @row-del="rowDel" @search-change="searchChange" @search-reset="searchReset"
               @selection-change="selectionChange" @current-change="currentChange" @size-change="sizeChange"
               @refresh-change="refreshChange" @on-load="onLoad">
      <template slot="menuLeft">
        <el-button size="small" icon="el-icon-delete" plain v-if="permission.security_delete" @click="handleDelete">删 除
        <el-button size="small" icon="el-icon-delete" plain v-if="permission.security_delete"
                   @click="handleDelete">删 除
        </el-button>
      </template>
      <template slot-scope="{type,size,row,index}" slot="menu">
        <el-button icon="el-icon-coordinate" :size="size" :type="type" @click="handlePersonList(row)">活动人员</el-button>
        <el-button icon="el-icon-data-line" :size="size" :type="type" @click="handleCarList(row)">活动车辆</el-button>
        <el-button icon="el-icon-coordinate" :size="size" :type="type"
                   @click="handlePersonList(row)">活动人员
        </el-button>
        <el-button icon="el-icon-data-line" :size="size" :type="type"
                   @click="handleCarList(row)">活动车辆
        </el-button>
      </template>
      <template slot="activityAreaForm">
<!--        <map-box ref="OpenLayersMap" @toData="toData" :routeRange="form.activityArea"></map-box>-->
        <dc-map ref="dcMap" @toData="toData" :range="form.activityArea"></dc-map>
      </template>
    </avue-crud>
    <el-drawer title="活动人员区域" :visible.sync="personBox" :append-to-body="true" size="50%" :destroy-on-close="true">
@@ -21,27 +32,48 @@
    <el-drawer title="活动车辆区域" :visible.sync="carBox" :append-to-body="true" size="50%" :destroy-on-close="true">
      <securityManageCar ref="car" :securityId="securityId"/>
    </el-drawer>
    <el-dialog
      title="提示"
      :visible.sync="placeBox"
      append-to-body
      destroy-on-close
      width="70%">
      <search-map @getLonLat="getLonLat" @getAddress="getAddress" :point-lon-lat="point"></search-map>
      <span slot="footer" class="dialog-footer">
            <el-button type="primary" @click="confirmLonLat">确 定</el-button>
          </span>
    </el-dialog>
  </basic-container>
</template>
<script>
import { getPage, getDetail, add, update, remove } from "@/api/security/security";
import { getUserInfos } from "@/api/system/user";
import {getPage, getDetail, add, update, remove} from "@/api/security/security"
import {getUserInfos} from "@/api/system/user"
// import AvueMap from 'avue-plugin-map';
import { mapGetters } from "vuex";
import {mapGetters} from "vuex"
import securityManage from "@/views/securityManage/securityManage"
import securityManageCar from "@/views/securityManageCar/securityManageCar"
import MapBox from "@/components/map/mapBox";
import SearchMap from "@/components/map/searchMap";
import DcMap from "@/components/map/dcMap";
export default {
  components: {
    DcMap,
    SearchMap,
    MapBox,
    securityManage,
    securityManageCar
  },
  data() {
    return {
      securityId:"",
      securityId: "",
      carBox: false,
      personBox: false,
      placeBox: false,
      point:"",
      chosePoint:{},
      form: {},
      query: {},
      loading: true,
@@ -72,40 +104,94 @@
            prop: "name",
            search: true,
            searchSpan: 4,
            rules: [{
              required: true,
              message: "请输入活动名称",
              trigger: "blur"
            }],
            overHidden:true,
          },
          {
            label: "负责单位",
            prop: "company",
            hide:true,
          },
          {
            label: "负责人",
            prop: "person",
            width: 80
            width: 80,
            rules: [{
              required: true,
              message: "请输入负责人",
              trigger: "blur"
            }],
          },
          {
            label: "联系方式",
            prop: "contact",
            width: 100
            width: 100,
            rules: [{
              required: true,
              message: "请输入联系方式",
              trigger: "blur"
            }],
          },
          {
            label: "活动地点",
            prop: "place",
            // addDisplay: false,
            // editDisplay: false,
            // viewDisplay: false,
            span: 24,
            click: () => {
              this.placeBox = !this.placeBox
            },
            overHidden:true,
          },
          {
            label: "经度",
            prop: "longitude",
            span: 12,
            hide: true,
            disabled:true,
            rules: [{
              required: true,
              message: "请输入纬度",
              trigger: "blur"
            }],
          },
          {
            label: "纬度",
            prop: "latitude",
            span: 12,
            hide: true,
            disabled: true,
            rules: [{
              required: true,
              message: "请输入纬度",
              trigger: "blur"
            }],
          },
          {
            label: "活动区域",
            prop: "activityArea",
            type: "input",
            hide: true,
            span: 24,
            display: true,
            addDisplay: true
          },
          {
            label: "所属辖区",
            prop: "deptId",
            type: "tree",
            dicUrl: "api/blade-system/dept/lazy-list",
            dicUrl: "api/blade-system/dept/getPoliceStationTree",
            props: {
              label: 'deptName',
              label: 'name',
              value: 'id',
              children: 'children'
            },
            search: true,
            searchSpan: 4,
            span: 24,
            defaultExpandAll:"true",
            width: 110,
            rules: [{
              required: true,
@@ -146,17 +232,6 @@
            }],
            width: 120,
          },
          {
            label: "活动内容",
            prop: "content",
          },
          {
            label: "经纬度",
            prop: "position",
            type: "input",
            span: 12,
            hide: true
          },
          // {
          //   label: "",
          //   prop: "map",
@@ -168,11 +243,6 @@
          //   // display:false,
          //   component: "AvueMap",
          // },
          {
            label: "人数",
            prop: "number",
            width: 60,
          },
          {
            label: "活动类型",
            prop: "type",
@@ -189,10 +259,27 @@
            }],
            width: 90,
          },
          {
            label: "人数",
            prop: "number",
            width: 60,
            rules: [{
              required: true,
              message: "请输入人数",
              trigger: "blur"
            }],
          },
          {
            label: "活动内容",
            prop: "content",
            type: "textarea",
            span: 24,
            hide:true,
          },
        ]
      },
      data: []
    };
    }
  },
  // watch: {
  //   //latitude   longitude   formattedAddress
@@ -213,58 +300,70 @@
        viewBtn: this.vaildData(this.permission.security_view, false),
        delBtn: this.vaildData(this.permission.security_delete, false),
        editBtn: this.vaildData(this.permission.security_edit, false)
      };
      }
    },
    ids() {
      let ids = [];
      let ids = []
      this.selectionList.forEach(ele => {
        ids.push(ele.id);
      });
      return ids.join(",");
        ids.push(ele.id)
      })
      return ids.join(",")
    }
  },
  created(){
    const tokenLength = window.location.href.indexOf('=');
    if(tokenLength>0){
  created() {
    const tokenLength = window.location.href.indexOf('=')
    if (tokenLength > 0) {
      //取“=”之后的token
      let z = window.location.href.substring(tokenLength + 1)
      this.$store.commit('SET_TOKEN', z);
      this.$store.commit('DEL_ALL_TAG');
      this.$store.commit('CLEAR_LOCK');
      this.getUserInfo()
    }
  },
  methods: {
    getUserInfo(){
      getUserInfos().then(res=>{
         this.$store.commit('SET_USER_INFO', res.data.data);
    getUserInfo() {
      getUserInfos().then(res => {
        const data = res.data
        this.$store.commit('SET_TOKEN', data.access_token)
        this.$store.commit('SET_REFRESH_TOKEN', data.refresh_token)
        this.$store.commit('SET_TENANT_ID', data.tenant_id)
        this.$store.commit('SET_USER_INFO', data)
        this.$store.commit('DEL_ALL_TAG')
        this.$store.commit('CLEAR_LOCK')
      })
    },
    rowSave(row, done, loading) {
      row.position = row.longitude + " " + row.latitude
      add(row).then(() => {
        this.onLoad(this.page);
        this.onLoad(this.page)
        this.$message({
          type: "success",
          message: "操作成功!"
        });
        done();
        })
        done()
      }, error => {
        loading();
        window.console.log(error);
      });
        loading()
        window.console.log(error)
      })
    },
    rowUpdate(row, index, done, loading) {
      if (!row.activityArea) {
        this.$message.warning("请绘制活动区域")
        loading()
        return
      }
      if (!row.activityArea.startsWith("'LINESTRING")){
        row.activityArea = "'LINESTRING("+row.activityArea+")'"
      }
      row.position = row.longitude + " " + row.latitude
      update(row).then(() => {
        this.onLoad(this.page);
        this.onLoad(this.page)
        this.$message({
          type: "success",
          message: "操作成功!"
        });
        done();
        })
        done()
      }, error => {
        loading();
        console.log(error);
      });
        loading()
        console.log(error)
      })
    },
    rowDel(row) {
      this.$confirm("确定将选择数据删除?", {
@@ -273,20 +372,20 @@
        type: "warning"
      })
        .then(() => {
          return remove(row.id);
          return remove(row.id)
        })
        .then(() => {
          this.onLoad(this.page);
          this.onLoad(this.page)
          this.$message({
            type: "success",
            message: "操作成功!"
          });
        });
          })
        })
    },
    handleDelete() {
      if (this.selectionList.length === 0) {
        this.$message.warning("请选择至少一条数据");
        return;
        this.$message.warning("请选择至少一条数据")
        return
      }
      this.$confirm("确定将选择数据删除?", {
        confirmButtonText: "确定",
@@ -294,78 +393,108 @@
        type: "warning"
      })
        .then(() => {
          return remove(this.ids);
          return remove(this.ids)
        })
        .then(() => {
          this.onLoad(this.page);
          this.onLoad(this.page)
          this.$message({
            type: "success",
            message: "操作成功!"
          });
          this.$refs.crud.toggleSelection();
        });
          })
          this.$refs.crud.toggleSelection()
        })
    },
    beforeOpen(done, type) {
      if (["edit", "view"].includes(type)) {
        getDetail(this.form.id).then(res => {
          this.form = res.data.data;
        });
          var data = res.data.data
          this.form = data
          this.form['longitude'] = data.position.split(" ")[0]
          this.form['latitude'] = data.position.split(" ")[1]
          this.point = "POINT("+this.form.longitude +" "+this.form.latitude+")"
          this.$refs.dcMap.showPolygon(this.form.activityArea)
        })
      }
      done();
      done()
    },
    searchReset() {
      this.query = {};
      this.onLoad(this.page);
      this.query = {}
      this.onLoad(this.page)
    },
    searchChange(params, done) {
      this.query = params;
      this.page.currentPage = 1;
      this.onLoad(this.page, params);
      done();
      this.query = params
      this.page.currentPage = 1
      this.onLoad(this.page, params)
      done()
    },
    selectionChange(list) {
      this.selectionList = list;
      this.selectionList = list
    },
    selectionClear() {
      this.selectionList = [];
      this.$refs.crud.toggleSelection();
      this.selectionList = []
      this.$refs.crud.toggleSelection()
    },
    currentChange(currentPage) {
      this.page.currentPage = currentPage;
      this.page.currentPage = currentPage
    },
    sizeChange(pageSize) {
      this.page.pageSize = pageSize;
      this.page.pageSize = pageSize
    },
    refreshChange() {
      this.onLoad(this.page, this.query);
      this.onLoad(this.page, this.query)
    },
    onLoad(page, params = {}) {
      this.loading = true;
      this.loading = true
      if (this.userInfo.role_name != "admin" && this.userInfo.role_name != "administrator") {
        params["jurisdiction"] = this.userInfo.dept_id;
        params["jurisdiction"] = this.userInfo.dept_id
      }
      getPage(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();
      });
        const data = res.data.data
        this.page.total = data.total
        this.data = data.records
        this.loading = false
        this.selectionClear()
      })
    },
    //活动人员区域点击按钮事件
    handlePersonList(row) {
      this.personBox = true;
      this.personBox = true
      this.securityId = row.id
    },
    //活动车辆区域点击按钮事件
    handleCarList(row) {
      this.carBox = true;
      this.carBox = true
      this.securityId = row.id
    },
    //地图传回的polygon坐标
    toData(data) {
      this.form.activityArea = data
    },
    getLonLat(data){
      this.chosePoint.longitude = data[0]
      this.chosePoint.latitude = data[1]
    },
    getAddress(data){
      this.chosePoint.address = data
    },
    confirmLonLat(){
      if(this.chosePoint.longitude){
        this.form.longitude =  this.chosePoint.longitude
        this.form.latitude =  this.chosePoint.latitude
        this.form.place = this.chosePoint.address
        this.point = "POINT("+this.form.longitude +" "+this.form.latitude+")"
        this.placeBox = false
      }else {
        this.$alert('该点没有位置信息,请重新选点!', '提示', {
          confirmButtonText: '确定',
        });
      }
    }
  }
};
}
</script>
<style>
src/views/securityManage/securityManage.vue
@@ -11,8 +11,8 @@
      </template>
      <template slot-scope="{type,size,row,index}" slot="menu">
        <el-button icon="el-icon-view" :size="size" :type="type" @click="handleDetail(row)">地 图</el-button>
        <el-button icon="el-icon-edit" v-if="permission.range_edit" :size="size" :type="type"
          @click="$refs.crud.rowEdit(row, index)">编 辑</el-button>
        <!-- <el-button icon="el-icon-edit" v-if="permission.range_edit" :size="size" :type="type"
          @click="$refs.crud.rowEdit(row, index)">编 辑</el-button> -->
        <el-button icon="el-icon-delete" v-if="permission.range_delete" :size="size" :type="type"
          @click="$refs.crud.rowDel(row, index)">删 除</el-button>
      </template>
@@ -58,6 +58,7 @@
        viewBtn: false,
        delBtn: false,
        editBtn: false,
        addBtn:false,
        selection: true,
        dialogClickModal: false,
        column: [
@@ -93,9 +94,10 @@
            prop: "deptId",
            type: "tree",
            disabled: true,
            dicUrl: "api/blade-system/dept/lazy-list",
            dicUrl: "api/blade-system/dept/getPoliceStationTree",
            defaultExpandAll:"true",
            props: {
              label: 'deptName',
              label: 'name',
              value: 'id',
              children: 'children'
            },
src/views/securityManageCar/securityManageCar.vue
@@ -11,8 +11,8 @@
      </template>
      <template slot-scope="{type,size,row,index}" slot="menu">
        <el-button icon="el-icon-view" :size="size" :type="type" @click="handleDetail(row)">地 图</el-button>
        <el-button icon="el-icon-edit" v-if="permission.range_edit" :size="size" :type="type"
          @click="$refs.crud.rowEdit(row, index)">编 辑</el-button>
        <!-- <el-button icon="el-icon-edit" v-if="permission.range_edit" :size="size" :type="type"
          @click="$refs.crud.rowEdit(row, index)">编 辑</el-button> -->
        <el-button icon="el-icon-delete" v-if="permission.range_delete" :size="size" :type="type"
          @click="$refs.crud.rowDel(row, index)">删 除</el-button>
      </template>
@@ -59,6 +59,7 @@
        viewBtn: false,
        delBtn: false,
        editBtn: false,
        addBtn:false,
        selection: true,
        dialogClickModal: false,
        column: [
@@ -101,9 +102,10 @@
            label: "所属辖区",
            prop: "deptId",
            type: "tree",
            dicUrl: "api/blade-system/dept/lazy-list",
            dicUrl: "api/blade-system/dept/getPoliceStationTree",
            defaultExpandAll:"true",
            props: {
              label: 'deptName',
              label: 'name',
              value: 'id',
              children: 'children'
            },
src/views/system/dept.vue
@@ -179,6 +179,15 @@
              }]
            },
            {
              label: "单位编号",
              prop: "code",
              rules: [{
                required: true,
                message: "请输入单位编号",
                trigger: "blur"
              }]
            },
            {
              label: "排序",
              prop: "sort",
              type: "number",
@@ -193,6 +202,7 @@
            {
              label: "备注",
              prop: "remark",
              span:24,
              rules: [{
                required: false,
                message: "请输入备注",
src/views/system/user.vue
@@ -1,173 +1,101 @@
<template>
  <el-row>
    <el-col :span="5">
      <div class="box">
        <el-scrollbar>
          <basic-container>
            <avue-tree :option="treeOption" :data="treeData" @node-click="nodeClick"/>
          </basic-container>
        </el-scrollbar>
      </div>
    </el-col>
    <el-col :span="19">
      <basic-container>
        <avue-crud :option="option"
                   :search.sync="search"
                   :table-loading="loading"
                   :data="data"
                   ref="crud"
                   v-model="form"
                   :defaults.sync="defaults"
                   :permission="permissionList"
                   @row-del="rowDel"
                   @row-update="rowUpdate"
                   @row-save="rowSave"
                   :before-open="beforeOpen"
                   :page.sync="page"
                   @search-change="searchChange"
                   @search-reset="searchReset"
                   @selection-change="selectionChange"
                   @current-change="currentChange"
                   @size-change="sizeChange"
                   @refresh-change="refreshChange"
                   @on-load="onLoad">
          <template slot="menuLeft">
            <el-button
                       size="small"
                       plain
                       icon="el-icon-delete"
                       v-if="permission.user_delete"
                       @click="handleDelete">删 除
            </el-button>
            <el-button
                       size="small"
                       plain
                       v-if="permission.user_role"
                       icon="el-icon-user"
                       @click="handleGrant">角色配置
            </el-button>
            <el-button
                       size="small"
                       plain
                       v-if="permission.user_reset"
                       icon="el-icon-refresh"
                       @click="handleReset">密码重置
            </el-button>
            <el-button
                       size="small"
                       plain
                       v-if="userInfo.role_name.indexOf('admin')"
                       icon="el-icon-setting"
                       @click="handlePlatform">平台配置
            </el-button>
            <el-button
                       size="small"
                       plain
                       v-if="userInfo.role_name.indexOf('admin')"
                       icon="el-icon-coordinate"
                       @click="handleLock">账号解封
            </el-button>
            <el-button
                       size="small"
                       plain
                       v-if="userInfo.role_name.indexOf('admin')"
                       icon="el-icon-upload2"
                       @click="handleImport">导入
            </el-button>
            <el-button
                       size="small"
                       plain
                       v-if="userInfo.role_name.indexOf('admin')"
                       icon="el-icon-download"
                       @click="handleExport">导出
            </el-button>
          </template>
          <template slot-scope="{row}"
                    slot="tenantName">
            <el-tag>{{row.tenantName}}</el-tag>
          </template>
          <template slot-scope="{row}"
                    slot="roleName">
            <el-tag>{{row.roleName}}</el-tag>
          </template>
          <template slot-scope="{row}"
                    slot="deptName">
            <el-tag>{{row.deptName}}</el-tag>
          </template>
          <template slot-scope="{row}"
                    slot="userTypeName">
            <el-tag>{{row.userTypeName}}</el-tag>
          </template>
        </avue-crud>
        <el-dialog title="用户角色配置"
                   append-to-body
                   :visible.sync="roleBox"
                   width="345px">
    <el-row>
        <el-col :span="5">
            <div class="box">
                <el-scrollbar>
                    <basic-container>
                        <avue-tree :option="treeOption" :data="treeData" @node-click="nodeClick" />
                    </basic-container>
                </el-scrollbar>
            </div>
        </el-col>
        <el-col :span="19">
            <basic-container>
                <avue-crud :option="option" :search.sync="search" :table-loading="loading" :data="data" ref="crud"
                    v-model="form" :defaults.sync="defaults" :permission="permissionList" @row-del="rowDel"
                    @row-update="rowUpdate" @row-save="rowSave" :before-open="beforeOpen" :page.sync="page"
                    @search-change="searchChange" @search-reset="searchReset" @selection-change="selectionChange"
                    @current-change="currentChange" @size-change="sizeChange" @refresh-change="refreshChange"
                    @on-load="onLoad">
                    <template slot="menuLeft">
                        <el-button size="small" plain icon="el-icon-delete" v-if="permission.user_delete"
                            @click="handleDelete">删 除
                        </el-button>
                        <el-button size="small" plain v-if="permission.user_role" icon="el-icon-user"
                            @click="handleGrant">角色配置
                        </el-button>
                        <el-button size="small" plain v-if="permission.user_reset" icon="el-icon-refresh"
                            @click="handleReset">密码重置
                        </el-button>
                        <el-button size="small" plain v-if="userInfo.role_name.indexOf('admin')" icon="el-icon-setting"
                            @click="handlePlatform">平台配置
                        </el-button>
                        <el-button size="small" plain v-if="userInfo.role_name.indexOf('admin')"
                            icon="el-icon-coordinate" @click="handleLock">账号解封
                        </el-button>
                        <el-button size="small" plain v-if="userInfo.role_name.indexOf('admin')" icon="el-icon-upload2"
                            @click="handleImport">导入
                        </el-button>
                        <el-button size="small" plain v-if="userInfo.role_name.indexOf('admin')" icon="el-icon-download"
                            @click="handleExport">导出
                        </el-button>
                    </template>
                    <template slot-scope="{row}" slot="tenantName">
                        <el-tag>{{ row.tenantName }}</el-tag>
                    </template>
                    <template slot-scope="{row}" slot="roleName">
                        <el-tag>{{ row.roleName }}</el-tag>
                    </template>
                    <template slot-scope="{row}" slot="deptName">
                        <el-tag>{{ row.deptName }}</el-tag>
                    </template>
                    <template slot-scope="{row}" slot="userTypeName">
                        <el-tag>{{ row.userTypeName }}</el-tag>
                    </template>
                </avue-crud>
                <el-dialog title="用户角色配置" append-to-body :visible.sync="roleBox" width="345px">
          <el-tree :data="roleGrantList"
                   show-checkbox
                   check-strictly
                   default-expand-all
                   node-key="id"
                   ref="treeRole"
                   :default-checked-keys="roleTreeObj"
                   :props="props">
          </el-tree>
                    <el-tree :data="roleGrantList" show-checkbox check-strictly default-expand-all node-key="id"
                        ref="treeRole" :default-checked-keys="roleTreeObj" :props="props">
                    </el-tree>
          <span slot="footer" class="dialog-footer">
            <el-button @click="roleBox = false">取 消</el-button>
            <el-button type="primary"
                       @click="submitRole">确 定</el-button>
          </span>
        </el-dialog>
        <el-dialog title="用户数据导入"
                   append-to-body
                   :visible.sync="excelBox"
                   width="555px">
          <avue-form :option="excelOption" v-model="excelForm" :upload-after="uploadAfter">
            <template slot="excelTemplate">
              <el-button type="primary" @click="handleTemplate">
                点击下载<i class="el-icon-download el-icon--right"></i>
              </el-button>
            </template>
          </avue-form>
        </el-dialog>
        <el-dialog title="用户平台配置"
                   append-to-body
                   :visible.sync="platformBox">
          <avue-crud :option="platformOption"
                     :table-loading="platformLoading"
                     :data="platformData"
                     ref="platformCrud"
                     v-model="platformForm"
                     :before-open="platformBeforeOpen"
                     :page.sync="platformPage"
                     :permission="platformPermissionList"
                     @row-update="platformRowUpdate"
                     @search-change="platformSearchChange"
                     @search-reset="platformSearchReset"
                     @selection-change="platformSelectionChange"
                     @current-change="platformCurrentChange"
                     @size-change="platformSizeChange"
                     @refresh-change="platformRefreshChange"
                     @on-load="platformOnLoad">
            <template slot-scope="{row}"
                      slot="tenantName">
              <el-tag>{{row.tenantName}}</el-tag>
            </template>
            <template slot-scope="{row}"
                      slot="userTypeName">
              <el-tag>{{row.userTypeName}}</el-tag>
            </template>
          </avue-crud>
        </el-dialog>
      </basic-container>
    </el-col>
  </el-row>
                    <span slot="footer" class="dialog-footer">
                        <el-button @click="roleBox = false">取 消</el-button>
                        <el-button type="primary" @click="submitRole">确 定</el-button>
                    </span>
                </el-dialog>
                <el-dialog title="用户数据导入" append-to-body :visible.sync="excelBox" width="555px">
                    <avue-form :option="excelOption" v-model="excelForm" :upload-after="uploadAfter">
                        <template slot="excelTemplate">
                            <el-button type="primary" @click="handleTemplate">
                                点击下载<i class="el-icon-download el-icon--right"></i>
                            </el-button>
                        </template>
                    </avue-form>
                </el-dialog>
                <el-dialog title="用户平台配置" append-to-body :visible.sync="platformBox">
                    <avue-crud :option="platformOption" :table-loading="platformLoading" :data="platformData"
                        ref="platformCrud" v-model="platformForm" :before-open="platformBeforeOpen"
                        :page.sync="platformPage" :permission="platformPermissionList" @row-update="platformRowUpdate"
                        @search-change="platformSearchChange" @search-reset="platformSearchReset"
                        @selection-change="platformSelectionChange" @current-change="platformCurrentChange"
                        @size-change="platformSizeChange" @refresh-change="platformRefreshChange"
                        @on-load="platformOnLoad">
                        <template slot-scope="{row}" slot="tenantName">
                            <el-tag>{{ row.tenantName }}</el-tag>
                        </template>
                        <template slot-scope="{row}" slot="userTypeName">
                            <el-tag>{{ row.userTypeName }}</el-tag>
                        </template>
                    </avue-crud>
                </el-dialog>
            </basic-container>
        </el-col>
    </el-row>
</template>
<script>
  import {
import {
    getList,
    getUser,
    getUserPlatform,
@@ -177,881 +105,881 @@
    add,
    grant,
    resetPassword, unlock
  } from "@/api/system/user";
  import {exportBlob} from "@/api/common";
  import {getDeptTree, getDeptLazyTree} from "@/api/system/dept";
  import {getRoleTree} from "@/api/system/role";
  import {getPostList} from "@/api/system/post";
  import {mapGetters} from "vuex";
  import website from '@/config/website';
  import {getToken} from '@/util/auth';
  import {downloadXls} from "@/util/util";
  import {dateNow} from "@/util/date";
  import NProgress from 'nprogress';
  import 'nprogress/nprogress.css';
  import func from "@/util/func";
} from "@/api/system/user"
import { exportBlob } from "@/api/common"
import { getDeptTree, getDeptLazyTree } from "@/api/system/dept"
import { getRoleTree } from "@/api/system/role"
//   import {getPostList} from "@/api/system/post";
import { mapGetters } from "vuex"
import website from '@/config/website'
import { getToken } from '@/util/auth'
import { downloadXls } from "@/util/util"
import { dateNow } from "@/util/date"
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import func from "@/util/func"
  export default {
    data() {
      const validatePass = (rule, value, callback) => {
        if (value === '') {
          callback(new Error('请输入密码'));
        } else {
          callback();
        }
      };
      const validatePass2 = (rule, value, callback) => {
        if (value === '') {
          callback(new Error('请再次输入密码'));
        } else if (value !== this.form.password) {
          callback(new Error('两次输入密码不一致!'));
        } else {
          callback();
        }
      };
      return {
        form: {},
        search:{},
        roleBox: false,
        excelBox: false,
        platformBox: false,
        initFlag: true,
        selectionList: [],
        query: {},
        loading: true,
        platformLoading: false,
        page: {
          pageSize: 10,
          currentPage: 1,
          total: 0
        },
        platformPage: {
          pageSize: 10,
          currentPage: 1,
          total: 0
        },
        init: {
          roleTree: [],
          deptTree: [],
        },
        props: {
          label: "title",
          value: "key"
        },
        roleGrantList: [],
        roleTreeObj: [],
        treeDeptId: '',
        treeData: [],
        treeOption: {
          nodeKey: 'id',
          lazy: true,
          treeLoad: function (node, resolve) {
            const parentId = (node.level === 0) ? 0 : node.data.id;
            getDeptLazyTree(parentId).then(res => {
              resolve(res.data.data.map(item => {
                return {
                  ...item,
                  leaf: !item.hasChildren
                }
              }))
            });
          },
          addBtn: false,
          menu: false,
          size: 'small',
          props: {
            labelText: '标题',
            label: 'title',
            value: 'value',
            children: 'children'
          }
        },
        option: {
          height: 'auto',
          calcHeight: 80,
          tip: false,
          searchShow: true,
          searchMenuSpan: 6,
          border: true,
          index: true,
          selection: true,
          menuWidth:250,
          viewBtn: true,
          dialogType: 'drawer',
          dialogClickModal: false,
          column: [
            {
              label: "登录账号",
              prop: "account",
              search: true,
              display: false
            },
            {
              label: "所属租户",
              prop: "tenantName",
              slot: true,
              display: false,
              hide: true
            },
            {
              label: "用户姓名",
              prop: "realName",
              search: true,
              display: false
            },
            {
              label: "所属角色",
              prop: "roleName",
              slot: true,
              display: false
            },
            {
              label: "所属单位",
              prop: "deptName",
              slot: true,
              display: false
            },
            {
              label: "用户平台",
              prop: "userTypeName",
              slot: true,
              display: false
            },
            {
              label: "用户平台",
              type: "select",
              dicUrl: "/api/blade-system/dict/dictionary?code=user_type",
              props: {
                label: "dictValue",
                value: "dictKey"
              },
              dataType: "number",
              search: true,
              hide: true,
              display: false,
              prop: "userType",
              rules: [{
                required: true,
                message: "请选择用户平台",
                trigger: "blur"
              }]
            },
          ],
          group: [
            {
              label: '基础信息',
              prop: 'baseInfo',
              icon: 'el-icon-user-solid',
              column: [
                {
                  label: "所属租户",
                  prop: "tenantId",
                  type: "tree",
                  dicUrl: "/api/blade-system/tenant/select",
                  props: {
                    label: "tenantName",
                    value: "tenantId"
                  },
                  hide: !website.tenantMode,
                  addDisplay: website.tenantMode,
                  editDisplay: website.tenantMode,
                  viewDisplay: website.tenantMode,
                  rules: [{
                    required: true,
                    message: "请输入所属租户",
                    trigger: "click"
                  }],
                  span: 24,
                },
                {
                  label: "登录账号",
                  prop: "account",
                  rules: [{
                    required: true,
                    message: "请输入登录账号",
                    trigger: "blur"
                  }],
                },
                {
                  label: "用户平台",
                  type: "select",
                  dicUrl: "/api/blade-system/dict/dictionary?code=user_type",
                  props: {
                    label: "dictValue",
                    value: "dictKey"
                  },
                  dataType: "number",
                  slot: true,
                  prop: "userType",
                  rules: [{
                    required: true,
                    message: "请选择用户平台",
                    trigger: "blur"
                  }]
                },
                {
                  label: '密码',
                  prop: 'password',
                  hide: true,
                  editDisplay: false,
                  viewDisplay: false,
                  rules: [{required: true, validator: validatePass, trigger: 'blur'}]
                },
                {
                  label: '确认密码',
                  prop: 'password2',
                  hide: true,
                  editDisplay: false,
                  viewDisplay: false,
                  rules: [{required: true, validator: validatePass2, trigger: 'blur'}]
                },
              ]
            },
            {
              label: '详细信息',
              prop: 'detailInfo',
              icon: 'el-icon-s-order',
              column: [
                {
                  label: "用户昵称",
                  prop: "name",
                  hide: true,
                  rules: [{
                    required: true,
                    message: "请输入用户昵称",
                    trigger: "blur"
                  }]
                },
                {
                  label: "用户姓名",
                  prop: "realName",
                  rules: [{
                    required: true,
                    message: "请输入用户姓名",
                    trigger: "blur"
                  }, {
                    min: 2,
                    max: 10,
                    message: '姓名长度在2到5个字符'
                  }]
                },
                {
                  label: "手机号码",
                  prop: "phone",
                  overHidden: true
                },
                {
                  label: "电子邮箱",
                  prop: "email",
                  hide: true,
                  overHidden: true
                },
                {
                  label: "用户性别",
                  prop: "sex",
                  type: "select",
                  dicData: [
                    {
                      label: "男",
                      value: 1
                    },
                    {
                      label: "女",
                      value: 2
                    },
                    {
                      label: "未知",
                      value: 3
                    }
                  ],
                  hide: true
                },
                {
                  label: "用户生日",
                  type: "date",
                  prop: "birthday",
                  format: "yyyy-MM-dd hh:mm:ss",
                  valueFormat: "yyyy-MM-dd hh:mm:ss",
                  hide: true
                },
                {
                  label: "账号状态",
                  prop: "statusName",
                  hide: true,
                  display: false
                }
              ]
            },
            {
              label: '职责信息',
              prop: 'dutyInfo',
              icon: 'el-icon-s-custom',
              column: [
                {
                  label: "用户编号",
                  prop: "code",
                },
                {
                  label: "所属角色",
                  prop: "roleId",
                  multiple: true,
                  type: "tree",
                  dicData: [],
                  props: {
                    label: "title"
                  },
                  /*control:() =>{
                    if (this.userInfo.role_name.indexOf("administrator")){
                      debugger
                      return{
                        roleId:{
                          disabled:true
                        }
                      }
                    }
                  },*/
                  checkStrictly: true,
                  slot: true,
                  rules: [{
                    required: true,
                    message: "请选择所属角色",
                    trigger: "click"
                  }]
                },
                {
                  label: "所属单位",
                  prop: "deptId",
                  type: "tree",
                  multiple: true,
                  dicData: [],
                  props: {
                    label: "title"
                  },
                  checkStrictly: true,
                  slot: true,
                  rules: [{
                    required: true,
                    message: "请选择所属单位",
                    trigger: "click"
                  }]
                },
/*                {
                  label: "所属岗位",
                  prop: "postId",
                  type: "tree",
                  multiple: true,
                  dicData: [],
                  props: {
                    label: "postName",
                    value: "id"
                  },
                  rules: [{
                    required: true,
                    message: "请选择所属岗位",
                    trigger: "click"
                  }],
                },*/
              ]
            },
          ]
        },
        data: [],
        platformQuery: {},
        platformSelectionList: [],
        platformData: [],
        platformForm: {},
        platformOption: {
          tip: false,
          searchShow: true,
          searchMenuSpan: 6,
          border: true,
          index: true,
          selection: true,
          viewBtn: true,
          dialogClickModal: false,
          menuWidth: 120,
          editBtnText: '配置',
          column: [
            {
              label: "登录账号",
              prop: "account",
              search: true,
              display: false
            },
            {
              label: "所属租户",
              prop: "tenantName",
              slot: true,
              display: false
            },
            {
              label: "用户姓名",
              prop: "realName",
              search: true,
              display: false
            },
            {
              label: "用户平台",
              prop: "userTypeName",
              slot: true,
              display: false
            },
            {
              label: "用户平台",
              type: "select",
              dicUrl: "/api/blade-system/dict/dictionary?code=user_type",
              props: {
                label: "dictValue",
                value: "dictKey"
              },
              dataType: "number",
              search: true,
              hide: true,
              display: false,
              prop: "userType",
              rules: [{
                required: true,
                message: "请选择用户平台",
                trigger: "blur"
              }]
            },
            {
              label: "用户拓展",
              prop: "userExt",
              type: "textarea",
              minRows: 8,
              span: 24,
              overHidden: true,
              row: true,
              hide: true,
            },
          ],
        },
        excelForm: {},
        excelOption: {
          submitBtn: false,
          emptyBtn: false,
          column: [
            {
              label: '模板上传',
              prop: 'excelFile',
              type: 'upload',
              drag: true,
              loadText: '模板上传中,请稍等',
              span: 24,
              propsHttp: {
                res: 'data'
              },
              tip: '请上传 .xls,.xlsx 标准格式文件',
              action: "/api/blade-user/import-user"
            },
            {
              label: "数据覆盖",
              prop: "isCovered",
              type: "switch",
              align: "center",
              width: 80,
              dicData: [
                {
                  label: "否",
                  value: 0
                },
                {
                  label: "是",
                  value: 1
                }
              ],
              value: 0,
              slot: true,
              rules: [
                {
                  required: true,
                  message: "请选择是否覆盖",
                  trigger: "blur"
                }
              ]
            },
            {
              label: '模板下载',
              prop: 'excelTemplate',
              formslot: true,
              span: 24,
export default {
    data () {
        const validatePass = (rule, value, callback) => {
            if (value === '') {
                callback(new Error('请输入密码'))
            } else {
                callback()
            }
          ]
        }
      };
        const validatePass2 = (rule, value, callback) => {
            if (value === '') {
                callback(new Error('请再次输入密码'))
            } else if (value !== this.form.password) {
                callback(new Error('两次输入密码不一致!'))
            } else {
                callback()
            }
        }
        return {
            form: {},
            search: {},
            roleBox: false,
            excelBox: false,
            platformBox: false,
            initFlag: true,
            selectionList: [],
            query: {},
            loading: true,
            platformLoading: false,
            page: {
                pageSize: 10,
                currentPage: 1,
                total: 0
            },
            platformPage: {
                pageSize: 10,
                currentPage: 1,
                total: 0
            },
            init: {
                roleTree: [],
                deptTree: [],
            },
            props: {
                label: "title",
                value: "key"
            },
            roleGrantList: [],
            roleTreeObj: [],
            treeDeptId: '',
            treeData: [],
            treeOption: {
                nodeKey: 'id',
                lazy: true,
                treeLoad: function (node, resolve) {
                    const parentId = (node.level === 0) ? 0 : node.data.id
                    getDeptLazyTree(parentId).then(res => {
                        resolve(res.data.data.map(item => {
                            return {
                                ...item,
                                leaf: !item.hasChildren
                            }
                        }))
                    })
                },
                addBtn: false,
                menu: false,
                size: 'small',
                props: {
                    labelText: '标题',
                    label: 'title',
                    value: 'value',
                    children: 'children'
                }
            },
            option: {
                height: 'auto',
                calcHeight: 80,
                tip: false,
                searchShow: true,
                searchMenuSpan: 6,
                border: true,
                index: true,
                selection: true,
                menuWidth: 250,
                viewBtn: true,
                dialogType: 'drawer',
                dialogClickModal: false,
                column: [
                    {
                        label: "登录账号",
                        prop: "account",
                        search: true,
                        display: false
                    },
                    {
                        label: "所属租户",
                        prop: "tenantName",
                        slot: true,
                        display: false,
                        hide: true
                    },
                    {
                        label: "用户姓名",
                        prop: "realName",
                        search: true,
                        display: false
                    },
                    {
                        label: "所属角色",
                        prop: "roleName",
                        slot: true,
                        display: false
                    },
                    {
                        label: "所属单位",
                        prop: "deptName",
                        slot: true,
                        display: false
                    },
                    {
                        label: "用户平台",
                        prop: "userTypeName",
                        slot: true,
                        display: false
                    },
                    {
                        label: "用户平台",
                        type: "select",
                        dicUrl: "/api/blade-system/dict/dictionary?code=user_type",
                        props: {
                            label: "dictValue",
                            value: "dictKey"
                        },
                        dataType: "number",
                        search: true,
                        hide: true,
                        display: false,
                        prop: "userType",
                        rules: [{
                            required: true,
                            message: "请选择用户平台",
                            trigger: "blur"
                        }]
                    },
                ],
                group: [
                    {
                        label: '基础信息',
                        prop: 'baseInfo',
                        icon: 'el-icon-user-solid',
                        column: [
                            {
                                label: "所属租户",
                                prop: "tenantId",
                                type: "tree",
                                dicUrl: "/api/blade-system/tenant/select",
                                props: {
                                    label: "tenantName",
                                    value: "tenantId"
                                },
                                hide: !website.tenantMode,
                                addDisplay: website.tenantMode,
                                editDisplay: website.tenantMode,
                                viewDisplay: website.tenantMode,
                                rules: [{
                                    required: true,
                                    message: "请输入所属租户",
                                    trigger: "click"
                                }],
                                span: 24,
                            },
                            {
                                label: "登录账号",
                                prop: "account",
                                rules: [{
                                    required: true,
                                    message: "请输入登录账号",
                                    trigger: "blur"
                                }],
                            },
                            {
                                label: "用户平台",
                                type: "select",
                                dicUrl: "/api/blade-system/dict/dictionary?code=user_type",
                                props: {
                                    label: "dictValue",
                                    value: "dictKey"
                                },
                                dataType: "number",
                                slot: true,
                                prop: "userType",
                                rules: [{
                                    required: true,
                                    message: "请选择用户平台",
                                    trigger: "blur"
                                }]
                            },
                            {
                                label: '密码',
                                prop: 'password',
                                hide: true,
                                editDisplay: false,
                                viewDisplay: false,
                                rules: [{ required: true, validator: validatePass, trigger: 'blur' }]
                            },
                            {
                                label: '确认密码',
                                prop: 'password2',
                                hide: true,
                                editDisplay: false,
                                viewDisplay: false,
                                rules: [{ required: true, validator: validatePass2, trigger: 'blur' }]
                            },
                        ]
                    },
                    {
                        label: '详细信息',
                        prop: 'detailInfo',
                        icon: 'el-icon-s-order',
                        column: [
                            {
                                label: "用户昵称",
                                prop: "name",
                                hide: true,
                                rules: [{
                                    required: true,
                                    message: "请输入用户昵称",
                                    trigger: "blur"
                                }]
                            },
                            {
                                label: "用户姓名",
                                prop: "realName",
                                rules: [{
                                    required: true,
                                    message: "请输入用户姓名",
                                    trigger: "blur"
                                }, {
                                    min: 2,
                                    max: 10,
                                    message: '姓名长度在2到5个字符'
                                }]
                            },
                            {
                                label: "手机号码",
                                prop: "phone",
                                overHidden: true
                            },
                            {
                                label: "电子邮箱",
                                prop: "email",
                                hide: true,
                                overHidden: true
                            },
                            {
                                label: "用户性别",
                                prop: "sex",
                                type: "select",
                                dicData: [
                                    {
                                        label: "男",
                                        value: 1
                                    },
                                    {
                                        label: "女",
                                        value: 2
                                    },
                                    {
                                        label: "未知",
                                        value: 3
                                    }
                                ],
                                hide: true
                            },
                            {
                                label: "用户生日",
                                type: "date",
                                prop: "birthday",
                                format: "yyyy-MM-dd hh:mm:ss",
                                valueFormat: "yyyy-MM-dd hh:mm:ss",
                                hide: true
                            },
                            {
                                label: "账号状态",
                                prop: "statusName",
                                hide: true,
                                display: false
                            }
                        ]
                    },
                    {
                        label: '职责信息',
                        prop: 'dutyInfo',
                        icon: 'el-icon-s-custom',
                        column: [
                            {
                                label: "用户编号",
                                prop: "code",
                            },
                            {
                                label: "所属角色",
                                prop: "roleId",
                                // multiple: true,
                                type: "tree",
                                dicData: [],
                                props: {
                                    label: "title"
                                },
                                /*control:() =>{
                                  if (this.userInfo.role_name.indexOf("administrator")){
                                    debugger
                                    return{
                                      roleId:{
                                        disabled:true
                                      }
                                    }
                                  }
                                },*/
                                checkStrictly: true,
                                slot: true,
                                rules: [{
                                    required: true,
                                    message: "请选择所属角色",
                                    trigger: "click"
                                }]
                            },
                            {
                                label: "所属单位",
                                prop: "deptId",
                                type: "tree",
                                // multiple: true,
                                dicData: [],
                                props: {
                                    label: "title"
                                },
                                checkStrictly: true,
                                slot: true,
                                rules: [{
                                    required: true,
                                    message: "请选择所属单位",
                                    trigger: "click"
                                }]
                            },
                            /*                {
                                              label: "所属岗位",
                                              prop: "postId",
                                              type: "tree",
                                              multiple: true,
                                              dicData: [],
                                              props: {
                                                label: "postName",
                                                value: "id"
                                              },
                                              rules: [{
                                                required: true,
                                                message: "请选择所属岗位",
                                                trigger: "click"
                                              }],
                                            },*/
                        ]
                    },
                ]
            },
            data: [],
            platformQuery: {},
            platformSelectionList: [],
            platformData: [],
            platformForm: {},
            platformOption: {
                tip: false,
                searchShow: true,
                searchMenuSpan: 6,
                border: true,
                index: true,
                selection: true,
                viewBtn: true,
                dialogClickModal: false,
                menuWidth: 120,
                editBtnText: '配置',
                column: [
                    {
                        label: "登录账号",
                        prop: "account",
                        search: true,
                        display: false
                    },
                    {
                        label: "所属租户",
                        prop: "tenantName",
                        slot: true,
                        display: false
                    },
                    {
                        label: "用户姓名",
                        prop: "realName",
                        search: true,
                        display: false
                    },
                    {
                        label: "用户平台",
                        prop: "userTypeName",
                        slot: true,
                        display: false
                    },
                    {
                        label: "用户平台",
                        type: "select",
                        dicUrl: "/api/blade-system/dict/dictionary?code=user_type",
                        props: {
                            label: "dictValue",
                            value: "dictKey"
                        },
                        dataType: "number",
                        search: true,
                        hide: true,
                        display: false,
                        prop: "userType",
                        rules: [{
                            required: true,
                            message: "请选择用户平台",
                            trigger: "blur"
                        }]
                    },
                    {
                        label: "用户拓展",
                        prop: "userExt",
                        type: "textarea",
                        minRows: 8,
                        span: 24,
                        overHidden: true,
                        row: true,
                        hide: true,
                    },
                ],
            },
            excelForm: {},
            excelOption: {
                submitBtn: false,
                emptyBtn: false,
                column: [
                    {
                        label: '模板上传',
                        prop: 'excelFile',
                        type: 'upload',
                        drag: true,
                        loadText: '模板上传中,请稍等',
                        span: 24,
                        propsHttp: {
                            res: 'data'
                        },
                        tip: '请上传 .xls,.xlsx 标准格式文件',
                        action: "/api/blade-user/import-user"
                    },
                    {
                        label: "数据覆盖",
                        prop: "isCovered",
                        type: "switch",
                        align: "center",
                        width: 80,
                        dicData: [
                            {
                                label: "否",
                                value: 0
                            },
                            {
                                label: "是",
                                value: 1
                            }
                        ],
                        value: 0,
                        slot: true,
                        rules: [
                            {
                                required: true,
                                message: "请选择是否覆盖",
                                trigger: "blur"
                            }
                        ]
                    },
                    {
                        label: '模板下载',
                        prop: 'excelTemplate',
                        formslot: true,
                        span: 24,
                    }
                ]
            }
        }
    },
    watch: {
      'form.tenantId'() {
        if (this.form.tenantId !== '' && this.initFlag) {
          this.initData(this.form.tenantId);
        'form.tenantId' () {
            if (this.form.tenantId !== '' && this.initFlag) {
                this.initData(this.form.tenantId)
            }
        },
        'excelForm.isCovered' () {
            if (this.excelForm.isCovered !== '') {
                const column = this.findObject(this.excelOption.column, "excelFile")
                column.action = `/api/blade-user/import-user?isCovered=${this.excelForm.isCovered}`
            }
        }
      },
      'excelForm.isCovered'() {
        if (this.excelForm.isCovered !== '') {
          const column = this.findObject(this.excelOption.column, "excelFile");
          column.action = `/api/blade-user/import-user?isCovered=${this.excelForm.isCovered}`;
        }
      }
    },
    computed: {
      ...mapGetters(["userInfo", "permission"]),
      permissionList() {
        return {
          addBtn: this.vaildData(this.permission.user_add, false),
          viewBtn: this.vaildData(this.permission.user_view, false),
          delBtn: this.vaildData(this.permission.user_delete, false),
          editBtn: this.vaildData(this.permission.user_edit, false)
        };
      },
      platformPermissionList() {
        return {
          addBtn: false,
          viewBtn: false,
          delBtn: false,
          editBtn: this.vaildData(this.permission.user_edit, false)
        };
      },
      ids() {
        let ids = [];
        this.selectionList.forEach(ele => {
          ids.push(ele.id);
        });
        return ids.join(",");
      },
        ...mapGetters(["userInfo", "permission"]),
        permissionList () {
            return {
                addBtn: this.vaildData(this.permission.user_add, false),
                viewBtn: this.vaildData(this.permission.user_view, false),
                delBtn: this.vaildData(this.permission.user_delete, false),
                editBtn: this.vaildData(this.permission.user_edit, false)
            }
        },
        platformPermissionList () {
            return {
                addBtn: false,
                viewBtn: false,
                delBtn: false,
                editBtn: this.vaildData(this.permission.user_edit, false)
            }
        },
        ids () {
            let ids = []
            this.selectionList.forEach(ele => {
                ids.push(ele.id)
            })
            return ids.join(",")
        },
    },
    mounted() {
      // 非租户模式默认加载管理组数据
      if (!website.tenantMode) {
        this.initData(website.tenantId);
      }
    mounted () {
        // 非租户模式默认加载管理组数据
        if (!website.tenantMode) {
            this.initData(website.tenantId)
        }
    },
    methods: {
      nodeClick(data) {
        this.treeDeptId = data.id;
        this.page.currentPage = 1;
        this.onLoad(this.page);
      },
      initData(tenantId) {
        getRoleTree(tenantId).then(res => {
          const column = this.findObject(this.option.group, "roleId");
          res.data.data[0].disabled = true;
          // res.data.data[1].disabled = true;
          column.dicData = res.data.data;
        });
        getDeptTree(tenantId).then(res => {
          const column = this.findObject(this.option.group, "deptId");
          column.dicData = res.data.data;
        });
        //getPostList(tenantId).then(res => {
        //  const column = this.findObject(this.option.group, "postId");
        //  column.dicData = res.data.data;
        //});
      },
      submitRole() {
        const roleList = this.$refs.treeRole.getCheckedKeys().join(",");
        grant(this.ids, roleList).then(() => {
          this.roleBox = false;
          this.$message({
            type: "success",
            message: "操作成功!"
          });
          this.onLoad(this.page);
        });
      },
      rowSave(row, done, loading) {
        row.deptId = row.deptId.join(",");
        row.roleId = row.roleId.join(",");
        // row.postId = row.postId.join(",");
        row.postId = '';
        add(row).then(() => {
          this.initFlag = false;
          this.onLoad(this.page);
          this.$message({
            type: "success",
            message: "操作成功!"
          });
          done();
        }, error => {
          window.console.log(error);
          loading();
        });
      },
      rowUpdate(row, index, done, loading) {
        row.deptId = row.deptId.join(",");
        row.roleId = row.roleId.join(",");
        // row.postId = row.postId.join(",");
        row.postId = '';
        update(row).then(() => {
          this.initFlag = false;
          this.onLoad(this.page);
          this.$message({
            type: "success",
            message: "操作成功!"
          });
          done();
        }, error => {
          window.console.log(error);
          loading();
        });
      },
      rowDel(row) {
        this.$confirm("确定将选择数据删除?", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        })
          .then(() => {
            return remove(row.id);
          })
          .then(() => {
            this.onLoad(this.page);
            this.$message({
              type: "success",
              message: "操作成功!"
            });
          });
      },
      searchReset() {
        this.query = {};
        this.treeDeptId = '';
        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();
      },
      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();
          });
      },
      handleReset() {
        if (this.selectionList.length === 0) {
          this.$message.warning("请选择至少一条数据");
          return;
        }
        this.$confirm("确定将选择账号密码重置为123456?", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        })
          .then(() => {
            return resetPassword(this.ids);
          })
          .then(() => {
            this.$message({
              type: "success",
              message: "操作成功!"
            });
            this.$refs.crud.toggleSelection();
          });
      },
      handleGrant() {
        if (this.selectionList.length === 0) {
          this.$message.warning("请选择至少一条数据");
          return;
        }
        this.roleTreeObj = [];
        if (this.selectionList.length === 1) {
          this.roleTreeObj = this.selectionList[0].roleId.split(",");
        }
        getRoleTree().then(res => {
          this.roleGrantList = res.data.data;
          this.roleBox = true;
        });
      },
      handlePlatform() {
        this.platformBox = true;
      },
      handleLock() {
        if (this.selectionList.length === 0) {
          this.$message.warning("请选择至少一条数据");
          return;
        }
        this.$confirm("确定将选择账号解封?", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        })
          .then(() => {
            return unlock(this.ids);
          })
          .then(() => {
            this.$message({
              type: "success",
              message: "操作成功!"
            });
          });
      },
      handleImport() {
        this.excelBox = true;
      },
      uploadAfter(res, done, loading, column) {
        window.console.log(column);
        this.excelBox = false;
        this.refreshChange();
        done();
      },
      handleExport() {
        const account = func.toStr(this.search.account);
        const realName = func.toStr(this.search.realName);
        this.$confirm("是否导出用户数据?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(() => {
          NProgress.start();
          exportBlob(`/api/blade-user/export-user?${this.website.tokenHeader}=${getToken()}&account=${account}&realName=${realName}`).then(res => {
            downloadXls(res.data, `用户数据表${dateNow()}.xlsx`);
            NProgress.done();
          })
        });
      },
      handleTemplate() {
        exportBlob(`/api/blade-user/export-template?${this.website.tokenHeader}=${getToken()}`).then(res => {
          downloadXls(res.data, "用户数据模板.xlsx");
        })
      },
      beforeOpen(done, type) {
        if (["edit", "view"].indexOf(type)) {
          getUser(this.form.id).then(res => {
            this.form = res.data.data;
            if(this.form.hasOwnProperty("deptId")){
              this.form.deptId = this.form.deptId.split(",");
        nodeClick (data) {
            this.treeDeptId = data.id
            this.page.currentPage = 1
            this.onLoad(this.page)
        },
        initData (tenantId) {
            getRoleTree(tenantId).then(res => {
                const column = this.findObject(this.option.group, "roleId")
                res.data.data[0].disabled = true
                // res.data.data[1].disabled = true;
                column.dicData = res.data.data
            })
            getDeptTree(tenantId).then(res => {
                const column = this.findObject(this.option.group, "deptId")
                column.dicData = res.data.data
            })
            //getPostList(tenantId).then(res => {
            //  const column = this.findObject(this.option.group, "postId");
            //  column.dicData = res.data.data;
            //});
        },
        submitRole () {
            const roleList = this.$refs.treeRole.getCheckedKeys().join(",")
            grant(this.ids, roleList).then(() => {
                this.roleBox = false
                this.$message({
                    type: "success",
                    message: "操作成功!"
                })
                this.onLoad(this.page)
            })
        },
        rowSave (row, done, loading) {
            // row.deptId = row.deptId.join(",")
            // row.roleId = row.roleId.join(",")
            // row.postId = row.postId.join(",");
            row.postId = ''
            add(row).then(() => {
                this.initFlag = false
                this.onLoad(this.page)
                this.$message({
                    type: "success",
                    message: "操作成功!"
                })
                done()
            }, error => {
                window.console.log(error)
                loading()
            })
        },
        rowUpdate (row, index, done, loading) {
            // row.deptId = row.deptId.join(",")
            // row.roleId = row.roleId.join(",")
            // row.postId = row.postId.join(",");
            row.postId = ''
            update(row).then(() => {
                this.initFlag = false
                this.onLoad(this.page)
                this.$message({
                    type: "success",
                    message: "操作成功!"
                })
                done()
            }, error => {
                window.console.log(error)
                loading()
            })
        },
        rowDel (row) {
            this.$confirm("确定将选择数据删除?", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning"
            })
                .then(() => {
                    return remove(row.id)
                })
                .then(() => {
                    this.onLoad(this.page)
                    this.$message({
                        type: "success",
                        message: "操作成功!"
                    })
                })
        },
        searchReset () {
            this.query = {}
            this.treeDeptId = ''
            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()
        },
        handleDelete () {
            if (this.selectionList.length === 0) {
                this.$message.warning("请选择至少一条数据")
                return
            }
            if(this.form.hasOwnProperty("roleId")){
              this.form.roleId = this.form.roleId.split(",");
            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()
                })
        },
        handleReset () {
            if (this.selectionList.length === 0) {
                this.$message.warning("请选择至少一条数据")
                return
            }
            if(this.form.hasOwnProperty("postId")){
              this.form.postId = this.form.postId.split(",");
            this.$confirm("确定将选择账号密码重置为123456?", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning"
            })
                .then(() => {
                    return resetPassword(this.ids)
                })
                .then(() => {
                    this.$message({
                        type: "success",
                        message: "操作成功!"
                    })
                    this.$refs.crud.toggleSelection()
                })
        },
        handleGrant () {
            if (this.selectionList.length === 0) {
                this.$message.warning("请选择至少一条数据")
                return
            }
          });
        }
        this.initFlag = true;
        done();
      },
      currentChange(currentPage) {
        this.page.currentPage = currentPage;
      },
      sizeChange(pageSize) {
        this.page.pageSize = pageSize;
      },
      refreshChange() {
        this.onLoad(this.page, this.query);
      },
      onLoad(page, params = {}) {
        this.loading = true;
            this.roleTreeObj = []
            if (this.selectionList.length === 1) {
                this.roleTreeObj = this.selectionList[0].roleId.split(",")
            }
            getRoleTree().then(res => {
                this.roleGrantList = res.data.data
                this.roleBox = true
            })
        },
        handlePlatform () {
            this.platformBox = true
        },
        handleLock () {
            if (this.selectionList.length === 0) {
                this.$message.warning("请选择至少一条数据")
                return
            }
            this.$confirm("确定将选择账号解封?", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning"
            })
                .then(() => {
                    return unlock(this.ids)
                })
                .then(() => {
                    this.$message({
                        type: "success",
                        message: "操作成功!"
                    })
                })
        },
        handleImport () {
            this.excelBox = true
        },
        uploadAfter (res, done, loading, column) {
            window.console.log(column)
            this.excelBox = false
            this.refreshChange()
            done()
        },
        handleExport () {
            const account = func.toStr(this.search.account)
            const realName = func.toStr(this.search.realName)
            this.$confirm("是否导出用户数据?", "提示", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning"
            }).then(() => {
                NProgress.start()
                exportBlob(`/api/blade-user/export-user?${this.website.tokenHeader}=${getToken()}&account=${account}&realName=${realName}`).then(res => {
                    downloadXls(res.data, `用户数据表${dateNow()}.xlsx`)
                    NProgress.done()
                })
            })
        },
        handleTemplate () {
            exportBlob(`/api/blade-user/export-template?${this.website.tokenHeader}=${getToken()}`).then(res => {
                downloadXls(res.data, "用户数据模板.xlsx")
            })
        },
        beforeOpen (done, type) {
            if (["edit", "view"].includes(type)) {
                getUser(this.form.id).then(res => {
                    this.form = res.data.data
                    // if (this.form.hasOwnProperty("deptId")) {
                    //     this.form.deptId = this.form.deptId.split(",")
                    // }
                    // if (this.form.hasOwnProperty("roleId")) {
                    //     this.form.roleId = this.form.roleId.split(",")
                    // }
                    // if (this.form.hasOwnProperty("postId")) {
                    //     this.form.postId = this.form.postId.split(",")
                    // }
                })
            }
            this.initFlag = true
            done()
        },
        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
        if (this.userInfo.role_name != "admin" && this.userInfo.role_name != "administrator"){
          params["jurisdiction"] = this.userInfo.dept_id;
        }
            if (this.userInfo.role_name != "admin" && this.userInfo.role_name != "administrator") {
                params["jurisdiction"] = this.userInfo.dept_id
            }
        getList(page.currentPage, page.pageSize, Object.assign(params, this.query), this.treeDeptId).then(res => {
          const data = res.data.data;
          this.page.total = data.total;
          this.data = data.records;
          this.loading = false;
          this.selectionClear();
        });
      },
      platformRowUpdate(row, index, done, loading) {
        updatePlatform(row.id, row.userType, row.userExt).then(() => {
          this.platformOnLoad(this.platformPage);
          this.$message({
            type: "success",
            message: "操作成功!"
          });
          done();
        }, error => {
          window.console.log(error);
          loading();
        });
      },
      platformBeforeOpen(done, type) {
        if (["edit", "view"].indexOf(type)) {
          getUserPlatform(this.platformForm.id).then(res => {
            this.platformForm = res.data.data;
          });
            getList(page.currentPage, page.pageSize, Object.assign(params, this.query), this.treeDeptId).then(res => {
                const data = res.data.data
                this.page.total = data.total
                this.data = data.records
                this.loading = false
                this.selectionClear()
            })
        },
        platformRowUpdate (row, index, done, loading) {
            updatePlatform(row.id, row.userType, row.userExt).then(() => {
                this.platformOnLoad(this.platformPage)
                this.$message({
                    type: "success",
                    message: "操作成功!"
                })
                done()
            }, error => {
                window.console.log(error)
                loading()
            })
        },
        platformBeforeOpen (done, type) {
            if (["edit", "view"].includes(type)) {
                getUserPlatform(this.platformForm.id).then(res => {
                    this.platformForm = res.data.data
                })
            }
            done()
        },
        platformSearchReset () {
            this.platformQuery = {}
            this.platformOnLoad(this.platformPage)
        },
        platformSearchChange (params, done) {
            this.platformQuery = params
            this.platformPage.currentPage = 1
            this.platformOnLoad(this.platformPage, params)
            done()
        },
        platformSelectionChange (list) {
            this.platformSelectionList = list
        },
        platformSelectionClear () {
            this.platformSelectionList = []
            this.$refs.platformCrud.toggleSelection()
        },
        platformCurrentChange (currentPage) {
            this.platformPage.currentPage = currentPage
        },
        platformSizeChange (pageSize) {
            this.platformPage.pageSize = pageSize
        },
        platformRefreshChange () {
            this.platformOnLoad(this.platformPage, this.platformQuery)
        },
        platformOnLoad (page, params = {}) {
            this.platformLoading = true
            getList(page.currentPage, page.pageSize, Object.assign(params, this.query), this.treeDeptId).then(res => {
                const data = res.data.data
                this.platformPage.total = data.total
                this.platformData = data.records
                this.platformLoading = false
                this.selectionClear()
            })
        }
        done();
      },
      platformSearchReset() {
        this.platformQuery = {};
        this.platformOnLoad(this.platformPage);
      },
      platformSearchChange(params, done) {
        this.platformQuery = params;
        this.platformPage.currentPage = 1;
        this.platformOnLoad(this.platformPage, params);
        done();
      },
      platformSelectionChange(list) {
        this.platformSelectionList = list;
      },
      platformSelectionClear() {
        this.platformSelectionList = [];
        this.$refs.platformCrud.toggleSelection();
      },
      platformCurrentChange(currentPage) {
        this.platformPage.currentPage = currentPage;
      },
      platformSizeChange(pageSize) {
        this.platformPage.pageSize = pageSize;
      },
      platformRefreshChange() {
        this.platformOnLoad(this.platformPage, this.platformQuery);
      },
      platformOnLoad(page, params = {}) {
        this.platformLoading = true;
        getList(page.currentPage, page.pageSize, Object.assign(params, this.query), this.treeDeptId).then(res => {
          const data = res.data.data;
          this.platformPage.total = data.total;
          this.platformData = data.records;
          this.platformLoading = false;
          this.selectionClear();
        });
      }
    }
  };
}
</script>
<style>
  .box {
.box {
    height: 800px;
  }
}
  .el-scrollbar {
.el-scrollbar {
    height: 100%;
  }
}
  .box .el-scrollbar__wrap {
.box .el-scrollbar__wrap {
    overflow: scroll;
  }
}
</style>
src/views/villagePersonInfo/villagePersonInfo.vue
New file
@@ -0,0 +1,354 @@
<template>
  <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"
               @on-load="onLoad">
      <template slot="menuLeft">
        <el-button type="success"
                   size="small"
                   plain
                   icon="el-icon-upload2"
                   @click="handleImport">导入
        </el-button>
        <el-button type="danger"
                   size="small"
                   icon="el-icon-delete"
                   plain
                   v-if="permission.villagePersonInfo_delete"
                   @click="handleDelete">删 除
        </el-button>
      </template>
    </avue-crud>
    <el-dialog title="数据导入"
               append-to-body
               :visible.sync="excelBox"
               width="555px">
      <avue-form :option="excelOption" v-model="excelForm" :upload-after="uploadAfter">
        <template slot="excelTemplate">
          <el-button type="primary" @click="handleTemplate">
            点击下载<i class="el-icon-download el-icon--right"></i>
          </el-button>
        </template>
      </avue-form>
    </el-dialog>
  </basic-container>
</template>
<script>
  import {getPage, getDetail, add, update, remove} from "@/api/villagePersonInfo/villagePersonInfo";
  import {mapGetters} from "vuex";
  import {exportBlob} from "@/api/common";
  import {downloadXls} from "@/util/util";
  import {getToken} from "@/util/auth";
  export default {
    data() {
      return {
        form: {},
        query: {},
        loading: true,
        page: {
          pageSize: 10,
          currentPage: 1,
          total: 0
        },
        selectionList: [],
        excelBox: false,
        excelForm: {},
        excelOption: {
          submitBtn: false,
          emptyBtn: false,
          column: [
            {
              label: '模板上传',
              prop: 'excelFile',
              type: 'upload',
              drag: true,
              loadText: '模板上传中,请稍等',
              span: 24,
              propsHttp: {
                res: 'data'
              },
              tip: '请上传 .xls,.xlsx 标准格式文件',
              action: "/api/villagePersonInfo/villagePersonInfo/import-village-person-info"
            },
            {
              label: "数据覆盖",
              prop: "isCovered",
              type: "switch",
              align: "center",
              width: 80,
              dicData: [
                {
                  label: "否",
                  value: 0
                },
                {
                  label: "是",
                  value: 1
                }
              ],
              value: 0,
              slot: true,
              rules: [
                {
                  required: true,
                  message: "请选择是否覆盖",
                  trigger: "blur"
                }
              ]
            },
            {
              label: '模板下载',
              prop: 'excelTemplate',
              formslot: true,
              span: 24,
            }
          ]
        },
        option: {
          height:'auto',
          calcHeight: 30,
          tip: false,
          searchShow: true,
          searchMenuSpan: 6,
          border: true,
          index: true,
          viewBtn: true,
          selection: true,
          dialogClickModal: false,
          //隐藏操作栏
          menu:false,
          column: [
            {
              label: "主键",
              prop: "id",
              type: "input",
              addDisplay: false,
              editDisplay: false,
              viewDisplay: false,
              hide: true,
            },
            {
              label: "房屋id",
              prop: "resBusId",
            },
            {
              label: "地址",
              prop: "address",
              type: "input",
            },
            {
              label: "姓名",
              prop: "realName",
              searchSpan:4,
              search:true,
              type: "input",
            },
            {
              label: "电话",
              prop: "phone",
              searchSpan:4,
              search:true,
              type: "input",
            },
            {
              label: "身份证号码",
              prop: "cardNo",
              search:true,
              searchLabelWidth:110,
              type: "input",
            },
            {
              label: "小区",
              prop: "aoiId",
              type: "select",
              dicUrl: "/api/villageInfo/villageInfo/all",
              props: {
                label: "aoiName",
                value: "aoiId"
              }
            },
            {
              label: "楼栋id",
              prop: "buildId",
              type: "input",
            },
          ]
        },
        data: []
      };
    },
    computed: {
      ...mapGetters(["permission"]),
      permissionList() {
        return {
          addBtn: this.vaildData(this.permission.villagePersonInfo_add, false),
          viewBtn: this.vaildData(this.permission.villagePersonInfo_view, false),
          delBtn: this.vaildData(this.permission.villagePersonInfo_delete, false),
          editBtn: this.vaildData(this.permission.villagePersonInfo_edit, false)
        };
      },
      ids() {
        let ids = [];
        this.selectionList.forEach(ele => {
          ids.push(ele.id);
        });
        return ids.join(",");
      }
    },
    watch: {
      'excelForm.isCovered'() {
        if (this.excelForm.isCovered !== '') {
          const column = this.findObject(this.excelOption.column, "excelFile");
          column.action = `/api/villagePersonInfo/villagePersonInfo/import-village-person-info?isCovered=${this.excelForm.isCovered}`;
        }
      }
    },
    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;
        getPage(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();
        });
      },
      //下面为导入操作
      handleImport() {
        this.excelBox = true;
      },
      uploadAfter(res, done, loading, column) {
        window.console.log(column);
        this.excelBox = false;
        this.refreshChange();
        done();
      },
      handleTemplate() {
        exportBlob(`/api/villagePersonInfo/villagePersonInfo/export-template?${this.website.tokenHeader}=${getToken()}`).then(res => {
          downloadXls(res.data, "小区人员数据模板.xlsx");
        })
      },
    }
  };
</script>
<style>
</style>
vue.config.js
@@ -1,3 +1,16 @@
/*
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2023-02-06 10:34:02
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2023-02-09 15:16:33
 * @FilePath: \srs-police-web\vue.config.js
 * @Description:
 *
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
 */
const path = require('path')
const CopywebpackPlugin = require('copy-webpack-plugin')
const dvgisDist = './node_modules/@dvgis'
module.exports = {
    //路径前缀
    publicPath: "/",
@@ -26,7 +39,7 @@
        proxy: {
            '/api': {
                //本地服务接口地址
                target: 'http://192.168.0.126:82/',
                target: 'http://localhost:82/',
                //远程演示服务地址,可用于直接启动项目
                //target: 'https://saber.bladex.vip/api',
                ws: true,