Files
PointsMall_Admin/src/utils/index.js
xiaozhiyong fb74b5bb1d 更新
2024-03-14 08:37:41 +08:00

697 lines
18 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* eslint-disable no-array-constructor */
/**
* Created by PanJiaChen on 16/11/18.
*/
import { compress } from 'image-conversion'
/**
* Parse the time to string
* @param {(Object|string|number)} time
* @param {string} cFormat
* @returns {string}
*/
export function parseTime(time, cFormat) {
if (time === null || time === undefined || time === '') {
return ''
}
if (arguments.length === 0) {
return null
}
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
time = parseInt(time)
}
if (typeof time === 'number' && time.toString().length === 10) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') {
return ['日', '一', '二', '三', '四', '五', '六'][value]
}
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return time_str
}
/**
* Parse the time to string
* @param {(Object|string|number)} time
* @param {string} cFormat
* @returns {string}
*/
export function parseDate(time, cFormat) {
if (time === null || time === undefined) {
return ''
}
if (arguments.length === 0) {
return null
}
const format = cFormat || '{y}-{m}-{d}'
let date
if (typeof time === 'object') {
date = time
} else {
if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
time = parseInt(time)
}
if (typeof time === 'number' && time.toString().length === 10) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
a: date.getDay()
}
const time_str = format.replace(/{(y|m|d|a)+}/g, (result, key) => {
let value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') {
return ['日', '一', '二', '三', '四', '五', '六'][value]
}
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return time_str
}
export function makeMap(str, expectsLowerCase) {
const map = Object.create(null)
const list = str.split(',')
for (let i = 0; i < list.length; i++) {
map[list[i]] = true
}
return expectsLowerCase ? val => map[val.toLowerCase()] : val => map[val]
}
/**
* @param {number} time
* @param {string} option
* @returns {string}
*/
export function formatTime(time, option) {
if (('' + time).length === 10) {
time = parseInt(time) * 1000
} else {
time = +time
}
const d = new Date(time)
const now = Date.now()
const diff = (now - d) / 1000
if (diff < 30) {
return '刚刚'
} else if (diff < 3600) {
// less 1 hour
return Math.ceil(diff / 60) + '分钟前'
} else if (diff < 3600 * 24) {
return Math.ceil(diff / 3600) + '小时前'
} else if (diff < 3600 * 24 * 2) {
return '1天前'
}
if (option) {
return parseTime(time, option)
} else {
return d.getMonth() + 1 + '月' + d.getDate() + '日' + d.getHours() + '时' + d.getMinutes() + '分'
}
}
/**
* @param {string} url
* @returns {Object}
*/
export function getQueryObject(url) {
url = url == null ? window.location.href : url
const search = url.substring(url.lastIndexOf('?') + 1)
const obj = {}
const reg = /([^?&=]+)=([^?&=]*)/g
search.replace(reg, (rs, $1, $2) => {
const name = decodeURIComponent($1)
let val = decodeURIComponent($2)
val = String(val)
obj[name] = val
return rs
})
return obj
}
/**
* @param {string} input value
* @returns {number} output value
*/
export function byteLength(str) {
// returns the byte length of an utf8 string
let s = str.length
for (var i = str.length - 1; i >= 0; i--) {
const code = str.charCodeAt(i)
if (code > 0x7f && code <= 0x7ff) s++
else if (code > 0x7ff && code <= 0xffff) s += 2
if (code >= 0xdc00 && code <= 0xdfff) i--
}
return s
}
/**
* @param {Array} actual
* @returns {Array}
*/
export function cleanArray(actual) {
const newArray = []
for (let i = 0; i < actual.length; i++) {
if (actual[i]) {
newArray.push(actual[i])
}
}
return newArray
}
/**
* @param {Object} json
* @returns {Array}
*/
export function param(json) {
if (!json) return ''
return cleanArray(
Object.keys(json).map(key => {
if (json[key] === undefined) return ''
return encodeURIComponent(key) + '=' + encodeURIComponent(json[key])
})
).join('&')
}
/**
* @param {string} url
* @returns {Object}
*/
export function param2Obj(url) {
const search = url.split('?')[1]
if (!search) {
return {}
}
return JSON.parse(
'{"' +
decodeURIComponent(search)
.replace(/"/g, '\\"')
.replace(/&/g, '","')
.replace(/=/g, '":"')
.replace(/\+/g, ' ') +
'"}'
)
}
/**
* @param {string} val
* @returns {string}
*/
export function html2Text(val) {
const div = document.createElement('div')
div.innerHTML = val
return div.textContent || div.innerText
}
/**
* Merges two objects, giving the last one precedence
* @param {Object} target
* @param {(Object|Array)} source
* @returns {Object}
*/
export function objectMerge(target, source) {
if (typeof target !== 'object') {
target = {}
}
if (Array.isArray(source)) {
return source.slice()
}
Object.keys(source).forEach(property => {
const sourceProperty = source[property]
if (typeof sourceProperty === 'object') {
target[property] = objectMerge(target[property], sourceProperty)
} else {
target[property] = sourceProperty
}
})
return target
}
/**
* @param {HTMLElement} element
* @param {string} className
*/
export function toggleClass(element, className) {
if (!element || !className) {
return
}
let classString = element.className
const nameIndex = classString.indexOf(className)
if (nameIndex === -1) {
classString += '' + className
} else {
classString = classString.substr(0, nameIndex) + classString.substr(nameIndex + className.length)
}
element.className = classString
}
/**
* @param {string} type
* @returns {Date}
*/
export function getTime(type) {
if (type === 'start') {
return new Date().getTime() - 3600 * 1000 * 24 * 90
} else {
return new Date(new Date().toDateString())
}
}
/**
* @param {Function} func
* @param {number} wait
* @param {boolean} immediate
* @return {*}
*/
export function debounce(func, wait, immediate) {
let timeout, args, context, timestamp, result
const later = function() {
// 据上一次触发时间间隔
const last = +new Date() - timestamp
// 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last)
} else {
timeout = null
// 如果设定为immediate===true因为开始边界已经调用过了此处无需调用
if (!immediate) {
result = func.apply(context, args)
if (!timeout) context = args = null
}
}
}
return function(...args) {
context = this
timestamp = +new Date()
const callNow = immediate && !timeout
// 如果延时不存在,重新设定延时
if (!timeout) timeout = setTimeout(later, wait)
if (callNow) {
result = func.apply(context, args)
context = args = null
}
return result
}
}
/**
* This is just a simple version of deep copy
* Has a lot of edge cases bug
* If you want to use a perfect deep copy, use lodash's _.cloneDeep
* @param {Object} source
* @returns {Object}
*/
export function deepClone(source) {
if (!source && typeof source !== 'object') {
throw new Error('error arguments', 'deepClone')
}
const targetObj = source.constructor === Array ? [] : {}
Object.keys(source).forEach(keys => {
if (source[keys] && typeof source[keys] === 'object') {
targetObj[keys] = deepClone(source[keys])
} else {
targetObj[keys] = source[keys]
}
})
return targetObj
}
/**
* @param {Array} arr
* @returns {Array}
*/
export function uniqueArr(arr) {
return Array.from(new Set(arr))
}
/**
* @returns {string}
*/
export function createUniqueString() {
const timestamp = +new Date() + ''
const randomNum = parseInt((1 + Math.random()) * 65536) + ''
return (+(randomNum + timestamp)).toString(32)
}
/**
* Check if an element has a class
* @param {HTMLElement} elm
* @param {string} cls
* @returns {boolean}
*/
export function hasClass(ele, cls) {
return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
}
/**
* Add class to element
* @param {HTMLElement} elm
* @param {string} cls
*/
export function addClass(ele, cls) {
if (!hasClass(ele, cls)) ele.className += ' ' + cls
}
/**
* Remove class from element
* @param {HTMLElement} elm
* @param {string} cls
*/
export function removeClass(ele, cls) {
if (hasClass(ele, cls)) {
const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
ele.className = ele.className.replace(reg, ' ')
}
}
/**
*图片压缩
* @param {} file
*/
export function imgCompress(file) {
//把图片文件作为参数传递到方法中
console.log(file)
if (file.type.indexOf('image/') === -1) {
this.$message.error('上传的文件不是图片格式!')
return false
} else if (file.size / 1024 / 1024 > 5) {
this.$message.error('上传图片大小不能超过 5MB!')
return false
} else {
return new Promise(resolve => {
compress(file, 0.6).then(res => {
resolve(res)
})
})
}
}
export function fileAdd(file, resolve, reject) {
console.log(file.size())
// 判断是否为图片文件
if (file.type.indexOf('image') === -1) {
resolve()
} else {
const reader = new FileReader()
const image = new Image()
reader.readAsDataURL(file)
reader.onload = function() {
file.src = this.result
image.onload = function() {
const width = image.width
const height = image.height
file.width = width
file.height = height
// _this.imgL = file.src // 页面上显示所选择的图片
}
image.src = file.src // 页面上显示所选择的图片
// if (file.size / 1024 > 1025) { // 判断图片的大小超过1M 进行压缩
startImgCompress(file, { quality: 0.2 }, resolve, reject)
// } else {
// _this.partitionBase = file.src.split(',')[1] // 这里是因为后台需要 base64和图片type类型两个数据所以进行了处理
// _this.imgType = '.' + file.type.split('/')[1]
// }
}
}
}
// 开始图片压缩
export function startImgCompress(path, obj, resolve, reject) {
// path是指上传的图片obj是压缩的品质越低越模糊
var img = new Image()
img.src = path.src
img.onload = function() {
var that = this // 这里的this 是把img的对象指向改变为that
// 默认按比例压缩
var w = that.width
var h = that.height
var scale = w / h
w = obj.width || w
h = obj.height || w / scale
var quality = 0.7 // 默认图片质量为0.7
// 生成canvas
var canvas = document.createElement('canvas')
var ctx = canvas.getContext('2d')
// 创建属性节点
var anw = document.createAttribute('width')
anw.nodeValue = w
var anh = document.createAttribute('height')
anh.nodeValue = h
canvas.setAttributeNode(anw)
canvas.setAttributeNode(anh)
ctx.drawImage(that, 0, 0, w, h)
// 图像质量
if (obj.quality && obj.quality <= 1 && obj.quality > 0) {
quality = obj.quality
}
// quality值越小所绘制出的图像越模糊
var base64 = canvas.toDataURL('image/png', quality)
// 回调函数返回base64的值
var urlFile = convertBase64UrlToBlob(base64) // 这个地方的处理是为了把压缩的base64转化为对象获得压缩后图片的大小size方便对压缩后的图片再次进行判断
console.log(urlFile.size)
if (urlFile.size / 1024 > 1025) {
reject()
} else {
resolve(urlFile)
}
}
}
// 将base64码转化为fileBlob
// 此处函数对压缩后的base64经过处理返回{size: "", type: ""}
export function convertBase64UrlToBlob(urlData) {
var arr = urlData.split(',')
var mime = arr[0].match(/:(.*?);/)[1]
var bstr = atob(arr[1])
var n = bstr.length
var u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], { type: mime })
}
// 格式化xml
export function formatXML(xml, tab) {
var formatted = ''
var indent = ''
tab = tab || ' '
xml.split(/>\s*</).forEach(function(node) {
if (node.match(/^\/\w/)) indent = indent.substring(tab.length)
formatted += indent + '<' + node + '>\r\n'
if (node.match(/^<?\w[^>]*[^\/]$/)) indent += tab
})
return formatted.substring(1, formatted.length - 3)
}
/**
* 获取指定日期的前n天
* @param {*} date 日期 格式yyyy-MM-dd
* @param {*} day 天数1表示后一天-1表示前一天
*/
export function getNextDate(date, day) {
var dd = new Date(date)
dd.setDate(dd.getDate() + day)
var y = dd.getFullYear()
var m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1
var d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate()
return y + '-' + m + '-' + d
}
/**
* 构造树型结构数据
* @param {*} data 数据源
* @param {*} id id字段 默认 'id'
* @param {*} parentId 父节点字段 默认 'parentId'
* @param {*} children 孩子节点字段 默认 'children'
* @param {*} rootId 根Id 默认 0
*/
export function handleTree(data, id, parentId, children, rootId) {
id = id || 'id'
parentId = parentId || 'parentId'
children = children || 'children'
rootId = rootId || '0'
// 循环所有项
const treeData = data.filter(father => {
const branchArr = data.filter(child => {
// 返回每一项的子级数组
return father[id] === child[parentId]
})
branchArr.length > 0 ? (father.children = branchArr) : ''
// 返回第一层
return father[parentId] === rootId
})
return treeData !== '' ? treeData : data
}
/**
* 部门构造树型结构数据
* @param {*} data 数据源
* @param {*} id id字段 默认 'id'
* @param {*} parentDetpId 父节点字段 默认 'parentDetpId'
* @param {*} children 孩子节点字段 默认 'children'
*/
export function deptHandleTree(data, id, parentDetpId, children) {
let config = {
id: id || 'id',
parentDetpId: parentDetpId || 'parentDetpId',
childrenList: children || 'children'
}
var childrenListMap = {}
var nodeIds = {}
var tree = []
for (let d of data) {
let parentDetpId = d[config.parentDetpId]
if (childrenListMap[parentDetpId] == null) {
childrenListMap[parentDetpId] = []
}
nodeIds[d[config.id]] = d
childrenListMap[parentDetpId].push(d)
}
for (let d of data) {
let parentDetpId = d[config.parentDetpId]
if (nodeIds[parentDetpId] == null) {
tree.push(d)
}
}
for (let t of tree) {
adaptToChildrenList(t)
}
function adaptToChildrenList(o) {
if (childrenListMap[o[config.id]] !== null) {
o[config.childrenList] = childrenListMap[o[config.id]]
}
if (o[config.childrenList]) {
for (let c of o[config.childrenList]) {
adaptToChildrenList(c)
}
}
}
return tree
}
// 首字母大小
export function titleCase(str) {
return str.replace(/( |^)[a-z]/g, L => L.toUpperCase())
}
// 下划转驼峰
export function camelCase(str) {
return str.replace(/-[a-z]/g, str1 => str1.substr(-1).toUpperCase())
}
export function isNumberStr(str) {
return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
}
export const beautifierConf = {
html: {
indent_size: '2',
indent_char: ' ',
max_preserve_newlines: '-1',
preserve_newlines: false,
keep_array_indentation: false,
break_chained_methods: false,
indent_scripts: 'separate',
brace_style: 'end-expand',
space_before_conditional: true,
unescape_strings: false,
jslint_happy: false,
end_with_newline: true,
wrap_line_length: '110',
indent_inner_html: true,
comma_first: false,
e4x: true,
indent_empty_lines: true
},
js: {
indent_size: '2',
indent_char: ' ',
max_preserve_newlines: '-1',
preserve_newlines: false,
keep_array_indentation: false,
break_chained_methods: false,
indent_scripts: 'normal',
brace_style: 'end-expand',
space_before_conditional: true,
unescape_strings: false,
jslint_happy: true,
end_with_newline: true,
wrap_line_length: '110',
indent_inner_html: true,
comma_first: false,
e4x: true,
indent_empty_lines: true
}
}
export const exportDefault = 'export default '
// 类型判断
export function typeJudgment(object) {
try {
let res = {}.__proto__.toString.call(object)
// let type = /(?<= ).+(?=\])/.exec(res);
let type = res.replace(/[\[\]]/g, '').split(' ')
return type.length ? type[1] : ''
} catch (error) {
return ''
}
}
// url取参
export function urlParamsHandle(url) {
const search = url.split('?')[1]
if (!search) {
return {}
}
const result = {}
const searchArr = search.split('&')
searchArr.forEach(v => {
const index = v.indexOf('=')
if (index !== -1) {
const name = v.substring(0, index)
const val = v.substring(index + 1, v.length)
result[name] = val
}
})
return result
}