This commit is contained in:
X1627315083
2025-10-09 09:35:36 +08:00
parent cc8c064d9c
commit bc8e03180e
107 changed files with 0 additions and 0 deletions

48
src/utils/flexible.js Normal file
View 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
View 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
View 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
View 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,
}