util.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838
  1. import { HTTP_REQUEST_URL } from '@/config/app.js';
  2. import {TerminalEnum} from "./dict";
  3. import wechat from "../libs/wechat";
  4. export default {
  5. /**
  6. * opt object | string
  7. * to_url object | string
  8. * 例:
  9. * this.Tips('/pages/test/test'); 跳转不提示
  10. * this.Tips({title:'提示'},'/pages/test/test'); 提示并跳转
  11. * this.Tips({title:'提示'},{tab:1,url:'/pages/index/index'}); 提示并跳转值table上
  12. * tab=1 一定时间后跳转至 table上
  13. * tab=2 一定时间后跳转至非 table上
  14. * tab=3 一定时间后返回上页面
  15. * tab=4 关闭所有页面跳转至非table上
  16. * tab=5 关闭当前页面跳转至table上
  17. */
  18. Tips: function(opt, to_url) {
  19. if (typeof opt == 'string') {
  20. to_url = opt;
  21. opt = {};
  22. }
  23. let title = opt.title || '',
  24. icon = opt.icon || 'none',
  25. endtime = opt.endtime || 2000,
  26. success = opt.success;
  27. if (title) uni.showToast({
  28. title: title,
  29. icon: icon,
  30. duration: endtime,
  31. success
  32. })
  33. if (to_url != undefined) {
  34. if (typeof to_url == 'object') {
  35. let tab = to_url.tab || 1,
  36. url = to_url.url || '';
  37. switch (tab) {
  38. case 1:
  39. //一定时间后跳转至 table
  40. setTimeout(function() {
  41. uni.switchTab({
  42. url: url
  43. })
  44. }, endtime);
  45. break;
  46. case 2:
  47. //跳转至非table页面
  48. setTimeout(function() {
  49. uni.navigateTo({
  50. url: url,
  51. })
  52. }, endtime);
  53. break;
  54. case 3:
  55. //返回上页面
  56. setTimeout(function() {
  57. // #ifndef H5
  58. uni.navigateBack({
  59. delta: parseInt(url),
  60. })
  61. // #endif
  62. // #ifdef H5
  63. history.back();
  64. // #endif
  65. }, endtime);
  66. break;
  67. case 4:
  68. //关闭当前所有页面跳转至非table页面
  69. setTimeout(function() {
  70. uni.reLaunch({
  71. url: url,
  72. })
  73. }, endtime);
  74. break;
  75. case 5:
  76. //关闭当前页面跳转至非table页面
  77. setTimeout(function() {
  78. uni.redirectTo({
  79. url: url,
  80. })
  81. }, endtime);
  82. break;
  83. }
  84. } else if (typeof to_url == 'function') {
  85. setTimeout(function() {
  86. to_url && to_url();
  87. }, endtime);
  88. } else {
  89. //没有提示时跳转不延迟
  90. setTimeout(function() {
  91. uni.navigateTo({
  92. url: to_url,
  93. })
  94. }, title ? endtime : 0);
  95. }
  96. }
  97. },
  98. /**
  99. * 移除数组中的某个数组并组成新的数组返回
  100. * @param array array 需要移除的数组
  101. * @param int index 需要移除的数组的键值
  102. * @param string | int 值
  103. * @return array
  104. *
  105. */
  106. ArrayRemove: function(array, index, value) {
  107. const valueArray = [];
  108. if (array instanceof Array) {
  109. for (let i = 0; i < array.length; i++) {
  110. if (typeof index == 'number' && array[index] != i) {
  111. valueArray.push(array[i]);
  112. } else if (typeof index == 'string' && array[i][index] != value) {
  113. valueArray.push(array[i]);
  114. }
  115. }
  116. }
  117. return valueArray;
  118. },
  119. /**
  120. * 生成海报获取文字
  121. * @param string text 为传入的文本
  122. * @param int num 为单行显示的字节长度
  123. * @return array
  124. */
  125. textByteLength: function(text, num) {
  126. let strLength = 0;
  127. let rows = 1;
  128. let str = 0;
  129. let arr = [];
  130. for (let j = 0; j < text.length; j++) {
  131. if (text.charCodeAt(j) > 255) {
  132. strLength += 2;
  133. if (strLength > rows * num) {
  134. strLength++;
  135. arr.push(text.slice(str, j));
  136. str = j;
  137. rows++;
  138. }
  139. } else {
  140. strLength++;
  141. if (strLength > rows * num) {
  142. arr.push(text.slice(str, j));
  143. str = j;
  144. rows++;
  145. }
  146. }
  147. }
  148. arr.push(text.slice(str, text.length));
  149. return [strLength, arr, rows] // [处理文字的总字节长度,每行显示内容的数组,行数]
  150. },
  151. /**
  152. * 获取分享海报
  153. * @param array arr2 海报素材
  154. * @param string store_name 素材文字
  155. * @param string price 价格
  156. * @param string ot_price 原始价格
  157. * @param function successFn 回调函数
  158. *
  159. *
  160. */
  161. PosterCanvas: function(arr2, store_name, price, ot_price, successFn) {
  162. let that = this;
  163. const ctx = uni.createCanvasContext('firstCanvas');
  164. ctx.clearRect(0, 0, 0, 0);
  165. /**
  166. * 只能获取合法域名下的图片信息,本地调试无法获取
  167. *
  168. */
  169. ctx.fillStyle = '#fff';
  170. ctx.fillRect(0, 0, 750, 1150);
  171. uni.getImageInfo({
  172. src: arr2[0],
  173. success: function(res) {
  174. const WIDTH = res.width;
  175. const HEIGHT = res.height;
  176. // ctx.drawImage(arr2[0], 0, 0, WIDTH, 1050);
  177. ctx.drawImage(arr2[1], 0, 0, WIDTH, WIDTH);
  178. ctx.save();
  179. let r = 110;
  180. let d = r * 2;
  181. let cx = 480;
  182. let cy = 790;
  183. ctx.arc(cx + r, cy + r, r, 0, 2 * Math.PI);
  184. // ctx.clip();
  185. ctx.drawImage(arr2[2], cx, cy, d, d);
  186. ctx.restore();
  187. const CONTENT_ROW_LENGTH = 20;
  188. let [contentLeng, contentArray, contentRows] = that.textByteLength(store_name,
  189. CONTENT_ROW_LENGTH);
  190. if (contentRows > 2) {
  191. contentRows = 2;
  192. let textArray = contentArray.slice(0, 2);
  193. textArray[textArray.length - 1] += '……';
  194. contentArray = textArray;
  195. }
  196. ctx.setTextAlign('left');
  197. ctx.setFontSize(36);
  198. ctx.setFillStyle('#000');
  199. // let contentHh = 36 * 1.5;
  200. let contentHh = 36;
  201. for (let m = 0; m < contentArray.length; m++) {
  202. // ctx.fillText(contentArray[m], 50, 1000 + contentHh * m,750);
  203. if (m) {
  204. ctx.fillText(contentArray[m], 50, 1000 + contentHh * m + 18, 1100);
  205. } else {
  206. ctx.fillText(contentArray[m], 50, 1000 + contentHh * m, 1100);
  207. }
  208. }
  209. ctx.setTextAlign('left')
  210. ctx.setFontSize(72);
  211. ctx.setFillStyle('#DA4F2A');
  212. ctx.fillText('¥' + price, 40, 820 + contentHh);
  213. ctx.setTextAlign('left')
  214. ctx.setFontSize(36);
  215. ctx.setFillStyle('#999');
  216. ctx.fillText('¥' + ot_price, 50, 876 + contentHh);
  217. var underline = function(ctx, text, x, y, size, color, thickness, offset) {
  218. var width = ctx.measureText(text).width;
  219. switch (ctx.textAlign) {
  220. case "center":
  221. x -= (width / 2);
  222. break;
  223. case "right":
  224. x -= width;
  225. break;
  226. }
  227. y += size + offset;
  228. ctx.beginPath();
  229. ctx.strokeStyle = color;
  230. ctx.lineWidth = thickness;
  231. ctx.moveTo(x, y);
  232. ctx.lineTo(x + width, y);
  233. ctx.stroke();
  234. }
  235. underline(ctx, '¥' + ot_price, 55, 865, 36, '#999', 2, 0)
  236. ctx.setTextAlign('left')
  237. ctx.setFontSize(28);
  238. ctx.setFillStyle('#999');
  239. ctx.fillText('长按或扫描查看', 490, 1030 + contentHh);
  240. ctx.draw(true, function() {
  241. uni.canvasToTempFilePath({
  242. canvasId: 'firstCanvas',
  243. fileType: 'png',
  244. destWidth: WIDTH,
  245. destHeight: HEIGHT,
  246. success: function(res) {
  247. // uni.hideLoading();
  248. successFn && successFn(res.tempFilePath);
  249. }
  250. })
  251. });
  252. },
  253. fail: function(err) {
  254. console.log('失败', err)
  255. uni.hideLoading();
  256. that.Tips({
  257. title: '无法获取图片信息'
  258. });
  259. }
  260. })
  261. },
  262. /**
  263. * 绘制文字自动换行
  264. * @param array arr2 海报素材
  265. * @param Number x , y 绘制的坐标
  266. * @param Number maxWigth 绘制文字的宽度
  267. * @param Number lineHeight 行高
  268. * @param Number maxRowNum 最大行数
  269. */
  270. canvasWraptitleText(canvas, text, x, y, maxWidth, lineHeight, maxRowNum) {
  271. if (typeof text != 'string' || typeof x != 'number' || typeof y != 'number') {
  272. return;
  273. }
  274. // canvas.font = '20px Bold PingFang SC'; //绘制文字的字号和大小
  275. // 字符分隔为数组
  276. var arrText = text.split('');
  277. var line = '';
  278. var rowNum = 1
  279. for (var n = 0; n < arrText.length; n++) {
  280. var testLine = line + arrText[n];
  281. var metrics = canvas.measureText(testLine);
  282. var testWidth = metrics.width;
  283. if (testWidth > maxWidth && n > 0) {
  284. if (rowNum >= maxRowNum) {
  285. var arrLine = testLine.split('')
  286. arrLine.splice(-9)
  287. var newTestLine = arrLine.join("")
  288. newTestLine += "..."
  289. canvas.fillText(newTestLine, x, y);
  290. //如果需要在省略号后面添加其他的东西,就在这个位置写(列如添加扫码查看详情字样)
  291. //canvas.fillStyle = '#2259CA';
  292. //canvas.fillText('扫码查看详情',x + maxWidth-90, y);
  293. return
  294. }
  295. canvas.fillText(line, x, y);
  296. line = arrText[n];
  297. y += lineHeight;
  298. rowNum += 1
  299. } else {
  300. line = testLine;
  301. }
  302. }
  303. canvas.fillText(line, x, y);
  304. },
  305. /**
  306. * 获取活动分享海报
  307. * @param array arr2 海报素材
  308. * @param string storeName 素材文字
  309. * @param string price 价格
  310. * @param string people 人数
  311. * @param string count 剩余人数
  312. * @param function successFn 回调函数
  313. */
  314. activityCanvas: function(arrImages, storeName, price, people, count,num,successFn) {
  315. let that = this;
  316. let rain = 2;
  317. const context = uni.createCanvasContext('activityCanvas');
  318. context.clearRect(0, 0, 0, 0);
  319. /**
  320. * 只能获取合法域名下的图片信息,本地调试无法获取
  321. *
  322. */
  323. context.fillStyle = '#fff';
  324. context.fillRect(0, 0, 594, 850);
  325. uni.getImageInfo({
  326. src: arrImages[0],
  327. success: function(res) {
  328. context.drawImage(arrImages[0], 0, 0, 594, 850);
  329. context.setFontSize(14*rain);
  330. context.setFillStyle('#333333');
  331. that.canvasWraptitleText(context, storeName, 110*rain, 110*rain, 230*rain, 30*rain, 1)
  332. context.drawImage(arrImages[2], 68*rain, 194*rain, 160*rain, 160*rain);
  333. context.save();
  334. context.setFontSize(14*rain);
  335. context.setFillStyle('#fc4141');
  336. context.fillText('¥', 157*rain, 145*rain);
  337. context.setFontSize(24*rain);
  338. context.setFillStyle('#fc4141');
  339. context.fillText(price, 170*rain, 145*rain);
  340. context.setFontSize(10*rain);
  341. context.setFillStyle('#fff');
  342. context.fillText(people, 118*rain, 143*rain);
  343. context.setFontSize(12*rain);
  344. context.setFillStyle('#666666');
  345. context.setTextAlign('center');
  346. context.fillText( count , (167-num)*rain, 166*rain);
  347. that.handleBorderRect(context, 27*rain, 94*rain, 75*rain, 75*rain, 6*rain);
  348. context.clip();
  349. context.drawImage(arrImages[1], 27*rain, 94*rain, 75*rain, 75*rain);
  350. context.draw(true, function() {
  351. uni.canvasToTempFilePath({
  352. canvasId: 'activityCanvas',
  353. fileType: 'png',
  354. destWidth: 594,
  355. destHeight: 850,
  356. success: function(res) {
  357. // uni.hideLoading();
  358. successFn && successFn(res.tempFilePath);
  359. }
  360. })
  361. });
  362. },
  363. fail: function(err) {
  364. console.log('失败', err)
  365. uni.hideLoading();
  366. that.Tips({
  367. title: '无法获取图片信息'
  368. });
  369. }
  370. })
  371. },
  372. /**
  373. * 图片圆角设置
  374. * @param string x x轴位置
  375. * @param string y y轴位置
  376. * @param string w 图片宽
  377. * @param string y 图片高
  378. * @param string r 圆角值
  379. */
  380. handleBorderRect(ctx, x, y, w, h, r) {
  381. ctx.beginPath();
  382. // 左上角
  383. ctx.arc(x + r, y + r, r, Math.PI, 1.5 * Math.PI);
  384. ctx.moveTo(x + r, y);
  385. ctx.lineTo(x + w - r, y);
  386. ctx.lineTo(x + w, y + r);
  387. // 右上角
  388. ctx.arc(x + w - r, y + r, r, 1.5 * Math.PI, 2 * Math.PI);
  389. ctx.lineTo(x + w, y + h - r);
  390. ctx.lineTo(x + w - r, y + h);
  391. // 右下角
  392. ctx.arc(x + w - r, y + h - r, r, 0, 0.5 * Math.PI);
  393. ctx.lineTo(x + r, y + h);
  394. ctx.lineTo(x, y + h - r);
  395. // 左下角
  396. ctx.arc(x + r, y + h - r, r, 0.5 * Math.PI, Math.PI);
  397. ctx.lineTo(x, y + r);
  398. ctx.lineTo(x + r, y);
  399. ctx.fill();
  400. ctx.closePath();
  401. },
  402. /*
  403. * 单图上传
  404. * @param object opt
  405. * @param callable successCallback 成功执行方法 data
  406. * @param callable errorCallback 失败执行方法
  407. */
  408. uploadImageOne: function(opt, successCallback, errorCallback) {
  409. let that = this;
  410. if (typeof opt === 'string') {
  411. let url = opt;
  412. opt = {};
  413. opt.url = url;
  414. }
  415. let count = opt.count || 1,
  416. sizeType = opt.sizeType || ['compressed'],
  417. sourceType = opt.sourceType || ['album', 'camera'],
  418. inputName = opt.name || 'file';
  419. uni.chooseImage({
  420. count: count, //最多可以选择的图片总数
  421. sizeType: sizeType, // 可以指定是原图还是压缩图,默认二者都有
  422. sourceType: sourceType, // 可以指定来源是相册还是相机,默认二者都有
  423. success: function(res) {
  424. //启动上传等待中...
  425. uni.showLoading({
  426. title: '图片上传中',
  427. });
  428. const urlPath = HTTP_REQUEST_URL + '/app-api/infra/file/upload'
  429. let localPath = res.tempFilePaths[0];
  430. uni.uploadFile({
  431. url: urlPath,
  432. filePath: localPath,
  433. name: inputName,
  434. header: {
  435. // #ifdef MP
  436. "Content-Type": "multipart/form-data",
  437. // #endif
  438. // TODO 芋艿:后续改成动态读取,不要写死
  439. 'tenant-id': 1,
  440. 'Authorization': 'Bearer test247'
  441. },
  442. success: function(res) {
  443. uni.hideLoading();
  444. if (res.statusCode === 403) {
  445. that.Tips({
  446. title: res.data
  447. });
  448. } else {
  449. let data = res.data ? JSON.parse(res.data) : {};
  450. if (data.code === 200 || data.code === 0) {
  451. // data.data.localPath = localPath;
  452. successCallback && successCallback(data)
  453. } else {
  454. errorCallback && errorCallback(data);
  455. that.Tips({
  456. title: data.message
  457. });
  458. }
  459. }
  460. },
  461. fail: function(res) {
  462. uni.hideLoading();
  463. that.Tips({
  464. title: '上传图片失败'
  465. });
  466. }
  467. })
  468. }
  469. })
  470. },
  471. /**
  472. * 处理服务器扫码带进来的参数
  473. * @param string param 扫码携带参数
  474. * @param string k 整体分割符 默认为:&
  475. * @param string p 单个分隔符 默认为:=
  476. * @return object
  477. *
  478. */
  479. // #ifdef MP
  480. getUrlParams: function(param, k, p) {
  481. if (typeof param != 'string') return {};
  482. k = k ? k : '&'; //整体参数分隔符
  483. p = p ? p : '='; //单个参数分隔符
  484. var value = {};
  485. if (param.indexOf(k) !== -1) {
  486. param = param.split(k);
  487. for (var val in param) {
  488. if (param[val].indexOf(p) !== -1) {
  489. var item = param[val].split(p);
  490. value[item[0]] = item[1];
  491. }
  492. }
  493. } else if (param.indexOf(p) !== -1) {
  494. var item = param.split(p);
  495. value[item[0]] = item[1];
  496. } else {
  497. return param;
  498. }
  499. return value;
  500. },
  501. /**根据格式组装公共参数
  502. * @param {Object} value
  503. */
  504. formatMpQrCodeData(value){
  505. let values = value.split(',');
  506. let result = {};
  507. if(values.length === 2){
  508. let v1 = values[0].split(":");
  509. if (v1[0] === 'pid') {
  510. result.spread = v1[1];
  511. } else{
  512. result.id = v1[1];
  513. }
  514. let v2 = values[1].split(":");
  515. if (v2[0] === 'pid') {
  516. result.spread = v2[1];
  517. }else{
  518. result.id = v2[1];
  519. }
  520. }else{
  521. result = values[0].split(":")[1];
  522. }
  523. return result;
  524. },
  525. // #endif
  526. /*
  527. * 合并数组
  528. */
  529. SplitArray(list, sp) {
  530. if (typeof list != 'object') return [];
  531. if (sp === undefined) sp = [];
  532. for (var i = 0; i < list.length; i++) {
  533. sp.push(list[i]);
  534. }
  535. return sp;
  536. },
  537. trim(str) {
  538. return String.prototype.trim.call(str);
  539. },
  540. $h: {
  541. //除法函数,用来得到精确的除法结果
  542. //说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
  543. //调用:$h.Div(arg1,arg2)
  544. //返回值:arg1除以arg2的精确结果
  545. Div: function(arg1, arg2) {
  546. arg1 = parseFloat(arg1);
  547. arg2 = parseFloat(arg2);
  548. var t1 = 0,
  549. t2 = 0,
  550. r1, r2;
  551. try {
  552. t1 = arg1.toString().split(".")[1].length;
  553. } catch (e) {}
  554. try {
  555. t2 = arg2.toString().split(".")[1].length;
  556. } catch (e) {}
  557. r1 = Number(arg1.toString().replace(".", ""));
  558. r2 = Number(arg2.toString().replace(".", ""));
  559. return this.Mul(r1 / r2, Math.pow(10, t2 - t1));
  560. },
  561. //加法函数,用来得到精确的加法结果
  562. //说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
  563. //调用:$h.Add(arg1,arg2)
  564. //返回值:arg1加上arg2的精确结果
  565. Add: function(arg1, arg2) {
  566. arg2 = parseFloat(arg2);
  567. var r1, r2, m;
  568. try {
  569. r1 = arg1.toString().split(".")[1].length
  570. } catch (e) {
  571. r1 = 0
  572. }
  573. try {
  574. r2 = arg2.toString().split(".")[1].length
  575. } catch (e) {
  576. r2 = 0
  577. }
  578. m = Math.pow(100, Math.max(r1, r2));
  579. return (this.Mul(arg1, m) + this.Mul(arg2, m)) / m;
  580. },
  581. //减法函数,用来得到精确的减法结果
  582. //说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的减法结果。
  583. //调用:$h.Sub(arg1,arg2)
  584. //返回值:arg1减去arg2的精确结果
  585. Sub: function(arg1, arg2) {
  586. arg1 = parseFloat(arg1);
  587. arg2 = parseFloat(arg2);
  588. var r1, r2, m, n;
  589. try {
  590. r1 = arg1.toString().split(".")[1].length
  591. } catch (e) {
  592. r1 = 0
  593. }
  594. try {
  595. r2 = arg2.toString().split(".")[1].length
  596. } catch (e) {
  597. r2 = 0
  598. }
  599. m = Math.pow(10, Math.max(r1, r2));
  600. //动态控制精度长度
  601. n = (r1 >= r2) ? r1 : r2;
  602. return ((this.Mul(arg1, m) - this.Mul(arg2, m)) / m).toFixed(n);
  603. },
  604. //乘法函数,用来得到精确的乘法结果
  605. //说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
  606. //调用:$h.Mul(arg1,arg2)
  607. //返回值:arg1乘以arg2的精确结果
  608. Mul: function(arg1, arg2) {
  609. arg1 = parseFloat(arg1);
  610. arg2 = parseFloat(arg2);
  611. var m = 0,
  612. s1 = arg1.toString(),
  613. s2 = arg2.toString();
  614. try {
  615. m += s1.split(".")[1].length
  616. } catch (e) {}
  617. try {
  618. m += s2.split(".")[1].length
  619. } catch (e) {}
  620. return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
  621. },
  622. },
  623. // 获取地理位置;
  624. $L: {
  625. async getLocation() {
  626. // #ifdef MP-WEIXIN || MP-TOUTIAO || MP-QQ
  627. let status = await this.getSetting();
  628. if (status === 2) {
  629. this.openSetting();
  630. return;
  631. }
  632. // #endif
  633. this.doGetLocation();
  634. },
  635. doGetLocation() {
  636. uni.getLocation({
  637. success: (res) => {
  638. uni.removeStorageSync('CACHE_LONGITUDE');
  639. uni.removeStorageSync('CACHE_LATITUDE');
  640. uni.setStorageSync('CACHE_LONGITUDE', res.longitude);
  641. uni.setStorageSync('CACHE_LATITUDE', res.latitude);
  642. },
  643. fail: (err) => {
  644. // #ifdef MP-BAIDU
  645. if (err.errCode === 202 || err.errCode === 10003) { // 202模拟器 10003真机 user deny
  646. this.openSetting();
  647. }
  648. // #endif
  649. // #ifndef MP-BAIDU
  650. if (err.errMsg.indexOf("auth deny") >= 0) {
  651. uni.showToast({
  652. title: "访问位置被拒绝"
  653. })
  654. } else {
  655. uni.showToast({
  656. title: err.errMsg
  657. })
  658. }
  659. // #endif
  660. }
  661. })
  662. },
  663. getSetting: function() {
  664. return new Promise((resolve, reject) => {
  665. uni.getSetting({
  666. success: (res) => {
  667. if (res.authSetting['scope.userLocation'] === undefined) {
  668. resolve(0);
  669. return;
  670. }
  671. if (res.authSetting['scope.userLocation']) {
  672. resolve(1);
  673. } else {
  674. resolve(2);
  675. }
  676. }
  677. });
  678. });
  679. },
  680. openSetting: function() {
  681. uni.openSetting({
  682. success: (res) => {
  683. if (res.authSetting && res.authSetting['scope.userLocation']) {
  684. this.doGetLocation();
  685. }
  686. },
  687. fail: (err) => {}
  688. })
  689. },
  690. async checkPermission() {
  691. let status = permision.isIOS ? await permision.requestIOS('location') :
  692. await permision.requestAndroid('android.permission.ACCESS_FINE_LOCATION');
  693. if (status === null || status === 1) {
  694. status = 1;
  695. } else if (status === 2) {
  696. uni.showModal({
  697. content: "系统定位已关闭",
  698. confirmText: "确定",
  699. showCancel: false,
  700. success: function(res) {}
  701. })
  702. } else if (status.code) {
  703. uni.showModal({
  704. content: status.message
  705. })
  706. } else {
  707. uni.showModal({
  708. content: "需要定位权限",
  709. confirmText: "设置",
  710. success: function(res) {
  711. if (res.confirm) {
  712. permision.gotoAppSetting();
  713. }
  714. }
  715. })
  716. }
  717. return status;
  718. },
  719. },
  720. toStringValue: function(obj) {
  721. if (obj instanceof Array) {
  722. var arr = [];
  723. for (var i = 0; i < obj.length; i++) {
  724. arr[i] = toStringValue(obj[i]);
  725. }
  726. return arr;
  727. } else if (typeof obj == 'object') {
  728. for (var p in obj) {
  729. obj[p] = toStringValue(obj[p]);
  730. }
  731. } else if (typeof obj == 'number') {
  732. obj = obj + '';
  733. }
  734. return obj;
  735. },
  736. /*
  737. * 替换域名
  738. */
  739. setDomain: function(url) {
  740. url = url ? url.toString() : '';
  741. if (url.indexOf("https://") > -1) return url;
  742. else return url.replace('http://', 'https://');
  743. },
  744. /**
  745. * 姓名除了姓显示其他
  746. */
  747. formatName: function(str) {
  748. return str.substr(0, 1) + new Array(str.length).join('*');
  749. },
  750. }
  751. /**
  752. * 将分转成元
  753. *
  754. * @param price 分,例如说 100 分
  755. * @returns {string} 元,例如说 1.00 元
  756. */
  757. export function fen2yuan(price) {
  758. return (price / 100.0).toFixed(2)
  759. }
  760. /**
  761. * 构造树型结构数据
  762. *
  763. * @param {*} data 数据源
  764. * @param {*} id id字段 默认 'id'
  765. * @param {*} parentId 父节点字段 默认 'parentId'
  766. * @param {*} children 孩子节点字段 默认 'children'
  767. * @param {*} rootId 根Id 默认 0
  768. */
  769. export function handleTree(data, id, parentId, children, rootId) {
  770. id = id || 'id'
  771. parentId = parentId || 'parentId'
  772. children = children || 'children'
  773. rootId = rootId || Math.min.apply(Math, data.map(item => {
  774. return item[parentId]
  775. })) || 0
  776. //对源数据深度克隆
  777. const cloneData = JSON.parse(JSON.stringify(data))
  778. //循环所有项
  779. const treeData = cloneData.filter(father => {
  780. let branchArr = cloneData.filter(child => {
  781. //返回每一项的子级数组
  782. return father[id] === child[parentId]
  783. });
  784. branchArr.length > 0 ? father.children = branchArr : '';
  785. //返回第一层
  786. return father[parentId] === rootId;
  787. });
  788. return treeData !== '' ? treeData : data;
  789. }
  790. /**
  791. * 获取终端类型
  792. * https://uniapp.dcloud.net.cn/tutorial/platform.html#preprocessor
  793. *
  794. * @return {number | null} 终端类型
  795. */
  796. export function getTerminal() {
  797. let terminal = null;
  798. // #ifdef MP-WEIXIN
  799. terminal = TerminalEnum.WECHAT_MINI_PROGRAM.terminal
  800. // #endif
  801. // #ifdef H5 || WEB
  802. terminal = wechat.isWeixin() ? TerminalEnum.WECHAT_WAP.terminal : TerminalEnum.H5.terminal
  803. // #endif
  804. // #ifdef APP-PLUS || APP
  805. terminal = TerminalEnum.APP.terminal
  806. // #endif
  807. return terminal;
  808. }