521 lines
14 KiB
JavaScript
521 lines
14 KiB
JavaScript
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<number,string>} 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 + "#";
|
||
}
|