app.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. const app = {};
  2. app.sys = class appSystem {
  3. /**
  4. * 环境版本判定回调
  5. * @param {Object.Function} callbacks 回调执行方法
  6. */
  7. static envVersion(callbacks) {
  8. if (!uni.getAccountInfoSync) return;
  9. const current = uni.getAccountInfoSync()?.miniProgram?.envVersion;
  10. const fn = callbacks[current];
  11. if (fn && typeof fn == "function") fn();
  12. }
  13. };
  14. app.url = class appUrl {
  15. /**
  16. * 跳转到地址
  17. * @param {String} url path字符串
  18. * @param {Boolean} mode 跳转模式; false时关闭当前窗口跳转 | null时关闭所有窗口跳转 | 默认为打开新窗口跳转(最多支持10层,页面栈超过10层后默认为false模式);
  19. */
  20. static goto(url, mode) {
  21. return new Promise((resolve, reject) => {
  22. const fail = (err) => uni.switchTab({ url, success });
  23. const success = () => resolve();
  24. if (mode === false) return uni.redirectTo({ url, fail });
  25. if (mode === null) return uni.reLaunch({ url, fail });
  26. if (getCurrentPages().length < 10) {
  27. uni.navigateTo({ url, fail, success });
  28. } else {
  29. uni.redirectTo({ url, fail, success });
  30. }
  31. });
  32. }
  33. /**
  34. * 返回页面
  35. * @param {int} delta 返回级数
  36. */
  37. static back(delta) {
  38. const pages = getCurrentPages();
  39. const targetPageIndex = pages.length - 1 - (delta || 1);
  40. if (targetPageIndex >= 0 && targetPageIndex < pages.length) {
  41. const targetPage = pages[targetPageIndex];
  42. uni.navigateBack({
  43. delta: delta || 1,
  44. success: () => {
  45. // 延迟执行刷新,确保页面已经返回
  46. setTimeout(() => {
  47. if (targetPage.onLoad) targetPage.onLoad(targetPage.options);
  48. if (targetPage.onShow) targetPage.onShow();
  49. }, 100);
  50. },
  51. });
  52. } else {
  53. uni.navigateBack({ delta: delta || 1 });
  54. }
  55. }
  56. /**
  57. * 刷新页面,会触发onLoad和onShow等钩子
  58. */
  59. static refresh() {
  60. const pages = getCurrentPages();
  61. const current = pages[pages.length - 1];
  62. const url = current.$page.fullPath;
  63. app.urlGoto(url, false);
  64. }
  65. /**
  66. * 打开新窗口并传递数据
  67. * @param {String} url path字符串
  68. * @param {any} data 传递数据
  69. */
  70. static open(url, data) {
  71. const pages = getCurrentPages();
  72. const current = pages[pages.length - 1].$page.fullPath;
  73. uni.navigateTo({
  74. url,
  75. success: (res) => {
  76. res.eventChannel.emit(`OPEN-DATA[${current}]`, data);
  77. },
  78. });
  79. }
  80. /**
  81. * 获取open方法发送到数据
  82. * @param {Component} component 组件对象
  83. */
  84. static load(component) {
  85. return new Promise((resolve, reject) => {
  86. if (component == undefined) return console.error(`app.url.load(this);`);
  87. const pages = getCurrentPages();
  88. const current = pages[pages.length - 2]?.$page?.fullPath;
  89. const caller = component?.getOpenerEventChannel;
  90. const channel = caller && caller.call(component);
  91. if (channel && channel.on)
  92. channel.on(`OPEN-DATA[${current}]`, (data) => resolve(data));
  93. });
  94. }
  95. /**
  96. * 打开其他小程序
  97. * @param {String} appid 小程序APPID
  98. * @param {String} path 要打开的程序路径
  99. * @param {Object} data 要传递给小程序狗子的参数
  100. */
  101. static applet(appid, path, data) {
  102. return new Promise((resolve, reject) => {
  103. uni.navigateToMiniProgram({
  104. appId: appid,
  105. path: path,
  106. extraData: data || {},
  107. success: (res) => resolve(res),
  108. });
  109. });
  110. }
  111. };
  112. app.storage = class appStorage {
  113. /**
  114. * 设置本地缓存数据
  115. * @param {String} key 数据键名
  116. * @param {any} data 存储数据,支持对象
  117. */
  118. static set(key, data) {
  119. try {
  120. uni.setStorageSync(key, data);
  121. } catch (err) {
  122. console.error("app.setStorageSync error: ", err);
  123. }
  124. }
  125. /**
  126. * 获取本地缓存数据
  127. * @param {String} key 数据键名
  128. */
  129. static get(key) {
  130. return uni.getStorageSync(key);
  131. }
  132. /**
  133. * 清除键缓存数据
  134. * @param {Object} key 数据键名
  135. */
  136. static remove(key) {
  137. uni.removeStorageSync(key);
  138. }
  139. /**
  140. * 清理所有缓存数据
  141. */
  142. static clear() {
  143. uni.clearStorageSync();
  144. }
  145. };
  146. app.math = class appMath {
  147. /**
  148. * 浮点精确相加
  149. * @param {Number} arg1 参数1
  150. * @param {Number} arg2 参数2
  151. */
  152. static add(arg1, arg2) {
  153. var r1, r2, m;
  154. try {
  155. r1 = arg1.toString().split(".")[1].length;
  156. } catch (e) {
  157. r1 = 0;
  158. }
  159. try {
  160. r2 = arg2.toString().split(".")[1].length;
  161. } catch (e) {
  162. r2 = 0;
  163. }
  164. m = Math.pow(10, Math.max(r1, r2));
  165. return (arg1 * m + arg2 * m) / m;
  166. }
  167. /**
  168. * 浮点精确相减
  169. * @param {Number} arg1 参数1
  170. * @param {Number} arg2 参数2
  171. */
  172. static sub(arg1, arg2) {
  173. var r1, r2, m, n;
  174. try {
  175. r1 = arg1.toString().split(".")[1].length;
  176. } catch (e) {
  177. r1 = 0;
  178. }
  179. try {
  180. r2 = arg2.toString().split(".")[1].length;
  181. } catch (e) {
  182. r2 = 0;
  183. }
  184. m = Math.pow(10, Math.max(r1, r2));
  185. n = (r1 = r2) ? r1 : r2;
  186. return ((arg1 * m - arg2 * m) / m).toFixed(n);
  187. }
  188. /**
  189. * 浮点精确相乘
  190. * @param {Number} arg1 参数1
  191. * @param {Number} arg2 参数2
  192. */
  193. static mul(arg1, arg2) {
  194. var m = 0,
  195. s1 = arg1.toString(),
  196. s2 = arg2.toString();
  197. try {
  198. m += s1.split(".")[1].length;
  199. } catch (e) {}
  200. try {
  201. m += s2.split(".")[1].length;
  202. } catch (e) {}
  203. return (
  204. (Number(s1.replace(".", "")) * Number(s2.replace(".", ""))) /
  205. Math.pow(10, m)
  206. );
  207. }
  208. /**
  209. * 浮点精确相除
  210. * @param {Number} arg1 参数1
  211. * @param {Number} arg2 参数2
  212. */
  213. static div(arg1, arg2) {
  214. var t1 = 0,
  215. t2 = 0,
  216. r1,
  217. r2;
  218. try {
  219. t1 = arg1.toString().split(".")[1].length;
  220. } catch (e) {}
  221. try {
  222. t2 = arg2.toString().split(".")[1].length;
  223. } catch (e) {}
  224. r1 = Number(arg1.toString().replace(".", ""));
  225. r2 = Number(arg2.toString().replace(".", ""));
  226. return (r1 / r2) * Math.pow(10, t2 - t1);
  227. }
  228. };
  229. app.date = class appDate {
  230. /**
  231. * 日期格式化
  232. * @param {String} fmt 格式规则
  233. * @param {String | Date} date 需要格式化的日期
  234. */
  235. static format(fmt, date) {
  236. if (!fmt) fmt = "yyyy-MM-dd hh:mm:sss";
  237. if (typeof date === "string") date = new Date(date.replaceAll("-", "/"));
  238. if (!date) date = new Date();
  239. var o = {
  240. "M+": date.getMonth() + 1, //月份
  241. "d+": date.getDate(), //日
  242. "h+": date.getHours(), //小时
  243. "m+": date.getMinutes(), //分
  244. "s+": date.getSeconds(), //秒
  245. "q+": Math.floor((date.getMonth() + 3) / 3), //季度
  246. S: date.getMilliseconds(), //毫秒
  247. };
  248. if (/(y+)/.test(fmt))
  249. fmt = fmt.replace(
  250. RegExp.$1,
  251. (date.getFullYear() + "").substr(4 - RegExp.$1.length)
  252. );
  253. for (var k in o)
  254. if (new RegExp("(" + k + ")").test(fmt))
  255. fmt = fmt.replace(
  256. RegExp.$1,
  257. RegExp.$1.length == 1
  258. ? o[k]
  259. : ("00" + o[k]).substr(("" + o[k]).length)
  260. );
  261. return fmt;
  262. }
  263. };
  264. app.popup = class appPopup {
  265. /**
  266. * 对话框
  267. * @param {String} content 弹窗内容
  268. * @param {String} title 弹窗标题
  269. * @param {Object} opts 参数
  270. */
  271. static confirm(content, title, opts) {
  272. return new Promise((resolve, reject) => {
  273. if (!title && title == null) title = "温馨提示";
  274. opts = Object.assign(
  275. {
  276. title: title,
  277. content: content,
  278. confirmColor: "#007AFF",
  279. success: (res) => resolve(res.confirm == true),
  280. fail: (err) => reject(err),
  281. },
  282. opts
  283. );
  284. uni.showModal(opts);
  285. });
  286. }
  287. /**
  288. * 提示框
  289. * @param {String} content 弹窗内容
  290. * @param {String} title 弹窗标题
  291. */
  292. static alert(content, title) {
  293. return appPopup.confirm(content, title || null, { showCancel: false });
  294. }
  295. /**
  296. * 轻提示
  297. * @param {String} content 提示内容
  298. * @param {Object} opts 参数
  299. */
  300. static toast(content, opts) {
  301. uni.showToast(
  302. Object.assign(
  303. {
  304. title: content,
  305. position: "bottom",
  306. duration: 2000,
  307. icon: "none",
  308. },
  309. opts
  310. )
  311. );
  312. }
  313. /**
  314. * 加载条
  315. * @param {Boolean} visible 显示
  316. * @param {Object} opts 参数
  317. */
  318. static loading(visible, opts) {
  319. if (visible) {
  320. uni.showLoading(Object.assign({ title: "载入中", mask: true }, opts));
  321. const timeout = opts?.timeout || 45 * 1000;
  322. setTimeout(() => appPopup.loading(false), timeout);
  323. } else {
  324. uni.hideLoading();
  325. }
  326. }
  327. /**
  328. * 操作菜单
  329. * @param {Array} data 列表数据
  330. * @param {String} key 指定显示字段
  331. * @param {Object} opts 参数
  332. */
  333. static sheet(data, key, opts) {
  334. return new Promise((resolve, reject) => {
  335. uni.showActionSheet(
  336. Object.assign(
  337. {
  338. title: "",
  339. itemList: data.map((item) =>
  340. key ? item[key] || String(item) : String(item)
  341. ),
  342. success: (res) =>
  343. resolve({ index: res.tapIndex, data: data[res.tapIndex] }),
  344. },
  345. opts
  346. )
  347. );
  348. });
  349. }
  350. };
  351. app.map = class appMap {
  352. /**
  353. * 获取当前位置坐标
  354. * @param {Boolean} high 是否调用高精度接口
  355. * @param {Object} opts 参数
  356. */
  357. static get(high, opts) {
  358. return new Promise((resolve, reject) => {
  359. const OPTS = Object.assign(
  360. {
  361. success: (res) => {
  362. console.log(res);
  363. },
  364. fail: (err) => {
  365. console.log(err);
  366. },
  367. },
  368. opts
  369. );
  370. high ? uni.getLocation(OPTS) : uni.getFuzzyLocation(OPTS);
  371. });
  372. }
  373. };
  374. app.act = class appAct {
  375. /**
  376. * 拨打电话
  377. * @param {String} phone
  378. */
  379. static callPhone(phone) {
  380. uni.makePhoneCall({ phoneNumber: phone });
  381. }
  382. /**
  383. * 调用扫描
  384. * @param {Object} opts 参数配置,详细查看 https://uniapp.dcloud.net.cn/api/system/barcode.html
  385. */
  386. static scan(opts) {
  387. return new Promise((resolve, reject) => {
  388. uni.scanCode(
  389. Object.assign(
  390. {},
  391. {
  392. success: (res) => resolve(res),
  393. // fail: err=>reject(err),
  394. },
  395. opts
  396. )
  397. );
  398. });
  399. }
  400. /**
  401. * 获取节点信息
  402. * @param {Component} component 组件
  403. * @param {String} selector 类似于 CSS 的选择器
  404. * @param {Boolean} multi 是否多节点
  405. */
  406. static selectorQuery(component, selector, multi) {
  407. return new Promise((resolve, reject) => {
  408. const query = uni
  409. .createSelectorQuery()
  410. .in(component)
  411. [multi ? "selectAll" : "select"](selector);
  412. query
  413. .boundingClientRect((data) => {
  414. if (data) resolve(data);
  415. })
  416. .exec();
  417. });
  418. }
  419. /**
  420. * 复制文本到剪贴板
  421. * @param {String} str 需要复制的文本
  422. */
  423. static copy(str) {
  424. return new Promise((resolve, reject) => {
  425. uni.setClipboardData({
  426. data: "hello",
  427. success: resolve(),
  428. fail: (err) => reject(err),
  429. });
  430. });
  431. }
  432. /**
  433. * 客服服务
  434. * @param {Object} id
  435. * @param {Object} url
  436. */
  437. static customerService(id, url) {
  438. return new Promise((resolve, reject) => {
  439. wx.openCustomerServiceChat({
  440. extInfo: { url: url },
  441. corpId: id,
  442. success: (res) => resolve(res),
  443. fail: (err) => reject(err),
  444. });
  445. });
  446. }
  447. };
  448. module.exports = app;