import { IObj, UseTableSetting } from "@/types/Basics"; import { resolveComponent } from "vue"; export default class Utils { /** * 格式化日期 * * @param {(Date | string)} 日期 * @param {string} fmt 格式化字符串 * @returns {string} 日期字符串 * @memberof Utils */ public static dateFormat(date: Date | string, fmt: string): string { if (typeof date === "string") date = date.replace(/\-/g, "/"); let dt = new Date(date); let o: IObj = { "M+": dt.getMonth() + 1, //月份 "d+": dt.getDate(), //日 "H+": dt.getHours(), //小时 "m+": dt.getMinutes(), //分 "s+": dt.getSeconds(), //秒 "q+": Math.floor((dt.getMonth() + 3) / 3), //季度 S: dt.getMilliseconds(), //毫秒 }; if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (dt.getFullYear() + "").substr(4 - RegExp.$1.length)); for (let k in o) if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)); return fmt; } /** * 获取地址栏指定参数 */ public static getUrlParam(name: string): string | null { let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); let r = window.location.search.substr(1).match(reg); if (r != null) return unescape(r[2]); else return null; } /** * 生成uuid */ public static uuid(): string { return "xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g, function (c) { let r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8; return v.toString(16); }); } /** * 返回文件大小 */ public static getFileSize(size: number): string { if (!size) return ""; if (size / 1024 < 1024) { size = Math.ceil(size / 1024); return size + "KB"; } else if (size / (1024 * 1024) < 1024) { size = Math.ceil((size / (1024 * 1024)) * 100) / 100; return size + "MB"; } else if (size / (1024 * 1024 * 1024) < 1024) { size = Math.ceil((size / (1024 * 1024 * 1024)) * 100) / 100; return size + "GB"; } else return ""; } /** * 在线预览大小上限(字节):日志大字段(请求体/响应)超过此值时隐藏"在线预览"、只保留"下载"。 * 浏览器 JSON 美化 +
 渲染在数百 KB 起会卡顿,50KB 为体验无损的保守阈值。
     */
    public static readonly PREVIEW_MAX_BYTES = 50 * 1024;

    /**
     * 是否允许在线预览:有内容(size > 0)且字节数不超过阈值。
     * size 为 null/undefined/0(未记录请求体、saveResponse=false、响应为空)→ 不可预览,仅下载。
     */
    public static canPreview(size?: number | null): boolean {
        return size != null && size > 0 && size <= Utils.PREVIEW_MAX_BYTES;
    }

    /**
     * 删除指定键
     */
    public static delKey(obj: IObj, ...args: string[]) {
        args.forEach(v => delete obj[v]);
        return obj;
    }

    /**
     * iview Tooltip封装
     */
    public static operatingHandle(
        h: any,
        info: string,
        iconClass: string,
        callback: Function,
        disabled: boolean = false,
    ) {
        if (disabled) iconClass += " disabled";

        return h(
            resolveComponent("Tooltip"),
            {
                content: info,
                placement: "bottom",
                transfer: true,
            },
            {
                default: () => [
                    h(
                        "div",
                        {
                            class: `operating-btn iconfont ${iconClass}`,
                            onClick: callback,
                        },
                        null,
                    ),
                ],
            },
        );
    }

    public static operatingTextHandle(
        h: any,
        info: string,
        className: string,
        callback: Function,
        disabled: boolean = false,
    ) {
        if (disabled) className += " disabled";
        return h(
            "div",
            {
                class: `operating-link ${className}`,
                onClick: disabled ? null : callback,
            },
            info,
        );
    }

    /**
     * 计算表格高度
     */
    public static useTableHeight({
        isSearch = false,
        isPage = false,
        isTabs = false,
        isOperat = false,
        otherH = 0,
    } = {}) {
        let bodyH = document.body.clientHeight,
            headerH = 112,
            searchH = 52,
            operatH = 48,
            tabsH = 56,
            pageH = 72,
            paddingH = 8;

        //@ts-ignore
        const bschUtil = BschLoadUtil.getInstance();
        if (!bschUtil.getIsSelf()) headerH = 56;
        let tableH = bodyH - headerH - paddingH;
        isOperat && (tableH -= operatH);
        isTabs && (tableH -= tabsH);
        isSearch && (tableH -= searchH);
        isPage && (tableH -= pageH);
        otherH > 0 && (tableH -= otherH);
        return tableH;
    }
    /**
     * 数字转大写汉字
     * @param num
     * @returns
     */
    public static convertToChinaNum(num: number) {
        var arr1 = new Array("零", "一", "二", "三", "四", "五", "六", "七", "八", "九");
        var arr2 = new Array(
            "",
            "十",
            "百",
            "千",
            "万",
            "十",
            "百",
            "千",
            "亿",
            "十",
            "百",
            "千",
            "万",
            "十",
            "百",
            "千",
            "亿",
        ); //可继续追加更高位转换值
        if (!num || isNaN(num)) {
            return "零";
        }
        var english = num.toString().split("");
        var result = "";
        for (var i = 0; i < english.length; i++) {
            var des_i = english.length - 1 - i; //倒序排列设值
            result = arr2[i] + result;
            var arr1_index: any = english[des_i];
            result = arr1[arr1_index] + result;
        }
        //将【零千、零百】换成【零】 【十零】换成【十】
        result = result.replace(/零(千|百|十)/g, "零").replace(/十零/g, "十");
        //合并中间多个零为一个零
        result = result.replace(/零+/g, "零");
        //将【零亿】换成【亿】【零万】换成【万】
        result = result.replace(/零亿/g, "亿").replace(/零万/g, "万");
        //将【亿万】换成【亿】
        result = result.replace(/亿万/g, "亿");
        //移除末尾的零
        result = result.replace(/零+$/, "");
        //将【零一十】换成【零十】
        //result = result.replace(/零一十/g, '零十');//貌似正规读法是零一十
        //将【一十】换成【十】
        result = result.replace(/^一十/g, "十");
        return result;
    }

    /**
     * 对象转url参数
     * @param num
     * @returns
     */
    public static createUrl(url: string, query: any) {
        var temp: any[] = [];
        for (var k in query) {
            if (query[k] != null) temp.push(k + "=" + query[k]);
        }
        return url + "?" + temp.join("&");
    }
    /**
     * 获取当前角色信息
     * @returns
     */
    public static getCurrentRoleInfo() {
        let currentRole = localStorage.getItem("currentRole");
        if (!currentRole) return null;
        let { schId, roleId, childId, userId } = JSON.parse(decodeURI(currentRole ?? ""));
        return { schId, roleId, childId, userId } as T;
    }

    /**
     * tree对象转化为数组
     * @param tree
     * @returns
     */
    public static treeToArray(tree: any[]): any[] {
        return tree.reduce((res, item) => {
            const { children, ...i } = item;
            return res.concat(i, children && children.length ? this.treeToArray(children) : []);
        }, []);
    }

    /**
     * 数组转化为tree对象
     * @param tree
     * @returns
     */
    public static arrayToTree(arr: any[], pid: number): any[] {
        return arr
            .filter(item => item.pid === pid)
            .map(item => ({ ...item, children: this.arrayToTree(arr, item.id) }));
    }

    //字符串的16进制表达
    public static strToHexCharCode(_str: string) {
        if (_str === "") return "";
        var hexCharCode: string[] = [];
        for (var i = 0; i < _str.length; i++) {
            var str = _str.charCodeAt(i).toString(16);
            if (_str.length == 1) str += "0" + _str;
            hexCharCode.push(str);
        }
        return hexCharCode.join("");
    }

    public static hexToString(hex: string) {
        if (hex === "") return "";
        // 处理奇数长度,补前导零
        if (hex.length % 2 !== 0) {
            hex = "0" + hex;
            [[3]];
        }
        let str = "";
        for (let i = 0; i < hex.length; i += 2) {
            // 每两位解析为一个字符的Unicode值
            const hexPair = hex.substr(i, 2);
            const charCode = parseInt(hexPair, 16);
            str += String.fromCharCode(charCode);
            [[14, 16]];
        }
        return str;
    }

    /**
     * 将颜色值HEX格式转换为rgb的格式
     * @param {hex} hex 需要转换的rgb字符串
     * @param {number} opacity 透明度
     * @return {string}  ;
     */
    public static hexToRgb(hex: string, opacity: number = 1) {
        let str = hex.replace("#", "");
        if (str.length % 3) {
            return "hex格式不正确!";
        }
        //获取截取的字符长度
        let count = str.length / 3;
        //根据字符串的长度判断是否需要 进行幂次方
        let power = 6 / str.length;
        let r = parseInt("0x" + str.substring(0 * count, 1 * count)) ** power;
        let g = parseInt("0x" + str.substring(1 * count, 2 * count)) ** power;
        let b = parseInt("0x" + str.substring(2 * count)) ** power;
        return `rgb(${r}, ${g}, ${b},${opacity})`;
    }

    public static removeHtmlTag(str: string) {
        str = str.replace(/<\/?[^>]*>/g, ""); //去除HTML tag
        str = str.replace(/[ | ]*\n/g, "\n"); //去除行尾空白
        str = str.replace(/\n[\s| | ]*\r/g, "\n"); //去除多余空行
        str = str.replace(/ /gi, ""); //去掉
        return str;
    }

    public static unpackPerms = (bits: number) => [
        !!(bits & 1), // create
        !!(bits & 2), // update
        !!(bits & 4), // move
        !!(bits & 8), // delete
    ];

    public static copyToClipboard(text: string) {
        const input = document.createElement("input");
        input.setAttribute("value", text);
        document.body.appendChild(input);
        input.select();
        try {
            const successful = document.execCommand("copy");
            if (successful) {
                return Promise.resolve();
            } else {
                return Promise.reject();
            }
        } catch (err) {
            return Promise.reject(err);
        } finally {
            document.body.removeChild(input);
        }
    }

    public static sleep(ms: number, callback?: () => void): Promise {
        return new Promise(resolve => {
            setTimeout(() => {
                callback?.();
                resolve();
            }, ms);
        });
    }
}