chore: initialize qiming workspace repository
This commit is contained in:
321
qiming-mobile/uni_modules/x-tools/tools/index.js
Normal file
321
qiming-mobile/uni_modules/x-tools/tools/index.js
Normal file
@@ -0,0 +1,321 @@
|
||||
export * as sugar from './sugar'
|
||||
export * as router from './router'
|
||||
export * as h5Utils from './h5Utils'
|
||||
export * as appletUtils from './appletUtils'
|
||||
export * from './retryAsync'
|
||||
|
||||
import pagesJson from '@/pages.json'
|
||||
|
||||
export const isPromise = (obj) => {
|
||||
return !!obj && (typeof obj === "object" || typeof obj === "function") && typeof obj.then === "function";
|
||||
}
|
||||
|
||||
let promisifyFlag = false
|
||||
export const promisify = () => {
|
||||
|
||||
if (promisifyFlag) return
|
||||
|
||||
promisifyFlag = true
|
||||
|
||||
// #ifdef VUE2
|
||||
uni.addInterceptor({
|
||||
returnValue(res) {
|
||||
if (isPromise(res)) {
|
||||
return new Promise((resolve, reject) => {
|
||||
res.then((res) => {
|
||||
if (Array.isArray(res)) {
|
||||
if (res[0]) reject(res[0])
|
||||
else resolve(res[1])
|
||||
} else {
|
||||
if (typeof res == 'object' && String(res.errMsg).includes(':ok')) {
|
||||
resolve(res)
|
||||
} else {
|
||||
reject(res)
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return res;
|
||||
},
|
||||
});
|
||||
// #endif
|
||||
}
|
||||
|
||||
// 获取类型
|
||||
export const _typeof = val => Object.prototype.toString.call(val).slice(8, -1).toLowerCase()
|
||||
|
||||
// 休眠
|
||||
export const sleep = ms => new Promise(r => setTimeout(r, ms))
|
||||
|
||||
// 获取当前页面信息
|
||||
export const getCurrentPage = () => {
|
||||
const pages = getCurrentPages()
|
||||
return pages[pages.length - 1] || {}
|
||||
}
|
||||
|
||||
// 获取当前页面 path
|
||||
export const getCurrentPagePath = (fullPath = false) => {
|
||||
const { route, $page } = getCurrentPage()
|
||||
return fullPath ? $page.fullPath : '/' + route
|
||||
}
|
||||
|
||||
// 判断当前页或指定 path 是否是 tabbar 页面
|
||||
export const isTabBarPage = path => {
|
||||
const { tabBar } = pagesJson
|
||||
if (!tabBar) return false
|
||||
path = path || getCurrentPagePath()
|
||||
return !(!tabBar || !tabBar.list || !tabBar.list.length || tabBar.list.findIndex(i => '/' + i.pagePath == path) == -1)
|
||||
}
|
||||
|
||||
// 获取应用运行页面信息
|
||||
export const getPageInfo = () => {
|
||||
|
||||
// 获取 pages 并去重
|
||||
const pages = getCurrentPages().reduce((p, c) => {
|
||||
if (!p.find(f => f.route == c.route)) p.push(c)
|
||||
return p
|
||||
}, [])
|
||||
|
||||
// 启动页
|
||||
const startPage = pagesJson.pages[0].path
|
||||
|
||||
// tabBar
|
||||
const tabBarList = pagesJson.tabBar?.list || []
|
||||
|
||||
// 首页
|
||||
const [page] = pages
|
||||
|
||||
return {
|
||||
currentPage: pages[pages.length - 1] || {},
|
||||
startPage,
|
||||
isSharePage: pages.length == 1 && page.route != startPage && !tabBarList.some(i => i.pagePath == page.route),
|
||||
pageStackLen: pages.length,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 倒计时
|
||||
* @func countDown
|
||||
* @param {String | Number} endTime 结束时间
|
||||
* @param {Function} callback 倒计时字符串更新回调函数 (info, isEnd) => {}
|
||||
* @param {String} formatStr 倒计时字符串显示格式 d=天, h=时, m=分, s=秒, 默认(hh:mm:ss)
|
||||
* @param {Number} refreshRate 更新频率 默认(100)
|
||||
* @return {Number} 定时器 id 用于结束倒计时
|
||||
*/
|
||||
export const countDown = function(endTime, callback, formatStr = 'hh:mm:ss', refreshRate = 100) {
|
||||
const targetTime = new Date(endTime).getTime();
|
||||
let cacheStr
|
||||
const intervalId = setInterval(function() {
|
||||
|
||||
const currentTime = new Date().getTime();
|
||||
|
||||
const distance = targetTime - currentTime;
|
||||
|
||||
const date = {
|
||||
d: Math.floor(distance / (1000 * 60 * 60 * 24)),
|
||||
h: Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)),
|
||||
m: Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)),
|
||||
s: Math.floor((distance % (1000 * 60)) / 1000)
|
||||
}
|
||||
|
||||
if (!formatStr.includes('d')) {
|
||||
date.h += date.d * 24;
|
||||
date.d = 0;
|
||||
}
|
||||
|
||||
if (!formatStr.includes('h')) {
|
||||
date.m += date.h * 60;
|
||||
date.h = 0;
|
||||
}
|
||||
|
||||
if (!formatStr.includes('m')) {
|
||||
date.s += date.m * 60;
|
||||
date.m = 0;
|
||||
}
|
||||
|
||||
let str = formatStr
|
||||
|
||||
Object.keys(date).forEach(key => {
|
||||
if (date[key] < 0) date[key] = 0
|
||||
if (str.includes(key)) {
|
||||
if (str.includes(key + key)) {
|
||||
str = str.replace(key + key, date[key].toString().padStart(2, 0))
|
||||
} else {
|
||||
str = str.replace(key, date[key])
|
||||
}
|
||||
}
|
||||
})
|
||||
if (cacheStr != str) {
|
||||
cacheStr = str
|
||||
if (date.d + date.h + date.m + date.s <= 0) {
|
||||
clearInterval(intervalId);
|
||||
callback && callback({ str, ...date }, true)
|
||||
} else {
|
||||
callback && callback({ str, ...date }, false)
|
||||
}
|
||||
}
|
||||
}, refreshRate);
|
||||
return intervalId
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @desc 轮询函数(等待结果)
|
||||
* @func pollingForResult
|
||||
* @param {Function} fun 返回值为 Promise 的函数
|
||||
* @param {Array} params fun函数调用的参数列表 ( 例: [param,param] )
|
||||
* @param {Function} judgeFun 拿到 fun 函数返回结果 res, 然后调用 judgeFun(res), judgeFun函数应返回 success 或 fail , 没有返回值即忽略本次
|
||||
* @param {Number} ms 最快多长时间调用一次 ( 默认 1000ms )
|
||||
* @param {Number} timeout 超时时间 ( 默认 1min )
|
||||
* @return {Promise} judgeFun 函数返回 success 或 fail 的调用结果
|
||||
*/
|
||||
export const pollingForResult = function(fun, params, judgeFun, ms = 1000, timeout = 1000 * 60) {
|
||||
// console.time('polling-time')
|
||||
console.log('polling-params', arguments);
|
||||
let startTime = Date.now()
|
||||
let prevCallTime = 0
|
||||
if (typeof judgeFun != 'function') throw new Error('judgeFun 参数应为一个 function');
|
||||
if (!(params instanceof Array)) params = [params]
|
||||
if (ms <= 0) ms = 1
|
||||
return new Promise((resolve, reject) => {
|
||||
function fun_call() {
|
||||
if ((prevCallTime + ms) > Date.now()) {
|
||||
setTimeout(() => {
|
||||
fun_call()
|
||||
}, (prevCallTime + ms) - Date.now());
|
||||
return
|
||||
}
|
||||
if ((timeout + startTime) < Date.now()) {
|
||||
reject('Timeout')
|
||||
return
|
||||
}
|
||||
prevCallTime = Date.now()
|
||||
// console.time('fun-call-time')
|
||||
fun(...params).then(res => {
|
||||
console.log('fun-call-res', res);
|
||||
// console.timeEnd('fun-call-time')
|
||||
if (judgeFun(res) === 'success') {
|
||||
resolve(res)
|
||||
// console.timeEnd('polling-time')
|
||||
} else if (judgeFun(res) === 'fail') {
|
||||
reject(res)
|
||||
// console.timeEnd('polling-time')
|
||||
} else {
|
||||
fun_call()
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log('fun-call-err', err);
|
||||
// console.timeEnd('fun-call-time')
|
||||
fun_call()
|
||||
})
|
||||
}
|
||||
fun_call()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 轮询函数(获取数据)
|
||||
* @func pollingForData
|
||||
* @param {Function} fun 返回值为 Promise 的函数
|
||||
* @param {Array} params fun函数调用的参数列表 ( 例: [param,param] )
|
||||
* @param {Function} callback 每次调用的结果 ( 例: (err, res, count) => {} )
|
||||
* @param {Number} ms 最快多长时间调用一次 ( 默认 1000ms )
|
||||
* @return {Function} 结束轮询函数
|
||||
*/
|
||||
export const pollingForData = function(fun, params, callback, ms = 1000) {
|
||||
console.log('polling-params', arguments);
|
||||
let prevCallTime = 0
|
||||
let endFlag = false
|
||||
let count = 0
|
||||
if (typeof callback != 'function') throw new Error('callback 参数应为一个 function');
|
||||
if (!(params instanceof Array)) params = [params]
|
||||
if (ms <= 0) ms = 1
|
||||
|
||||
function fun_call() {
|
||||
if (endFlag) return
|
||||
if ((prevCallTime + ms) > Date.now()) {
|
||||
setTimeout(() => {
|
||||
fun_call()
|
||||
}, (prevCallTime + ms) - Date.now());
|
||||
return
|
||||
}
|
||||
prevCallTime = Date.now()
|
||||
count++
|
||||
fun(...params).then(res => {
|
||||
callback && callback(null, res, count)
|
||||
fun_call()
|
||||
}).catch(err => {
|
||||
callback && callback(err, null, count)
|
||||
fun_call()
|
||||
})
|
||||
}
|
||||
fun_call()
|
||||
return () => {
|
||||
console.log('polling-end');
|
||||
endFlag = true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 深拷贝
|
||||
* @func deepClone
|
||||
* @param {Object} target 被拷贝的对象
|
||||
* @return {Object} 新对象
|
||||
*/
|
||||
export const deepClone = (target, map = new WeakMap()) => {
|
||||
if (target === null || typeof target !== 'object') {
|
||||
return target;
|
||||
}
|
||||
|
||||
if (target instanceof Date) {
|
||||
return new Date(target);
|
||||
}
|
||||
|
||||
if (target instanceof RegExp) {
|
||||
return new RegExp(target.source, target.flags);
|
||||
}
|
||||
|
||||
if (target instanceof Map) {
|
||||
const newMap = new Map();
|
||||
target.forEach((value, key) => {
|
||||
newMap.set(deepClone(key, map), deepClone(value, map));
|
||||
});
|
||||
return newMap;
|
||||
}
|
||||
|
||||
if (target instanceof Set) {
|
||||
const newSet = new Set();
|
||||
target.forEach(value => {
|
||||
newSet.add(deepClone(value, map));
|
||||
});
|
||||
return newSet;
|
||||
}
|
||||
|
||||
if (typeof target === 'function') {
|
||||
return target;
|
||||
}
|
||||
|
||||
if (map.has(target)) {
|
||||
return map.get(target);
|
||||
}
|
||||
|
||||
const cloneTarget = Array.isArray(target) ? [] : {};
|
||||
|
||||
map.set(target, cloneTarget);
|
||||
|
||||
const symbolKeys = Object.getOwnPropertySymbols(target);
|
||||
if (symbolKeys.length > 0) {
|
||||
symbolKeys.forEach(symKey => {
|
||||
cloneTarget[symKey] = deepClone(target[symKey], map);
|
||||
});
|
||||
}
|
||||
|
||||
for (let key in target) {
|
||||
if (Object.prototype.hasOwnProperty.call(target, key)) {
|
||||
cloneTarget[key] = deepClone(target[key], map);
|
||||
}
|
||||
}
|
||||
|
||||
return cloneTarget;
|
||||
}
|
||||
Reference in New Issue
Block a user