fix
This commit is contained in:
48
src/utils/flexible.js
Normal file
48
src/utils/flexible.js
Normal file
@@ -0,0 +1,48 @@
|
||||
import { getUniversalZoomLevel } from '@/utils/tools'
|
||||
|
||||
let flexible = (designWidth, maxWidth,minWidth) =>{
|
||||
var doc = document, win = window, docEl = doc.documentElement, remStyle = document.createElement("style"), tid;
|
||||
designWidth = designWidth || 1920;
|
||||
// maxWidth = maxWidth || 1920;
|
||||
// minWidth = minWidth || 500;
|
||||
// minWidth = minWidth || 1024;
|
||||
function refreshRem() {
|
||||
var width = docEl.getBoundingClientRect().width;
|
||||
var height = docEl.getBoundingClientRect().height;
|
||||
width = getUniversalZoomLevel() * width
|
||||
height = getUniversalZoomLevel() * height
|
||||
// width > maxWidth && (width = maxWidth);
|
||||
// width < minWidth && (width = minWidth);
|
||||
if(width >= 1024){
|
||||
designWidth = 1920
|
||||
}else{
|
||||
designWidth = 375
|
||||
}
|
||||
var rem = Math.round(width * 10 / designWidth);
|
||||
docEl.style.fontSize = rem+'px'
|
||||
remStyle.innerHTML = 'html{font-size:' + rem + 'px;}';
|
||||
}
|
||||
//要等 wiewport 设置好后才能执行 refreshRem,不然 refreshRem 会执行2次;
|
||||
refreshRem();
|
||||
win.addEventListener("resize", function() {
|
||||
clearTimeout(tid); //防止执行两次
|
||||
tid = setTimeout(refreshRem, 300);
|
||||
}, false);
|
||||
|
||||
win.addEventListener("pageshow", function(e) {
|
||||
if (e.persisted) { // 浏览器后退的时候重新计算
|
||||
clearTimeout(tid);
|
||||
tid = setTimeout(refreshRem, 300);
|
||||
}
|
||||
}, false);
|
||||
|
||||
if (doc.readyState === "complete") {
|
||||
doc.body.style.fontSize = "16px";
|
||||
} else {
|
||||
doc.addEventListener("DOMContentLoaded", function(e) {
|
||||
doc.body.style.fontSize = "16px";
|
||||
}, false);
|
||||
}
|
||||
};
|
||||
|
||||
export default flexible
|
||||
12
src/utils/local.ts
Normal file
12
src/utils/local.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
function getLocal(key = 'token') {
|
||||
return localStorage.getItem(key)
|
||||
}
|
||||
// 删除
|
||||
function removeLocal(key = 'token') {
|
||||
window.localStorage.removeItem(key)
|
||||
}
|
||||
// 保存
|
||||
function setLocal(value: any, key = 'token') {
|
||||
window.localStorage.setItem(key, value)
|
||||
}
|
||||
export { getLocal, removeLocal, setLocal }
|
||||
173
src/utils/request.ts
Normal file
173
src/utils/request.ts
Normal file
@@ -0,0 +1,173 @@
|
||||
import axios from 'axios'
|
||||
// import { Message, Loading, MessageBox } from 'element-ui'
|
||||
import { ElMessage, ElLoading, ElMessageBox } from 'element-plus'
|
||||
import { useUserInfoStore } from '@/stores/modules/userInfo'
|
||||
const store = useUserInfoStore()
|
||||
import { getLocal } from '@/utils/local'
|
||||
|
||||
// 创建axios实例
|
||||
console.log(import.meta.env.VITE_APP_URL)
|
||||
const service = axios.create({
|
||||
baseURL: import.meta.env.VITE_APP_URL, // api的base_url
|
||||
// baseURL: import.meta.env.VITE_APP_URL, // api的base_url
|
||||
timeout: 5000 // 请求超时时间
|
||||
})
|
||||
axios.defaults.headers.post["Content-Type"] = "application/json";
|
||||
axios.defaults.headers.post['lang'] = 'en'; //配置语言请求头
|
||||
axios.defaults.withCredentials = true; //跨域携带cookie
|
||||
|
||||
// request拦截器
|
||||
service.interceptors.request.use(
|
||||
(config: any) => {
|
||||
removePending(config)
|
||||
// 如果repeatRequest不配置,那么默认该请求就取消重复接口请求
|
||||
!config.repeatRequest && addPending(config)
|
||||
// 打开loading
|
||||
if (config.loading) {
|
||||
LoadingInstance._count++
|
||||
if (LoadingInstance._count === 1) {
|
||||
openLoading(config.loadingDom)
|
||||
}
|
||||
}
|
||||
// 如果登录了,有token,则请求携带token
|
||||
// Do something before request is sent
|
||||
if (store.token) {
|
||||
config.headers.Authorization = getLocal('token') // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
|
||||
// config.headers['X-Token'] = getLocal('token') // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
|
||||
}
|
||||
return config
|
||||
},
|
||||
(error) => {
|
||||
// Do something with request error
|
||||
console.log(error) // for debug
|
||||
Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
// respone拦截器
|
||||
service.interceptors.response.use(
|
||||
// response => response,
|
||||
/**
|
||||
* 下面的注释为通过response自定义code来标示请求状态,当code返回如下情况为权限有问题,登出并返回到登录页
|
||||
* 如通过xmlhttprequest 状态码标识 逻辑可写在下面error中
|
||||
*/
|
||||
(response: any) => {
|
||||
// 已完成请求的删除请求中数组
|
||||
removePending(response.config)
|
||||
// 关闭loading
|
||||
if (response.config.loading) {
|
||||
closeLoading()
|
||||
}
|
||||
|
||||
const res = response.data
|
||||
// 处理异常的情况
|
||||
if (res.errCode != 0) {
|
||||
ElMessage({
|
||||
message: res.errMsg,
|
||||
type: 'error',
|
||||
duration: 5 * 1000
|
||||
})
|
||||
// 403:非法的token; 50012:其他客户端登录了; 401:Token 过期了;
|
||||
if (res.errCode === 403 || res.errCode === 50012 || res.errCode === 401) {
|
||||
ElMessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
|
||||
confirmButtonText: '重新登录',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
store.loginOut().then(() => {
|
||||
location.reload() // 为了重新实例化vue-router对象 避免bug
|
||||
})
|
||||
})
|
||||
}
|
||||
return Promise.reject(new Error('error'))
|
||||
} else {
|
||||
// 默认只返回data,不返回状态码和message
|
||||
// 通过 meta 中的 responseAll 配置来取决后台是否返回所有数据(包括状态码,message和data)
|
||||
const isbackAll = response.config.meta && response.config.meta.responseAll
|
||||
if (isbackAll) {
|
||||
return res
|
||||
} else {
|
||||
return res.data
|
||||
}
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
error.config && removePending(error.config)
|
||||
// 关闭loading
|
||||
if (error.config?.loading) {
|
||||
closeLoading()
|
||||
}
|
||||
console.log('err' + error) // for debug
|
||||
ElMessage({
|
||||
message: error.message,
|
||||
type: 'error',
|
||||
duration: 5 * 1000
|
||||
})
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
// --------------------------------取消接口重复请求的函数-----------------------------------
|
||||
// axios.js
|
||||
const pendingMap = new Map()
|
||||
/**
|
||||
* 生成每个请求唯一的键
|
||||
* @param {*} config
|
||||
* @returns string
|
||||
*/
|
||||
function getPendingKey(config: any) {
|
||||
const { url, method, params } = config
|
||||
let { data } = config
|
||||
if (typeof data === 'string') data = JSON.parse(data) // response里面返回的config.data是个字符串对象
|
||||
return [url, method, JSON.stringify(params), JSON.stringify(data)].join('&')
|
||||
}
|
||||
|
||||
/**
|
||||
* 储存每个请求唯一值, 也就是cancel()方法, 用于取消请求
|
||||
* @param {*} config
|
||||
*/
|
||||
function addPending(config: any) {
|
||||
const pendingKey = getPendingKey(config)
|
||||
config.cancelToken =
|
||||
config.cancelToken ||
|
||||
new axios.CancelToken((cancel) => {
|
||||
if (!pendingMap.has(pendingKey)) {
|
||||
pendingMap.set(pendingKey, cancel)
|
||||
}
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 删除重复的请求
|
||||
* @param {*} config
|
||||
*/
|
||||
function removePending(config: any) {
|
||||
const pendingKey = getPendingKey(config)
|
||||
if (pendingMap.has(pendingKey)) {
|
||||
const cancelToken = pendingMap.get(pendingKey)
|
||||
cancelToken(pendingKey)
|
||||
pendingMap.delete(pendingKey)
|
||||
}
|
||||
}
|
||||
// ----------------------------------loading的函数-------------------------------
|
||||
const LoadingInstance: { _target: any; _count: number } = {
|
||||
_target: null, // 保存Loading实例
|
||||
_count: 0
|
||||
}
|
||||
function openLoading(loadingDom: any) {
|
||||
LoadingInstance._target = ElLoading.service({
|
||||
lock: true,
|
||||
text: '数据正在加载中',
|
||||
spinner: 'el-icon-loading',
|
||||
background: 'rgba(25, 32, 53, 1)',
|
||||
target: loadingDom || 'body'
|
||||
})
|
||||
}
|
||||
function closeLoading() {
|
||||
if (LoadingInstance._count > 0) LoadingInstance._count--
|
||||
if (LoadingInstance._count === 0) {
|
||||
LoadingInstance._target.close()
|
||||
LoadingInstance._target = null
|
||||
}
|
||||
}
|
||||
|
||||
export default service
|
||||
48
src/utils/tools.ts
Normal file
48
src/utils/tools.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
function getUniversalZoomLevel() {
|
||||
// 现代浏览器方案
|
||||
if (window.visualViewport) {
|
||||
return window.visualViewport.scale;
|
||||
}
|
||||
// 备用方案1
|
||||
if (window.devicePixelRatio) {
|
||||
return window.devicePixelRatio;
|
||||
}
|
||||
// 备用方案2(不精确)
|
||||
return window.outerWidth / window.innerWidth;
|
||||
}
|
||||
const getMousePosition = (e:any,bor:any) => {
|
||||
// if(e?.stopPropagation)e.stopPropagation()
|
||||
// if(e?.preventDefault)e.preventDefault();
|
||||
let event:any
|
||||
if(bor){
|
||||
const touch = e.changedTouches[0] as any;
|
||||
event = {
|
||||
offsetX:touch.clientX - e.target.getBoundingClientRect().left,
|
||||
offsetY: touch.clientY - e.target.getBoundingClientRect().top,
|
||||
clientX:touch.clientX,
|
||||
clientY:touch.clientY,
|
||||
screenX:touch.screenX,
|
||||
screenY:touch.screenY,
|
||||
target:e.target,
|
||||
}
|
||||
// if(dom){
|
||||
// event.offsetX = touch.clientX - dom.getBoundingClientRect().left
|
||||
// event.offsetY = touch.clientY - dom.getBoundingClientRect().top
|
||||
// }
|
||||
}else{
|
||||
event = {
|
||||
offsetX:e.offsetX,
|
||||
offsetY:e.offsetY,
|
||||
clientX:e.clientX,
|
||||
clientY:e.clientY,
|
||||
screenX:e.screenX,
|
||||
screenY:e.screenY,
|
||||
target:e.target,
|
||||
}
|
||||
}
|
||||
return event
|
||||
}
|
||||
export {
|
||||
getUniversalZoomLevel,
|
||||
getMousePosition,
|
||||
}
|
||||
Reference in New Issue
Block a user