1
guanqb
2022-12-26 8bf041207b0aee1433f90cffe3bb6b8a8fe943e1
1
11 files modified
4 files added
18928 ■■■■■ changed files
package-lock.json 17831 ●●●●● patch | view | raw | blame | history
prod.env.js 2 ●●● patch | view | raw | blame | history
src/api/login/login.js 51 ●●●●● patch | view | raw | blame | history
src/components/map/index.vue 44 ●●●●● patch | view | raw | blame | history
src/router/axios.js 6 ●●●● patch | view | raw | blame | history
src/store/index.js 6 ●●●● patch | view | raw | blame | history
src/store/modules/user.js 70 ●●●●● patch | view | raw | blame | history
src/styles/media/index.scss 16 ●●●●● patch | view | raw | blame | history
src/utils/auth.js 12 ●●●●● patch | view | raw | blame | history
src/utils/store.js 116 ●●●●● patch | view | raw | blame | history
src/utils/validate.js 253 ●●●●● patch | view | raw | blame | history
src/views/home/components/rightContainer.vue 73 ●●●●● patch | view | raw | blame | history
src/views/login/index.vue 117 ●●●● patch | view | raw | blame | history
src/views/lyout/index.vue 46 ●●●●● patch | view | raw | blame | history
vue.config.js 285 ●●●● patch | view | raw | blame | history
package-lock.json
Diff too large
prod.env.js
@@ -2,5 +2,5 @@
module.exports = {
    NODE_ENV: '"production"',
    BASE_API: '"http://192.168.0.105:18080"',
    OUTSIDE_API: '"http://192.168.0.102:1888"'
    OUTSIDE_API: '"http://192.168.0.115:82"'
}
src/api/login/login.js
New file
@@ -0,0 +1,51 @@
import request from "@/router/axios.js";
/**
 * 登录
 * @param {*} tenantId
 * @param {*} username
 * @param {*} password
 * @param {*} type
 * @param {*} key
 * @param {*} code
 * @returns
 */
export const loginByUsername = (
  tenantId,
  username,
  password,
  type,
  key,
  code
) => {
  return request({
    url: "/api/blade-auth/oauth/token",
    method: "post",
    headers: {
      Authorization: "Basic c2FiZXI6c2FiZXJfc2VjcmV0",
      "Tenant-Id": "000000",
      "Cross-Method": "CORS",
      "Content-Type": "application/json",
    },
    params: {
      tenantId,
      username,
      password,
      grant_type: "password",
      scope: "all",
      type,
    },
  });
};
/**
 * 登出
 */
export const logout = () =>{
  return request({
    url: '/api/blade-auth/oauth/logout',
    method: 'get',
    params: {}
  })
}
src/components/map/index.vue
@@ -2,7 +2,7 @@
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2022-08-18 17:00:30
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2022-12-19 16:50:46
 * @LastEditTime: 2022-12-26 09:18:51
 * @FilePath: \srs-police-affairs\src\components\map\index.vue
 * @Description: 公用地图组件
 * 
@@ -169,35 +169,27 @@
            // global.viewer.addTerrain(terrain)
            // 天地图 影像
            // global.viewer.imageryLayers.addImageryProvider(
            //     new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
            //         url: 'http://t{s}.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
            //         subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
            //         format: 'image/jpeg',
            //         show: true,
            //         maximumLevel: 18
            //     })
            // )
            // 上饶部署,内网使用的
            global.viewer.imageryLayers.addImageryProvider(
                new global.DC.Namespace.Cesium.WebMapTileServiceImageryProvider({
                    url: "http://10.141.11.11: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(),
                new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
                    url: 'http://t{s}.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
                    subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
                    format: 'image/jpeg',
                    show: true,
                    maximumLevel: 18
                })
            )
            // 加载顺丰底图
            // 上饶部署,内网使用的
            // global.viewer.imageryLayers.addImageryProvider(
            //     new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
            //         url: "http://36.14.131.102:8899/tile?x={x}&y={y}&z={z}&mid=basemap&p=0&f=pbf"
            //         // url: "https://webmap-tile.sf-express.com/MapTileService/rt?x={x}&y={y}&z={z}"
            //     new global.DC.Namespace.Cesium.WebMapTileServiceImageryProvider({
            //         url: "http://10.141.11.11: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(),
            //     })
            // )
@@ -291,7 +283,7 @@
            global.viewer.use(new global.DC.Measure())
            global.viewer.locationBar.enable = true
            // global.viewer.locationBar.enable = true
            // 缩放
            global.viewer.zoomController.enable = true
            // 比例尺
src/router/axios.js
@@ -33,13 +33,14 @@
    // baseURL: 'http://192.168.0.112:18080',
    baseURL: 'http://192.168.0.115:1888/api',
    // baseURL: 'http://192.168.0.112:9091',
    // baseURL: 'http://192.168.0.115:82',
    // baseURL: 'http://192.168.0.106:1888/api',
    // 内网部署地址
    // baseURL: 'http://10.141.11.11:82',
    timeout: 600000 // request timeout
})
// 返回其他状态码
service.defaults.validateStatus = function (status) {
@@ -55,7 +56,7 @@
        // 调用监控平台的
        if (config.requestBaseUrl == 'outside') {
            // config.baseURL = 'http://192.168.0.102:1888/api'
            // config.baseURL = 'http://192.168.0.115:1888/api'
            // config.baseURL = 'http://192.168.0.105:80/api'
            // config.baseURL = 'http://192.168.0.115:18080/api'
            // 内网部署地址
@@ -81,7 +82,6 @@
// http response 拦截
service.interceptors.response.use(
    (res) => {
        // console.log(res, 12569)
        const code = res.data.code
        if (code == 403 && res.data.data == 'token 验证失败!') {
            // sessionStorage.removeItem('token')
src/store/index.js
@@ -2,13 +2,17 @@
import Vuex from 'vuex'
import popupParams from './modules/popupParams'
import user from './modules/user'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
    modules: {
        popupParams
        popupParams,
        user
    },
    getters
})
src/store/modules/user.js
New file
@@ -0,0 +1,70 @@
import { loginByUsername,logout } from "@/api/login/login";
import {Message} from 'element-ui'
import md5 from "js-md5";
import * as auth from '@/utils/auth'
import {setStore, getStore} from '@/utils/store'
const user = {
  state: {
    userInfo: getStore({name: 'userInfo'}) || [],
    token: getStore({name: 'token'}) || '',
  },
  actions: {
    //根据用户名登录
    LoginByUsername({ commit }, loginForm) {
      return new Promise((resolve, reject) => {
        loginByUsername(
          loginForm.tenantId,
          loginForm.username,
          md5(loginForm.password),
          loginForm.type,
          loginForm.key,
          loginForm.code
        )
          .then((res) => {
            const data = res.data;
            if (data.error_description) {
              Message({
                message: data.error_description,
                type: "error",
              });
              //跳转首页
              this.$router.push({ path: "/login" });
            } else {
              commit("SET_TOKEN", data.access_token);
              commit('SET_USER_INFO', data);
            }
            resolve();
          })
          .catch((error) => {
            reject(error);
          });
      });
    },
    //登出
    LogOut({commit}) {
      return new Promise((resolve, reject) => {
        logout().then(() => {
          commit('SET_TOKEN', '');
          auth.removeToken();
          auth.removeUserInfo();
          resolve();
        }).catch(error => {
          reject(error)
        })
      })
    },
  },
  mutations:{
    SET_TOKEN: (state, token) => {
      auth.setToken(token);
    },
    SET_USER_INFO: (state, userInfo) => {
      state.userInfo = userInfo;
      auth.setUserInfo(state.userInfo)
      setStore({name: 'userInfo', content: state.userInfo})
    },
  }
};
export default user;
src/styles/media/index.scss
@@ -143,22 +143,6 @@
                                        }
                                    }
                                    .legend {
                                        width: calc(100% - countSizeVw(36, 1920));
                                        ul {
                                            li {
                                                margin-right: countSizeVw(10, 1920);
                                                div {
                                                    width: countSizeVw(20, 1920);
                                                    border-radius: countSizeVh(4);
                                                    margin-top: countSizeVh(5);
                                                    margin-right: countSizeVw(2, 1920);
                                                }
                                            }
                                        }
                                    }
                                }
                                .table-box {
src/utils/auth.js
@@ -17,3 +17,15 @@
export const removeToken = () => {
    return window.sessionStorage.removeItem('token')
}
export const getUserInfo = () => {
    return window.sessionStorage.getItem('userInfo')
}
export const setUserInfo = user => {
    return window.sessionStorage.setItem('userInfo', JSON.stringify(user))
}
export const removeUserInfo = () => {
    return window.sessionStorage.removeItem('userInfo')
}
src/utils/store.js
New file
@@ -0,0 +1,116 @@
import {
    validatenull
} from '@/utils/validate';
/**
 * 存储localStorage
 */
export const setStore = (params = {}) => {
    let {
        name,
        content,
        type,
    } = params;
    let obj = {
        dataType: typeof (content),
        content: content,
        type: type,
        datetime: new Date().getTime()
    }
    if (type) window.sessionStorage.setItem(name, JSON.stringify(obj));
    else window.localStorage.setItem(name, JSON.stringify(obj));
}
/**
 * 获取localStorage
 */
export const getStore = (params = {}) => {
    let {
        name,
        debug
    } = params;
    let obj = {},
        content;
    obj = window.sessionStorage.getItem(name);
    if (validatenull(obj)) obj = window.localStorage.getItem(name);
    if (validatenull(obj)) return;
    try {
        obj = JSON.parse(obj);
    } catch{
        return obj;
    }
    if (debug) {
        return obj;
    }
    if (obj.dataType == 'string') {
        content = obj.content;
    } else if (obj.dataType == 'number') {
        content = Number(obj.content);
    } else if (obj.dataType == 'boolean') {
        content = eval(obj.content);
    } else if (obj.dataType == 'object') {
        content = obj.content;
    }
    return content;
}
/**
 * 删除localStorage
 */
export const removeStore = (params = {}) => {
    let {
        name,
        type
    } = params;
    if (type) {
        window.sessionStorage.removeItem(name);
    } else {
        window.localStorage.removeItem(name);
    }
}
/**
 * 获取全部localStorage
 */
export const getAllStore = (params = {}) => {
    let list = [];
    let {
        type
    } = params;
    if (type) {
        for (let i = 0; i <= window.sessionStorage.length; i++) {
            list.push({
                name: window.sessionStorage.key(i),
                content: getStore({
                    name: window.sessionStorage.key(i),
                    type: 'session'
                })
            })
        }
    } else {
        for (let i = 0; i <= window.localStorage.length; i++) {
            list.push({
                name: window.localStorage.key(i),
                content: getStore({
                    name: window.localStorage.key(i),
                })
            })
        }
    }
    return list;
}
/**
 * 清空全部localStorage
 */
export const clearStore = (params = {}) => {
    let { type } = params;
    if (type) {
        window.sessionStorage.clear();
    } else {
        window.localStorage.clear()
    }
}
src/utils/validate.js
New file
@@ -0,0 +1,253 @@
/**
 * Created by jiachenpan on 16/11/18.
 */
export function isvalidUsername(str) {
    const valid_map = ['admin', 'editor']
    return valid_map.indexOf(str.trim()) >= 0
}
/* 合法uri*/
export function validateURL(textval) {
    const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
    return urlregex.test(textval)
}
/**
 * 邮箱
 * @param {*} s
 */
export function isEmail(s) {
    return /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test(s)
}
/**
 * 手机号码
 * @param {*} s
 */
export function isMobile(s) {
    return /^1[0-9]{10}$/.test(s)
}
/**
 * 电话号码
 * @param {*} s
 */
export function isPhone(s) {
    return /^([0-9]{3,4}-)?[0-9]{7,8}$/.test(s)
}
/**
 * URL地址
 * @param {*} s
 */
export function isURL(s) {
    return /^http[s]?:\/\/.*/.test(s)
}
/* 小写字母*/
export function validateLowerCase(str) {
    const reg = /^[a-z]+$/
    return reg.test(str)
}
/* 大写字母*/
export function validateUpperCase(str) {
    const reg = /^[A-Z]+$/
    return reg.test(str)
}
/* 大小写字母*/
export function validatAlphabets(str) {
    const reg = /^[A-Za-z]+$/
    return reg.test(str)
}
/*验证pad还是pc*/
export const vaildatePc = function() {
        const userAgentInfo = navigator.userAgent;
        const Agents = ["Android", "iPhone",
            "SymbianOS", "Windows Phone",
            "iPad", "iPod"
        ];
        let flag = true;
        for (var v = 0; v < Agents.length; v++) {
            if (userAgentInfo.indexOf(Agents[v]) > 0) {
                flag = false;
                break;
            }
        }
        return flag;
    }
    /**
     * validate email
     * @param email
     * @returns {boolean}
     */
export function validateEmail(email) {
    const re = /^(([^<>()\\[\]\\.,;:\s@"]+(\.[^<>()\\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
    return re.test(email)
}
/**
 * 判断身份证号码
 */
export function cardid(code) {
    let list = [];
    let result = true;
    let msg = '';
    var city = {
        11: "北京",
        12: "天津",
        13: "河北",
        14: "山西",
        15: "内蒙古",
        21: "辽宁",
        22: "吉林",
        23: "黑龙江 ",
        31: "上海",
        32: "江苏",
        33: "浙江",
        34: "安徽",
        35: "福建",
        36: "江西",
        37: "山东",
        41: "河南",
        42: "湖北 ",
        43: "湖南",
        44: "广东",
        45: "广西",
        46: "海南",
        50: "重庆",
        51: "四川",
        52: "贵州",
        53: "云南",
        54: "西藏 ",
        61: "陕西",
        62: "甘肃",
        63: "青海",
        64: "宁夏",
        65: "新疆",
        71: "台湾",
        81: "香港",
        82: "澳门",
        91: "国外 "
    };
    if (!validatenull(code)) {
        if (code.length == 18) {
            if (!code || !/(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(code)) {
                msg = "证件号码格式错误";
            } else if (!city[code.substr(0, 2)]) {
                msg = "地址编码错误";
            } else {
                //18位身份证需要验证最后一位校验位
                code = code.split('');
                //∑(ai×Wi)(mod 11)
                //加权因子
                var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
                //校验位
                var parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2, 'x'];
                var sum = 0;
                var ai = 0;
                var wi = 0;
                for (var i = 0; i < 17; i++) {
                    ai = code[i];
                    wi = factor[i];
                    sum += ai * wi;
                }
                if (parity[sum % 11] != code[17]) {
                    msg = "证件号码校验位错误";
                } else {
                    result = false;
                }
            }
        } else {
            msg = "证件号码长度不为18位";
        }
    } else {
        msg = "证件号码不能为空";
    }
    list.push(result);
    list.push(msg);
    return list;
}
/**
 * 判断手机号码是否正确
 */
export function isvalidatemobile(phone) {
    let list = [];
    let result = true;
    let msg = '';
    var isPhone = /^0\d{2,3}-?\d{7,8}$/;
    //增加134 减少|1349[0-9]{7},增加181,增加145,增加17[678]
    if (!validatenull(phone)) {
        if (phone.length == 11) {
            if (isPhone.test(phone)) {
                msg = '手机号码格式不正确';
            } else {
                result = false;
            }
        } else {
            msg = '手机号码长度不为11位';
        }
    } else {
        msg = '手机号码不能为空';
    }
    list.push(result);
    list.push(msg);
    return list;
}
/**
 * 判断姓名是否正确
 */
export function validatename(name) {
    var regName = /^[\u4e00-\u9fa5]{2,4}$/;
    if (!regName.test(name)) return false;
    return true;
}
/**
 * 判断是否为整数
 */
export function validatenum(num, type) {
    let regName = /[^\d.]/g;
    if (type == 1) {
        if (!regName.test(num)) return false;
    } else if (type == 2) {
        regName = /[^\d]/g;
        if (!regName.test(num)) return false;
    }
    return true;
}
/**
 * 判断是否为小数
 */
export function validatenumord(num, type) {
    let regName = /[^\d.]/g;
    if (type == 1) {
        if (!regName.test(num)) return false;
    } else if (type == 2) {
        regName = /[^\d.]/g;
        if (!regName.test(num)) return false;
    }
    return true;
}
/**
 * 判断是否为空
 */
export function validatenull(val) {
    if (typeof val == 'boolean') {
        return false;
    }
    if (typeof val == 'number') {
        return false;
    }
    if (val instanceof Array) {
        if (val.length == 0) return true;
    } else if (val instanceof Object) {
        if (JSON.stringify(val) === '{}') return true;
    } else {
        if (val == 'null' || val == null || val == 'undefined' || val == undefined || val == '') return true;
        return false;
    }
    return false;
}
src/views/home/components/rightContainer.vue
@@ -63,45 +63,6 @@
                    <span :class="{ choosed: linetype == 0 }" @click="lineTabClick(0)">设备种类</span>/
                    <span :class="{ choosed: linetype == 1 }" @click="lineTabClick(1)">设备状态</span>
                </div>
                <div class="legend" v-show="(linetype == 0)">
                    <ul>
                        <li style="color:#5470FE">
                            <img src="/img/icon/pCar.png" alt />
                            车辆
                        </li>
                        <li style="color:#90cb75">
                            <img src="/img/icon/monitor.png" alt />
                            摄像头
                        </li>
                        <li style="color:#fed85e">
                            <img src="/img/icon/recorder.png" alt />
                            执法记录仪
                        </li>
                        <li style="color:#f06767">
                            <img src="/img/icon/pPhone.png" alt />
                            手台
                        </li>
                    </ul>
                </div>
                <div class="legend" v-show="(linetype == 1)">
                    <ul>
                        <li style="color:#4caf50">
                            <div style="background-color:#4caf50"></div>正常
                        </li>
                        <li style="color:#2979ff">
                            <div style="background-color:#2979ff"></div>保养
                        </li>
                        <li style="color:#ffd600">
                            <div style="background-color:#ffd600"></div>故障
                        </li>
                        <li style="color:#0d47a1">
                            <div style="background-color:#0d47a1"></div>停用
                        </li>
                        <li style="color:#b71c1c">
                            <div style="background-color:#b71c1c"></div>封存
                        </li>
                    </ul>
                </div>
            </div>
            <div style="overflow: hidden;" id="EquipmentEcharts" class="echarts-box"></div>
        </div>
@@ -795,40 +756,6 @@
                font-weight: 700;
                margin-left: 50%;
                letter-spacing: 1px;
            }
            .legend {
                position: absolute;
                width: calc(100% - 36px);
                height: 70%;
                top: 120%;
                font-style: normal;
                font-weight: normal;
                ul {
                    display: flex;
                    height: 100%;
                    li {
                        height: 100%;
                        display: flex;
                        line-height: 160%;
                        margin-right: 10px;
                        img {
                            height: 60%;
                        }
                        div {
                            width: 20px;
                            height: 42%;
                            background-color: #fff;
                            border-radius: 4px;
                            margin-top: 5px;
                            margin-right: 2px;
                        }
                    }
                }
            }
        }
src/views/login/index.vue
@@ -33,26 +33,18 @@
        <div class="loginTitle">社区警务平台</div>
        <div class="layui-form login_content">
            <p>用户登录</p>
            <el-form :model="user" ref="formName" status-icon :rules="rules">
            <el-form :model="loginForm" ref="formName" status-icon :rules="rules">
                <el-form-item prop="username">
                    <el-input
                        v-model="user.username"
                        prefix-icon="el-icon-user"
                        placeholder="请输入您的用户名"
                        autocomplete="off"
                    ></el-input>
                    <el-input v-model="loginForm.username" prefix-icon="el-icon-user" placeholder="请输入您的用户名"
                        autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item prop="password">
                    <el-input
                        type="password"
                        v-model="user.password"
                        prefix-icon="el-icon-lock"
                        placeholder="请输入您密码"
                        autocomplete="off"
                    ></el-input>
                    <el-input type="password" v-model="loginForm.password" prefix-icon="el-icon-lock"
                        placeholder="请输入您密码" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click.enter="onLogin(user)">登&nbsp;录</el-button>
                    <!-- <el-button type="primary" @click.enter="onLogin()">登&nbsp;录</el-button> -->
                    <div class="login-btn" @click.enter="onLogin()">登&nbsp;录</div>
                </el-form-item>
            </el-form>
        </div>
@@ -61,17 +53,34 @@
<script>
import nprogress from 'nprogress'
import md5 from 'js-md5'
import axios from 'axios'
import * as auth from '@/utils/auth'
export default {
    name: 'AppRegister',
    data () {
    data() {
        return {
            user: {
                username: '',
                password: ''
            },
            loginForm: {
                //租户ID
                tenantId: "000000",
                //部门ID
                deptId: "",
                //角色ID
                roleId: "",
                //用户名
                username: "admin",
                //密码
                password: "admin",
                //账号类型
                type: "account",
                //验证码的值
                code: "",
                //验证码的索引
                key: "",
                //预加载白色背景
                image: "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",
            },
            rules: {
                username: [
@@ -97,54 +106,34 @@
            newAxios: null
        }
    },
    created () {
    created() {
        var that = this
        this.newAxios = axios.create({
            baseURL: 'http://dev.jxpskj.com:8020/api',
            timeout: 600000,
            headers: {
                Authorization: 'Basic c2FiZXI6c2FiZXJfc2VjcmV0',
                'Tenant-Id': '000000'
            }
        })
        document.onkeydown = (e) => {
            const _key = window.event.keyCode
            if (_key === 13) {
                that.onLogin(that.user)
                that.onLogin()
            }
        }
    },
    methods: {
        onLogin ({ username, password }) {
        onLogin() {
            this.$refs.formName.validate((valid) => {
                if (valid) {
                    nprogress.start()
                    this.newAxios({
                        method: 'POST',
                        url: '/blade-auth/oauth/token',
                        params: {
                            username: username,
                            password: md5(password),
                            tenantId: '000000'
                        }
                    }).then((res) => {
                        if (res.data.access_token) {
                            this.$store.commit('setUser', res.data)
                            auth.setToken(res.data.access_token)
                            console.log('23232323', res.data)
                            window.localStorage.setItem('userName', res.data.nick_name)//赋值
                            this.$router.push({ path: '/' })
                        } else {
                            this.$message({
                                type: 'warning',
                                message: '用户名或密码不正确,请重新输入'
                            })
                        }
                        nprogress.done()
                    })
                    const loading = this.$loading({
                        lock: true,
                        text: '登录中,请稍后。。。',
                        spinner: "el-icon-loading"
                    });
                    this.$store.dispatch("LoginByUsername", this.loginForm).then((res) => {
                        //跳转首页
                        this.$router.push({ path: "/lyout/home" });
                        loading.close();
                    }).catch(() => {
                        loading.close();
                    });
                }
            })
        }
@@ -153,6 +142,23 @@
</script>
<style scoped lang="scss">
.login-btn{
    background-color: #409EFF;
    border-radius: 2px;
    height: 30px;
    cursor: pointer;
    line-height: 30px;
    font-size: 14px;
}
.login-btn:hover{
    background-color: #66B1FF;
}
.auth-page {
    position: fixed;
    top: 0;
@@ -174,6 +180,7 @@
        right: 25%;
        transform: translateX(50%);
    }
    .login_content {
        width: 300px;
        position: absolute;
@@ -196,11 +203,13 @@
            margin-bottom: 15px;
            letter-spacing: 4px;
        }
        :deep(.el-button--primary) {
            width: 100%;
            height: 34px;
            border-radius: 2px;
        }
        :deep(.el-button) {
            line-height: 14px;
        }
src/views/lyout/index.vue
@@ -18,8 +18,8 @@
                    <div class="sub-nav-list" v-show="item.children && item.childrenFlag">
                        <div v-for="(subItem, subIndex) in item.children" :key="subIndex" @click="goToPath(subItem)">
                            {{
                                    subItem.menuName
                            }}
        subItem.menuName
}}
                        </div>
                    </div>
                </div>
@@ -37,8 +37,8 @@
                    <div class="sub-nav-list" v-show="item.children && item.childrenFlag">
                        <div v-for="(subItem, subIndex) in item.children" :key="subIndex" @click="goToPath(subItem)">
                            {{
                                    subItem.menuName
                            }}
        subItem.menuName
}}
                        </div>
                    </div>
                </div>
@@ -46,14 +46,14 @@
            <!-- 用户登录展示的 -->
            <div class="user-infor" @click="openUser">
                <div class="userIcon" :class="{on: userOn == true}">
                <div class="userIcon" :class="{ on: userOn == true }">
                    <i class="el-icon-user-solid"></i>
                </div>
                <div class="userDetail" v-if="isShowUserDetail">
                    <div class="triangle"></div>
                    <div class="userName">用户名:{{userName}}</div>
                    <div class="userName">用户名:{{ user.user_name }}</div>
                    <div class="userBtn">
                        <div class="edit" @click="goTOLogin">
                        <div class="edit" @click="goTOLogout">
                            <img src="../../../public/img/bg/editLogin.webp" alt />
                        </div>
                    </div>
@@ -93,8 +93,9 @@
</template>
<script>
import getUserInfo from '@/utils/auth'
export default {
    data () {
    data() {
        return {
            menuLeftList: [
                {
@@ -147,16 +148,19 @@
            currentUrl: '/lyout/home',
            userOn: false,
            isShowUserDetail: false,
            user: {}
        }
    },
    created () {
    created() {
        this.currentUrl = this.$route.path
        this.user = getUserInfo()
        console.log(this.user, 4451211)
    },
    watch: {
        $route: {
            handler (newPath, oldPath) {
            handler(newPath, oldPath) {
                this.currentUrl = newPath.path
                this.$nextTick(() => {
@@ -176,17 +180,23 @@
        }
    },
    mounted () {
    mounted() {
    },
    methods: {
        //登出
        goTOLogout() {
            this.$store.dispatch("LogOut").then(() => {
                this.$router.push({ path: "/login" });
            });
        },
        /**
         * @description: 路由跳转的事件
         *                  通过给父元素绑定事件-子元素触发,并传入参数
         * @param {*} e 子元素上绑定的的自定义属性
         * @return {*} 没有返回值
         */
        goToPath (params) {
        goToPath(params) {
            if (params.openExternal) {
                window.open(params.path)
                return
@@ -203,7 +213,7 @@
        },
        flexibelClick () {
        flexibelClick() {
            this.show = !this.show
            if (this.$refs['target-name'].boxResize) this.$refs['target-name'].boxResize(this.show)
@@ -223,7 +233,7 @@
            }
        },
        resize (val, flag = false) {
        resize(val, flag = false) {
            this.boxWidth = val
            this.show = flag
@@ -248,7 +258,7 @@
            })
        },
        openUser () {
        openUser() {
            this.userOn = !this.userOn
            this.isShowUserDetail = !this.isShowUserDetail
        },
@@ -435,6 +445,7 @@
            .userIcon.on {
                color: rgba(252, 189, 86, 1);
            }
            .userDetail {
                width: 180px;
                height: 92px;
@@ -457,6 +468,7 @@
                    border-left-color: transparent;
                    border-right-color: transparent;
                }
                .userName {
                    width: 100%;
                    height: 40px;
@@ -468,6 +480,7 @@
                    position: absolute;
                    top: 0px;
                }
                .userBtn {
                    width: 100%;
                    height: 50px;
@@ -477,13 +490,14 @@
                    justify-content: space-around;
                    padding-top: 4px;
                    & > div {
                    &>div {
                        width: 100px;
                        height: 40px;
                        background-color: rgba(168, 222, 255, 0.6);
                        border-radius: 4px;
                        cursor: pointer;
                        line-height: 44px;
                        img {
                            width: 76px;
                            height: 20px;
vue.config.js
@@ -4,151 +4,162 @@
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2022-12-01 14:31:03
 * @FilePath: \srs-police-affairs\vue.config.js
 * @Description:
 *
 * Copyright (c) 2022 by shuishen 1109946754@qq.com, All Rights Reserved.
 * @Description:
 *
 * Copyright (c) 2022 by shuishen 1109946754@qq.com, All Rights Reserved.
 */
const path = require('path')
const CopywebpackPlugin = require('copy-webpack-plugin')
const dvgisDist = './node_modules/@dvgis'
const webpack = require('webpack')
const path = require("path");
const CopywebpackPlugin = require("copy-webpack-plugin");
const dvgisDist = "./node_modules/@dvgis";
const webpack = require("webpack");
const CompressionPlugin = require('compression-webpack-plugin')
const pxtovw = require('postcss-px-to-viewport')
const CompressionPlugin = require("compression-webpack-plugin");
const pxtovw = require("postcss-px-to-viewport");
const productionGzipExtensions = ['js', 'css']
const productionGzipExtensions = ["js", "css"];
module.exports = {
    css: {
        loaderOptions: {
            // 给 sass-loader 传递选项
            scss: {
                prependData: `@import "~@/styles/scssFile.scss";`
            },
            // postcss: {
            //     plugins: [   //配置px转rem进行适配
            //         require('postcss-px2rem')({
            //             // 根标签字号大小根据设计稿宽度/flexible.js里的份数得到,这里假定设计稿宽度为3840 3840/24 = 160px
            //             remUnit: 80
            //         }),
            //     ]
            // }
            // postcss: {
            //     //给postcss-loader传递选项
            //     plugins: [
            //         new pxtovw({
            //             unitToConvert: 'px', //需要转换的单位,默认为"px";
            //             viewportWidth: 1920, //设计稿的视口宽度
            //             viewportHeight: 1080, //设计稿的视口宽度
            //             unitPrecision: 5, //单位转换后保留的小数位数
            //             propList: ['*'], //要进行转换的属性列表,*表示匹配所有,!表示不转换
            //             viewportUnit: 'vw', //转换后的视口单位
            //             fontViewportUnit: 'vw', //转换后字体使用的视口单位
            //             selectorBlackList: [], //不进行转换的css选择器,继续使用原有单位
            //             minPixelValue: 1, //设置最小的转换数值
            //             mediaQuery: false, //设置媒体查询里的单位是否需要转换单位
            //             replace: true, //是否直接更换属性值,而不添加备用属性
            //             exclude: [/node_modules/], //忽略某些文件夹下的文件
            //             // landscape: true,
            //             // landscapeUnit: 'vw',
            //             // landscapeWidth: 1920
            //         })
            //     ]
            // }
  css: {
    loaderOptions: {
      // 给 sass-loader 传递选项
      scss: {
        prependData: `@import "~@/styles/scssFile.scss";`,
      },
      // postcss: {
      //     plugins: [   //配置px转rem进行适配
      //         require('postcss-px2rem')({
      //             // 根标签字号大小根据设计稿宽度/flexible.js里的份数得到,这里假定设计稿宽度为3840 3840/24 = 160px
      //             remUnit: 80
      //         }),
      //     ]
      // }
      // postcss: {
      //     //给postcss-loader传递选项
      //     plugins: [
      //         new pxtovw({
      //             unitToConvert: 'px', //需要转换的单位,默认为"px";
      //             viewportWidth: 1920, //设计稿的视口宽度
      //             viewportHeight: 1080, //设计稿的视口宽度
      //             unitPrecision: 5, //单位转换后保留的小数位数
      //             propList: ['*'], //要进行转换的属性列表,*表示匹配所有,!表示不转换
      //             viewportUnit: 'vw', //转换后的视口单位
      //             fontViewportUnit: 'vw', //转换后字体使用的视口单位
      //             selectorBlackList: [], //不进行转换的css选择器,继续使用原有单位
      //             minPixelValue: 1, //设置最小的转换数值
      //             mediaQuery: false, //设置媒体查询里的单位是否需要转换单位
      //             replace: true, //是否直接更换属性值,而不添加备用属性
      //             exclude: [/node_modules/], //忽略某些文件夹下的文件
      //             // landscape: true,
      //             // landscapeUnit: 'vw',
      //             // landscapeWidth: 1920
      //         })
      //     ]
      // }
    },
  },
  // 其他配置
  chainWebpack: (config) => {
    config.plugin("copy").use(CopywebpackPlugin, [
      [
        {
          from: path.join(dvgisDist, "dc-sdk/dist/resources"),
          to: "libs/dc-sdk/resources",
        },
    },
    // 其他配置
    chainWebpack: (config) => {
        config.plugin('copy').use(CopywebpackPlugin, [
            [
                {
                    from: path.join(dvgisDist, 'dc-sdk/dist/resources'),
                    to: 'libs/dc-sdk/resources',
                },
                {
                    from: './public/img',
                    to: 'img'
                },
                {
                    from: './public/model',
                    to: 'model'
                },
                {
                    from: './public/video',
                    to: 'video'
                },
                {
                    from: './public/libs',
                    to: 'libs'
                },
                {
                    from: './public/depend',
                    to: 'depend'
                },
            ],
        ])
        // config.plugin("define").tap((args) => {
        //     args[0]["process"] = { ...args[0]["process.env"] }
        //     return args
        // })
    },
    configureWebpack: {
        externals: {
            vue: 'Vue',
            Vuex: 'Vuex',
            'vue-router': 'VueRouter',
            'element-ui': 'ELEMENT',
            echarts: 'echarts'
        {
          from: "./public/img",
          to: "img",
        },
        // webpack plugins
        plugins: [
            // Ignore all locale files of moment.js
            new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
        {
          from: "./public/model",
          to: "model",
        },
        {
          from: "./public/video",
          to: "video",
        },
        {
          from: "./public/libs",
          to: "libs",
        },
        {
          from: "./public/depend",
          to: "depend",
        },
      ],
    ]);
            // 配置compression-webpack-plugin压缩
            new CompressionPlugin({
                algorithm: 'gzip',
                test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
                threshold: 10240,
                minRatio: 0.8
            }),
            new webpack.optimize.LimitChunkCountPlugin({
                maxChunks: 5,
                minChunkSize: 100
            })
            // 提供带 Content-Encoding 编码的压缩版的资源
            // new CompressionPlugin({
            //     algorithm: 'gzip',
            //     test: /\.js$|\.html$|\.css/, // 匹配文件名
            //     // test: /\.(js|css)$/,
            //     threshold: 10240, // 对超过10k的数据压缩
            //     deleteOriginalAssets: false, // 不删除源文件
            //     minRatio: 0.8 // 压缩比
            // })
        ]
    },
    // config.plugin("define").tap((args) => {
    //     args[0]["process"] = { ...args[0]["process.env"] }
    //     return args
    // })
  },
    devServer: {
        open: false, // 编译完成是否打开网页
        host: '0.0.0.0', // 指定使用地址,默认localhost,0.0.0.0代表可以被外界访问
        port: 8081, // 访问端口
        https: false, // 编译失败时刷新页面
        hot: true, // 开启热加载
        hotOnly: false,
        // proxy: {
        //     [process.env.VUE_APP_API]: {//拦截器(拦截链接中有/api)
        //         target: process.env.VUE_API_DEV_TARGET,//'http://192.168.1.114:3000', //process.env.VUE_API_DEV_TARGET, //API服务器的地址
        //         changeOrigin: true,
        //         pathRewrite: {
        //             //'^/api': '/'
        //             [`^${process.env.VUE_APP_API}`]: '',
        //             //[`^${process.env.VUE_APP_API}`]: '/', //配置出来的接口没有 /api
        //         }
        //     }
        // }
  configureWebpack: {
    externals: {
      vue: "Vue",
      Vuex: "Vuex",
      "vue-router": "VueRouter",
      "element-ui": "ELEMENT",
      echarts: "echarts",
    },
}
    // webpack plugins
    plugins: [
      // Ignore all locale files of moment.js
      new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
      // 配置compression-webpack-plugin压缩
      new CompressionPlugin({
        algorithm: "gzip",
        test: new RegExp("\\.(" + productionGzipExtensions.join("|") + ")$"),
        threshold: 10240,
        minRatio: 0.8,
      }),
      new webpack.optimize.LimitChunkCountPlugin({
        maxChunks: 5,
        minChunkSize: 100,
      }),
      // 提供带 Content-Encoding 编码的压缩版的资源
      // new CompressionPlugin({
      //     algorithm: 'gzip',
      //     test: /\.js$|\.html$|\.css/, // 匹配文件名
      //     // test: /\.(js|css)$/,
      //     threshold: 10240, // 对超过10k的数据压缩
      //     deleteOriginalAssets: false, // 不删除源文件
      //     minRatio: 0.8 // 压缩比
      // })
    ],
  },
  devServer: {
    open: false, // 编译完成是否打开网页
    host: "0.0.0.0", // 指定使用地址,默认localhost,0.0.0.0代表可以被外界访问
    port: 8081, // 访问端口
    https: false, // 编译失败时刷新页面
    hot: true, // 开启热加载
    hotOnly: false,
    // proxy: {
    //     [process.env.VUE_APP_API]: {//拦截器(拦截链接中有/api)
    //         target: process.env.VUE_API_DEV_TARGET,//'http://192.168.1.114:3000', //process.env.VUE_API_DEV_TARGET, //API服务器的地址
    //         changeOrigin: true,
    //         pathRewrite: {
    //             //'^/api': '/'
    //             [`^${process.env.VUE_APP_API}`]: '',
    //             //[`^${process.env.VUE_APP_API}`]: '/', //配置出来的接口没有 /api
    //         }
    //     }
    // }
    proxy: {
      "/api": {
        // target用于配置你允许访问数据的计算机名称,即是你的api接口的服务器地址
        target: "http://192.168.0.115:82",
        // ws: true, //启用webSocket
        changeOrigin: true, //开启代理跨域
        pathRewrite: {
          "^/api": "",
        },
      },
    },
  },
};