2025-03-30 22:09:19 +08:00
|
|
|
|
// 引入导出Excel表格依赖
|
|
|
|
|
import * as FileSaver from "file-saver"
|
|
|
|
|
import * as XLSX from "xlsx"
|
|
|
|
|
import { getItem } from "@/utils/storage"
|
|
|
|
|
import { getApi, postApi } from "@/api/tobAcco_api.js"
|
|
|
|
|
import store from "@/store"
|
|
|
|
|
import { ElLoading } from "element-plus"
|
|
|
|
|
|
|
|
|
|
// 获取图片访问路径
|
|
|
|
|
export const getImgUrl = iconName => {
|
|
|
|
|
if (process.env.NODE_ENV === "development") {
|
2025-03-30 22:20:09 +08:00
|
|
|
|
return "http://192.168.1.6:8888/" + iconName
|
2025-03-30 22:09:19 +08:00
|
|
|
|
} else if (process.env.NODE_ENV === "production") {
|
|
|
|
|
return window.location.origin + "/files/" + iconName//云平台
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//是否是字符串类型
|
|
|
|
|
export function isString(value) {
|
|
|
|
|
return typeof value === "string"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//生成uuid
|
|
|
|
|
export function generateUUID() {
|
|
|
|
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
|
|
|
|
|
var r = (Math.random() * 16) | 0,
|
|
|
|
|
v = c === "x" ? r : (r & 0x3) | 0x8
|
|
|
|
|
return v.toString(16)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 下载模板,携带token
|
|
|
|
|
export function downloadTemplate(type, fileName) {
|
|
|
|
|
fileName = fileName ? fileName : "模板"
|
|
|
|
|
let url = `/mosty-api/mosty-jcgl/common/exportExcelTemplate?type=${type}`
|
|
|
|
|
let token = getItem("token")
|
|
|
|
|
const headers = new Headers()
|
|
|
|
|
headers.append("Authorization", token) // 设置token
|
|
|
|
|
// 发起 Fetch 请求
|
|
|
|
|
fetch(url, {
|
|
|
|
|
method: "GET",
|
|
|
|
|
headers: headers
|
|
|
|
|
})
|
|
|
|
|
.then(res => res.blob())
|
|
|
|
|
.then(blob => {
|
|
|
|
|
let a = document.createElement("a")
|
|
|
|
|
a.download = fileName + ".xlsx"
|
|
|
|
|
a.href = window.URL.createObjectURL(blob)
|
|
|
|
|
a.style.display = "none"
|
|
|
|
|
document.body.appendChild(a)
|
|
|
|
|
a.click()
|
|
|
|
|
a.remove()
|
|
|
|
|
})
|
|
|
|
|
.catch(error => console.error("下载失败:", error))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 下载模板,携带token
|
|
|
|
|
export function downloadewm(url, fileName) {
|
|
|
|
|
const loading = ElLoading.service({
|
|
|
|
|
lock: true,
|
|
|
|
|
text: "下载中...",
|
|
|
|
|
background: "rgba(0, 0, 0, 0.7)"
|
|
|
|
|
})
|
|
|
|
|
fileName = fileName ? fileName : ""
|
|
|
|
|
let token = getItem("token")
|
|
|
|
|
const headers = new Headers()
|
|
|
|
|
headers.append("Authorization", token) // 设置token
|
|
|
|
|
// 发起 Fetch 请求
|
|
|
|
|
fetch(url, {
|
|
|
|
|
method: "GET",
|
|
|
|
|
headers: headers
|
|
|
|
|
})
|
|
|
|
|
.then(res => res.blob())
|
|
|
|
|
.then(blob => {
|
|
|
|
|
let a = document.createElement("a")
|
|
|
|
|
a.download = fileName + ".zip"
|
|
|
|
|
a.href = window.URL.createObjectURL(blob)
|
|
|
|
|
a.style.display = "none"
|
|
|
|
|
document.body.appendChild(a)
|
|
|
|
|
a.click()
|
|
|
|
|
a.remove()
|
|
|
|
|
loading.close()
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
loading.close()
|
|
|
|
|
console.error("下载失败:", error)
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 下载二维码
|
|
|
|
|
export function qrcodeImg(id, type, ...name) {
|
|
|
|
|
let url = `/mosty-api/mosty-jcgl/common/createQrCode?objid=${id}&type=${type}`
|
|
|
|
|
if (name.length > 0) {
|
|
|
|
|
for (let i = 0; i < name.length; i++) {
|
|
|
|
|
const el = name[i]
|
|
|
|
|
url = url + `&texts=${el}`
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return url
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//下载培训二维码
|
|
|
|
|
export function qrcodepxImg(id, type, name, ...texts) {
|
|
|
|
|
let url = `/mosty-api/mosty-jcgl/common/createQrCodeNoStyle?objid=${id}&objname=${name}&type=${type}`
|
|
|
|
|
if (texts.length > 0) {
|
|
|
|
|
for (let i = 0; i < texts.length; i++) {
|
|
|
|
|
const el = texts[i]
|
|
|
|
|
url = url + `&texts=${el}`
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return url
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 数据去重 相同数据值累加
|
|
|
|
|
* @param {Object} array 数据
|
|
|
|
|
*/
|
|
|
|
|
export function setArray(array) {
|
|
|
|
|
let newArr = []
|
|
|
|
|
array.forEach(item => {
|
|
|
|
|
const res = newArr.findIndex(ol => {
|
|
|
|
|
//组织机构代码相同 并且报警类别相同
|
|
|
|
|
return item.ssbmdm == ol.ssbmdm && item.bjlb == ol.bjlb
|
|
|
|
|
})
|
|
|
|
|
if (res !== -1) {
|
|
|
|
|
newArr[res].sl = newArr[res].sl + item.sl
|
|
|
|
|
} else {
|
|
|
|
|
newArr.push(item)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return newArr
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 合并数据
|
|
|
|
|
* @param {Object} array 数据
|
|
|
|
|
*/
|
|
|
|
|
export function hbArray(array, item1, item2, item3) {
|
|
|
|
|
let newArr = []
|
|
|
|
|
array.forEach(item => {
|
|
|
|
|
const res = newArr.findIndex(ol => {
|
|
|
|
|
//组织机构代码相同 并且报警类别相同
|
|
|
|
|
return item.product == ol.product
|
|
|
|
|
})
|
|
|
|
|
if (res !== -1) {
|
|
|
|
|
newArr[res][item1] = newArr[res][item1] + item[item1]
|
|
|
|
|
newArr[res][item2] = newArr[res][item2] + item[item2]
|
|
|
|
|
newArr[res][item3] = newArr[res][item3] + item[item3]
|
|
|
|
|
} else {
|
|
|
|
|
newArr.push(item)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return newArr
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*时间格式
|
|
|
|
|
* @export
|
|
|
|
|
* @param {*} [obj={}] type:时间类型 time:时间
|
|
|
|
|
* @return {*} 返回的时间
|
|
|
|
|
*/
|
|
|
|
|
export function dateFormat(obj = {}) {
|
|
|
|
|
let { type, time } = obj
|
|
|
|
|
let date
|
|
|
|
|
if (time) {
|
|
|
|
|
date = new Date(time)
|
|
|
|
|
} else {
|
|
|
|
|
date = new Date()
|
|
|
|
|
}
|
|
|
|
|
let year = date.getFullYear()
|
|
|
|
|
let month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1
|
|
|
|
|
let hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours()
|
|
|
|
|
let minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()
|
|
|
|
|
let seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds()
|
|
|
|
|
let day
|
|
|
|
|
|
|
|
|
|
if (type == "front_one_day") {
|
|
|
|
|
//前一天日期
|
|
|
|
|
day = date.getDate() - 1
|
|
|
|
|
day = day < 10 ? "0" + day : day
|
|
|
|
|
return `${year}-${month}-${day}`
|
|
|
|
|
} else if (type == "month") {
|
|
|
|
|
// month = month < 10 ? "0" + month : month;
|
|
|
|
|
//返回年月
|
|
|
|
|
return `${year}-${month}`
|
|
|
|
|
} else if (type == "one") {
|
|
|
|
|
//返回当年一月
|
|
|
|
|
month = date.getMonth() - date.getMonth() + 1
|
|
|
|
|
month = month < 10 ? "0" + month : month
|
|
|
|
|
return `${year}-${month}`
|
|
|
|
|
} else if (type == "all") {
|
|
|
|
|
//格式化日期时间
|
|
|
|
|
day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate()
|
|
|
|
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
|
|
|
|
} else if (type == "queen_two_hour") {
|
|
|
|
|
//后两小时
|
|
|
|
|
let date1 = new Date(date.getTime() + 2 * 60 * 60 * 1000)
|
|
|
|
|
return setTimeTormat(date1)
|
|
|
|
|
} else if (type == "year") {
|
|
|
|
|
//返回年份
|
|
|
|
|
return year
|
|
|
|
|
} else if (type == "sfm") {
|
|
|
|
|
//返回年份
|
|
|
|
|
let hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours()
|
|
|
|
|
let minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()
|
|
|
|
|
let seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds()
|
|
|
|
|
return `${hours}:${minutes}:${seconds}`
|
|
|
|
|
} else if (type == "day") {
|
|
|
|
|
day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate()
|
|
|
|
|
// month = month < 10 ? "0" + month : month;
|
|
|
|
|
//返回年月日
|
|
|
|
|
return `${year}-${month}-${day}`
|
|
|
|
|
} else if (type == "ones") {
|
|
|
|
|
//返回当年一月
|
|
|
|
|
month = date.getMonth() - date.getMonth() + 1
|
|
|
|
|
month = month < 10 ? "0" + month : month
|
|
|
|
|
day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate()
|
|
|
|
|
return `${year}-${month}-${day}`
|
|
|
|
|
} else if (type == "lastmonth") {
|
|
|
|
|
// 计算上一个月的年份和月份
|
|
|
|
|
date.setMonth(date.getMonth() - 1)
|
|
|
|
|
let months = date.getMonth() + 1
|
|
|
|
|
if (months < 10) {
|
|
|
|
|
months = "0" + (date.getMonth() + 1)
|
|
|
|
|
}
|
|
|
|
|
return `${date.getFullYear()}-${months}`
|
|
|
|
|
} else if (type == "firstday") {
|
|
|
|
|
// 获取当年第一天
|
|
|
|
|
return `${year}-01-01`
|
|
|
|
|
} else {
|
|
|
|
|
//当天日期
|
|
|
|
|
day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate()
|
|
|
|
|
return `${year}-${month}-${day}`
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 累加或者累减保持精度
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {*String} type 默认add加
|
|
|
|
|
* @param {*Number} part 保留几位小数 4
|
|
|
|
|
* @param {...any} args 需要加减的参数
|
|
|
|
|
* @param {Number} total 初始值
|
|
|
|
|
* @returns
|
|
|
|
|
*/
|
|
|
|
|
export function numAdd(type = "add", part = 4, total = 0, ...args) {
|
|
|
|
|
let count = Number(total)
|
|
|
|
|
for (let i = 0; i < args.length; i++) {
|
|
|
|
|
if (isNaN(args[i])) {
|
|
|
|
|
continue
|
|
|
|
|
} else {
|
|
|
|
|
args[i] = Number(args[i])
|
|
|
|
|
count = type == "add" ? (count += args[i]) : (count -= args[i])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return part != -1 ? Number(count.toPrecision(20)).toFixed(part) : Number(count.toPrecision(20))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//设置时间
|
|
|
|
|
function setTimeTormat(date) {
|
|
|
|
|
let year1 = date.getFullYear()
|
|
|
|
|
let month1 = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1
|
|
|
|
|
let day1 = date.getDate() < 10 ? "0" + date.getDate() : date.getDate()
|
|
|
|
|
let hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours()
|
|
|
|
|
let minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()
|
|
|
|
|
let seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds()
|
|
|
|
|
return `${year1}-${month1}-${day1} ${hours}:${minutes}:${seconds}`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 查询当天日期
|
|
|
|
|
*/
|
|
|
|
|
export function getNowDate() {
|
|
|
|
|
const timeOne = new Date()
|
|
|
|
|
const year = timeOne.getFullYear()
|
|
|
|
|
let month = timeOne.getMonth() + 1
|
|
|
|
|
let day = timeOne.getDate()
|
|
|
|
|
month = month < 10 ? "0" + month : month
|
|
|
|
|
day = day < 10 ? "0" + day : day
|
|
|
|
|
const NOW_MONTHS_AGO = `${year}.${month}.${day}`
|
|
|
|
|
return NOW_MONTHS_AGO
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取当前系统的时间
|
|
|
|
|
export function formatTime(data, flag) {
|
|
|
|
|
const date = data ? new Date(data) : new Date()
|
|
|
|
|
const y = date.getFullYear()
|
|
|
|
|
let m = date.getMonth() + 1
|
|
|
|
|
m = m < 10 ? "0" + m : m
|
|
|
|
|
let d = date.getDate()
|
|
|
|
|
d = d < 10 ? "0" + d : d
|
|
|
|
|
let h = date.getHours()
|
|
|
|
|
h = h < 10 ? "0" + h : h
|
|
|
|
|
let minute = date.getMinutes()
|
|
|
|
|
minute = minute < 10 ? "0" + minute : minute
|
|
|
|
|
let second = date.getSeconds()
|
|
|
|
|
second = second < 10 ? "0" + second : second
|
|
|
|
|
if (flag == "ymd") {
|
|
|
|
|
return y + "-" + m + "-" + d
|
|
|
|
|
} else if (flag == "ym") {
|
|
|
|
|
return y + "-" + m
|
|
|
|
|
} else {
|
|
|
|
|
return h + ":" + minute + ":" + second
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//选择出生日期
|
|
|
|
|
export function getDefaultDate() {
|
|
|
|
|
const now = new Date()
|
|
|
|
|
const oneYearAgo = new Date(now.getFullYear() - 18, now.getMonth(), now.getDate())
|
|
|
|
|
return oneYearAgo.toISOString().substring(0, 10)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//禁止选择18年后的日期
|
|
|
|
|
export function disabledDate(time) {
|
|
|
|
|
const date = new Date(time)
|
|
|
|
|
const year = date.getFullYear()
|
|
|
|
|
return year > new Date().getFullYear() - 18
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//禁止选择当前系统之前的时间以及当前系统日期
|
|
|
|
|
export function disablednowDate(time) {
|
|
|
|
|
return time.getTime() + 24 * 60 * 60 * 1000 > Date.now()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function disablednowDate1(time) {
|
|
|
|
|
return time.getTime() > Date.now()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//禁止选择当前系统之后的时间
|
|
|
|
|
export function disablednowDates(time) {
|
|
|
|
|
return time.getTime() + 24 * 60 * 60 * 1000 < Date.now()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//禁止选择当前系统之后的月份
|
|
|
|
|
export function disablednowmonth(time) {
|
|
|
|
|
return time.getTime() < Date.now()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//数字超长处理
|
|
|
|
|
export function handleNum(num) {
|
|
|
|
|
var data = 0
|
|
|
|
|
if (num) {
|
|
|
|
|
try {
|
|
|
|
|
if (num * 1 > 100000) {
|
|
|
|
|
data = (num / 10000).toFixed(0) + "万"
|
|
|
|
|
} else {
|
|
|
|
|
data = (num * 1).toFixed(0)
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
data = 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 文件是否是图片
|
|
|
|
|
* @param {*} val
|
|
|
|
|
*/
|
|
|
|
|
export function IS_PNG(val) {
|
|
|
|
|
return (
|
|
|
|
|
["bmp", "jpg", "png", "tif", "gif", "pcx", "tga", "exif", "fpx", "svg", "psd", "cdr", "pcd", "dxf", "ufo", "eps", "ai", "raw", "wmf", "webp", "avif", "apng"].indexOf(
|
|
|
|
|
val.toLowerCase()
|
|
|
|
|
) !== -1
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 文件是否是音频
|
|
|
|
|
* @param {*} val
|
|
|
|
|
*/
|
|
|
|
|
export function IS_MP3(val) {
|
|
|
|
|
return ["mp3", "wav", "wma", "mp2", "flac", "midi", "ra", "ape", "aac", "cda", "mov"].indexOf(val.toLowerCase()) !== -1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 文件是否是视频
|
|
|
|
|
* @param {*} val
|
|
|
|
|
*/
|
|
|
|
|
export function IS_MP4(val) {
|
|
|
|
|
return ["avi", "wmv", "mpeg", "mp4", "m4v", "mov", "asf", "fiv", "f4v", "mvb", "rm", "3gp", "vob"].indexOf(val.toLowerCase()) !== -1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*对象数组排序
|
|
|
|
|
* @export
|
|
|
|
|
* @param {*} attr 排序的字段
|
|
|
|
|
* @param {*} rev true 升序 false 降序
|
|
|
|
|
*/
|
|
|
|
|
export function compare(attr, rev) {
|
|
|
|
|
if (rev == undefined) {
|
|
|
|
|
rev = 1
|
|
|
|
|
} else {
|
|
|
|
|
rev = rev ? 1 : -1
|
|
|
|
|
}
|
|
|
|
|
return (a, b) => {
|
|
|
|
|
a = a[attr]
|
|
|
|
|
b = b[attr]
|
|
|
|
|
if (a > b) {
|
|
|
|
|
return rev * -1
|
|
|
|
|
}
|
|
|
|
|
if (a < b) {
|
|
|
|
|
return rev * 1
|
|
|
|
|
}
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//附件下载
|
|
|
|
|
export function createAndClickLink(downloadUrl, fileName) {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
const xhr = new window.XMLHttpRequest()
|
|
|
|
|
xhr.open("GET", downloadUrl, true)
|
|
|
|
|
xhr.responseType = "blob"
|
|
|
|
|
|
|
|
|
|
xhr.onload = () => {
|
|
|
|
|
const url = window.URL.createObjectURL(xhr.response)
|
|
|
|
|
const a = document.createElement("a")
|
|
|
|
|
a.href = url
|
|
|
|
|
a.download = fileName
|
|
|
|
|
// 使用 setTimeout 延迟点击操作
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
a.click()
|
|
|
|
|
window.URL.revokeObjectURL(url) // 释放资源
|
|
|
|
|
resolve() // 解决 Promise
|
|
|
|
|
}, 0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xhr.onerror = () => {
|
|
|
|
|
reject(new Error("文件下载失败"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xhr.send()
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*导出表格
|
|
|
|
|
* @export
|
|
|
|
|
* @param {object} title 表头
|
|
|
|
|
* @param {Array} data 数据
|
|
|
|
|
* @param {*} XLSX 插件实例化对象
|
|
|
|
|
* @param {*} fileName 文件名称
|
|
|
|
|
*/
|
|
|
|
|
export function exportXlsx(title, tableData, XLSX, fileName) {
|
|
|
|
|
const list = tableData.map(item => {
|
|
|
|
|
const obj = {}
|
|
|
|
|
for (const k in item) {
|
|
|
|
|
if (title[k]) {
|
|
|
|
|
obj[title[k]] = item[k]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return obj
|
|
|
|
|
})
|
|
|
|
|
//创建表个数据
|
|
|
|
|
const data = XLSX.utils.json_to_sheet(list)
|
|
|
|
|
const wb = XLSX.utils.book_new()
|
|
|
|
|
XLSX.utils.book_append_sheet(wb, data, "data")
|
|
|
|
|
XLSX.writeFile(wb, fileName + ".xlsx")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//节流
|
|
|
|
|
|
|
|
|
|
export function _throttle(func, delay) {
|
|
|
|
|
let timer = null
|
|
|
|
|
let startTime = Date.now()
|
|
|
|
|
return () => {
|
|
|
|
|
let curTime = Date.now()
|
|
|
|
|
let remaining = delay - (curTime - startTime)
|
|
|
|
|
let context = this
|
|
|
|
|
let args = arguments
|
|
|
|
|
clearTimeout(timer)
|
|
|
|
|
if (remaining <= 0) {
|
|
|
|
|
func.apply(context, args)
|
|
|
|
|
startTime = Date.now()
|
|
|
|
|
} else {
|
|
|
|
|
timer = setTimeout(func, remaining)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//echarts自适应
|
|
|
|
|
export function chartAdaptation(chart) {
|
|
|
|
|
const DELAY = 500 // 延迟时间
|
|
|
|
|
let fnn = _throttle(() => {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
chart.resize()
|
|
|
|
|
}, 300)
|
|
|
|
|
}, DELAY)
|
|
|
|
|
window.addEventListener("resize", fnn)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//深拷贝
|
|
|
|
|
export function deepClone(obj, cache = new WeakMap()) {
|
|
|
|
|
if (typeof obj !== "object") return obj // 普通类型,直接返回
|
|
|
|
|
if (obj === null) return obj
|
|
|
|
|
if (cache.get(obj)) return cache.get(obj) // 防止循环引用,程序进入死循环
|
|
|
|
|
if (obj instanceof Date) return new Date(obj)
|
|
|
|
|
if (obj instanceof RegExp) return new RegExp(obj)
|
|
|
|
|
|
|
|
|
|
// 找到所属原型上的constructor,所属原型上的constructor指向当前对象的构造函数
|
|
|
|
|
let cloneObj = new obj.constructor()
|
|
|
|
|
cache.set(obj, cloneObj) // 缓存拷贝的对象,用于处理循环引用的情况
|
|
|
|
|
for (let key in obj) {
|
|
|
|
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
|
|
|
cloneObj[key] = deepClone(obj[key], cache) // 递归拷贝
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return cloneObj
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//导出为Excel表格 exportExcel
|
|
|
|
|
export function exportExcel(tabname) {
|
|
|
|
|
//从表生成工作簿对象
|
|
|
|
|
var wb = XLSX.utils.table_to_book(document.querySelector("#out-table"))
|
|
|
|
|
//获取二进制字符串作为输出
|
|
|
|
|
var wbout = XLSX.write(wb, {
|
|
|
|
|
bookType: "xlsx",
|
|
|
|
|
bookSST: true,
|
|
|
|
|
type: "array"
|
|
|
|
|
})
|
|
|
|
|
try {
|
|
|
|
|
FileSaver.saveAs(
|
|
|
|
|
//Blob 对象表示一个不可变、原始数据的类文件对象。
|
|
|
|
|
//Blob 表示的不一定是JavaScript原生格式的数据。
|
|
|
|
|
//File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。
|
|
|
|
|
//返回一个新创建的 Blob 对象,其内容由参数中给定的数组串联组成。
|
|
|
|
|
new Blob([wbout], { type: "application/octet-stream" }),
|
|
|
|
|
//设置导出文件名称
|
|
|
|
|
`${tabname ? tabname : "index"}.xlsx`
|
|
|
|
|
)
|
|
|
|
|
} catch (e) {
|
|
|
|
|
if (typeof console !== "undefined") {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return wbout
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//表格合计
|
|
|
|
|
export function getSummaries(param) {
|
|
|
|
|
const { columns, data } = param
|
|
|
|
|
const sums = []
|
|
|
|
|
columns.forEach((column, index) => {
|
|
|
|
|
if (index === 0) {
|
|
|
|
|
sums[index] = "合计"
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
const values = data.map(item => Number(item[column.property]))
|
|
|
|
|
if (!values.every(value => isNaN(value))) {
|
|
|
|
|
sums[index] = values.reduce((prev, curr) => {
|
|
|
|
|
const value = Number(curr)
|
|
|
|
|
if (!isNaN(value)) {
|
|
|
|
|
return numAdd("add", -1, prev, curr)
|
|
|
|
|
} else {
|
|
|
|
|
return prev
|
|
|
|
|
}
|
|
|
|
|
}, 0)
|
|
|
|
|
} else {
|
|
|
|
|
sums[index] = "N/A"
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
return sums
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//合并数组方法
|
|
|
|
|
export function mergeArray(arr1, arr2) {
|
|
|
|
|
const newArray = []
|
|
|
|
|
let length1 = arr1.length
|
|
|
|
|
let length2 = arr2.length
|
|
|
|
|
for (let i = 0; i < length1; i++) {
|
|
|
|
|
for (let j = 0; j < length2; j++) {
|
|
|
|
|
if (i == j) {
|
|
|
|
|
let mergeItem = Object.assign(arr1[i], arr2[j])
|
|
|
|
|
newArray.push(mergeItem)
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return newArray
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 1 . 手机校验 */
|
|
|
|
|
export const validatePhone = rule => {
|
|
|
|
|
return (rule, value, callback) => {
|
|
|
|
|
if (!value) {
|
|
|
|
|
} else {
|
|
|
|
|
const reg = /^1[3|4|5|7|8][0-9]\d{8}$/
|
|
|
|
|
if (reg.test(value)) {
|
|
|
|
|
callback()
|
|
|
|
|
} else {
|
|
|
|
|
return callback(new Error("请输入正确的手机号"))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//身份证校验
|
|
|
|
|
export const validateIdentity = () => {
|
|
|
|
|
return (rule, value, callback) => {
|
|
|
|
|
if (!value) {
|
|
|
|
|
// return callback(new Error('身份证号不能为空'));
|
|
|
|
|
} else if (!/(^\d{15}$)|(^\d{17}(\d|X|x)$)/.test(value)) {
|
|
|
|
|
callback(new Error("输入的身份证长度或格式错误"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//身份证城市
|
|
|
|
|
var aCity = {
|
|
|
|
|
11: "北京",
|
|
|
|
|
12: "天津",
|
|
|
|
|
13: "河北",
|
|
|
|
|
14: "山西",
|
|
|
|
|
15: "内蒙古",
|
|
|
|
|
21: "辽宁",
|
|
|
|
|
22: "吉林",
|
|
|
|
|
23: "黑龙江",
|
|
|
|
|
31: "上海",
|
|
|
|
|
32: "江苏",
|
|
|
|
|
33: "浙江",
|
|
|
|
|
34: "安徽",
|
|
|
|
|
35: "福建",
|
|
|
|
|
36: "江西",
|
|
|
|
|
37: "山东",
|
|
|
|
|
41: "河南",
|
|
|
|
|
42: "湖北",
|
|
|
|
|
43: "湖南",
|
|
|
|
|
44: "广东",
|
|
|
|
|
45: "广西",
|
|
|
|
|
46: "海南",
|
|
|
|
|
50: "重庆",
|
|
|
|
|
51: "四川",
|
|
|
|
|
52: "贵州",
|
|
|
|
|
53: "云南",
|
|
|
|
|
54: "西藏",
|
|
|
|
|
61: "陕西",
|
|
|
|
|
62: "甘肃",
|
|
|
|
|
63: "青海",
|
|
|
|
|
64: "宁夏",
|
|
|
|
|
65: "新疆",
|
|
|
|
|
71: "台湾",
|
|
|
|
|
81: "香港",
|
|
|
|
|
82: "澳门",
|
|
|
|
|
91: "国外"
|
|
|
|
|
}
|
|
|
|
|
if (!aCity[parseInt(value.substr(0, 2))]) {
|
|
|
|
|
callback(new Error("身份证地区非法"))
|
|
|
|
|
}
|
|
|
|
|
// 出生日期验证
|
|
|
|
|
var sBirthday = (value.substr(6, 4) + "-" + Number(value.substr(10, 2)) + "-" + Number(value.substr(12, 2))).replace(/-/g, "/"),
|
|
|
|
|
d = new Date(sBirthday)
|
|
|
|
|
if (sBirthday !== d.getFullYear() + "/" + (d.getMonth() + 1) + "/" + d.getDate()) {
|
|
|
|
|
callback(new Error("身份证上的出生日期非法"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 身份证号码校验
|
|
|
|
|
var sum = 0,
|
|
|
|
|
weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2],
|
|
|
|
|
codes = "10X98765432"
|
|
|
|
|
for (var i = 0; i < value.length - 1; i++) {
|
|
|
|
|
sum += value[i] * weights[i]
|
|
|
|
|
}
|
|
|
|
|
var last = codes[sum % 11] //计算出来的最后一位身份证号码
|
|
|
|
|
if (value[value.length - 1] !== last) {
|
|
|
|
|
callback(new Error("输入的身份证号非法"))
|
|
|
|
|
}
|
|
|
|
|
callback()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据身份证计算出生日期
|
|
|
|
|
* @param {*} idCard
|
|
|
|
|
* @returns
|
|
|
|
|
*/
|
|
|
|
|
export function getBirthdayFromIdCard(idCard) {
|
|
|
|
|
var birthday = ""
|
|
|
|
|
if (idCard != null && idCard != "") {
|
|
|
|
|
if (idCard.length == 15) {
|
|
|
|
|
birthday = "19" + idCard.substr(6, 6)
|
|
|
|
|
} else if (idCard.length == 18) {
|
|
|
|
|
birthday = idCard.substr(6, 8)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
birthday = birthday.replace(/(.{4})(.{2})/, "$1-$2-")
|
|
|
|
|
}
|
|
|
|
|
return birthday
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 倒计时
|
|
|
|
|
* @param {*} time 目标时间
|
|
|
|
|
* @returns
|
|
|
|
|
*/
|
|
|
|
|
export function countDown(time) {
|
|
|
|
|
// 设置目标时间,这里以毫秒为单位。例如,设置为当前时间后的1小时
|
|
|
|
|
let countDownDate = time ? new Date(time).getTime() : new Date().getTime() // 1小时后的时间
|
|
|
|
|
// 获取当前时间
|
|
|
|
|
let now = new Date().getTime()
|
|
|
|
|
// 计算距离时间
|
|
|
|
|
let distance = countDownDate - now
|
|
|
|
|
// 倒计时时间计算
|
|
|
|
|
let num,
|
|
|
|
|
obj = { overtime: false, timeValue: "" }
|
|
|
|
|
if (distance > 0) {
|
|
|
|
|
num = distance
|
|
|
|
|
} else {
|
|
|
|
|
// 如果倒计时结束
|
|
|
|
|
num = Math.floor(Math.abs(distance))
|
|
|
|
|
obj.overtime = true
|
|
|
|
|
}
|
|
|
|
|
let days = Math.floor(num / (1000 * 60 * 60 * 24))
|
|
|
|
|
let hours = Math.floor((num % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
|
|
|
|
|
let minutes = Math.floor((num % (1000 * 60 * 60)) / (1000 * 60))
|
|
|
|
|
let seconds = Math.floor((num % (1000 * 60)) / 1000)
|
|
|
|
|
obj.timeValue = days + "天 " + hours + "时 " + minutes + "分 " + seconds + "秒 "
|
|
|
|
|
return obj
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function weekValidate(date) {
|
|
|
|
|
let val = (new Date(date)).getDay()
|
|
|
|
|
switch (val) {
|
|
|
|
|
case 0:
|
|
|
|
|
return "星期日"
|
|
|
|
|
case 1:
|
|
|
|
|
return "星期一"
|
|
|
|
|
case 2:
|
|
|
|
|
return "星期二"
|
|
|
|
|
case 3:
|
|
|
|
|
return "星期三"
|
|
|
|
|
case 4:
|
|
|
|
|
return "星期四"
|
|
|
|
|
case 5:
|
|
|
|
|
return "星期五"
|
|
|
|
|
case 6:
|
|
|
|
|
return "星期六"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 转换时间格式
|
|
|
|
|
export function timeValidate(date, type) {
|
|
|
|
|
const time = date ? new Date(date) : new Date()
|
|
|
|
|
const yyyy = time.getFullYear()
|
|
|
|
|
const MM = (time.getMonth() + 1).toString().padStart(2, 0)
|
|
|
|
|
const dd = time.getDate().toString().padStart(2, "0")
|
|
|
|
|
const hh = time.getHours().toString().padStart(2, "0")
|
|
|
|
|
const mm = time.getMinutes().toString().padStart(2, "0")
|
|
|
|
|
const ss = time.getSeconds().toString().padStart(2, "0")
|
|
|
|
|
if (type == "ymd") {
|
|
|
|
|
return `${yyyy}-${MM}-${dd}`
|
|
|
|
|
}
|
|
|
|
|
if (type == "md") {
|
|
|
|
|
return `${MM}.${dd}`
|
|
|
|
|
}
|
|
|
|
|
return `${yyyy}-${MM}-${dd} ${hh}:${mm}:${ss}`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**根据字典获取值
|
|
|
|
|
* @param {Array} dicArr 字典数组
|
|
|
|
|
* @param {String} val 值
|
|
|
|
|
*/
|
|
|
|
|
export function getValByDic(val, dicArr) {
|
|
|
|
|
|
|
|
|
|
val = typeof val === "string" ? val : ""
|
|
|
|
|
/** 是否多个数值 */
|
|
|
|
|
const isMult = val.indexOf(",") > -1
|
|
|
|
|
if (val === undefined) return ""
|
|
|
|
|
dicArr = Array.isArray(dicArr) ? dicArr : []
|
|
|
|
|
/** 字典对象 */
|
|
|
|
|
let dicObj = {}
|
|
|
|
|
for (let i = 0; i < dicArr.length; i++) {
|
|
|
|
|
const item = dicArr[i]
|
|
|
|
|
dicObj[item.value] = item.label
|
|
|
|
|
}
|
|
|
|
|
if (isMult) {
|
|
|
|
|
let valArr = val.split(",")
|
|
|
|
|
return valArr.map(dm => dicObj[dm]).join(",")
|
|
|
|
|
} else {
|
|
|
|
|
return dicObj[val] || val || "" // 查询不到返回原值
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 按钮权限 */
|
|
|
|
|
export function getAuth() {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
// 先强制为 true TODO: 方便所有人有权限
|
|
|
|
|
resolve(true)
|
|
|
|
|
// 后面以后用
|
|
|
|
|
// getApi({}, '/mosty-jcgl/securitychild/isAqyPower').then(res => {
|
|
|
|
|
// store.dispatch('user/setAuth', res)
|
|
|
|
|
// resolve(res)
|
|
|
|
|
// })
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 限制小数位数
|
|
|
|
|
* @param { Number,String} 值
|
|
|
|
|
* @param {Number} num 小数位数
|
|
|
|
|
*/
|
|
|
|
|
export function numberLimit(val, num = 2) {
|
|
|
|
|
if (val === 0) return "0"
|
|
|
|
|
if (!val) return ""
|
|
|
|
|
if (typeof val === "number") val = String(val)
|
|
|
|
|
if (typeof val !== "string") return ""
|
|
|
|
|
switch (num) {
|
|
|
|
|
case 1:
|
|
|
|
|
return val.match(/\d+\.?\d{0,1}/)?.[0] || ""
|
|
|
|
|
break
|
|
|
|
|
case 2:
|
|
|
|
|
return val.match(/\d+\.?\d{0,2}/)?.[0] || ""
|
|
|
|
|
break
|
|
|
|
|
case 3:
|
|
|
|
|
return val.match(/\d+\.?\d{0,3}/)?.[0] || ""
|
|
|
|
|
break
|
|
|
|
|
case 4:
|
|
|
|
|
return val.match(/\d+\.?\d{0,4}/)?.[0] || ""
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 将数字转换为中文数字表示形式 如11: 十一
|
|
|
|
|
*
|
|
|
|
|
* @param {number} num - 要转换的数字。
|
|
|
|
|
* @returns {string} - 转换后的中文数字字符串。
|
|
|
|
|
*/
|
|
|
|
|
export function toChineseNumber(num) {
|
|
|
|
|
// 四位四位的进行分割
|
|
|
|
|
const parts = num
|
|
|
|
|
.toString()
|
|
|
|
|
.replace(/(?=(\d{4})+$)/g, ",")
|
|
|
|
|
.split(",")
|
|
|
|
|
.filter(Boolean)
|
|
|
|
|
|
|
|
|
|
const map = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"]
|
|
|
|
|
const units = ["", "十", "百", "千"]
|
|
|
|
|
|
|
|
|
|
// 把连续的零给去掉 合并为1个零 当零在末尾的时候去掉
|
|
|
|
|
function _handleZero(str) {
|
|
|
|
|
return str.replace(/零+/g, "零").replace(/零$/, "")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function _transform(n) {
|
|
|
|
|
let result = ""
|
|
|
|
|
for (let i = 0; i < n.length; i++) {
|
|
|
|
|
const c = map[n[i]]
|
|
|
|
|
let u = units[n.length - i - 1]
|
|
|
|
|
if (c === "零") {
|
|
|
|
|
u = ""
|
|
|
|
|
}
|
|
|
|
|
result += c + u
|
|
|
|
|
}
|
|
|
|
|
result = _handleZero(result)
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const bigUnits = ["", "万", "亿"]
|
|
|
|
|
let result = ""
|
|
|
|
|
for (let i = 0; i < parts.length; i++) {
|
|
|
|
|
const p = parts[i]
|
|
|
|
|
const c = _transform(p)
|
|
|
|
|
const u = bigUnits[parts.length - i - 1]
|
|
|
|
|
if (c === "") {
|
|
|
|
|
result += "零"
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
result += c + u
|
|
|
|
|
}
|
|
|
|
|
result = _handleZero(result)
|
|
|
|
|
if (result === "一十一") return "十一"
|
|
|
|
|
if (result === "一十二") return "十二"
|
|
|
|
|
if (result === "一十三") return "十三"
|
|
|
|
|
if (result === "一十四") return "十四"
|
|
|
|
|
if (result === "一十五") return "十五"
|
|
|
|
|
if (result === "一十六") return "十六"
|
|
|
|
|
if (result === "一十七") return "十七"
|
|
|
|
|
if (result === "一十八") return "十八"
|
|
|
|
|
if (result === "一十九") return "十九"
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从一个列表中过滤目标数组
|
|
|
|
|
* @param originalData
|
|
|
|
|
* @param filteredData
|
|
|
|
|
*/
|
|
|
|
|
export const arrayFiltering = (originalData, filteredData) => {
|
|
|
|
|
let data = originalData
|
|
|
|
|
for (let i = 0; i < data.length; i++) {
|
|
|
|
|
for (let j = 0; j < filteredData.length; j++) {
|
|
|
|
|
if (filteredData[j] in data[i]) {
|
|
|
|
|
if (typeof data[i][filteredData[j]] !== "number" && typeof data[i][filteredData[j]] !== "boolean") {
|
|
|
|
|
if (data[i][filteredData[j]] !== null && (typeof data[i][filteredData[j]] === "string" || data[i][filteredData[j]] instanceof Array) && data[i][filteredData[j]].length) {
|
|
|
|
|
if (j === filteredData.length - 1) {
|
|
|
|
|
data[i]["sign"] = true
|
|
|
|
|
}
|
|
|
|
|
}else {
|
|
|
|
|
data[i]["sign"] = false
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
data[i]["sign"] = false
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 检查原始对象中是否包含合规的数据
|
|
|
|
|
* @param primaryObject
|
|
|
|
|
* @param filterArray
|
|
|
|
|
*/
|
|
|
|
|
export const singleObjectCheck = (primaryObject, filterArray) => {
|
|
|
|
|
for (let i = 0; i < filterArray.length; i++) {
|
|
|
|
|
if (filterArray[i] in primaryObject) {
|
|
|
|
|
if (typeof primaryObject[filterArray[i]] !== "number" && typeof primaryObject[filterArray[i]] !== "boolean" && typeof primaryObject[filterArray[i]] !== "undefined") {
|
|
|
|
|
if (primaryObject[filterArray[i]] !== null && (typeof primaryObject[filterArray[i]] === "string" || primaryObject[filterArray[i]] instanceof Array) && primaryObject[filterArray[i]].length) {
|
|
|
|
|
if (i === filterArray.length - 1) {
|
|
|
|
|
primaryObject["sign"] = true
|
|
|
|
|
}
|
|
|
|
|
}else {
|
|
|
|
|
primaryObject["sign"] = false
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}else {
|
|
|
|
|
primaryObject["sign"] = true
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
primaryObject["sign"] = false
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return primaryObject
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 判断两个数组是否有交集
|
|
|
|
|
* @param arr1
|
|
|
|
|
* @param arr2
|
|
|
|
|
* @returns {boolean}
|
|
|
|
|
*/
|
|
|
|
|
export const haveIntersection = (arr1, arr2) => {
|
|
|
|
|
return arr1.filter(item => arr2.includes(item)).length > 0;
|
|
|
|
|
}
|