第一次提交

This commit is contained in:
caolc
2022-09-08 16:13:28 +08:00
parent 56635a948b
commit a31960fc1a
45 changed files with 9371 additions and 9230 deletions

64
src/utils/auth.js Normal file
View File

@@ -0,0 +1,64 @@
import Cookies from 'js-cookie'
const TokenKey = 'Authorization'
const NetWorkId = 'networkId'
const UserName = 'username'
const PassWord = 'password'
const Checked = 'checked'
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token, { expires: 1 })
}
export function removeToken() {
return Cookies.remove(TokenKey)
}
export function setNet(networkId) {
return Cookies.set(NetWorkId, networkId, { expires: 7 })
}
export function setUsername(username) {
return Cookies.set(UserName, username, { expires: 7 })
}
export function setPassword(password) {
return Cookies.set(PassWord, password, { expires: 7 })
}
export function getNet() {
return Cookies.get(NetWorkId)
}
export function getUsername() {
return Cookies.get(UserName)
}
export function getPassword() {
return Cookies.get(PassWord)
}
export function setChecked(checked) {
return Cookies.set(Checked, checked, { expires: 7 })
}
export function getChecked() {
return Cookies.get(Checked)
}
export function removeNet() {
return Cookies.remove(NetWorkId)
}
export function removeChecked() {
return Cookies.remove(Checked)
}
export function removeUsername() {
return Cookies.remove(UserName)
}
export function removePassword() {
return Cookies.remove(PassWord)
}

47
src/utils/encode.js Normal file
View File

@@ -0,0 +1,47 @@
import CryptoJS from 'crypto-js'
import bcrypt from 'bcryptjs'
import md5 from 'js-md5'
var keyStr = 'qDfajQ*v@W1mCruZ'
export default {
/**
* @param {*需要加密的字符串 注对象转化为json字符串再加密} word
* @param {*aes加密需要的key值这个key值后端同学会告诉你} keyStr
*/
encrypt(word) { // 加密
var key = CryptoJS.enc.Utf8.parse(keyStr)
var srcs = CryptoJS.enc.Utf8.parse(word)
var encrypted = CryptoJS.AES.encrypt(srcs, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }) // 加密模式为ECB补码方式为PKCS5Padding也就是PKCS7
return encrypted.toString()
},
decrypt(word) { // 解密
var key = CryptoJS.enc.Utf8.parse(keyStr)
var decrypt = CryptoJS.AES.decrypt(word, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 })
return CryptoJS.enc.Utf8.stringify(decrypt).toString()
},
md5Salt(str) { // md5盐加密
return md5(str + 'kdq*&qflbn1gga?aDq')
},
md5NoSalt(str) {
return md5(str)
},
uuid() { // 获取uuid
var s = []
var hexDigits = '0123456789abcdef'
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
}
s[14] = '4'
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1)
s[8] = s[13] = s[18] = s[23] = '-'
var uuid = s.join('')
return uuid
},
bcrypt(str) {
var salt = bcrypt.genSaltSync(10) // 定义密码加密的计算强度,默认10
var hash = bcrypt.hashSync(this.md5Salt(str), salt) // 把要加密的内容带进去,变量hash就是加密后的密码
return hash
}
}

View File

@@ -1,168 +1,167 @@
import axios from 'axios'
import Cookie from 'js-cookie'
import utils from '@/utils/encode'
import store from '@/store'
import { getToken } from '@/utils/auth'
import { message } from 'ant-design-vue';
const CancelToken = axios.CancelToken;
// 跨域认证信息 header 名
const xsrfHeaderName = 'Authorization'
const timeout = 20000
const WhiteApiErr = ['userSavePermissionByPhone','batchEnableDisable','batchPriceEnableDisable','getPushOrderInfo']
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: timeout // 默认请求超时时间
})
const timeoutWhite = ['/oil-finance/oilOrderInfo/importExcelOrder']
axios.defaults.timeout = 5000
axios.defaults.withCredentials= true
axios.defaults.xsrfHeaderName= xsrfHeaderName
axios.defaults.xsrfCookieName= xsrfHeaderName
// 认证类型
const AUTH_TYPE = {
BEARER: 'Bearer',
BASIC: 'basic',
AUTH1: 'auth1',
AUTH2: 'auth2',
}
// http method
const METHOD = {
GET: 'get',
POST: 'post'
}
/**
* axios请求
* @param url 请求地址
* @param method {METHOD} http method
* @param params 请求参数
* @returns {Promise<AxiosResponse<T>>}
*/
async function request(url, method, params, config) {
switch (method) {
case METHOD.GET:
return axios.get(url, {params, ...config})
case METHOD.POST:
return axios.post(url, params, config)
default:
return axios.get(url, {params, ...config})
}
}
/**
* 设置认证信息
* @param auth {Object}
* @param authType {AUTH_TYPE} 认证类型,默认:{AUTH_TYPE.BEARER}
*/
function setAuthorization(auth, authType = AUTH_TYPE.BEARER) {
switch (authType) {
case AUTH_TYPE.BEARER:
Cookie.set(xsrfHeaderName, 'Bearer ' + auth.token, {expires: auth.expireAt})
break
case AUTH_TYPE.BASIC:
case AUTH_TYPE.AUTH1:
case AUTH_TYPE.AUTH2:
default:
break
}
}
/**
* 移出认证信息
* @param authType {AUTH_TYPE} 认证类型
*/
function removeAuthorization(authType = AUTH_TYPE.BEARER) {
switch (authType) {
case AUTH_TYPE.BEARER:
Cookie.remove(xsrfHeaderName)
break
case AUTH_TYPE.BASIC:
case AUTH_TYPE.AUTH1:
case AUTH_TYPE.AUTH2:
default:
break
}
}
/**
* 检查认证信息
* @param authType
* @returns {boolean}
*/
function checkAuthorization(authType = AUTH_TYPE.BEARER) {
switch (authType) {
case AUTH_TYPE.BEARER:
if (Cookie.get(xsrfHeaderName)) {
return true
// 加密白名单
const encryptWhite = ['/oil-finance/oilOrderInfo/importExcelOrder']
let a = []
// request 拦截器
service.interceptors.request.use(
config => {
let source = CancelToken.source();
config.cancelToken = source.token;
if(a.includes(config.url)){
source.cancel(`tooRapid`);
return config
}
a.push(config.url)
if ( timeoutWhite.includes(config.url)) {
config.timeout = 0
} else {
config.timeout = timeout
}
const notEncrypt = config.notEncrypt
config.headers['dataSources'] = 'WEB'
if (store.getters.token) {
config.headers['Authorization'] = getToken()
}
const JSESSIONID = utils.uuid()
config.headers['JSESSIONID'] = JSESSIONID
config.headers['token'] = utils.bcrypt(JSESSIONID)
const env = process.env.VUE_APP_ENV
if (env === 'test') {
console.log('这里是测试')
// 测试环境,加密,打印参数
// 设置jsessionid和token
if (!notEncrypt && encryptWhite.indexOf(config.url) < 0) {
const data = { // 用于存储加密
params: '' // 加密后的密文
}
// 要加密
console.log('请求路径', config.url, '参数加密前', config.data)
data.params = utils.encrypt(JSON.stringify(config.data))
config.data = data
}
break
case AUTH_TYPE.BASIC:
case AUTH_TYPE.AUTH1:
case AUTH_TYPE.AUTH2:
default:
break
}
return false
}
}
if (env === 'development') {
console.log('这里是测试')
// 测试环境,不加密,打印参数
console.log('请求路径', config.url, '参数加密前', config.data)
}
/**
* 加载 axios 拦截器
* @param interceptors
* @param options
*/
function loadInterceptors(interceptors, options) {
const {request, response} = interceptors
// 加载请求拦截器
request.forEach(item => {
let {onFulfilled, onRejected} = item
if (!onFulfilled || typeof onFulfilled !== 'function') {
onFulfilled = config => config
if (env === 'production') {
console.log('这里是生产')
// 生产环境,加密,不输出任何东西
// 设置jsessionid和token
const JSESSIONID = utils.uuid()
config.headers['JSESSIONID'] = JSESSIONID
config.headers['token'] = utils.bcrypt(JSESSIONID)
if (!notEncrypt && encryptWhite.indexOf(config.url) < 0) {
const data = { // 用于存储加密
params: '' // 加密后的密文
}
// 要加密
data.params = utils.encrypt(JSON.stringify(config.data))
config.data = data
}
}
if (!onRejected || typeof onRejected !== 'function') {
onRejected = error => Promise.reject(error)
}
axios.interceptors.request.use(
config => onFulfilled(config, options),
error => onRejected(error, options)
)
})
// 加载响应拦截器
response.forEach(item => {
let {onFulfilled, onRejected} = item
if (!onFulfilled || typeof onFulfilled !== 'function') {
onFulfilled = response => response
}
if (!onRejected || typeof onRejected !== 'function') {
onRejected = error => Promise.reject(error)
}
axios.interceptors.response.use(
response => onFulfilled(response, options),
error => onRejected(error, options)
)
})
}
return config
},
error => {
console.log(error.message,'req')
return Promise.reject(error)
}
)
/**
* 解析 url 中的参数
* @param url
* @returns {Object}
*/
function parseUrlParams(url) {
const params = {}
if (!url || url === '' || typeof url !== 'string') {
return params
}
const paramsStr = url.split('?')[1]
if (!paramsStr) {
return params
}
const paramsArr = paramsStr.replace(/&|=/g, ' ').split(' ')
for (let i = 0; i < paramsArr.length / 2; i++) {
const value = paramsArr[i * 2 + 1]
params[paramsArr[i * 2]] = value === 'true' ? true : (value === 'false' ? false : value)
}
return params
}
// response 拦截器
service.interceptors.response.use(
response => {
let urlIndex = a.indexOf(response.config.url)
if(urlIndex!==-1){
a.splice(urlIndex,1);
console.log(a,'防抖移除')
}
console.log(a,response.config.url,'闭包')
// 这里设置loading
const res = response.data
const env = process.env.VUE_APP_ENV
if (response.headers['content-type'].indexOf('application/json') !== -1) {
if (env === 'test') {
// 测试环境,进行加密解密,打印路径和数据
if (res.encrypt === 1) {
// 加密的数据,需要解密
console.log('请求路径', response.config.url, '返回结果解密前', res)
const dataParam = JSON.parse(utils.decrypt(res.data))
res.data = JSON.stringify(dataParam) === '{}' ? null : dataParam
console.log('请求路径', response.config.url, '返回结果解密后', res)
console.log('-------------------------------------------')
} else {
console.log('请求路径', response.config.url, '返回结果未加密', res)
console.log('-------------------------------------------')
}
}
if (env === 'production') {
// 生产环境,进行加密解密,不输出日志
if (res.encrypt === 1) {
// 加密的数据,需要解密
const dataParam = JSON.parse(utils.decrypt(res.data))
res.data = JSON.stringify(dataParam) === '{}' ? null : dataParam
}
}
} else {
return res
}
export {
METHOD,
AUTH_TYPE,
request,
setAuthorization,
removeAuthorization,
checkAuthorization,
loadInterceptors,
parseUrlParams
}
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (res && res.code) {
if (res.code === 42011) {
message.error(res.msg||'您的登录已失效,请重新登录')
// to re-login
// Message({
// message: res.msg || '您的登录已失效,请重新登录',
// type: 'error',
// duration: 5 * 1000
// })
store.dispatch('user/resetToken').then(() => {
location.reload()
})
// 排除自定义的车队返回结果状态码
} else if (res.code !== 20000 && res.code !== 30001 && res.code !== 30002 && res.code !== 20001) {
if(WhiteApiErr.includes(response.config.url.split('/')[3])){
return res
}else{
message.error(res.msg||'操作失败')
return Promise.reject(new Error(res.message || '操作失败'))
}
} else {
return res
}
}
},
(error) => {
if(error.message=='tooRapid'){
console.log(error,'res防抖拦截')
message.warning ('请求过于频繁!')
}else{
let urlIndex = a.indexOf(error.config.url)
if(urlIndex!==-1){
a.splice(urlIndex,1);
}
message.error ('操作失败!')
}
return Promise.reject(error)
}
)
export default service

View File

@@ -253,13 +253,18 @@ function getI18nKey(path) {
* @param options
*/
function loadGuards(guards, options) {
//获取参数
const {beforeEach, afterEach} = guards
const {router} = options
//初始化路由配置
beforeEach.forEach(guard => {
// 检测配置参数
if (guard && typeof guard === 'function') {
//运行各种配置
router.beforeEach((to, from, next) => guard(to, from, next, options))
}
})
//同上
afterEach.forEach(guard => {
if (guard && typeof guard === 'function') {
router.afterEach((to, from) => guard(to, from, options))