初次提交

This commit is contained in:
2025-06-30 10:17:15 +08:00
commit 5446088524
989 changed files with 365987 additions and 0 deletions

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

@ -0,0 +1,37 @@
import Cookies from 'js-cookie'
const TokenKey = 'token'
export function getToken() {
return Cookies.get(TokenKey)
}
export function getScreenToken() {
return Cookies.get('ScreenTokenKey') || localStorage.getItem('SCREEN_TOKEN')
}
export function setToken(token) {
localStorage.setItem('USER_TOKEN', token)
return Cookies.set(TokenKey, token)
}
export function setScreenToken(token) {
localStorage.setItem('SCREEN_TOKEN', token)
return Cookies.set('ScreenTokenKey', token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}
export function setAseKey(key) {
return Cookies.set('aseKey', key)
}
export function getAseKey() {
return Cookies.get('aseKey')
}
export function setIV(iv) {
return Cookies.set('iv', iv)
}
export function getIV() {
return Cookies.get('iv')
}

32
src/utils/clipboard.js Normal file
View File

@ -0,0 +1,32 @@
import Vue from 'vue'
import Clipboard from 'clipboard'
function clipboardSuccess() {
Vue.prototype.$message({
message: 'Copy successfully',
type: 'success',
duration: 1500
})
}
function clipboardError() {
Vue.prototype.$message({
message: 'Copy failed',
type: 'error'
})
}
export default function handleClipboard(text, event) {
const clipboard = new Clipboard(event.target, {
text: () => text
})
clipboard.on('success', () => {
clipboardSuccess()
clipboard.destroy()
})
clipboard.on('error', () => {
clipboardError()
clipboard.destroy()
})
clipboard.onClick(event)
}

36
src/utils/error-log.js Normal file
View File

@ -0,0 +1,36 @@
import Vue from 'vue'
import store from '@/store'
import { isString, isArray } from '@/utils/validate'
import settings from '@/settings'
// you can set in settings.js
// errorLog:'production' | ['production', 'development']
const { errorLog: needErrorLog } = settings
function checkNeed() {
const env = process.env.NODE_ENV
if (isString(needErrorLog)) {
return env === needErrorLog
}
if (isArray(needErrorLog)) {
return needErrorLog.includes(env)
}
return false
}
if (checkNeed()) {
Vue.config.errorHandler = function(err, vm, info, a) {
// Don't ask me why I use Vue.nextTick, it just a hack.
// detail see https://forum.vuejs.org/t/dispatch-in-vue-config-errorhandler-has-some-problem/23500
Vue.nextTick(() => {
store.dispatch('errorLog/addErrorLog', {
err,
vm,
info,
url: window.location.href
})
console.error(err, info)
})
}
}

View File

@ -0,0 +1,13 @@
import defaultSettings from '@/settings'
import i18n from '@/lang'
const title = defaultSettings.title || 'Vue Element Admin'
export default function getPageTitle(key) {
const hasKey = i18n.te(`route.${key}`)
if (hasKey) {
const pageName = i18n.t(`route.${key}`)
return `${pageName} - ${title}`
}
return `${title}`
}

12
src/utils/i18n.js Normal file
View File

@ -0,0 +1,12 @@
// translate router.meta.title, be used in breadcrumb sidebar tagsview
export function generateTitle(title) {
const hasKey = this.$te('route.' + title)
if (hasKey) {
// $t :this method from vue-i18n, inject in @/lang/index.js
const translatedTitle = this.$t('route.' + title)
return translatedTitle
}
return title
}

1057
src/utils/index.js Normal file

File diff suppressed because it is too large Load Diff

25
src/utils/open-window.js Normal file
View File

@ -0,0 +1,25 @@
/**
*Created by PanJiaChen on 16/11/29.
* @param {Sting} url
* @param {Sting} title
* @param {Number} w
* @param {Number} h
*/
export default function openWindow(url, title, w, h) {
// Fixes dual-screen position Most browsers Firefox
const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left
const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top
const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width
const height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height
const left = ((width / 2) - (w / 2)) + dualScreenLeft
const top = ((height / 2) - (h / 2)) + dualScreenTop
const newWindow = window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=yes, copyhistory=no, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left)
// Puts focus on the newWindow
if (window.focus) {
newWindow.focus()
}
}

21
src/utils/permission.js Normal file
View File

@ -0,0 +1,21 @@
import store from '@/store'
/**
* @param {Array} value
* @returns {Boolean}
* @example see @/views/permission/directive.vue
*/
export default function checkPermission(value) {
if (value && value instanceof Array && value.length > 0) {
const roles = store.getters && store.getters.roles
const permissionRoles = value
const hasPermission = roles.some(role => {
return permissionRoles.includes(role)
})
return hasPermission
} else {
console.error(`need roles! Like v-permission="['admin','editor']"`)
return false
}
}

117
src/utils/request.js Normal file
View File

@ -0,0 +1,117 @@
import axios from 'axios'
import { Message } from 'element-ui'
import store from '@/store'
import router from '@/router'
import { getToken, getScreenToken } from '@/utils/auth'
// create an axios instance
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
timeout: 10000 // request timeout
})
// request interceptor
service.interceptors.request.use(
config => {
config.headers['lang'] = sessionStorage.getItem('language') === 'en' ? 'en_US' : 'zh_CN'
// do something before request is sent
if (config.headers.isScreen) {
config.headers['authorization'] = getScreenToken()
} else {
if (store.getters.token) {
config.headers['authorization'] = getToken()
// let each request carry token
// ['X-Token'] is a custom headers key
// please modify it according to the actual situation
}
}
return config
},
error => {
// do something with request error
// for debug
return Promise.reject(error)
}
)
// response interceptor
service.interceptors.response.use(
/**
* If you want to get http information such as headers or status
* Please return response => response
*/
/**
* Determine the request status by custom code
* Here is just an example
* You can also judge the status by HTTP Status Code
*/
response => {
const res = response.data
// if the custom code is not 20000, it is judged as an error.
if (res.code !== 200) {
console.log(123, res)
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (res.code === 401001 || res.code === 401002) {
Message({
message: '登录凭证已过期,请重新登录' || 'Error',
type: 'warning',
duration: 2 * 1000
})
// to re-login
store.dispatch('user/resetToken').then(() => {
// location.reload()
router.push(localStorage.getItem('loginPage'))
})
} else if (res.code === 60000) {
Message({
message: res.msg || 'Error',
type: 'warning',
duration: 2 * 1000
})
} else {
Message({
message: res.msg || 'Error',
type: 'error',
duration: 2 * 1000
})
}
// debugger
return Promise.reject(new Error(res.message || 'Error'))
} else {
return res
}
},
error => {
if (error.code === 'ECONNABORTED' || error.message === 'Network Error' || error.message.includes('timeout')) {
// Message({
// message: '服务器繁忙,请稍后重试',
// type: 'warning',
// duration: 2 * 1000
// })
// 判断licence校验
} else if (error.response.data.code === 401) {
Message({
message: error.response.data.message,
type: 'warning',
duration: 2 * 1000
})
} else {
console.log(error.response.status)
if (error.response.status !== 503 && error.response.status !== 500) {
Message({
message: error.message,
type: 'error',
duration: 2 * 1000
})
}
}
return Promise.reject(error)
}
)
export default service

58
src/utils/scroll-to.js Normal file
View File

@ -0,0 +1,58 @@
Math.easeInOutQuad = function(t, b, c, d) {
t /= d / 2
if (t < 1) {
return c / 2 * t * t + b
}
t--
return -c / 2 * (t * (t - 2) - 1) + b
}
// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
var requestAnimFrame = (function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
})()
/**
* Because it's so fucking difficult to detect the scrolling element, just move them all
* @param {number} amount
*/
function move(amount) {
document.documentElement.scrollTop = amount
document.body.parentNode.scrollTop = amount
document.body.scrollTop = amount
}
function position() {
return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
}
/**
* @param {number} to
* @param {number} duration
* @param {Function} callback
*/
export function scrollTo(to, duration, callback) {
const start = position()
const change = to - start
const increment = 20
let currentTime = 0
duration = (typeof (duration) === 'undefined') ? 500 : duration
var animateScroll = function() {
// increment the time
currentTime += increment
// find the value with the quadratic in-out easing function
var val = Math.easeInOutQuad(currentTime, start, change, duration)
// move the document.body
move(val)
// do the animation unless its over
if (currentTime < duration) {
requestAnimFrame(animateScroll)
} else {
if (callback && typeof (callback) === 'function') {
// the animation is done so lets callback
callback()
}
}
}
animateScroll()
}

165
src/utils/validate.js Normal file
View File

@ -0,0 +1,165 @@
/**
* Created by PanJiaChen on 16/11/18.
*/
/**
* @param {string} path
* @returns {Boolean}
*/
export function isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validUsername(str) {
const valid_map = ['admin', 'editor']
return valid_map.indexOf(str.trim()) >= 0
}
/**
* @param {string} phone
* @returns {}
*/
export function isvalidatemobile(phone) {
const list = []
let result = true
let msg = ''
var isPhone = /^0\d{2,3}-?\d{7,8}$/
// 增加134 减少|1349[0-9]{7}增加181,增加145增加17[678]]ss
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 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
}
/**
* @param {string} url
* @returns {Boolean}
*/
export function validURL(url) {
const reg = /^(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 reg.test(url)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validLowerCase(str) {
const reg = /^[a-z]+$/
return reg.test(str)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validUpperCase(str) {
const reg = /^[A-Z]+$/
return reg.test(str)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validAlphabets(str) {
const reg = /^[A-Za-z]+$/
return reg.test(str)
}
/**
* @param {string} email
* @returns {Boolean}
*/
export function validEmail(email) {
const reg = /^(([^<>()\[\]\\.,;:\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 reg.test(email)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function isString(str) {
if (typeof str === 'string' || str instanceof String) {
return true
}
return false
}
/**
* @param {Array} arg
* @returns {Boolean}
*/
export function isArray(arg) {
if (typeof Array.isArray === 'undefined') {
return Object.prototype.toString.call(arg) === '[object Array]'
}
return Array.isArray(arg)
}
/**
*
* @param value 关键字
* @param arr 要过滤的数组
* @param key 过滤的key
* @returns []过滤的数组
*/
export function searchTree(value, arr, key) {
const newArr = []
arr.forEach((element, index) => {
if (element[key].indexOf(value) > -1) {
// 判断条件
newArr.push(element)
} else {
if (element.children && element.children.length > 0) {
const redata = searchTree(value, element.children, key)
if (redata && redata.length > 0) {
const obj = {
...element,
children: redata
}
newArr.push(obj)
}
}
}
})
return newArr
}