整理常用 JS语句

常用的js语句

格式化时间

/**
 * @description 格式化时间
 * @param value 时间 
 * @param pattern 格式化的模式
 */
export function formatDate(value: number | string, pattern = 'YYYY-MM-DD hh:mm:ss') {
    if (!value) {
        return '';
    }
    let val = value;
    if (typeof val === 'string') {
        val = val.replace(/-/g, '/');
    }
    const date = new Date(val);
    const chinese = ['一', '二', '三', '四', '五', '六', '日'];
    let model = pattern;
    const year = String(date.getFullYear());
    const month = String(date.getMonth() + 1);
    const week = String(date.getDay());
    const day = String(date.getDate());
    const hour = String(date.getHours());
    const minute = String(date.getMinutes());
    const second = String(date.getSeconds());
    const time = String(date.getTime());
    if (model === 'time' || model === 'Time') {
        return time;
    }
    model = model.replace(/YYYY/, year);
    model = model.replace(/YY/, (String(year)).slice(2));
    model = model.replace(/MM/, addZero(month));
    model = model.replace(/M/, month);
    model = model.replace(/[wW]+/, '星期' + chinese[week]);
    model = model.replace(/DD/, addZero(day));
    model = model.replace(/D/, day);
    model = model.replace(/hh/, addZero(hour));
    model = model.replace(/h/, hour);
    model = model.replace(/mm/, addZero(minute));
    model = model.replace(/m/, minute);
    model = model.replace(/ss/, addZero(second));
    model = model.replace(/s/, second);
    return model;
}

金额转换

export const absnumber = (number, decimals = isInteger(number) ? 0 : 2, dec_point = ".", thousands_sep = ",", showCurrency = true) => {
    // export const absnumber = (number, decimals = 2, dec_point = ".", thousands_sep = ",") => {
    /*
    * 参数说明:
    * number:要格式化的数字
    * decimals:保留几位小数
    * dec_point:小数点符号
    * thousands_sep:千分位符号
    * */
    number = (number + '').replace(/[^0-9+-Ee.]/g, '');
    var n = !isFinite(+number) ? 0 : +number,
        prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
        sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
        dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
        toFixedFix = function (n, prec) {
            var k = Math.pow(10, prec);
            return '' + Math.ceil(n * k) / k;
        };


    let sArray = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');

    var re = /(-?\d+)(\d{3})/;
    while (re.test(sArray[0])) {
        sArray[0] = sArray[0].replace(re, "$1" + sep + "$2");
    }

    if ((sArray[1] || '').length < prec) {
        sArray[1] = sArray[1] || '';
        sArray[1] += new Array(prec - sArray[1].length + 1).join('0');
    }

    return showCurrency ? `¥${sArray.join(dec)}` : `${sArray.join(dec)}`;
}

防抖函数

/**
 * @description 防抖函数
 * @param {function} func 执行函数
 * @param {number} wait 等待时间
 * @param {boolean} immediate 立即执行
 * @return {function} 防抖控制函数
 */
export const debounce = <T>(func: T, wait: number, immediate?: boolean): T => {
    let timer: any = null;

    const cb: any = (...args: any[]) => {
        if (immediate && !timer) {
            (func as any)(...args);
        }
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(() => {
            (func as any)(...args);
            timer = null;
        }, wait);
    };

    return cb;
};

解析 url 参数

/**
 * @description 解析 url 参数
 * @param {string} queryStr 参数字符串
 * @return {object} 结果对象
 */
export const parseQuery = (queryStr = '') => {
    const maps: { [key: string]: string } = {};
    const list = queryStr.split('&');
    for (const item of list) {
        if (item.includes('=')) {
            const data = item.split('=');
            maps[data[0]] = data[1];
        }
    }
    return maps;
};

生成多行省略的 CSS(React)

/**
 * @description 生成多行省略的 CSS,由于写在 CSS 中会有毛病,只能这样来了
 * @param {number} line 参数字符串
 * @return {object} 结果对象
 */
export const multipleText = (line = 2) => {
    const style: React.CSSProperties = {
        wordBreak: 'break-all',
        overflow: 'hidden',
        textOverflow: 'ellipsis',
        display: '-webkit-box',
        WebkitLineClamp: line,
        WebkitBoxOrient: 'vertical',
    };
    return style;
};

金额正则

/**
 * 钱的正则
 * @param obj
 */
export function moneyExchange(obj) {
    let modal = obj;
    const reg = new RegExp('([0]*)([1-9]+[0-9]+)', 'g');
    modal = modal.replace(/[^\d.]/g, ''); // 清除'数字'和'.'以外的字符
    modal = modal.replace(reg, '$2');
    modal = modal.replace(/^\./g, ''); // 验证第一个字符是数字
    modal = modal.replace(/\.{2,}/g, '.'); // 只保留第一个, 清除多余的
    modal = modal.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.');
    modal = modal.replace(/^(\d-)*(\d+)\.(\d\d).*$/, '$1$2.$3'); // 只能输入两个小数
    return modal;
}

时间戳转时间对象

/**
 * @param {Number} timeStamp 传入的时间戳
 * @param {Number} startType 要返回的时间字符串的格式类型,传入'year'则返回年开头的完整时间
 */
export function timestampToTime(updateTime) {
    if (updateTime === null) {
        return ''
    }
    const now = new Date().getTime()
    const second = (updateTime - now) / (1000)
    const minute = second / 60
    const hour = minute / 60
    const day = hour / 24
    const month = day / 31
    const year = month / 12
    return { year, month, day, hour, minute, second };
}

秒数转换时分秒

export function formatSeconds(sec) {
    if (!sec) {
        return '-'
    }
    var min = Math.floor(sec % 3600);//分钟
    const hh = Math.floor(sec / 3600) > 9 ? Math.floor(sec / 3600) : `0${Math.floor(sec / 3600)}`
    const mm = Math.floor(min / 60) > 9 ? Math.floor(min / 60) : `0${Math.floor(min / 60)}`
    const ss = sec % 60 > 9 ? sec % 60 : `0${sec % 60}`
    return hh + ":" + mm + ":" + ss;
}

根据时间戳-计算距离当前时间

/**
 * @description 根据时间戳-计算距离当前时间
 * @param {number} time
 * @param pattern 格式化的模式
 */

export const getDateDiff = (updateTime) => {
    if (updateTime === null) {
        return ''
    }
    const now = new Date().getTime()
    const second = Math.floor((now - updateTime) / (1000))
    const minute = Math.floor(second / 60)
    const hour = Math.floor(minute / 60)
    const day = Math.floor(hour / 24)
    const month = Math.floor(day / 31)
    const year = Math.floor(month / 12)
    if (year > 0) {
        return year + '年前'
    } else if (month > 0) {
        return month + '月前'
    } else if (day > 0) {
        let ret = day + '天前'
        if (day >= 7 && day < 14) {
            ret = '1周前'
        } else if (day >= 14 && day < 21) {
            ret = '2周前'
        } else if (day >= 21 && day < 28) {
            ret = '3周前'
        } else if (day >= 28 && day < 31) {
            ret = '4周前'
        }
        return ret
    } else if (hour > 0) {
        return hour + '小时前'
    } else if (minute > 0) {
        return minute + '分钟前'
    } else if (second > 0) {
        return second + '秒前'
    }
    return '刚刚'
}

表情转为字符

export const utf16toEntities = (str) => {
    const patt = /[\ud800-\udbff][\udc00-\udfff]/g; // 检测utf16字符正则 
    const newStr = str.replace(patt, (char) => {
        let Hstring = "" as any; let Lstring = "" as any; let code = "" as any;
        if (char.length === 2) {
            Hstring = char.charCodeAt(0); // 取出高位 
            Lstring = char.charCodeAt(1); // 取出低位 
            code = (Hstring - 0xD800) * 0x400 + 0x10000 + Lstring - 0xDC00; // 转换算法 
            return "&#" + code + ";";
        }
        return char;
    });
    return newStr;
}

字符转为表情

export const uncodeUtf16 = (str) => {
    const reg = /\&#.*?;/g;
    const result = str.replace(reg, (char) => {
        let Hstring = "" as any; let Lstring = "" as any; let code = "" as any;
        if (char.length === 9) {
            // eslint-disable-next-line radix
            code = parseInt(char.match(/[0-9]+/g));
            Hstring = Math.floor((code - 0x10000) / 0x400) + 0xD800;
            Lstring = (code - 0x10000) % 0x400 + 0xDC00;
            return unescape("%u" + Hstring.toString(16) + "%u" + Lstring.toString(16));
        }
        return char;
    });
    return result;
}

生成唯一标识符

/**
 * 生成唯一标识符
 *
 * @export
 * @returns
 */
export function guid() {
    return (S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4());
}
function S4() {
    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}

生成唯一id

/**
 * @description: 生成唯一id
 * @param {number} length 数字长度
 * @return {string} 
 */
export function genID(length = 3) {
    return Number(Math.random().toString().substr(3, length) + Date.now()).toString(36);
}

指定数量切割分组

/**指定数量切割分组 **/
export const getNewArray = (arr = [] as any, size = 5) => {
    const arrNum = Math.ceil(arr.length / size); // Math.ceil()向上取整的方法,用来计算拆分后数组的长度
    let index = 0; // 定义初始索引
    let resIndex = 0; // 用来保存每次拆分的长度
    const result = [];
    while (index < arrNum) {
        result[index] = arr.slice(resIndex, size + resIndex);
        resIndex += size;
        index++;
    }
    return result;
};

中文数字转阿拉伯数字

// 中文数字转阿拉伯数字
const map = {
    "零": 0,

    "一": 1,
    "壹": 1,

    "二": 2,
    "贰": 2,
    "两": 2,

    "三": 3,
    "叁": 3,

    "四": 4,
    "肆": 4,

    "五": 5,
    "伍": 5,

    "六": 6,
    "陆": 6,

    "七": 7,
    "柒": 7,

    "八": 8,
    "捌": 8,

    "九": 9,
    "玖": 9,

    "十": 10,
    "拾": 10,

    "百": 100,
    "佰": 100,

    "千": 1000,
    "仟": 1000,

    "万": 10000,
    "十万": 100000,
    "百万": 1000000,
    "千万": 10000000,
    "亿": 100000000
} as any;

// 解析失败返回-1,成功返回转换后的数字,不支持负数
export function chineseNumberToDigit(chinese_number: string): any {
    if (chinese_number) {
        let len = chinese_number.length;
        if (len == 0) return -1;
        if (len == 1) return (map[chinese_number] <= 10) ? map[chinese_number] : -1;
        // 返回的总和
        let summary = 0;

        // 十开头省略一的情况 例 `十二` 和 `一十二`
        if (map[chinese_number[0]] == 10) {
            chinese_number = "一" + chinese_number;
            len++;
        }

        // 单位结尾,省略末尾单位的情况  例 一万二  三千一 二百五
        if (len >= 3 && map[chinese_number[len - 1]] < 10) {
            const last_second_num = map[chinese_number[len - 2]];
            if (last_second_num == 100 || last_second_num == 1000 || last_second_num == 10000 || last_second_num == 100000000) {
                for (const key in map) {
                    if (map[key] == last_second_num / 10) {
                        chinese_number += key;
                        len += key.length;
                        break;
                    }
                }
            }
        }

        const matchYi = chinese_number.match(/亿/g);
        // 不支持 一亿亿xxx  十亿亿xx ...
        if (matchYi && matchYi.length > 1) return -1;

        // 处理一亿以上的情况 例 三百二十三亿三千二百万两千零二十二
        let splited = chinese_number.split("亿");
        const rest = splited[1] == "" ? 0 : chineseNumberToDigit(splited[1]);
        if (splited.length == 2) {

            return summary + chineseNumberToDigit(splited[0]) * 100000000 + rest;
        }

        // 下面处理小于一亿的情况 例 三千二百万两千零二十二
        splited = chinese_number.split("万");
        if (splited.length == 2) {

            return summary + chineseNumberToDigit(splited[0]) * 10000 + rest;
        }

        // 下面处理小于一万的情况 例 两千零二十二
        let i = 0;
        while (i < len) {
            const first_char_num = map[chinese_number[i]];
            const second_char_num = map[chinese_number[i + 1]];
            if (second_char_num > 9)
                summary += first_char_num * second_char_num;
            i++;
            if (i == len)
                summary += first_char_num <= 9 ? first_char_num : 0;
        }
        return summary;
    }
}

阿拉伯数字转中文大写

export const capitalAmount = (amount: any) => {
    // 汉字的数字
    const cnNums = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"];
    // 基本单位
    const cnIntRadice = ["", "拾", "佰", "仟"];
    // 对应整数部分扩展单位
    const cnIntUnits = ["", "万", "亿", "兆"];
    // 对应小数部分单位
    const cnDecUnits = ["角", "分", "毫", "厘"];
    // 整数金额时后面跟的字符
    const cnInteger = "整";
    // 整型完以后的单位
    const cnIntLast = "元";
    // 最大处理的数字
    const maxNum = 9999999999999999.99;
    // 金额整数部分
    let integerNum;
    // 金额小数部分
    let decimalNum;
    // 输出的中文金额字符串
    let chineseStr = "";
    // 分离金额后用的数组,预定义
    let parts;
    if (amount === "") { return ""; }
    amount = parseFloat(amount);
    if (amount >= maxNum) {
        // 超出最大处理数字
        return "";
    }
    if (amount === 0) {
        chineseStr = cnNums[0] + cnIntLast + cnInteger;
        return chineseStr;
    }
    // 转换为字符串
    amount = amount.toString();
    if (amount.indexOf(".") === -1) {
        integerNum = amount;
        decimalNum = "";
    } else {
        parts = amount.split(".");
        integerNum = parts[0];
        decimalNum = parts[1].substr(0, 4);
    }
    // 获取整型部分转换
    if (parseInt(integerNum, 10) > 0) {
        let zeroCount = 0;
        const IntLen = integerNum.length;
        for (let i = 0; i < IntLen; i++) {
            const n = integerNum.substr(i, 1);
            const p = IntLen - i - 1;
            const q = p / 4;
            const m = p % 4;
            if (n === "0") {
                zeroCount++;
            } else {
                if (zeroCount > 0) {
                    chineseStr += cnNums[0];
                }
                // 归零
                zeroCount = 0;
                chineseStr += cnNums[parseInt(n, 10)] + cnIntRadice[m];
            }
            if (m === 0 && zeroCount < 4) {
                chineseStr += cnIntUnits[q];
            }
        }
        chineseStr += cnIntLast;
    }
    // 小数部分
    if (decimalNum !== "") {
        const decLen = decimalNum.length;
        for (let i = 0; i < decLen; i++) {
            const n = decimalNum.substr(i, 1);
            if (n !== "0") {
                chineseStr += cnNums[Number(n)] + cnDecUnits[i];
            }
        }
    }
    if (chineseStr === "") {
        chineseStr += cnNums[0] + cnIntLast + cnInteger;
    } else if (decimalNum === "") {
        chineseStr += cnInteger;
    }
    return chineseStr;
};

函数返回值均是最后一个函数的返回值 返回值转为promise

/**
 * 所有函数返回值均是最后一个函数的返回值 返回值转为promise
 *
 * @export
 * @param {number} [time=200]
 * @returns {MethodDecorator}
 */
export function merge(time = 200): MethodDecorator {
    let st = '' as any;
    let resloveFunction: any;
    let returnPromise = {} as any;
    return (_target, _name, descriptor: any) => {
        const fun = descriptor.value;
        descriptor.value = function (...args: []) {
            if (!returnPromise) {
                returnPromise = new Promise(resolve => {
                    resloveFunction = resolve;
                });
            }

            clearTimeout(st);
            st = setTimeout(() => {
                resloveFunction(fun.apply(this, args));
                returnPromise = undefined;
            }, time);

            return returnPromise;
        };
        return descriptor;
    };
}

获取文件名称后缀

//获取文件名称后缀
export const get_suffix = (fileName: string) => {
    const suffix = fileName.substring(fileName.lastIndexOf('.') + 1);
    return suffix;
};