import { ElMessage } from "element-plus"; /** * @description 计算序号 * @param {Object} pagination 分页数据对象 * @param {number | string} pagination.currentPage 当前页 * @param {number | string} pagination.pageSize 每页条数 * @param {number} index 当页数据的索引值 * @return {number} 序号 **/ export function serialNumber(pagination, index) { return (pagination.currentPage - 1) * pagination.pageSize + (index + 1); } /** * @description 字符串数组转数组 * @param {string} value 转换的字符串数组 * @return {Array} 转换后的数组 **/ export function toArrayString(value) { // eslint-disable-next-line no-eval return value ? eval(value).map(String) : []; } /** * @description 判断文件后缀名是否符合 * @param {string} name 文件名字 * @param {string} suffix 文件后缀 * @return {boolean} 是否符合 **/ export function interceptTheSuffix(name, suffix) { return ( name.substring(name.lastIndexOf("."), name.length).toLowerCase() === suffix.toLowerCase() ); } /** * @description 图片转base64 * @param {string} imgUrl 图片地址 * @return {Promise} Promise实例,then包含base64编码 **/ export function image2Base64(imgUrl) { return new Promise((resolve) => { const img = new Image(); img.src = imgUrl; img.crossOrigin = "Anonymous"; img.onload = function () { const canvas = document.createElement("canvas"); canvas.width = img.width; canvas.height = img.height; const ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0, img.width, img.height); const ext = img.src.substring(img.src.lastIndexOf(".") + 1).toLowerCase(); resolve(canvas.toDataURL("image/" + ext)); }; }); } export function image2Base642(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = (e) => { resolve(e.target.result); // 返回 base64 }; reader.onerror = (error) => { reject(error); // 处理错误 }; }); } /** * @description 判断图片是否可访问成功 * @param {string} imgUrl 图片地址 * @return {Promise} Promise实例 **/ export function checkImgExists(imgUrl) { return new Promise((resolve, reject) => { const ImgObj = new Image(); ImgObj.src = imgUrl; ImgObj.onload = function (res) { resolve(res); }; ImgObj.onerror = function (err) { reject(err); }; }); } /** * @description 获取数据类型 * @param {any} data 数据 * @return {string} 数据类型 **/ export function getDataType(data) { return Object.prototype.toString.call(data).slice(8, -1); } /** * @description 数组去重 * @param {Array} arr 去重的数组 * @return {Array} 去重后的数组 **/ export function ArrayDeduplication(arr) { return [...new Set(arr)]; } /** * @description 数组对象去重 * @param {Array} arr 去重的数组 * @param {string} name 去重的key * @return {Array} 去重后的数组 **/ export function arrayObjectDeduplication(arr, name) { const obj = {}; arr = arr.reduce(function (previousValue, currentValue) { if (!obj[currentValue[name]]) { obj[currentValue[name]] = true; previousValue.push(currentValue); } return previousValue; }, []); return arr; } /** * @description 查找字符串中指定的值第几次出现的位置 * @param {Array} str 查找的字符串数组 * @param {string} char 查找的值 * @param {number} num 第几次出现 * @return {number} 出现的位置 **/ export function findCharIndex(str, char, num) { let index = str.indexOf(char); if (index === -1) return -1; for (let i = 0; i < num - 1; i++) { index = str.indexOf(char, index + 1); if (index === -1) return -1; } return index; } /** * @description 生成指定两个值之间的随机数 * @param {number} min 最小值 * @param {number} max 最大值 * @return {number} 随机数 **/ export function randoms(min, max) { return Math.random() * (max - min + 1) + min; } /** * @description 千位分隔符 * @param {number | string} num 转换的值 * @return {string} 转换后的值 **/ export function numFormat(num) { if (num) { const numArr = num.toString().split("."); const arr = numArr[0].split("").reverse(); let res = []; for (let i = 0; i < arr.length; i++) { if (i % 3 === 0 && i !== 0) { res.push(","); } res.push(arr[i]); } res.reverse(); if (numArr[1]) { res = res.join("").concat("." + numArr[1]); } else { res = res.join(""); } return res; } } /** * @description 验证是否为空 * @param {any} value 验证的值 * @return {boolean} 是否为空 **/ export function isEmpty(value) { return ( value === undefined || value === null || (typeof value === "object" && Object.keys(value).length === 0) || (typeof value === "string" && value.trim().length === 0) ); } /** * @description 获取url参数 * @param {string} name 获取的key * @return {string} 获取的值 **/ export function getUrlParam(name) { const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); const r = window.location.search.substr(1).match(reg); if (r != null) return decodeURI(r[2]); return ""; } /** * @description 数据分页 * @param {Array} list 分页的数组 * @param {number | string} currentPage 当前页 * @param {number | string} pageSize 每页条数 * @return {Array} 分页后的数组 **/ export function paging(list, currentPage, pageSize) { return list.filter((item, index) => { return ( index < +currentPage * +pageSize && index >= (+currentPage - 1) * +pageSize ); }); } /** * @description 获取文件后缀 * @param {string} name 文件名 * @return {string} 文件后缀 **/ export function getFileSuffix(name) { return name.substring(name.lastIndexOf(".") + 1); } /** * @description 获取文件名称 * @param {string} name 文件地址 * @return {string} 文件名称 **/ export function getFileName(name) { if (!name) return ""; return name.substring(name.lastIndexOf("/") + 1); } /** * @description 读取txt文档 * @param {string} filePah 文档路径 * @return {resolve,string} 读取后的内容 **/ export function readTxtDocument(filePah) { return new Promise((resolve) => { const FILE_URL = getFileUrl(); const file_url = FILE_URL + filePah; const xhr = new XMLHttpRequest(); xhr.open("get", file_url, true); xhr.responseType = "blob"; xhr.onload = function (event) { const reader = new FileReader(); reader.readAsText(event.target.response, "GB2312"); reader.onload = function () { resolve(reader.result); }; }; xhr.send(); }); } /** * @description 将秒转换成时分秒 * @param {string,number} second 需要转换的秒数 * @return {string} 转换后的时间 **/ export function secondConversion(second) { if (!second) return 0; const h = parseInt(second / 60 / 60, 10); const m = parseInt((second / 60) % 60, 10); const s = parseInt(second % 60, 10); if (h) { return h + "小时" + m + "分钟" + s + "秒"; } else { if (m) { return m + "分钟" + s + "秒"; } else { return s + "秒"; } } } /** * @description 附件添加前缀 * @param {Array} list 附件数组 * @param {Object} options 配置选项 * @param {string} [options.pathKey="filePath"] 附件路径字段名 * @param {string} [options.nameKey="fileName"] 附件名称字段名 * @param {string} [options.idKey="imgFilesId"] 附件id字段名 * @return {Array} 添加完前缀后的数组 **/ export function addingPrefixToFile(list, options = {}) { if (!list) return []; const { pathKey = "filePath", nameKey = "fileName", idKey = "imgFilesId", } = options; const FILE_URL = getFileUrl(); for (let i = 0; i < list.length; i++) { list[i].url = FILE_URL + list[i][pathKey]; list[i].name = list[i][nameKey] || getFileName(list[i][pathKey]); list[i].imgFilesId = list[i][idKey]; } return list; } /** * @description 验证重复选择 * @param {Array} list 验证的数组 * @param {number} index 选择的索引 * @param {string} key 验证的字段 * @param {string} id 验证的值 **/ export async function verifyDuplicateSelection(list, index, key, id) { return new Promise((resolve, reject) => { if (list.some((item) => item[key] === id)) { ElMessage.warning("不能重复选择"); reject(new Error("不能重复选择")); } else { list[index][key] = id; resolve(); } }); } /** * @description 翻译状态 * @param {number | string} status 状态 * @param {Array} list 翻译的数组 * @param {String} idKey * @param {String} nameKey * @return {string} 翻译后的状态 **/ export function getLabelName(status, list, idKey = "id", nameKey = "name") { for (let i = 0; i < list.length; i++) { if (status?.toString() === list[i][idKey]?.toString()) { return list[i][nameKey]; } } } /** * @description 计算文件大小 * @param {number | string} size 文件kb * @return {string} 计算后的文件大小 **/ export function calculateFileSize(size) { return size > 1024 ? (size / 1024 + "").substring(0, (size / 1024 + "").lastIndexOf(".") + 3) + "MB" : size + "KB"; } /** * @description 根据身份证号获取出生日期和性别 * @param {String} idCard 身份证号 * @return {Object} 出生日期和性别 date sex **/ export function idCardGetDateAndGender(idCard) { const reg = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/; let sex = ""; let date = ""; if (reg.test(idCard)) { const org_birthday = idCard.substring(6, 14); const org_gender = idCard.substring(16, 17); const birthday = org_birthday.substring(0, 4) + "-" + org_birthday.substring(4, 6) + "-" + org_birthday.substring(6, 8); const birthdays = new Date(birthday.replace(/-/g, "/")); const Month = birthdays.getMonth() + 1; let MonthDate; const DayDate = birthdays.getDate(); let Day; if (Month < 10) MonthDate = "0" + Month; else MonthDate = Month; if (DayDate < 10) Day = "0" + DayDate; else Day = DayDate; sex = org_gender % 2 === 1 ? "1" : "0"; date = birthdays.getFullYear() + "-" + MonthDate + "-" + Day; } return { sex, date }; } /** * @description 获取select中指定项组成的数组 * @param {Array} list 获取的数组 * @param {Array} value 获取的值 * @param {string?} idKey 获取的id * @return {Array} list中指定项组成的数组 **/ export function getSelectAppointItemList(list, value, idKey = "id") { return list.filter((item) => value.includes(item[idKey])); } /** * @description json转换为树形结构 * @param {Array} json 需要转换的json * @param {string} idStr id字段 * @param {string} pidStr 父级id字段 * @param {string} childrenStr 子级字段 * @return {Array} 转换完的树形结构 **/ export function listTransTree(json, idStr, pidStr, childrenStr) { const r = []; const hash = {}; const id = idStr; const pid = pidStr; const children = childrenStr; let i = 0; let j = 0; const len = json.length; for (; i < len; i++) { hash[json[i][id]] = json[i]; } for (; j < len; j++) { const aVal = json[j]; const hashVP = hash[aVal[pid]]; if (hashVP) { !hashVP[children] && (hashVP[children] = []); hashVP[children].push(aVal); } else { r.push(aVal); } } return r; } /** * @description 将值转换为"是"/"否"显示文本 * @param {any} value 需要转换的值 * @param {Object} options 配置选项 * @param {string} options.yesText 真值时显示的文本,默认为"是" * @param {string} options.noText 假值时显示的文本,默认为"否" * @param {string|number} options.yesValue 判断为真的值,默认为"1" * @return {string} 转换后的显示文本 **/ export function isEmptyToWhether(value, options = {}) { const { yesText = "是", noText = "否", yesValue = "1" } = options; return !isEmpty(value) ? value.toString() === yesValue.toString() ? yesText : noText : ""; } /** * @description 计算表格中需要合并的行信息 * @param {Array} data 表格数据数组 * @param {string} field 用于比较的字段名,相同值的行需要合并 * @param {Number} rowIndex 当前行索引 * @returns {Object} 包含rowspan和colspan属性的对象,用于表格单元格合并 * - rowspan {number} 合并行数 * - colspan {number} 合并列数 */ export function getRowSpans(data, field, rowIndex) { if (!Array.isArray(data) || data.length === 0 || rowIndex < 0) { return { rowspan: 1, colspan: 1 }; } if (data.length === 1) { return { rowspan: 1, colspan: 1 }; } let currentSpanCount = 1; let currentSpanIndex = 0; for (let i = 1; i < data.length; i++) { const currentValue = data[i][field]; const previousValue = data[i - 1][field]; if (currentValue === previousValue) { currentSpanCount++; if (i === rowIndex) { return { rowspan: 0, colspan: 0 }; } } else { if (currentSpanIndex === rowIndex) { return { rowspan: currentSpanCount, colspan: 1 }; } currentSpanIndex = i; currentSpanCount = 1; } } if (currentSpanIndex === rowIndex) { return { rowspan: currentSpanCount, colspan: 1 }; } return { rowspan: 1, colspan: 1 }; } /** * @description 生成指定长度的guid * @param {number} len 生成的guid长度 * @return {string} 生成的guid **/ export function createGuid(len = 32) { const chars = "abcdefghijklmnopqrstuvwxyz0123456789"; let result = ""; for (let i = 0; i < len; i++) { result += chars.charAt(Math.floor(Math.random() * chars.length)); } return result; } /** * @description 获取文件路径前缀地址 * @return {string} 文件路径前缀地址 **/ export function getFileUrl() { return import.meta.env.VITE_FILE_URL; } export function getBaseUrl() { return import.meta.env[import.meta.env.DEV ? "VITE_PROXY" : "VITE_BASE_URL"]; } export function getWebUrl() { return window.location.origin + window.location.pathname + "#"; }