import _ from 'lodash'; import { toThousands } from '@mx/util/to-thousands'; /** * toThousands千分位格式化 * * ### Example * ``` * const n = '12344.33' * toThousands(n); // 12,344.33 * ``` */ // 時間格式化 export function getTimeStr (date) { if (typeof date === 'number') { date = new Date(date); } let hours = `${date.getHours()}`; let minutes = `${date.getMinutes()}`; let secodes = `${date.getSeconds()}`; if (hours.length < 2) { hours = `0${hours}`; } if (minutes.length < 2) { minutes = `0${minutes}`; } if (secodes.length < 2) { secodes = `0${secodes}`; } return `${hours}:${minutes}:${secodes}`; } // 日期格式化 export function getDateStr (date, flag = '-') { if (!date) { return ''; } if (typeof date === 'number') { date = new Date(date); } let year = `${date.getFullYear()}`; let month = `${date.getMonth() + 1}`; let day = `${date.getDate()}`; if (month.length < 2) { month = `0${month}`; } if (day.length < 2) { day = `0${day}`; } return `${year}${flag}${month}${flag}${day}`; } // 綜合時間格式化 export function formatDate (date) { if (!date) { return '--'; } return `${getDateStr(date)} ${getTimeStr(date)}`; } // 數字格式保留指定位小數,返回字符串格式 export function fixedNumber (num, count = 2) { if (typeof num !== 'number') { num = Number(num); } return num.toFixed(count); } // 金額 分=>元 export function amountCentToYuan (cent) { if (typeof cent !== 'number' || Number.isNaN(cent)) { return null; } return round(cent / 100, 2); } // 金額 元=>分 export function amountYuanToCent (yuan) { if (typeof yuan !== 'number' || Number.isNaN(yuan)) { return null; } return round(yuan * 100, 2); } // 小數四捨五入 export function round (number, precision) { return Math.round(+number + 'e' + precision) / Math.pow(10, precision); } // 千分位格式化,可選擇金額單位爲分 export function amountToThousands (amount, isCent = false) { if (!amount && amount !== 0) { return ''; } if (isCent) { amount = Number.parseFloat(amount) / 100; } // 產品要強制帶小數點兩位 let amountStr = toThousands(`${amount}`); if (!amountStr.includes('.')) { amountStr += '.00'; } else { // 小數點後只有一位的話,還須要補齊 if (amountStr.split('.')[1].length < 2) { amountStr += '0'; } } return amountStr; } // 數字大寫格式映射 export function getNumberCap (num) { num = num.trim(); if (!num) { return ''; } if (!/^(0|[1-9]\d*)(\.\d+)?$/.test(num)) { return '異常金額'; } let unit = '千百拾億千百拾萬千百拾元角分'; let str = ''; num += '00'; const p = num.indexOf('.'); if (p >= 0) { num = num.substring(0, p) + num.substr(p + 1, 2); } unit = unit.substr(unit.length - num.length); for (let i = 0; i < num.length; i++) { str += '零壹貳叄肆伍陸柒捌玖'.charAt(num.charAt(i)) + unit.charAt(i); } return str.replace(/零(千|百|拾|角)/g, '零') .replace(/(零)+/g, '零') .replace(/零(萬|億|元)/g, '$1') .replace(/(億)萬|壹(拾)/g, '$1$2') .replace(/^元零?|零分/g, '') .replace(/元$/g, '元整'); } // 根據正則剔除字符串指定內容,默認剔除非數字 export function replaceByRex (val, rex = /^[0-9]*$/) { if (!val) { return ''; } return Array.from(val).filter(str => Array.isArray(str.match(rex))).join(''); } // 剔除字符串中非數字部分並返回 export function replaceNotNum (val) { return replaceByRex(val, /^[0-9]*$/); } // 提出字符串中非數字和字母的部分並返回 export function replaceNotNumAndLetter (val) { return replaceByRex(val, /^[0-9a-zA-Z]*$/); } // 函數節流,多用於提交接口,默認2s export function throttle (fn, wait = 2000) { return _.throttle(fn, wait); } // 對象深拷貝 export function deepCopy (obj) { return JSON.parse(JSON.stringify(obj)); } // 截取字符串中的數字部分並返回,返回值是字符串格式 // 卡號等不太適用,很是大的數字計算會有問題 export function getNumberByString (str, isFloat = false, precision = 2) { str = str.trim(); if (!str) { return ''; } const reg = isFloat ? /[0-9.]*/g : /[0-9]*/g; const resultArr = str.match(reg); let resultStr = ''; if (Array.isArray(resultArr)) { resultStr = resultArr.join(''); } if (!isFloat) { // 爲了保險起見,先轉成數字再轉回來 return `${Number.parseInt(resultStr)}`; } else { // 小數可能存在多個小數點存在,小數點也可能在開頭或者結尾,都須要處理 // 結尾的小數點暫不處理,由於輸入小數輸一半是必然會通過這一過程的 if (resultStr.startsWith('.')) { // 開頭的小數點會處理成0. resultStr = '0' + resultStr; } if (resultStr.indexOf('.') !== resultStr.lastIndexOf('.')) { // 若是有多個小數點,則第二個小數點及以後的內容將會被捨棄 const arr = resultStr.split('.'); resultStr = `${arr[0]}.${arr[1]}`; } // 小數位數限制 if (typeof precision === 'number' && precision >= 0) { if (resultStr.includes('.')) { let [int, float] = resultStr.split('.'); if (float.length > precision) { float = float.substring(0, precision); } resultStr = `${int}.${float}`; } } // 保險起見,先轉成數字再轉回來 // 不過只要有小數點,就可能不適用 if (resultStr.includes('.')) { return resultStr; } return `${Number.parseFloat(resultStr)}`; } } // 銀行卡號展現,開始三位有一個空格,以後每四位會有一空格 export function showBankNo (bankCardNo) { if (!bankCardNo) { return ''; } let showCardNo = ''; for (let i = 1; i <= bankCardNo.length; i++) { showCardNo += bankCardNo[i - 1]; if (i === 3) { showCardNo += ' '; } else if (i > 4) { if ((i % 4) === 0 && i !== bankCardNo.length) { showCardNo += ' '; } } } return showCardNo; } function compareNumbers (a, b) { a = Number(a); b = Number(b); return a === b ? 0 : a > b ? 1 : -1; } export function formatCommaSeparatedNumbersToNumberArray (v = '') { if (v === null) { return []; } let values = v.split(',') .map(value => { const num = Number(value); if (num) { return num; } }) .filter(v => typeof v === 'number') .filter(value => { const v = Number(value); return v > 0 && Number.isInteger(v); }); if (values.length === 0) { return []; } return Array.from(new Set(values)).sort(compareNumbers); } export function formatCommaSeparatedNumbersToArray (v = '') { if (v === null) { return []; } let values = v.split(',').filter((value = '') => { if (value === '') { return false; } const v = Number(value); return v > 0 && Number.isInteger(v); }); if (values.length === 0) { return []; } return Array.from(new Set(values)).sort(compareNumbers); } // 當前環境區分 export function getEnvRuntime () { if (/\.dev\.sankuai\.com/.test(location.host)) { return 'dev'; } else if (/\.test\.sankuai\.com/.test(location.host)) { return 'test'; } else if (/\.st\.(sankuai|meituan)\.com/.test(location.host)) { return 'st'; } else if (/(promomis-promotion|promo)\.(sankuai|meituan)\.com/.test(location.host)) { return 'prod'; } else { return 'local'; } } // 獲取協議模板 export function getAgreementTemplate (no, params) { let agreementTemplate = ''; if (no) { agreementTemplate = require(`client/business/agreements/${no}.html`); } if (agreementTemplate) { // 協議裏存在變量,須要分別填充,具體運算規則不在公共方法中處理,而是由外部傳入數據決定 const variable = _.template(agreementTemplate); return params ? variable(params) : variable(); } console.warn(`協議${no}不存在`); return '沒有對應協議'; } // 遞歸合併對象,只合並同級字段 export function meargeObject (base, opt, copyBase = true) { if (!base || typeof base !== 'object') { return opt || {}; } if (copyBase) { base = deepCopy(base); } if (!opt || typeof opt !== 'object') { return base; } // 遞歸遍歷對比,須要根據typeof來判斷 for (const [optKey, optVal] of Object.entries(opt)) { let val = null; for (const [baseKey, baseVal] of Object.entries(base)) { if (baseKey === optKey) { if (Array.isArray(baseVal)) { val = baseVal.concat(optVal); } else if (Array.isArray(optVal)) { // 這種很奇怪了,原數據不是數組,但新數據是,我就先按照徹底替換處理了 val = optVal; } else if (typeof baseVal === typeof optVal === 'object') { val = meargeObject(baseVal, optVal, false); } else { val = optVal; } } } if (!val) { base[optKey] = optVal; } else { base[optKey] = val; } } return base; } // JS下載指定url文件 export function downFile (url) { const iframe = document.createElement('iframe'); iframe.src = url; iframe.style.display = 'none'; document.body.appendChild(iframe); }