This commit is contained in:
张成
2025-10-08 15:10:33 +08:00
commit 2e1cd65b07
161 changed files with 19936 additions and 0 deletions

219
src/utils/http.js Normal file
View File

@@ -0,0 +1,219 @@
import axios from 'axios'
import { formatDate } from './tools'
class Http {
constructor() {
this.config = {
apiUrl: '',
timeout: 300000
}
this.store = null
}
init(config, store) {
this.config = { ...this.config, ...config }
this.store = store
}
baseUrl() {
return this.config.apiUrl
}
ImgSrc(src) {
return this.baseUrl() + src
}
getHttpInstance(config) {
let defaultConfig = {
timeout: this.config.timeout,
headers: {},
baseURL: this.baseUrl(),
responseType: 'json',
transformResponse: [
function(data) {
return data
}
]
}
let newConfig = Object.assign({}, defaultConfig, config)
if (this.store && this.store.state.user) {
newConfig.headers['admin-token'] = this.store.state.user.token
}
let instance = axios.create(newConfig)
instance.interceptors.request.use(
config => {
return config
},
error => {
return Promise.reject(error)
}
)
instance.interceptors.response.use(
response => {
if (response.status === 200) {
if (response.data && response.data.code === 0) {
return response
} else {
this.hideLoad()
let msg = response.data.message
this.showError(msg)
return Promise.reject(msg)
}
} else {
this.hideLoad()
return Promise.reject(response)
}
},
error => {
this.hideLoad()
if (error && error.response && error.response.status === 401) {
if (this.store) {
this.store.commit('user/setToken', '')
}
if (window.rootVue && window.rootVue.$router) {
window.rootVue.$router.push({ name: 'login' })
}
return Promise.reject(error)
}
let msg = error.message
if (msg.indexOf('Network Error') > -1) {
msg = '网络错误,请刷新后重试'
} else if (msg.indexOf('timeout of') > -1) {
msg = '请求超时,请稍后后重试'
}
this.showError(msg)
return Promise.reject(error)
}
)
return instance
}
showLoad() {
let loadWarp = document.getElementById('spin-box-one')
if (loadWarp) {
loadWarp.style.display = 'block'
}
}
hideLoad() {
let loadWarp = document.getElementById('spin-box-one')
if (loadWarp) {
loadWarp.style.display = 'none'
}
}
showError(msg) {
if (window.rootVue && window.rootVue.$Message) {
window.rootVue.$Message.error({ content: msg, duration: 3 })
}
}
formatParamete(param) {
param = param || {}
if (param) {
for (let key in param) {
if (param[key] && param[key].getFullYear) {
param[key] = formatDate(param[key], 'YYYY-MM-DD HH:mm:ss')
}
}
}
param = JSON.parse(JSON.stringify(param))
return param
}
formatFormDataParam(param) {
let formData = new FormData()
Object.keys(param).forEach(key => {
formData.append(key, param[key])
})
return formData
}
async get(url, param, config) {
let instance = this.getHttpInstance()
param = this.formatParamete(param)
let promise = new Promise((resolve, reject) => {
if (!config || !config.hideLoad) {
this.showLoad()
}
instance.get(url, { params: param }).then(async response => {
this.hideLoad()
resolve(response.data)
}).catch(error => {
reject(error)
})
})
return promise
}
async postFormData(url, data) {
let instance = this.getHttpInstance({
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})
let param = this.formatFormDataParam(data)
let promise = new Promise((resolve, reject) => {
instance.post(url, param).then(response => {
this.hideLoad()
resolve(response.data)
}).catch(error => {
reject(error)
})
})
return promise
}
async post(url, param, config) {
let instance = this.getHttpInstance(config)
param = this.formatParamete(param)
let promise = new Promise((resolve, reject) => {
this.showLoad()
instance.post(url, param).then(response => {
this.hideLoad()
resolve(response.data)
}).catch(error => {
reject(error)
})
})
return promise
}
async fileExport(url, param) {
let formData = this.formatFormDataParam(param)
let config = {
headers: {
'admin-token': this.store ? this.store.state.user.token : '',
'Content-Type': 'application/json'
},
baseURL: this.baseUrl(),
url: url,
responseType: 'blob'
}
let res = await axios.post(url, formData, config)
const filename = res.headers.filename
const a = document.createElement('a')
const href = window.URL.createObjectURL(res.data)
a.href = href
a.download = filename
a.click()
window.URL.revokeObjectURL(url)
}
}
const http = new Http()
export default http

502
src/utils/tools.js Normal file
View File

@@ -0,0 +1,502 @@
// 数组工具方法
export const forEach = (arr, fn) => {
if (!arr.length || !fn) return
let i = -1
let len = arr.length
while (++i < len) {
let item = arr[i]
fn(item, i, arr)
}
}
export const reverse = (arr) => {
let arrResult = []
let j = 0
for (let i = arr.length - 1; i >= 0; i--, j++) {
arrResult[j] = arr[i]
}
return arrResult
}
import dayjs from 'dayjs'
import Cookies from 'js-cookie'
export const getIntersection = (arr1, arr2) => {
let len = Math.min(arr1.length, arr2.length)
let i = -1
let res = []
while (++i < len) {
const item = arr2[i]
if (arr1.indexOf(item) > -1) res.push(item)
}
return res
}
export const getUnion = (arr1, arr2) => {
return Array.from(new Set([...arr1, ...arr2]))
}
export const hasOneOf = (targetarr, arr) => {
return targetarr.some(_ => arr.indexOf(_) > -1)
}
export function oneOf(value, validList) {
for (let i = 0; i < validList.length; i++) {
if (value === validList[i]) {
return true
}
}
return false
}
export const hasKey = (obj, key) => {
if (key) return key in obj
else {
let keysArr = Object.keys(obj)
return keysArr.length
}
}
// 对象工具方法
export const objEqual = (obj1, obj2) => {
const keysArr1 = Object.keys(obj1)
const keysArr2 = Object.keys(obj2)
if (keysArr1.length !== keysArr2.length) return false
else if (keysArr1.length === 0 && keysArr2.length === 0) return true
else return !keysArr1.some(key => obj1[key] !== obj2[key])
}
export const isObjectEqual = (a, b) => {
let isEqual = true
for (var key in a) {
if (a[key] !== b[key]) {
isEqual = false
break
}
}
return isEqual
}
// 文件下载工具方法
export const downStream = res => {
const fileName = new Date().getTime() + '.xlsx'
let blob = new Blob([res.data])
let downloadElement = document.createElement('a')
let href = window.URL.createObjectURL(blob)
downloadElement.href = href
downloadElement.download = fileName
document.body.appendChild(downloadElement)
downloadElement.click()
document.body.removeChild(downloadElement)
window.URL.revokeObjectURL(href)
}
export const downloadImg = (url, name) => {
const aLink = document.createElement('a')
aLink.download = name
aLink.href = url
aLink.dispatchEvent(new MouseEvent('click', {}))
}
// 数据验证工具方法
export const isNullorEmpty = (obj) => {
if (typeof obj === 'undefined' || obj == null || obj === '') {
return true
}
return false
}
export const removeEmptyObject = (data) => {
data = data || {}
for (let index in data) {
if (data[index] === '' || data[index] === '全部') {
delete data[index]
}
}
return data
}
// 随机数生成工具方法
export const generateUUID = () => {
var d = new Date().getTime()
if (window.performance && typeof window.performance.now === 'function') {
d += performance.now()
}
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
/[xy]/g,
function(c) {
var r = (d + Math.random() * 16) % 16 | 0
d = Math.floor(d / 16)
return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16)
}
)
return uuid
}
export const createCode = (codeLength = 4) => {
var code = ''
var random = '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]'
random = JSON.parse(random)
for (var i = 0; i < codeLength; i++) {
var index = Math.floor(Math.random() * 36)
code += random[index]
}
return code
}
export const getRandomNum = (minNum, maxNum) => {
switch (arguments.length) {
case 1:
return parseInt(Math.random() * minNum + 1, 10)
case 2:
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10)
default:
return 0
}
}
// 数据转换工具方法
export const toJson = (data) => {
return JSON.parse(JSON.stringify(data))
}
// Cookie 工具方法
export const setCookie = (name, value) => {
var exdate = new Date()
var expiredays = 7
exdate.setDate(exdate.getDate() + expiredays)
document.cookie =
name +
'=' +
escape(value) +
(expiredays == null ? '' : ';expires=' + exdate.toGMTString())
}
export const getCookie = (name) => {
if (document.cookie.length > 0) {
var c_start = document.cookie.indexOf(name + '=')
if (c_start !== -1) {
c_start = c_start + name.length + 1
var c_end = document.cookie.indexOf(';', c_start)
if (c_end === -1) c_end = document.cookie.length
return unescape(document.cookie.substring(c_start, c_end))
}
}
return ''
}
// 日期格式化工具方法
export const formatDate = (val, fmt) => {
val = val || new Date()
if (!isNullorEmpty(val)) {
fmt = fmt || 'YYYY-MM-DD'
if (!val.getDate) {
val = new Date(val)
}
var date = dayjs(val).format(fmt)
return date
}
return val
}
// 组件高度计算工具方法
export const getComponentHeight = (diffHegiht) => {
let curBodyHeight = document.documentElement.clientHeight
let height = curBodyHeight - diffHegiht
return height
}
// URL 参数获取工具方法
export const getUrlParam = (key) => {
var index = window.location.href.indexOf('?') + 1
var reg = new RegExp('(^|&)' + key + '=([^&]*)(&|$)')
var r = window.location.href.substr(index).match(reg)
if (r != null) return unescape(r[2])
return null
}
// 日期验证工具方法
export const isDate = (date) => {
var reDateTime = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/
var isDateTime = reDateTime.test(date)
return isDateTime
}
// 安全检查字符串工具方法
export const getCheckString = (value) => {
let curTemp = !isNullorEmpty(value) ? value : ''
return curTemp
}
// Token 管理工具方法
export const TOKEN_KEY = 'token'
export const MENU_KEY = 'authoritymenu'
export const setToken = (token, cookieExpires = 7) => {
Cookies.set(TOKEN_KEY, token, {
expires: cookieExpires
})
}
export const getToken = () => {
const token = Cookies.get(TOKEN_KEY)
if (token) return token
else return false
}
// 路由和菜单工具方法
export const hasChild = item => {
return item.children && item.children.length !== 0
}
const showThisMenuEle = (item, access) => {
if (item.meta && item.meta.access && item.meta.access.length) {
if (hasOneOf(item.meta.access, access)) return true
else return false
} else return true
}
export const getMenuByRouter = (list, access) => {
let res = []
forEach(list, item => {
if (!item.meta || (item.meta && !item.meta.hideInMenu)) {
let obj = {
icon: (item.meta && item.meta.icon) || '',
name: item.name,
meta: item.meta
}
if (
(hasChild(item) || (item.meta && item.meta.showAlways)) &&
showThisMenuEle(item, access)
) {
obj.children = getMenuByRouter(item.children, access)
}
if (item.meta && item.meta.href) obj.href = item.meta.href
if (showThisMenuEle(item, access)) res.push(obj)
}
})
return res
}
export const getBreadCrumbList = (route, homeRoute) => {
let routeMetched = route.matched
let res = routeMetched
.filter(item => {
return item.meta === undefined || !item.meta.hideInBread
})
.map(item => {
let meta = { ...item.meta }
if (meta.title && typeof meta.title === 'function') {
meta.__titleIsFunction__ = true
meta.title = meta.title(route)
}
let obj = {
icon: (item.meta && item.meta.icon) || '',
name: item.name,
meta: meta
}
if (item.name === homeRoute.name) {
obj.to = homeRoute.path
}
return obj
})
res = res.filter(item => {
return !item.meta.hideInMenu
})
res.splice(0, 1)
return [...res]
}
export const getRouteTitleHandled = route => {
let router = { ...route }
let meta = { ...route.meta }
let title = ''
if (meta.title) {
if (typeof meta.title === 'function') {
meta.__titleIsFunction__ = true
title = meta.title(router)
} else title = meta.title
}
meta.title = title
router.meta = meta
return router
}
export const showTitle = (item, vm) => {
let title = item.name
if (!title) return
return title
}
export const setTagNavListInLocalstorage = list => {
localStorage.tagNaveList = JSON.stringify(list)
}
export const getTagNavListFromLocalstorage = () => {
const list = localStorage.tagNaveList
return list ? JSON.parse(list) : []
}
export const getHomeRoute = (routers, homeName = 'home') => {
let homeRoute = routers.find(item => {
return item.name === homeName
})
if (homeRoute) {
delete homeRoute.children
delete homeRoute.component
}
return homeRoute || {}
}
export const getNewTagList = (list, newRoute) => {
const { name, path, meta } = newRoute
let newList = [...list]
if (newList.findIndex(item => item.name === name) >= 0) return newList
else {
newList.push({ name, path, meta })
}
return newList
}
const hasAccess = (access, route) => {
if (route.meta && route.meta.access)
return hasOneOf(access, route.meta.access)
else return true
}
export const canTurnTo = (name, access, routes) => {
const routePermissionJudge = list => {
return list.some(item => {
if (item.children && item.children.length) {
return routePermissionJudge(item.children)
} else if (item.name === name) {
return hasAccess(access, item)
}
})
}
return routePermissionJudge(routes)
}
export const getParams = url => {
const keyValueArr = url.split('?')[1].split('&')
let paramObj = {}
keyValueArr.forEach(item => {
const keyValue = item.split('=')
paramObj[keyValue[0]] = keyValue[1]
})
return paramObj
}
export const getNextRoute = (list, route) => {
let res = {}
if (list.length === 2) {
res = getHomeRoute(list)
} else {
const index = list.findIndex(item => routeEqual(item, route))
if (index === list.length - 1) res = list[list.length - 2]
else res = list[index + 1]
}
return res
}
export const routeEqual = (route1, route2) => {
const params1 = route1.params || {}
const params2 = route2.params || {}
const query1 = route1.query || {}
const query2 = route2.query || {}
return (
route1.name === route2.name &&
objEqual(params1, params2) &&
objEqual(query1, query2)
)
}
export const localSave = (key, value) => {
localStorage.setItem(key, value)
}
export const localRead = key => {
return localStorage.getItem(key) || ''
}
export const filterMenu = menu => {
if (menu && menu.length > 0) {
menu = menu.filter(p => {
return !(p.meta && p.meta.isMenu === false)
})
menu.forEach(p => {
if (p.children && p.children.length > 0) {
p.children = filterMenu(p.children)
}
})
return menu
}
return menu
}
// DOM 操作工具方法
export const findNodeUpperByClasses = (ele, classes) => {
let parentNode = ele.parentNode
if (parentNode) {
let classList = parentNode.classList
if (classList && classes.every(className => classList.contains(className))) {
return parentNode
} else {
return findNodeUpperByClasses(parentNode, classes)
}
}
}
export const scrollTop = (el, from = 0, to, duration = 500, endCallback) => {
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = (
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
return window.setTimeout(callback, 1000/60)
}
)
}
const difference = Math.abs(from - to)
const step = Math.ceil(difference / duration * 50)
function scroll (start, end, step) {
if (start === end) {
endCallback && endCallback()
return
}
let d = (start + step > end) ? end : start + step
if (start > end) {
d = (start - step < end) ? end : start - step
}
if (el === window) {
window.scrollTo(d, d)
} else {
el.scrollTop = d
}
window.requestAnimationFrame(() => scroll(d, end, step))
}
scroll(from, to, step)
}
export const on = (element, event, handler) => {
if (element && event && handler) {
element.addEventListener(event, handler, false)
}
}
export const off = (element, event, handler) => {
if (element && event && handler) {
element.removeEventListener(event, handler, false)
}
}

198
src/utils/uiTool.js Normal file
View File

@@ -0,0 +1,198 @@
import http from './http'
export default class uiTool {
static setRem() {
let whdef = 100 / 1920
let bodyWidth = document.body.clientWidth
if (bodyWidth < 1360) {
bodyWidth = 1360
}
let rem = bodyWidth * whdef
document.documentElement.style.fontSize = rem + 'px'
console.log('自适应html字体大小', parseInt(rem))
console.log('自适应缩放比列', (rem / 100).toFixed(3))
window.$whdef = rem
}
static getImgSrc(src) {
if (src) {
return http.baseUrl() + src
} else {
return '/assets/img/noImg.png'
}
}
static getBtn(h, options) {
let rets = []
if (!options) {
options = [options]
}
options.forEach(item => {
rets.push(
h(
'Button',
{
props: {
type: 'text',
ghost: true,
loading: item.loading
},
style: {
margin: '2px',
color: '#2d8cf0'
},
on: {
click: () => {
item.click && item.click()
}
}
},
item.title
)
)
})
return h('div', { style: { margin: '5px' } }, rets)
}
static getDropdown(h, items) {
let btns = []
if (items && items.length > 0) {
items.forEach(item => {
btns.push(
h(
'DropdownItem',
{
on: {
click: () => {
item.click && item.click()
}
}
},
item.title
)
)
})
}
return h('Dropdown', {}, [
h('a', {}, ['更多', h('Icon', { props: { type: 'ios-arrow-down' } })]),
h('DropdownMenu', { slot: 'list' }, btns)
])
}
static delConfirm(callback) {
if (window.rootVue && window.rootVue.$Modal) {
window.rootVue.$Modal.confirm({
title: '温馨提示',
content: '<p>你确定删除吗?</p>',
onOk: () => {
callback && callback()
}
})
}
}
static showConfirm({ title = '温馨提示', content = '内容' }, callback) {
if (window.rootVue && window.rootVue.$Modal) {
window.rootVue.$Modal.confirm({
title,
content,
onOk: () => {
callback && callback()
}
})
}
}
static subTree(curTree, tree, callback) {
if (curTree && curTree.length > 0) {
curTree.forEach(p => {
let childrenTree = tree.filter(p2 => p.id === p2.parent_id)
if (childrenTree) {
let subTree = uiTool.subTree(childrenTree, tree, callback)
p.children = subTree || []
}
})
if (callback) {
return curTree.map(p => {
return callback(p)
})
}
return curTree
}
return []
}
static transformTree(tree, callback) {
let rootTree = tree.filter(p => p.parent_id === 0)
let curTrees = uiTool.subTree(rootTree, tree, callback)
return curTrees
}
static menuToRoute(menus, ParentView, Page404) {
if (menus && menus.length > 0) {
menus.forEach(item => {
if (item.type === '菜单') {
item.component = ParentView
} else if (item.type === '页面' || item.type === '功能') {
try {
let componentName = item.component
// 这里需要在使用时动态导入
item.componentPath = componentName
item.component = Page404
} catch (e) {
item.component = Page404
}
} else {
item.component = ParentView
}
item.meta = {
icon: item.icon,
isMenu: item.is_show_menu,
type: item.type
}
if (item.children && item.children.length > 0) {
item.children = uiTool.menuToRoute(item.children, ParentView, Page404)
}
})
return menus
}
return []
}
static getRoutes(Main, ParentView, Page404) {
let mainRoute = {
path: '/',
name: '主视图',
redirect: '/home',
component: Main,
meta: { title: '首页', notCache: true },
children: []
}
if (
localStorage.authorityMenus &&
localStorage.authorityMenus !== 'undefined'
) {
let authorityMenus = JSON.parse(localStorage.authorityMenus) || []
if (authorityMenus && authorityMenus.length > 0) {
let menus = uiTool.transformTree(authorityMenus)
let curRoutes = uiTool.menuToRoute(menus, ParentView, Page404)
mainRoute.children = curRoutes
}
}
return mainRoute
}
}