Oroqen-Manage/src/utils/common/compUtils.ts

616 lines
17 KiB
TypeScript
Raw Normal View History

2025-08-07 21:32:38 +08:00
import { useGlobSetting } from '/@/hooks/setting';
import { merge, random } from 'lodash-es';
import { isArray } from '/@/utils/is';
import { FormSchema } from '/@/components/Form';
import { reactive } from "vue";
import { getTenantId, getToken } from "/@/utils/auth";
import { useUserStoreWithOut } from "/@/store/modules/user";
import dayjs from 'dayjs';
import Big from 'big.js';
import { Modal } from "ant-design-vue";
import { defHttp } from "@/utils/http/axios";
import { useI18n } from "@/hooks/web/useI18n";
const globSetting = useGlobSetting();
const baseApiUrl = globSetting.domainUrl;
/**
* 访
* @param fileUrl
* @param prefix(http) http/https
*/
export const getFileAccessHttpUrl = (fileUrl, prefix = 'http') => {
let result = fileUrl;
try {
if (fileUrl && fileUrl.length > 0 && !fileUrl.startsWith(prefix)) {
// 检查是否是blob URL如果是则直接返回
if (fileUrl.startsWith('blob:')) {
return fileUrl;
}
2025-08-07 21:32:38 +08:00
//判断是否是数组格式
let isArray = fileUrl.indexOf('[') != -1;
if (!isArray) {
let prefix = `${baseApiUrl}/sys/common/static/`;
// 判断是否已包含前缀
if (!fileUrl.startsWith(prefix)) {
result = `${prefix}${fileUrl}`;
}
}
}
} catch (err) {}
return result;
};
/**
* window.resize
*/
export function triggerWindowResizeEvent() {
let event: any = document.createEvent('HTMLEvents');
event.initEvent('resize', true, true);
event.eventType = 'message';
window.dispatchEvent(event);
}
/**
*
* @param length
*/
export const getRandom = (length: number = 1) => {
return '-' + parseInt(String(Math.random() * 10000 + 1), length);
};
/**
*
* @param length
* @param chats
* @return string
*/
export function randomString(length: number, chats?: string) {
if (!length) length = 1;
if (!chats) {
// noinspection SpellCheckingInspection
chats = '0123456789qwertyuioplkjhgfdsazxcvbnm';
}
let str = '';
for (let i = 0; i < length; i++) {
let num = random(0, chats.length - 1);
str += chats[num];
}
return str;
}
/**
* tree结构
* @param array tree数据
* @param opt
* @param startPid
*/
export const listToTree = (array, opt, startPid) => {
const obj = {
primaryKey: opt.primaryKey || 'key',
parentKey: opt.parentKey || 'parentId',
titleKey: opt.titleKey || 'title',
startPid: opt.startPid || '',
currentDept: opt.currentDept || 0,
maxDept: opt.maxDept || 100,
childKey: opt.childKey || 'children',
};
if (startPid) {
obj.startPid = startPid;
}
return toTree(array, obj.startPid, obj.currentDept, obj);
};
/**
* tree
* @param list
* @param startPid
* @param currentDept
* @param opt
* @returns {Array}
*/
export const toTree = (array, startPid, currentDept, opt) => {
if (opt.maxDept < currentDept) {
return [];
}
let child = [];
if (array && array.length > 0) {
child = array
.map((item) => {
// 筛查符合条件的数据(主键 = startPid
if (typeof item[opt.parentKey] !== 'undefined' && item[opt.parentKey] === startPid) {
// 满足条件则递归
const nextChild = toTree(array, item[opt.primaryKey], currentDept + 1, opt);
// 节点信息保存
if (nextChild.length > 0) {
item['isLeaf'] = false;
item[opt.childKey] = nextChild;
} else {
item['isLeaf'] = true;
}
item['title'] = item[opt.titleKey];
item['label'] = item[opt.titleKey];
item['key'] = item[opt.primaryKey];
item['value'] = item[opt.primaryKey];
return item;
}
})
.filter((item) => {
return item !== undefined;
});
}
return child;
};
/**
*
* @param tableData
* @param fieldKeys
*/
export function mapTableTotalSummary(tableData: Recordable[], fieldKeys: string[]) {
let totals: any = { _row: '合计', _index: '合计' };
fieldKeys.forEach((key) => {
totals[key] = tableData.reduce((prev, next) => {
// update-begin--author:liaozhiyang---date:20240118---for【QQYUN-7891】PR 合计工具方法转换为Nuber类型再计算
const value = Number(next[key]);
if (!Number.isNaN(value)) {
// update-begin--author:liaozhiyang---date:20250224---for【issues/7830】合计小数计算精度
prev = Big(prev).plus(value).toString();
// update-end--author:liaozhiyang---date:20250224---for【issues/7830】合计小数计算精度
}
// update-end--author:liaozhiyang---date:20240118---for【issues/7830】PR 合计工具方法转换为Nuber类型再计算
return prev;
}, 0);
// update-begin--author:liaozhiyang---date:20250224---for【issues/7830】合计小数计算精度
totals[key] = +totals[key];
// update-end--author:liaozhiyang---date:20250224---for【issues/7830】合计小数计算精度
});
return totals;
}
/**
*
*
* (debounce)(delay)100ms
* 100ms内再次执行函数
*
*
* @param fn
* @param delay
* @returns {Function}
*/
export function simpleDebounce(fn, delay = 100) {
let timer: any | null = null;
return function () {
let args = arguments;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
// @ts-ignore
fn.apply(this, args);
}, delay);
};
}
/**
*
* @param date
* @param block
*/
export function dateFormat(date, block) {
if (!date) {
return '';
}
let format = block || 'yyyy-MM-dd';
date = new Date(date);
const map = {
M: date.getMonth() + 1, // 月份
d: date.getDate(), // 日
h: date.getHours(), // 小时
m: date.getMinutes(), // 分
s: date.getSeconds(), // 秒
q: Math.floor((date.getMonth() + 3) / 3), // 季度
S: date.getMilliseconds(), // 毫秒
};
format = format.replace(/([yMdhmsqS])+/g, (all, t) => {
let v = map[t];
if (v !== undefined) {
if (all.length > 1) {
v = `0${v}`;
v = v.substr(v.length - 2);
}
return v;
} else if (t === 'y') {
return date
.getFullYear()
.toString()
.substr(4 - all.length);
}
return all;
});
return format;
}
/**
* IE11EdgeChromeFirefoxSafari
* 使JVxeTable Span模式
*/
export function getEventPath(event) {
let target = event.target;
let path = (event.composedPath && event.composedPath()) || event.path;
if (path != null) {
return path.indexOf(window) < 0 ? path.concat(window) : path;
}
if (target === window) {
return [window];
}
let getParents = (node, memo) => {
const parentNode = node.parentNode;
if (!parentNode) {
return memo;
} else {
return getParents(parentNode, memo.concat(parentNode));
}
};
return [target].concat(getParents(target, []), window);
}
/**
* push
* @param array
* @param value
* @param key id
* @returns {boolean} push true false
*/
export function pushIfNotExist(array, value, key?) {
for (let item of array) {
if (key && item[key] === value[key]) {
return false;
} else if (item === value) {
return false;
}
}
array.push(value);
return true;
}
/**
*
* @param obj
* @returns {*}
*/
export function filterObj(obj) {
if (!(typeof obj == 'object')) {
return;
}
for (let key in obj) {
if (obj.hasOwnProperty(key) && (obj[key] == null || obj[key] == undefined || obj[key] === '')) {
delete obj[key];
}
}
return obj;
}
/**
* 线
* @param string
*/
export function underLine2CamelCase(string: string) {
return string.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
}
/**
*
* @param treeList
* @param fn
* @param childrenKey
*/
export function findTree(treeList: any[], fn: Fn, childrenKey = 'children') {
for (let i = 0; i < treeList.length; i++) {
let item = treeList[i];
if (fn(item, i, treeList)) {
return item;
}
let children = item[childrenKey];
if (isArray(children)) {
let findResult = findTree(children, fn, childrenKey);
if (findResult) {
return findResult;
}
}
}
return null;
}
/** 获取 mapFormSchema 方法 */
export function bindMapFormSchema<T>(spanMap, spanTypeDef: T) {
return function (s: FormSchema, spanType: T = spanTypeDef) {
return merge(
{
disabledLabelWidth: true,
} as FormSchema,
spanMap[spanType],
s
);
};
}
/**
* null或null字符串
* @param str
* @return {boolean}
*/
export function stringIsNull(str) {
// 两个 == 可以同时判断 null 和 undefined
return str == null || str === 'null' || str === 'undefined';
}
/**
* divmodal上
* @param node
*/
export function getAutoScrollContainer(node: HTMLElement) {
let element: Nullable<HTMLElement> = node
while (element != null) {
if (element.classList.contains('scrollbar__view')) {
// 判断是否有滚动条
if (element.clientHeight < element.scrollHeight) {
// 有滚动条时,挂载到父级,解决滚动问题
return node.parentElement
} else {
// 无滚动条时挂载到body上解决下拉框遮盖问题
return document.body
}
} else {
element = element.parentElement
}
}
// 不在弹窗内,走默认逻辑
return node.parentElement
}
/**
*
* @param menuTreeItem
*/
export function checkChildrenHidden(menuTreeItem){
//是否是聚合路由
let alwaysShow=menuTreeItem.alwaysShow;
if(alwaysShow){
return false;
}
if(!menuTreeItem.children){
return false
}
return menuTreeItem.children?.find((item) => item.hideMenu == false) != null;
}
/**
*
* @param fileSize
* @param unit
* @return
*/
export function calculateFileSize(fileSize, unit?) {
let unitArr = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
if (unit && unit.length > 0) {
unitArr = unit;
}
let size = fileSize;
let unitIndex = 0;
while (size >= 1024 && unitIndex < unitArr.length - 1) {
size /= 1024;
unitIndex++;
}
//保留两位小数,四舍五入
size = Math.round(size * 100) / 100;
return size + unitArr[unitIndex];
}
/**
* header
*/
export function getHeaders() {
let tenantId = getTenantId();
return reactive({
'X-Access-Token': getToken(),
'X-Tenant-Id': tenantId ? tenantId : '0',
});
}
/** 根据表达式获取相应的用户信息 */
export function getUserInfoByExpression(expression) {
if (!expression) {
return expression;
}
// 当前日期
if (expression === 'sys_date' || expression === 'sysDate') {
return dayjs().format('YYYY-MM-DD');
}
// 当前时间
if (expression === 'sys_time' || expression === 'sysTime') {
return dayjs().format('HH:mm:ss');
}
const userStore = useUserStoreWithOut();
let userInfo = userStore.getUserInfo;
if (userInfo) {
switch (expression) {
case 'sysUserId':
return userInfo.id;
// 当前登录用户登录账号
case 'sysUserCode':
case 'sys_user_code':
return userInfo.username;
// 当前登录用户真实名称
case 'sysUserName':
return userInfo.realname;
// 当前登录用户部门编号
case 'sysOrgCode':
case 'sys_org_code':
return userInfo.orgCode;
}
}
return expression;
}
/**
* #{xxx}
* @param expression
*/
export function replaceUserInfoByExpression(expression: string | any[]) {
if (!expression) {
return expression;
}
const isString = typeof expression === 'string';
const isArray = Array.isArray(expression)
if (!isString && !isArray) {
return expression;
}
const reg = /#{(.*?)}/g;
const replace = (str) => {
if (typeof str !== 'string') {
return str;
}
let result = str.match(reg);
if (result && result.length > 0) {
result.forEach((item) => {
let userInfo = getUserInfoByExpression(item.substring(2, item.length - 1));
str = str.replace(item, userInfo);
});
}
return str;
};
// @ts-ignore
return isString ? replace(expression) : expression.map(replace);
}
/**
* 退
*
* @param tenantId
*/
export async function userExitChangeLoginTenantId(tenantId){
const userStore = useUserStoreWithOut();
//step 1 获取用户租户
const url = '/sys/tenant/getCurrentUserTenant'
let currentTenantId = null;
const data = await defHttp.get({ url });
if(data && data.list){
let arr = data.list;
if(arr.length>0){
//step 2.判断当前id是否存在用户租户中
let filterTenantId = arr.filter((item) => item.id == tenantId);
//存在说明不是退出的不是当前租户,还用用来的租户即可
if(filterTenantId && filterTenantId.length>0){
currentTenantId = tenantId;
}else{
//不存在默认第一个
currentTenantId = arr[0].id
}
}
}
let loginTenantId = getTenantId();
userStore.setTenant(currentTenantId);
//update-begin---author:wangshuai---date:2023-11-07---for:【QQYUN-7005】退租户判断退出的租户ID与当前租户ID一致再刷新---
//租户为空,说明没有租户了,需要刷新页面。或者当前租户和退出的租户一致则需要刷新浏览器
if(!currentTenantId || tenantId == loginTenantId){
window.location.reload();
}
//update-end---author:wangshuai---date:2023-11-07---for:【QQYUN-7005】退租户判断退出的租户ID与当前租户ID一致再刷新---
}
/**
*
*
* @param title
*/
export function tenantSaasMessage(title){
let tenantId = getTenantId();
if(!tenantId){
Modal.confirm({
title:title,
content: '此菜单需要在多租户模式下使用,否则数据会出现混乱',
okText: '确认',
okType: 'danger',
// @ts-ignore
cancelButtonProps: { style: { display: 'none' } },
})
}
}
/**
*
* @param dateStr
*/
export function sameDay(dateStr) {
if (!dateStr) {
return false;
}
// 获取当前日期
let currentDate = new Date();
let currentDay = currentDate.getDate();
let currentMonth = currentDate.getMonth();
let currentYear = currentDate.getFullYear();
//创建另一个日期进行比较
let otherDate = new Date(dateStr);
let otherDay = otherDate.getDate();
let otherMonth = otherDate.getMonth();
let otherYear = otherDate.getFullYear();
//比较日期
if (currentDay === otherDay && currentMonth === otherMonth && currentYear === otherYear) {
return true;
} else {
return false;
}
}
/**
*
* 2024-02-28
* liaozhiyang
* @param data
*/
export function translateTitle(data) {
if (data?.length) {
const { t } = useI18n();
data.forEach((item) => {
if (item.slotTitle) {
if (item.slotTitle.includes("t('") && t) {
item.slotTitle = new Function('t', `return ${item.slotTitle}`)(t);
}
}
if (item.children?.length) {
translateTitle(item.children);
}
});
}
return data;
}
/**
*
*
* @param obj Object or Array
*/
export function freezeDeep(obj: Recordable | Recordable[]) {
if (obj != null) {
if (Array.isArray(obj)) {
obj.forEach(item => freezeDeep(item))
} else if (typeof obj === 'object') {
Object.values(obj).forEach(value => {
freezeDeep(value)
})
}
Object.freeze(obj)
}
return obj
}