import moment from 'moment' import storeInfo from '../../store/index' import router from "../../router" import { isIdentityId } from '@/views/utils/validate' import * as XLSX from 'xlsx' import * as XLSXStyle from 'xlsx-style' import { FundFilled } from '@ant-design/icons' //对象、一维数组去重(返回一个新数组) export const singleArr = (arr, val) => { let newArr = arr.concat() let len = newArr.length; if (val) { for (let i = 0; i < len; i++) { for (let j = i + 1; j < len; j++) { if (newArr[i][val] == newArr[j][val]) { newArr.splice(j, 1); len--; j--; } } } } else { for (let i = 0; i < len; i++) { for (let j = i + 1; j < len; j++) { if (newArr[i] == newArr[j]) { newArr.splice(j, 1); len--; j--; } } } } return newArr; } //删除关闭详情的页面 export const closedDetail = (url, goToUrl) => { let tabs = JSON.parse(window.sessionStorage.getItem('tabs')) for (let i = 0; i < tabs.length; i++) { if (tabs[i].key == url) { tabs.splice(i, 1) window.sessionStorage.setItem('tabs', JSON.stringify(tabs)) storeInfo.commit('changeTabs', tabs) if (goToUrl) { router.push(goToUrl) } else { router.push(tabs[i - 1].path) } } } } //判断对象values是否为空 并返回不为空对象 export const isEmptyParams = (obj) => { let obje = {} Object.assign(obje, obj) for (let key in obje) { if (obje[key] === '' || typeof obje[key] === 'undefined' || obje[key] === null || obje[key].length == 0) { delete obje[key] } if (obje[key] instanceof Array) { for (let i in obje[key]) { if (obje[key][i] instanceof Object) { for (let j in obje[key][i]) { if (obje[key][i][j] === '' || typeof obje[key][i][j] === 'undefined' || obje[key][i][j] === null || obje[key][i][j].length == 0) { delete obje[key][i][j] } } } } } } return obje } //数组转为树形结构 // toTree(数组,父id,父id属性key, id当前节点id key) export const toTree = (list, parId, pId, id) => { let len = list.length function loop (parId) { let res = []; for (let i = 0; i < len; i++) { let item = list[i] if (item[pId] == parId) { item.children = loop(item[id]) res.push(item) } } return res } return loop(parId) } //树形数据转数组 export const treeToArray = (source) => { let res = [] const fn = (source) => { source.forEach(el => { res.push(el) el.children && el.children.length > 0 ? fn(el.children) : "" }) return res } return fn(source) } //删除树状结构数据中空children export const removeEmptyChildren = (data) => { data.forEach(item => { if (item.children === null || item.children.length === 0) { delete item.children } else { removeEmptyChildren(item.children) } }) return data } //修改时间格式 export const timeFormat = (time, format = 'YYYY-MM-DD') => { let atime = moment(time).format(format) return atime } /** * 非空判断 已挂载到原型上$isNot * 解决Vue Template模板中无法使用可选链的问题 * eg: * let ces = { data: { data1: { name: '测试' } } } let b = this.$isNot(ces, 'data', 'data1', 'name') //测试 {{$isNot(ces, 'data', 'data1', 'name')}} //测试 */ // export const optionalChaining = (obj, ...rest) => { // let tmp = obj; // for (let key in rest) { // let name = rest[key]; // tmp = tmp?.[name]; //es11可选链 // } // return tmp ?? "未知"; // }; // 校验时间域 export const checkDateRange = (rule, dates, callback) => { if (dates.length === 2) { if (!dates[0] || !dates[1]) { callback('请选择时间') } else { callback() } } else { callback('请选择时间') } } // 校验手机号 export const checkPhone = (rule, value, callback) => { if (value == '' || value == undefined) { callback() } var ckPhone = /^1(?:3[0-9]|4[5-9]|5[0-9]|6[12456]|7[0-8]|8[0-9]|9[0-9])[0-9]{8}$/; if (ckPhone.test(value)) { callback() } else { callback(new Error('请输入正确的手机号')); } } export const checkEmail = (rule, value, callback) => { if (value == '' || value == undefined) { callback() } var ckEmail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/; if (ckEmail.test(value)) { callback() } else { callback(new Error('请输入正确的邮箱')); } } export const checkIdentitytionId = (rule, value, callback) => { if (value == '' || value == undefined) { callback() } var errorMsg = isIdentityId(value); if (errorMsg != "") { callback(new Error(errorMsg)); } callback() } export const personBirthday = (identityId) => { return ( identityId.substr(6, 4) + "-" + Number(identityId.substr(10, 2)) + "-" + Number(identityId.substr(12, 2)) ) //return new Date(sBirthday); } export const personGender = (identityId) => { let sex = identityId.substr(16, 1) return sex % 2 === 0 ? '女' : '男' } //根据枚举标识获取下拉数据 export const getEnumByFlag = (enumFlag) => { let result = [] let enumSessionStorange = JSON.parse(window.sessionStorage.getItem('allEnum')) if (enumSessionStorange && enumFlag) { for (let obj in enumSessionStorange) { if (obj == enumFlag) { result = enumSessionStorange[obj] } } } return result } /** * 获取js变量的数据类型 * @param obj * @returns {*} */ export const getType = (obj) => { const type = typeof obj; if (type !== 'object') { return type; } return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1'); }; /** * 把文件按照二进制进行读取 * @param file * @returns */ export function readFile (file) { return new Promise(resolve => { let reader = new FileReader(); reader.readAsBinaryString(file); reader.onload = ev => { resolve(ev.target?.result); } }); } export function hideIdCard (idCard) { return idCard.replace(/^(.{8})(?:\w+)(.{1})$/, "\$1*********\$2") } export function hidePhone (phone) { return phone.replace(/(\d{3})\d{4}(\d{4})/, '\$1****\$2'); } export function getCardInfo (idCard) { let sex = null; let birth = null; let myDate = new Date(); let month = myDate.getMonth() + 1; let day = myDate.getDate(); let age = 0; if (idCard.length === 18) { age = myDate.getFullYear() - idCard.substring(6, 10) - 1; sex = idCard.substring(16, 17); birth = idCard.substring(6, 10) + "-" + idCard.substring(10, 12) + "-" + idCard.substring(12, 14); if (idCard.substring(10, 12) < month || idCard.substring(10, 12) === month && idCard.substring(12, 14) <= day) age++; } if (idCard.length === 15) { age = myDate.getFullYear() - idCard.substring(6, 8) - 1901; sex = idCard.substring(13, 14); birth = "19" + idCard.substring(6, 8) + "-" + idCard.substring(8, 10) + "-" + idCard.substring(10, 12); if (idCard.substring(8, 10) < month || idCard.substring(8, 10) === month && idCard.substring(10, 12) <= day) age++; } if (sex % 2 === 0) sex = '女'; // 性别代码 1代表男,0代表女,暂时不涉及其他类型性别 else sex = '男'; return { age, sex, birth } } export async function readExcelFile (file, sheetIndex) { let data = await readFile(file); let workbook = XLSX.read(data, { type: 'binary' }); let worksheet = workbook.Sheets[workbook.SheetNames[sheetIndex]]; data = XLSX.utils.sheet_to_json(worksheet); return data; } /** * @function 生成表格的方法 * @param {String} excelName 文件名 * @param {Array} titleArr 数据表头显示 * @param {Array} dataArr 数据内容显示 */ export const ToDoExcel = (excelName, titleArr, dataArr) => { var filename = excelName + ".xlsx" //文件名称 var data = [titleArr, ...dataArr] //数据,一定注意需要时二维数组 var ws_name = "Sheet1" //Excel第一个sheet的名称 var wb = XLSX.utils.book_new(), ws = XLSX.utils.aoa_to_sheet(data) XLSX.utils.book_append_sheet(wb, ws, ws_name) //将数据添加到工作薄 XLSX.writeFile(wb, filename) } /** * 生成导出Excel的数据数组 * @param {Array} tableColumns 列名数组 * @param {Array} tableData 导出数据 * @returns */ export const filterExportExcelData = (tableColumns, tableData) => { let arr = [] tableData.forEach((val, index, val_arr) => { let arr1 = [] for (let j = 0; j < tableColumns.length; j++) { for (let i = 0; i < Object.getOwnPropertyNames(val).length; i++) { if (tableColumns[j].dataIndex === undefined) { if (tableColumns[j].scopedSlots.customRender === Object.keys(val)[i]) { arr1.push(val[Object.keys(val)[i]]) break } } else if (tableColumns[j].dataIndex === Object.keys(val)[i]) { arr1.push(val[Object.keys(val)[i]]) break } } } arr.push(arr1) }) return arr } /** * 生成导出Excel列名 * @param {Array} tableColumns 列名数组 */ export const tableColumnsName = (tableColumns) => { let arr = [] tableColumns.map((item) => { if (item.title !== '操作') arr.push(item.title) }) return arr } export const toChineseNum = (num) => { let changeNum = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']; let unit = ["", "十", "百", "千", "万"]; num = parseInt(num); let getWan = (temp) => { let strArr = temp.toString().split("").reverse(); let newNum = ""; for (var i = 0; i < strArr.length; i++) { newNum = (i == 0 && strArr[i] == 0 ? "" : (i > 0 && strArr[i] == 0 && strArr[i - 1] == 0 ? "" : changeNum[strArr[i]] + (strArr[i] == 0 ? unit[0] : unit[i]))) + newNum; } return newNum; } let overWan = Math.floor(num / 10000); let noWan = num % 10000; if (noWan.toString().length < 4) noWan = "0" + noWan; return overWan ? getWan(overWan) + "万" + getWan(noWan) : getWan(num); } /** * 生成UUID * @returns */ export function CreateUUID () { var s = []; var hexDigits = "0123456789abcdef"; for (var i = 0; i < 36; i++) { s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); } s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010 s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01 s[8] = s[13] = s[18] = s[23] = "-"; var uuid = s.join(""); return uuid; } export function getFileExtension (fileName) { return fileName.substring(fileName.lastIndexOf('.') + 1, fileName.length).toLowerCase() } /** * 验证文件是否为图片 * @param {文件名称} fileName * @returns */ export function checkImageFileType (fileName) { let fileType = getFileExtension(fileName).toLowerCase() var imgType = ['bmp', 'jpg', 'jpeg', 'png', 'tif', 'gif', 'pcx', 'tga', 'exif', 'fpx', 'svg', 'psd', 'cdr', 'pcd', 'dxf', 'ufo', 'eps', 'ai', 'raw', 'WMF', 'webp', 'avif', 'apng'] if (imgType.includes(fileType)) return true else return false } /** * 验证文件是否为可查看文件 * @param {文件名称} fileName * @returns */ export function checkDocumentFileType (fileName) { let fileType = getFileExtension(fileName).toLowerCase() var wordType = ['text', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'bmp', 'jpg', 'jpeg', 'png', 'tif', 'gif'] //'ppt','pptx','rar','zip','7z','apz','ar','bz','car','dar','cpgz','f','ha','hbc','hbc2','hbe','hpk','hyp' if (wordType.includes(fileType)) return true else return false } const enums = { fileColor: { text: 'gray', pdf: 'red', doc: 'blue', docx: 'blue', xls: 'green', xlsx: 'green', bmp: 'pink', jpg: 'pink', jpeg: 'pink', png: 'pink', tif: 'pink', gif: 'pink' } } export { enums } export function toTextarea (str) { if (str == undefined) { return '' } str = str.replace(/\n|\r\n/g, '
') str = str.replace(/ /g, '  ') return str } export function mergeRow (key, data) { const tableData = data for (var i = 0; i < tableData.length; i++) { const item = tableData[i] let count = 1 for (let j = i + 1; j < tableData.length; j++) { // 如果是同一个值,往后递增 if (item[key] === tableData[j][key]) { count++ // 往后相同的值都设为空单元格 tableData[j][`${key}RowSpan`] = 0 // 只有同值第一个才设置合并的单元格数 item[`${key}RowSpan`] = count // 所有都是为同一个值的情况 // 如果到了尾部,则循环结束 if (j === tableData.length - 1) { return tableData } } else { // 指针跳转到下一个,从下一排开始 i = j - 1 count = 1 tableData[j][`${key}RowSpan`] = 0 break } } } return tableData }