271 lines
6.5 KiB
JavaScript
271 lines
6.5 KiB
JavaScript
function batchFindObjctValue (obj = {}, keys = []) {
|
||
const values = {}
|
||
for (let i = 0; i < keys.length; i++) {
|
||
const key = keys[i]
|
||
const keyPath = key.split('.')
|
||
let currentKey = keyPath.shift()
|
||
let result = obj
|
||
while (currentKey) {
|
||
if (!result) {
|
||
break
|
||
}
|
||
result = result[currentKey]
|
||
currentKey = keyPath.shift()
|
||
}
|
||
values[key] = result
|
||
}
|
||
return values
|
||
}
|
||
|
||
function getType (val) {
|
||
return Object.prototype.toString.call(val).slice(8, -1).toLowerCase()
|
||
}
|
||
|
||
function hasOwn (obj, key) {
|
||
return Object.prototype.hasOwnProperty.call(obj, key)
|
||
}
|
||
|
||
function isValidString (val) {
|
||
return val && getType(val) === 'string'
|
||
}
|
||
|
||
function isPlainObject (obj) {
|
||
return getType(obj) === 'object'
|
||
}
|
||
|
||
function isFn (fn) {
|
||
// 务必注意AsyncFunction
|
||
return typeof fn === 'function'
|
||
}
|
||
|
||
// 获取文件后缀,只添加几种图片类型供客服消息接口使用
|
||
const mime2ext = {
|
||
'image/png': 'png',
|
||
'image/jpeg': 'jpg',
|
||
'image/gif': 'gif',
|
||
'image/svg+xml': 'svg',
|
||
'image/bmp': 'bmp',
|
||
'image/webp': 'webp'
|
||
}
|
||
|
||
function getExtension (contentType) {
|
||
return mime2ext[contentType]
|
||
}
|
||
|
||
const isSnakeCase = /_(\w)/g
|
||
const isCamelCase = /[A-Z]/g
|
||
|
||
function snake2camel (value) {
|
||
return value.replace(isSnakeCase, (_, c) => (c ? c.toUpperCase() : ''))
|
||
}
|
||
|
||
function camel2snake (value) {
|
||
return value.replace(isCamelCase, str => '_' + str.toLowerCase())
|
||
}
|
||
|
||
function parseObjectKeys (obj, type) {
|
||
let parserReg, parser
|
||
switch (type) {
|
||
case 'snake2camel':
|
||
parser = snake2camel
|
||
parserReg = isSnakeCase
|
||
break
|
||
case 'camel2snake':
|
||
parser = camel2snake
|
||
parserReg = isCamelCase
|
||
break
|
||
}
|
||
for (const key in obj) {
|
||
if (hasOwn(obj, key)) {
|
||
if (parserReg.test(key)) {
|
||
const keyCopy = parser(key)
|
||
obj[keyCopy] = obj[key]
|
||
delete obj[key]
|
||
if (isPlainObject(obj[keyCopy])) {
|
||
obj[keyCopy] = parseObjectKeys(obj[keyCopy], type)
|
||
} else if (Array.isArray(obj[keyCopy])) {
|
||
obj[keyCopy] = obj[keyCopy].map((item) => {
|
||
return parseObjectKeys(item, type)
|
||
})
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return obj
|
||
}
|
||
|
||
function snake2camelJson (obj) {
|
||
return parseObjectKeys(obj, 'snake2camel')
|
||
}
|
||
|
||
function camel2snakeJson (obj) {
|
||
return parseObjectKeys(obj, 'camel2snake')
|
||
}
|
||
|
||
function getOffsetDate (offset) {
|
||
return new Date(
|
||
Date.now() + (new Date().getTimezoneOffset() + (offset || 0) * 60) * 60000
|
||
)
|
||
}
|
||
|
||
function getDateStr (date, separator = '-') {
|
||
date = date || new Date()
|
||
const dateArr = []
|
||
dateArr.push(date.getFullYear())
|
||
dateArr.push(('00' + (date.getMonth() + 1)).substr(-2))
|
||
dateArr.push(('00' + date.getDate()).substr(-2))
|
||
return dateArr.join(separator)
|
||
}
|
||
|
||
function getTimeStr (date, separator = ':') {
|
||
date = date || new Date()
|
||
const timeArr = []
|
||
timeArr.push(('00' + date.getHours()).substr(-2))
|
||
timeArr.push(('00' + date.getMinutes()).substr(-2))
|
||
timeArr.push(('00' + date.getSeconds()).substr(-2))
|
||
return timeArr.join(separator)
|
||
}
|
||
|
||
function getFullTimeStr (date) {
|
||
date = date || new Date()
|
||
return getDateStr(date) + ' ' + getTimeStr(date)
|
||
}
|
||
|
||
function getDistinctArray (arr) {
|
||
return Array.from(new Set(arr))
|
||
}
|
||
|
||
/**
|
||
* 拼接url
|
||
* @param {string} base 基础路径
|
||
* @param {string} path 在基础路径上拼接的路径
|
||
* @returns
|
||
*/
|
||
function resolveUrl (base, path) {
|
||
if (/^https?:/.test(path)) {
|
||
return path
|
||
}
|
||
return base + path
|
||
}
|
||
|
||
function getVerifyCode (len = 6) {
|
||
let code = ''
|
||
for (let i = 0; i < len; i++) {
|
||
code += Math.floor(Math.random() * 10)
|
||
}
|
||
return code
|
||
}
|
||
|
||
function coverMobile (mobile) {
|
||
if (typeof mobile !== 'string') {
|
||
return mobile
|
||
}
|
||
return mobile.slice(0, 3) + '****' + mobile.slice(7)
|
||
}
|
||
|
||
function getNonceStr (length = 16) {
|
||
let str = ''
|
||
while (str.length < length) {
|
||
str += Math.random().toString(32).substring(2)
|
||
}
|
||
return str.substring(0, length)
|
||
}
|
||
|
||
try {
|
||
require('lodash.merge')
|
||
} catch (error) {
|
||
console.error('uni-id-co缺少依赖,请在uniCloud/cloudfunctions/uni-id-co目录执行 npm install 安装依赖')
|
||
throw error
|
||
}
|
||
|
||
function isMatchUserApp (userAppList, matchAppList) {
|
||
if (userAppList === undefined || userAppList === null) {
|
||
return true
|
||
}
|
||
if (getType(userAppList) !== 'array') {
|
||
return false
|
||
}
|
||
if (userAppList.includes('*')) {
|
||
return true
|
||
}
|
||
if (getType(matchAppList) === 'string') {
|
||
matchAppList = [matchAppList]
|
||
}
|
||
return userAppList.some(item => matchAppList.includes(item))
|
||
}
|
||
|
||
function checkIdCard (idCardNumber) {
|
||
if (!idCardNumber || typeof idCardNumber !== 'string' || idCardNumber.length !== 18) return false
|
||
|
||
const coefficient = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
|
||
const checkCode = [1, 0, 'x', 9, 8, 7, 6, 5, 4, 3, 2]
|
||
const code = idCardNumber.substring(17)
|
||
|
||
let sum = 0
|
||
for (let i = 0; i < 17; i++) {
|
||
sum += Number(idCardNumber.charAt(i)) * coefficient[i]
|
||
}
|
||
|
||
return checkCode[sum % 11].toString() === code.toLowerCase()
|
||
}
|
||
|
||
function catchAwait (fn, finallyFn) {
|
||
if (!fn) return [new Error('no function')]
|
||
|
||
if (Promise.prototype.finally === undefined) {
|
||
// eslint-disable-next-line no-extend-native
|
||
Promise.prototype.finally = function (finallyFn) {
|
||
return this.then(
|
||
res => Promise.resolve(finallyFn()).then(() => res),
|
||
error => Promise.resolve(finallyFn()).then(() => { throw error })
|
||
)
|
||
}
|
||
}
|
||
|
||
return fn
|
||
.then((data) => [undefined, data])
|
||
.catch((error) => [error])
|
||
.finally(() => typeof finallyFn === 'function' && finallyFn())
|
||
}
|
||
|
||
function dataDesensitization (value = '', options = {}) {
|
||
const { onlyLast = false } = options
|
||
const [firstIndex, middleIndex, lastIndex] = onlyLast ? [0, 0, -1] : [0, 1, -1]
|
||
|
||
if (!value) return value
|
||
const first = value.slice(firstIndex, middleIndex)
|
||
const middle = value.slice(middleIndex, lastIndex)
|
||
const last = value.slice(lastIndex)
|
||
const star = Array.from(new Array(middle.length), (v) => '*').join('')
|
||
|
||
return first + star + last
|
||
}
|
||
|
||
function getCurrentDateTimestamp (date = Date.now(), targetTimezone = 8) {
|
||
const oneHour = 60 * 60 * 1000
|
||
return parseInt((date + targetTimezone * oneHour) / (24 * oneHour)) * (24 * oneHour) - targetTimezone * oneHour
|
||
}
|
||
|
||
module.exports = {
|
||
getType,
|
||
isValidString,
|
||
batchFindObjctValue,
|
||
isPlainObject,
|
||
isFn,
|
||
getDistinctArray,
|
||
getFullTimeStr,
|
||
resolveUrl,
|
||
getOffsetDate,
|
||
camel2snakeJson,
|
||
snake2camelJson,
|
||
getExtension,
|
||
getVerifyCode,
|
||
coverMobile,
|
||
getNonceStr,
|
||
isMatchUserApp,
|
||
checkIdCard,
|
||
catchAwait,
|
||
dataDesensitization,
|
||
getCurrentDateTimestamp
|
||
}
|