|
|
|
|
/**
|
|
|
|
|
* @description: 工具类
|
|
|
|
|
* @fileName: index
|
|
|
|
|
* @author: luhuixu
|
|
|
|
|
* @date: 2023/5/27-13:36
|
|
|
|
|
* @version: V1.0.0
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @description 格式化时间
|
|
|
|
|
* @param time
|
|
|
|
|
* @param cFormat
|
|
|
|
|
* @returns {string|null}
|
|
|
|
|
*/
|
|
|
|
|
export function parseTime(time, cFormat) {
|
|
|
|
|
if (!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]
|
|
|
|
|
if (key === 'a') {
|
|
|
|
|
return ['日', '一', '二', '三', '四', '五', '六'][value]
|
|
|
|
|
}
|
|
|
|
|
if (result.length > 0 && value < 10) {
|
|
|
|
|
value = '0' + value
|
|
|
|
|
}
|
|
|
|
|
return value || 0
|
|
|
|
|
})
|
|
|
|
|
return time_str
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* @description 根据状态返回对应tag 值
|
|
|
|
|
* @param str
|
|
|
|
|
* @returns {string}
|
|
|
|
|
*/
|
|
|
|
|
export function backTagStatusWithString(str) {
|
|
|
|
|
let tagType = ''
|
|
|
|
|
switch (str) {
|
|
|
|
|
case '1':
|
|
|
|
|
// 待发布
|
|
|
|
|
tagType = 'danger'
|
|
|
|
|
break
|
|
|
|
|
case '2':
|
|
|
|
|
// 报名中
|
|
|
|
|
tagType = 'primary'
|
|
|
|
|
break
|
|
|
|
|
case '3':
|
|
|
|
|
// 待制定
|
|
|
|
|
tagType = 'warning'
|
|
|
|
|
break
|
|
|
|
|
case '4':
|
|
|
|
|
// 进行中
|
|
|
|
|
tagType = 'success'
|
|
|
|
|
break
|
|
|
|
|
case '5':
|
|
|
|
|
// 批阅中
|
|
|
|
|
tagType = 'primary'
|
|
|
|
|
break
|
|
|
|
|
case '6':
|
|
|
|
|
// 待公示
|
|
|
|
|
tagType = 'warning'
|
|
|
|
|
break
|
|
|
|
|
case '7':
|
|
|
|
|
// 待归档
|
|
|
|
|
tagType = 'warning'
|
|
|
|
|
break
|
|
|
|
|
case '8':
|
|
|
|
|
// 已归档
|
|
|
|
|
tagType = 'info'
|
|
|
|
|
break
|
|
|
|
|
case '9':
|
|
|
|
|
// 待批阅
|
|
|
|
|
tagType = 'warning'
|
|
|
|
|
break
|
|
|
|
|
case '10':
|
|
|
|
|
// 待审核
|
|
|
|
|
tagType = 'warning'
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
return tagType
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* @author lhx
|
|
|
|
|
* @description 防抖函数
|
|
|
|
|
* @param val
|
|
|
|
|
* @returns {string}
|
|
|
|
|
*/
|
|
|
|
|
export function debounce(func, delay = 500) {
|
|
|
|
|
let timer
|
|
|
|
|
return function(...args) {
|
|
|
|
|
clearTimeout(timer)
|
|
|
|
|
timer = setTimeout(() => {
|
|
|
|
|
func.call(this, ...args)
|
|
|
|
|
}, delay)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 参数解析:
|
|
|
|
|
* ctx: canvas绘图上下文
|
|
|
|
|
* str: 需要绘制的文本内容
|
|
|
|
|
* draw_width: 绘制后的文字显示宽度
|
|
|
|
|
* lineNum: 最大行数,多出部分用'...'表示, 如果传-1可以达到自动换行效果
|
|
|
|
|
* startX: 绘制文字的起点 X 轴坐标
|
|
|
|
|
* startY: 绘制文字的起点 Y 轴坐标
|
|
|
|
|
* steps: 文字行间距
|
|
|
|
|
* textIndent: 是否首行缩进两个字符
|
|
|
|
|
*/
|
|
|
|
|
export function toFormateStr(ctx, str, draw_width, lineNum, startX, startY, steps, textIndent) {
|
|
|
|
|
var strWidth = ctx.measureText(str).width // 测量文本源尺寸信息(宽度)
|
|
|
|
|
var startpoint = startY; var keyStr = ''; var sreLN = strWidth / draw_width
|
|
|
|
|
// 计算文本源一共能生成多少行
|
|
|
|
|
var liner = Math.ceil(sreLN)
|
|
|
|
|
// 等比缩放测量一行文本显示多少个字符
|
|
|
|
|
const strlen = parseInt(str.length / sreLN)
|
|
|
|
|
// 若文本不足一行,则直接绘制,反之大于传入的最多行数(lineNum)以省略号(...)代替
|
|
|
|
|
if (strWidth < draw_width) {
|
|
|
|
|
ctx.fillText(str, startX, startpoint)
|
|
|
|
|
} else {
|
|
|
|
|
for (var i = 1; i < liner + 1; i++) {
|
|
|
|
|
const startPoint = strlen * (i - 1)
|
|
|
|
|
if (i < lineNum || lineNum === -1) {
|
|
|
|
|
keyStr = str.substr(startPoint, strlen)
|
|
|
|
|
ctx.fillText(keyStr, i === 1 && textIndent ? startX + draw_width / strlen * 2 : startX, startpoint)
|
|
|
|
|
} else {
|
|
|
|
|
keyStr = str.substr(startPoint, strlen - 5) + '...'
|
|
|
|
|
ctx.fillText(keyStr, startX, startpoint)
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
startpoint = startpoint + steps
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* file转base64
|
|
|
|
|
* @param { * } file 图片文件
|
|
|
|
|
* @return {base64}
|
|
|
|
|
*/
|
|
|
|
|
export const fileToBase64 = file => {
|
|
|
|
|
const reader = new FileReader()
|
|
|
|
|
reader.readAsDataURL(file)
|
|
|
|
|
reader.onload = function(e) {
|
|
|
|
|
return e.target.result
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* base64转 file
|
|
|
|
|
* @param { * } dataurl 图片链接
|
|
|
|
|
* filename 图片名称
|
|
|
|
|
* @return {file}
|
|
|
|
|
*/
|
|
|
|
|
export const base64ImgtoFile = (dataurl, filename = 'file') => {
|
|
|
|
|
const arr = dataurl.split(',')
|
|
|
|
|
const mime = arr[0].match(/:(.*?);/)[1]
|
|
|
|
|
const suffix = mime.split('/')[1]
|
|
|
|
|
// atob : 解码使用 base-64 编码的字符串
|
|
|
|
|
const bstr = window.atob(arr[1])
|
|
|
|
|
let n = bstr.length
|
|
|
|
|
const u8arr = new Uint8Array(n)
|
|
|
|
|
while (n--) {
|
|
|
|
|
u8arr[n] = bstr.charCodeAt(n)
|
|
|
|
|
}
|
|
|
|
|
return new File([u8arr], `${filename}.${suffix}`, {
|
|
|
|
|
type: mime
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 树形结构扁平化
|
|
|
|
|
* @param tree 树形结构数据
|
|
|
|
|
* @return []
|
|
|
|
|
*/
|
|
|
|
|
export function treeToArray(tree) {
|
|
|
|
|
var res = []
|
|
|
|
|
for (const item of tree) {
|
|
|
|
|
const { children, ...i } = item
|
|
|
|
|
if (children && children.length) {
|
|
|
|
|
res = res.concat(treeToArray(children))
|
|
|
|
|
}
|
|
|
|
|
res.push(i)
|
|
|
|
|
}
|
|
|
|
|
return res
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* @author lhx
|
|
|
|
|
* @description 返回树形数据
|
|
|
|
|
* @param val
|
|
|
|
|
* @returns {string}
|
|
|
|
|
*/
|
|
|
|
|
export function jsonToTree(objects, keyName, parentKeyName) {
|
|
|
|
|
if (!keyName) {
|
|
|
|
|
keyName = 'id'
|
|
|
|
|
}
|
|
|
|
|
if (!parentKeyName) {
|
|
|
|
|
parentKeyName = 'parentId'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// * 先生成parent建立父子关系
|
|
|
|
|
const obj = {}
|
|
|
|
|
objects.forEach((item) => {
|
|
|
|
|
obj[item[keyName]] = item
|
|
|
|
|
})
|
|
|
|
|
const parentList = []
|
|
|
|
|
objects.forEach((item) => {
|
|
|
|
|
// item.hasChildren = false;
|
|
|
|
|
const parent = obj[item[parentKeyName]]
|
|
|
|
|
if (parent) {
|
|
|
|
|
// * 当前项有父节点
|
|
|
|
|
parent.children = parent.children || []
|
|
|
|
|
parent.children.push(item)
|
|
|
|
|
// parent.hasChildren = true;
|
|
|
|
|
} else {
|
|
|
|
|
// * 当前项没有父节点 -> 顶层
|
|
|
|
|
parentList.push(item)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
return parentList
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* @author lhx
|
|
|
|
|
* @description 迭代方式实现补零
|
|
|
|
|
* @param val
|
|
|
|
|
* @returns {string}
|
|
|
|
|
*/
|
|
|
|
|
export function zeroFill(num, length) {
|
|
|
|
|
for (var len = (num + '').length; len < length; len = num.length) {
|
|
|
|
|
num = '0' + num
|
|
|
|
|
}
|
|
|
|
|
return num
|
|
|
|
|
}
|