|
@@ -0,0 +1,305 @@
|
|
|
+// 字符串处理相关函数
|
|
|
+// 手机号中间4位加* ------------>
|
|
|
+export function addConfusionForTel (tel) {
|
|
|
+ const reg = /^(\d{3})\d{4}(\d{4})$/
|
|
|
+ return tel.replace(reg, '$1****$2')
|
|
|
+}
|
|
|
+// 手机号加空格 ------------>
|
|
|
+export function addSpaceForTel (tel) {
|
|
|
+ const regMap = {
|
|
|
+ isConfuse: /^(\d{3})\*{4}(\d{4})$/,
|
|
|
+ addSpace: /^(\d{3})(\d{4})(\d{4})$/
|
|
|
+ }
|
|
|
+ const confusion = regMap.isConfuse.test(tel)
|
|
|
+ if (confusion) {
|
|
|
+ return tel.replace(regMap.isConfuse, '$1 **** $2')
|
|
|
+ } else {
|
|
|
+ return tel.replace(regMap.addSpace, '$1 $2 $3')
|
|
|
+ }
|
|
|
+}
|
|
|
+// 银行卡加空格
|
|
|
+export function addSpaceForBank (v, hasConfusion = false) {
|
|
|
+ // 无*银行卡号加空格
|
|
|
+ if (hasConfusion) {
|
|
|
+ // 带有*的银行卡号字符串加空格
|
|
|
+ return v.replace(/\s/g, '').replace(/(.{4})/g, '$1 ')
|
|
|
+ } else {
|
|
|
+ // 纯数字银行卡号字符串加空格
|
|
|
+ return v.replace(/\s/g, '').replace(/(\d{4})(?=\d)/g, '$1 ')
|
|
|
+ }
|
|
|
+}
|
|
|
+// 银行卡加 **
|
|
|
+export function addConfusionForBank (v) {
|
|
|
+ if (String(v).length < 12) {
|
|
|
+ return v.replace(/\s/g, '').replace(/^(\d{2})\d+(\d{2})$/, '$1 **** **** $2')
|
|
|
+ } else {
|
|
|
+ return v.replace(/\s/g, '').replace(/^(\d{4})\d+(\d{4})$/, '$1 **** **** $2')
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 金额处理
|
|
|
+// 分转元
|
|
|
+export function fen2Yuan (v) {
|
|
|
+ return v / 100
|
|
|
+}
|
|
|
+
|
|
|
+// 金额大写,链接:https://juejin.im/post/5a2a7a5051882535cd4abfce
|
|
|
+// upDigit(1682) result:"人民币壹仟陆佰捌拾贰元整"
|
|
|
+// upDigit(-1693) result:"欠壹仟陆佰玖拾叁元整"
|
|
|
+export function upPrice (n) {
|
|
|
+ const fraction = ['角', '分', '厘']
|
|
|
+ const digit = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
|
|
|
+ const unit = [
|
|
|
+ ['元', '万', '亿'],
|
|
|
+ ['', '拾', '佰', '仟']
|
|
|
+ ]
|
|
|
+ // const head = n < 0 ? '欠人民币' : '人民币'
|
|
|
+ const head = ''
|
|
|
+ n = Math.abs(n)
|
|
|
+ let s = ''
|
|
|
+ for (let i = 0; i < fraction.length; i++) {
|
|
|
+ s += (digit[Math.floor(n * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(/零./, '')
|
|
|
+ }
|
|
|
+ s = s || '整'
|
|
|
+ n = Math.floor(n)
|
|
|
+ for (let i = 0; i < unit[0].length && n > 0; i++) {
|
|
|
+ let p = ''
|
|
|
+ for (let j = 0; j < unit[1].length && n > 0; j++) {
|
|
|
+ p = digit[n % 10] + unit[1][j] + p
|
|
|
+ n = Math.floor(n / 10)
|
|
|
+ }
|
|
|
+ s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s
|
|
|
+ // s = p + unit[0][i] + s;
|
|
|
+ }
|
|
|
+ return head + s.replace(/(零.)*零元/, '元').replace(/(零.)+/g, '零').replace(/^整$/, '零元整')
|
|
|
+}
|
|
|
+
|
|
|
+// 金额3位逗号分隔 ------------>
|
|
|
+/**
|
|
|
+ * @param s 要格式化的数字(四舍五入)
|
|
|
+ * @param n 保留几位小数(不传或者传-1 --> 如果为整数,则不保留小数。如果为浮点数,则保留两位小数)
|
|
|
+ * @param comma 是否小数点前每3位添加逗号
|
|
|
+ */
|
|
|
+export function newFormat (s = 0, n = -1, comma = false) {
|
|
|
+ n = n === -1 ? 0 : n
|
|
|
+ if (n > 20 || n < -1) {
|
|
|
+ n = 2
|
|
|
+ }
|
|
|
+ s = Number(s)
|
|
|
+ return s.toLocaleString('zh-CN', {
|
|
|
+ style: 'decimal',
|
|
|
+ useGrouping: comma,
|
|
|
+ minimumFractionDigits: n,
|
|
|
+ maximumFractionDigits: n
|
|
|
+ })
|
|
|
+}
|
|
|
+export function formatPrice (s, n = -1, comma = false) {
|
|
|
+ // 如果不传s或者s为空,则直接返回0
|
|
|
+ if (!s) return 0
|
|
|
+
|
|
|
+ if (n !== -1) n = n > 0 && n <= 20 ? n : 2
|
|
|
+ const intS = parseInt(String(s))
|
|
|
+ let point = '.'
|
|
|
+ let left = []
|
|
|
+ let right = ''
|
|
|
+ s = parseFloat((s + '').replace(/[^\d.-]/g, ''))
|
|
|
+ // 没传n或者n为-1,默认(如果为整数,则不保留小数。如果为浮点数,则保留两位小数)
|
|
|
+ if (n === -1) {
|
|
|
+ if (s === intS) {
|
|
|
+ n = 0
|
|
|
+ right = ''
|
|
|
+ point = ''
|
|
|
+ } else {
|
|
|
+ n = 2
|
|
|
+ s = s.toFixed(n)
|
|
|
+ right = s.split('.')[1]
|
|
|
+ }
|
|
|
+ s = s + ''
|
|
|
+ left = s.split('.')[0].split('').reverse()
|
|
|
+ } else {
|
|
|
+ s = parseFloat((s + '').replace(/[^\d.-]/g, '')).toFixed(n) + ''
|
|
|
+ left = s.split('.')[0].split('').reverse()
|
|
|
+ right = s.split('.')[1]
|
|
|
+ }
|
|
|
+
|
|
|
+ if (comma) {
|
|
|
+ let t = ''
|
|
|
+ for (let i = 0; i < left.length; i++) {
|
|
|
+ t += left[i] + ((i + 1) % 3 === 0 && (i + 1) !== left.length ? ',' : '')
|
|
|
+ }
|
|
|
+ return t.split('').reverse().join('') + point + right
|
|
|
+ }
|
|
|
+
|
|
|
+ return left.reverse().join('') + point + right
|
|
|
+}
|
|
|
+
|
|
|
+// 时间格式化相关函数
|
|
|
+/*
|
|
|
+* 时间格式化函数(将时间格式化为,2019年08月12日,2019-08-12,2019/08/12的形式)
|
|
|
+* pattern参数(想要什么格式的数据就传入什么格式的数据)
|
|
|
+* · 'yyyy-MM-dd' ---> 输出如2019-09-20
|
|
|
+* · 'yyyy-MM-dd HH:mm' ---> 输出如2019-09-20 18:20
|
|
|
+* · 'yyyy-MM-dd HH:mm:ss' ---> 输出如2019-09-20 06:20:23
|
|
|
+* · 'yyyy/MM/dd' ---> 输出如2019/09/20
|
|
|
+* · 'yyyy年MM月dd日' ---> 输出如2019年09月20日
|
|
|
+* · 'yyyy年MM月dd日 HH时mm分' ---> 输出如2019年09月20日 18时20分
|
|
|
+* · 'yyyy年MM月dd日 HH时mm分ss秒' ---> 输出如2019年09月20日 18时20分23秒
|
|
|
+* · 'yyyy年MM月dd日 HH时mm分ss秒 EE' ---> 输出如2019年09月20日 18时20分23秒 周二
|
|
|
+* · 'yyyy年MM月dd日 HH时mm分ss秒 EEE' ---> 输出如2019年09月20日 18时20分23秒 星期二
|
|
|
+* 参考: https://www.cnblogs.com/mr-wuxiansheng/p/6296646.html
|
|
|
+*/
|
|
|
+export function dateFormatter (date, fmt = 'yyyy-MM-dd HH:mm:ss') {
|
|
|
+ // 将传入的date转为时间对象
|
|
|
+ if (!date) return ''
|
|
|
+ date = new Date(date)
|
|
|
+ const o = {
|
|
|
+ 'y+': date.getFullYear(),
|
|
|
+ 'M+': date.getMonth() + 1, // 月份
|
|
|
+ 'd+': date.getDate(), // 日
|
|
|
+ // 12小时制
|
|
|
+ 'h+': date.getHours() % 12 === 0 ? 12 : date.getHours() % 12, // 小时
|
|
|
+ // 24小时制
|
|
|
+ 'H+': date.getHours(), // 小时
|
|
|
+ 'm+': date.getMinutes(), // 分
|
|
|
+ 's+': date.getSeconds(), // 秒
|
|
|
+ 'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
|
|
|
+ S: date.getMilliseconds(), // 毫秒
|
|
|
+ 'E+': date.getDay() // 周
|
|
|
+ }
|
|
|
+ const week = ['日', '一', '二', '三', '四', '五', '六']
|
|
|
+
|
|
|
+ if (/(y+)/.test(fmt)) {
|
|
|
+ fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
|
|
|
+ }
|
|
|
+ if (/(E+)/.test(fmt)) {
|
|
|
+ fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? '星期' : '周') : '') + week[date.getDay()])
|
|
|
+ }
|
|
|
+ for (const 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
|
|
|
+}
|
|
|
+
|
|
|
+// 时间戳转换 多少秒、多少分、多少小时前、多少天前 超出10天显示年月日
|
|
|
+// 传入一个时间戳
|
|
|
+export function dateFromNow (timestamp) {
|
|
|
+ const date1 = new Date(timestamp) // 开始时间
|
|
|
+ const date2 = new Date() // 结束时间
|
|
|
+ const date3 = date2.getTime() - date1.getTime() // 时间差的毫秒数
|
|
|
+ // 计算出相差天数
|
|
|
+ const days = Math.floor(date3 / (24 * 3600 * 1000))
|
|
|
+ // 计算出小时数
|
|
|
+ const leave1 = date3 % (24 * 3600 * 1000) // 计算天数后剩余的毫秒数
|
|
|
+ const hours = Math.floor(leave1 / (3600 * 1000))
|
|
|
+ // 计算相差分钟数
|
|
|
+ const leave2 = leave1 % (3600 * 1000) // 计算小时数后剩余的毫秒数
|
|
|
+ const minutes = Math.floor(leave2 / (60 * 1000))
|
|
|
+ // 计算相差秒数
|
|
|
+ let td = '30秒前'
|
|
|
+ if (days > 0) {
|
|
|
+ if (days > 10) {
|
|
|
+ const date1year = date1.getFullYear()
|
|
|
+ const date2year = date2.getFullYear()
|
|
|
+ let date1month = date1.getMonth() + 1
|
|
|
+ let date1day = date1.getDate()
|
|
|
+ if (date1month < 10) {
|
|
|
+ date1month = '0' + date1month
|
|
|
+ }
|
|
|
+ if (date1day < 10) {
|
|
|
+ date1day = '0' + date1day
|
|
|
+ }
|
|
|
+ if (date1year < date2year) {
|
|
|
+ td = date1.getFullYear() + '-' + date1month + '-' + date1day
|
|
|
+ } else {
|
|
|
+ td = date1month + '-' + date1day
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ td = days + '天前'
|
|
|
+ }
|
|
|
+ } else if (hours > 0) {
|
|
|
+ td = hours + '小时前'
|
|
|
+ } else if (minutes > 0) {
|
|
|
+ td = minutes + '分钟前'
|
|
|
+ }
|
|
|
+ return td
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 通用关键字高亮替换
|
|
|
+ * @param {String} value 要高亮的字符串
|
|
|
+ * @param {String|Array} oldChar 要被替换的字符串(或数组)
|
|
|
+ * @param {String|Array} newChar 要替换成的字符串(或数组)
|
|
|
+ *
|
|
|
+ * 比如:要将 - `剑鱼标讯工具函数` 字符串中的 `工具` 高亮
|
|
|
+ * 则此时 value -> `剑鱼标讯工具函数`
|
|
|
+ * oldChar -> `工具`
|
|
|
+ * newChar -> `<span class="highlight-text">工具</span>`
|
|
|
+ *
|
|
|
+ * 批量高亮-----
|
|
|
+ * 比如:要将 - `剑鱼标讯工具函数` 字符串中的 `工具` `剑鱼` 高亮
|
|
|
+ * 则此时 value -> `剑鱼标讯工具函数批量高亮`
|
|
|
+ * oldChar -> ['工具', '剑鱼']
|
|
|
+ * newChar -> ['<span class="highlight-text">', '</span>']
|
|
|
+ *
|
|
|
+ * 注意:此时newChar为一个长度为2的数组,数组中为高亮标签的起始标签和结束标签
|
|
|
+ *
|
|
|
+ */
|
|
|
+export function replaceKeyword (value, oldChar, newChar) {
|
|
|
+ if (!oldChar || !newChar) return value
|
|
|
+ // oldChar的字符串数组,用来循环替换
|
|
|
+ var oldCharArr = []
|
|
|
+
|
|
|
+ if (Array.isArray(oldChar)) {
|
|
|
+ oldCharArr = oldChar.concat()
|
|
|
+ } else {
|
|
|
+ oldCharArr.push(oldChar)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 数组去重
|
|
|
+ oldCharArr = Array.from(new Set(oldCharArr))
|
|
|
+
|
|
|
+ try {
|
|
|
+ oldCharArr.forEach(function (item) {
|
|
|
+ // 去空格之后为空字符串,则直接跳过当前替换
|
|
|
+ if (item.replace(/\s+/g, '')) {
|
|
|
+ var oc = item
|
|
|
+ oc = oc.replace(/\$/g, '\\$')
|
|
|
+ .replace(/\(/g, '\\(')
|
|
|
+ .replace(/\)/g, '\\)')
|
|
|
+ .replace(/\*/g, '\\*')
|
|
|
+ .replace(/\+/g, '\\+')
|
|
|
+ .replace(/\./g, '\\.')
|
|
|
+ .replace(/\[/g, '\\[')
|
|
|
+ .replace(/\]/g, '\\]')
|
|
|
+ .replace(/\?/g, '\\?')
|
|
|
+ .replace(/\\/g, '\\')
|
|
|
+ .replace(/\//g, '\\/')
|
|
|
+ .replace(/\^/g, '\\^')
|
|
|
+ .replace(/\{/g, '\\{')
|
|
|
+ .replace(/\}/g, '\\}')
|
|
|
+ .replace(/\|/g, '\\|')
|
|
|
+
|
|
|
+ if (Array.isArray(newChar)) {
|
|
|
+ // 批量高亮
|
|
|
+ var tempV = value
|
|
|
+ value = value.replace(new RegExp('(' + oc + ')', 'gmi'), newChar[0] + oc + newChar[1])
|
|
|
+ if (value === tempV && oc.indexOf('+') !== -1) {
|
|
|
+ var splitReg = oc.split('\\+')
|
|
|
+ splitReg.map(function (v) {
|
|
|
+ value = value.replace(new RegExp('(' + v + ')', 'gmi'), newChar[0] + v + newChar[1])
|
|
|
+ })
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 普通单个高亮
|
|
|
+ value = value.replace(new RegExp('(' + oc + ')', 'gmi'), newChar)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } catch (e) {
|
|
|
+ console.log(e)
|
|
|
+ return value
|
|
|
+ }
|
|
|
+ return value
|
|
|
+}
|