utils.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. function batchFindObjctValue (obj = {}, keys = []) {
  2. const values = {}
  3. for (let i = 0; i < keys.length; i++) {
  4. const key = keys[i]
  5. const keyPath = key.split('.')
  6. let currentKey = keyPath.shift()
  7. let result = obj
  8. while (currentKey) {
  9. if (!result) {
  10. break
  11. }
  12. result = result[currentKey]
  13. currentKey = keyPath.shift()
  14. }
  15. values[key] = result
  16. }
  17. return values
  18. }
  19. function getType (val) {
  20. return Object.prototype.toString.call(val).slice(8, -1).toLowerCase()
  21. }
  22. function hasOwn (obj, key) {
  23. return Object.prototype.hasOwnProperty.call(obj, key)
  24. }
  25. function isValidString (val) {
  26. return val && getType(val) === 'string'
  27. }
  28. function isPlainObject (obj) {
  29. return getType(obj) === 'object'
  30. }
  31. function isFn (fn) {
  32. // 务必注意AsyncFunction
  33. return typeof fn === 'function'
  34. }
  35. // 获取文件后缀,只添加几种图片类型供客服消息接口使用
  36. const mime2ext = {
  37. 'image/png': 'png',
  38. 'image/jpeg': 'jpg',
  39. 'image/gif': 'gif',
  40. 'image/svg+xml': 'svg',
  41. 'image/bmp': 'bmp',
  42. 'image/webp': 'webp'
  43. }
  44. function getExtension (contentType) {
  45. return mime2ext[contentType]
  46. }
  47. const isSnakeCase = /_(\w)/g
  48. const isCamelCase = /[A-Z]/g
  49. function snake2camel (value) {
  50. return value.replace(isSnakeCase, (_, c) => (c ? c.toUpperCase() : ''))
  51. }
  52. function camel2snake (value) {
  53. return value.replace(isCamelCase, str => '_' + str.toLowerCase())
  54. }
  55. function parseObjectKeys (obj, type) {
  56. let parserReg, parser
  57. switch (type) {
  58. case 'snake2camel':
  59. parser = snake2camel
  60. parserReg = isSnakeCase
  61. break
  62. case 'camel2snake':
  63. parser = camel2snake
  64. parserReg = isCamelCase
  65. break
  66. }
  67. for (const key in obj) {
  68. if (hasOwn(obj, key)) {
  69. if (parserReg.test(key)) {
  70. const keyCopy = parser(key)
  71. obj[keyCopy] = obj[key]
  72. delete obj[key]
  73. if (isPlainObject(obj[keyCopy])) {
  74. obj[keyCopy] = parseObjectKeys(obj[keyCopy], type)
  75. } else if (Array.isArray(obj[keyCopy])) {
  76. obj[keyCopy] = obj[keyCopy].map((item) => {
  77. return parseObjectKeys(item, type)
  78. })
  79. }
  80. }
  81. }
  82. }
  83. return obj
  84. }
  85. function snake2camelJson (obj) {
  86. return parseObjectKeys(obj, 'snake2camel')
  87. }
  88. function camel2snakeJson (obj) {
  89. return parseObjectKeys(obj, 'camel2snake')
  90. }
  91. function getOffsetDate (offset) {
  92. return new Date(
  93. Date.now() + (new Date().getTimezoneOffset() + (offset || 0) * 60) * 60000
  94. )
  95. }
  96. function getDateStr (date, separator = '-') {
  97. date = date || new Date()
  98. const dateArr = []
  99. dateArr.push(date.getFullYear())
  100. dateArr.push(('00' + (date.getMonth() + 1)).substr(-2))
  101. dateArr.push(('00' + date.getDate()).substr(-2))
  102. return dateArr.join(separator)
  103. }
  104. function getTimeStr (date, separator = ':') {
  105. date = date || new Date()
  106. const timeArr = []
  107. timeArr.push(('00' + date.getHours()).substr(-2))
  108. timeArr.push(('00' + date.getMinutes()).substr(-2))
  109. timeArr.push(('00' + date.getSeconds()).substr(-2))
  110. return timeArr.join(separator)
  111. }
  112. function getFullTimeStr (date) {
  113. date = date || new Date()
  114. return getDateStr(date) + ' ' + getTimeStr(date)
  115. }
  116. function getDistinctArray (arr) {
  117. return Array.from(new Set(arr))
  118. }
  119. /**
  120. * 拼接url
  121. * @param {string} base 基础路径
  122. * @param {string} path 在基础路径上拼接的路径
  123. * @returns
  124. */
  125. function resolveUrl (base, path) {
  126. if (/^https?:/.test(path)) {
  127. return path
  128. }
  129. return base + path
  130. }
  131. function getVerifyCode (len = 6) {
  132. let code = ''
  133. for (let i = 0; i < len; i++) {
  134. code += Math.floor(Math.random() * 10)
  135. }
  136. return code
  137. }
  138. function coverMobile (mobile) {
  139. if (typeof mobile !== 'string') {
  140. return mobile
  141. }
  142. return mobile.slice(0, 3) + '****' + mobile.slice(7)
  143. }
  144. function getNonceStr (length = 16) {
  145. let str = ''
  146. while (str.length < length) {
  147. str += Math.random().toString(32).substring(2)
  148. }
  149. return str.substring(0, length)
  150. }
  151. try {
  152. require('lodash.merge')
  153. } catch (error) {
  154. console.error('uni-id-co缺少依赖,请在uniCloud/cloudfunctions/uni-id-co目录执行 npm install 安装依赖')
  155. throw error
  156. }
  157. function isMatchUserApp (userAppList, matchAppList) {
  158. if (userAppList === undefined || userAppList === null) {
  159. return true
  160. }
  161. if (getType(userAppList) !== 'array') {
  162. return false
  163. }
  164. if (userAppList.includes('*')) {
  165. return true
  166. }
  167. if (getType(matchAppList) === 'string') {
  168. matchAppList = [matchAppList]
  169. }
  170. return userAppList.some(item => matchAppList.includes(item))
  171. }
  172. function checkIdCard (idCardNumber) {
  173. if (!idCardNumber || typeof idCardNumber !== 'string' || idCardNumber.length !== 18) return false
  174. const coefficient = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
  175. const checkCode = [1, 0, 'x', 9, 8, 7, 6, 5, 4, 3, 2]
  176. const code = idCardNumber.substring(17)
  177. let sum = 0
  178. for (let i = 0; i < 17; i++) {
  179. sum += Number(idCardNumber.charAt(i)) * coefficient[i]
  180. }
  181. return checkCode[sum % 11].toString() === code.toLowerCase()
  182. }
  183. function catchAwait (fn, finallyFn) {
  184. if (!fn) return [new Error('no function')]
  185. if (Promise.prototype.finally === undefined) {
  186. // eslint-disable-next-line no-extend-native
  187. Promise.prototype.finally = function (finallyFn) {
  188. return this.then(
  189. res => Promise.resolve(finallyFn()).then(() => res),
  190. error => Promise.resolve(finallyFn()).then(() => { throw error })
  191. )
  192. }
  193. }
  194. return fn
  195. .then((data) => [undefined, data])
  196. .catch((error) => [error])
  197. .finally(() => typeof finallyFn === 'function' && finallyFn())
  198. }
  199. function dataDesensitization (value = '', options = {}) {
  200. const { onlyLast = false } = options
  201. const [firstIndex, middleIndex, lastIndex] = onlyLast ? [0, 0, -1] : [0, 1, -1]
  202. if (!value) return value
  203. const first = value.slice(firstIndex, middleIndex)
  204. const middle = value.slice(middleIndex, lastIndex)
  205. const last = value.slice(lastIndex)
  206. const star = Array.from(new Array(middle.length), (v) => '*').join('')
  207. return first + star + last
  208. }
  209. function getCurrentDateTimestamp (date = Date.now(), targetTimezone = 8) {
  210. const oneHour = 60 * 60 * 1000
  211. return parseInt((date + targetTimezone * oneHour) / (24 * oneHour)) * (24 * oneHour) - targetTimezone * oneHour
  212. }
  213. module.exports = {
  214. getType,
  215. isValidString,
  216. batchFindObjctValue,
  217. isPlainObject,
  218. isFn,
  219. getDistinctArray,
  220. getFullTimeStr,
  221. resolveUrl,
  222. getOffsetDate,
  223. camel2snakeJson,
  224. snake2camelJson,
  225. getExtension,
  226. getVerifyCode,
  227. coverMobile,
  228. getNonceStr,
  229. isMatchUserApp,
  230. checkIdCard,
  231. catchAwait,
  232. dataDesensitization,
  233. getCurrentDateTimestamp
  234. }