util.js 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513
  1. // +----------------------------------------------------------------------
  2. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  3. // +----------------------------------------------------------------------
  4. // | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
  5. // +----------------------------------------------------------------------
  6. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  7. // +----------------------------------------------------------------------
  8. // | Author: CRMEB Team <admin@crmeb.com>
  9. // +----------------------------------------------------------------------
  10. import {
  11. TOKENNAME,
  12. HTTP_REQUEST_URL
  13. } from '../config/app.js';
  14. import store from '../store';
  15. import animationType from '@/utils/animationType.js'
  16. // #ifdef APP-PLUS
  17. import permision from "./permission.js"
  18. // #endif
  19. export default {
  20. /**
  21. * 时间截取成字符串 23-06-26
  22. * @param {Object} time 2023-06-26 15:13:00
  23. */
  24. getTime(time) {
  25. let reg = new RegExp('-', 'g'); //g代表全部
  26. return time.split(' ')[0].replace(reg, '.').substring(2, 10);
  27. },
  28. /**优惠券展示的使用有效期均根据今天进行判断,
  29. * 没到使用期的展示「开始日期-结束日期 有效」,
  30. * 已经可以使用的展示「有效期至 结束日期」
  31. * @param {Object} time
  32. */
  33. getCouponTime(startTime, endTime) {
  34. let start = new Date(startTime).getTime();
  35. let newTime = Date.now();
  36. let reg = new RegExp('-', 'g') //g代表全部
  37. if (newTime < start) {
  38. return startTime.slice(0, 16).replace(reg, '.') + ' - ' + endTime.slice(0, 16).replace(reg, '.') + ' 可用';
  39. } else {
  40. return '有效期至 ' + endTime.slice(0, 16).replace(reg, '.');
  41. }
  42. },
  43. /**
  44. * opt object | string
  45. * to_url object | string
  46. * 例:
  47. * this.Tips('/pages/test/test'); 跳转不提示
  48. * this.Tips({title:'提示'},'/pages/test/test'); 提示并跳转
  49. * this.Tips({title:'提示'},{tab:1,url:'/pages/index/index'}); 提示并跳转值table上
  50. * tab=1 一定时间后跳转至 table上
  51. * tab=2 一定时间后跳转至非 table上
  52. * tab=3 一定时间后返回上页面
  53. * tab=4 关闭所有页面跳转至非table上
  54. * tab=5 关闭当前页面跳转至table上
  55. */
  56. Tips: function(opt, to_url) {
  57. if (typeof opt == 'string') {
  58. to_url = opt;
  59. opt = {};
  60. }
  61. let title = opt.title || '',
  62. icon = opt.icon || 'none',
  63. endtime = opt.endtime || 1000,
  64. success = opt.success;
  65. if (title) uni.showToast({
  66. title: title,
  67. icon: icon,
  68. duration: endtime,
  69. success
  70. })
  71. if (to_url != undefined) {
  72. if (typeof to_url == 'object') {
  73. let tab = to_url.tab || 1,
  74. url = to_url.url || '';
  75. switch (tab) {
  76. case 1:
  77. //一定时间后跳转至 table
  78. setTimeout(function() {
  79. uni.switchTab({
  80. url: url
  81. })
  82. }, endtime);
  83. break;
  84. case 2:
  85. //跳转至非table页面
  86. setTimeout(function() {
  87. uni.navigateTo({
  88. url: url,
  89. })
  90. }, endtime);
  91. break;
  92. case 3:
  93. //返回上页面
  94. setTimeout(function() {
  95. // #ifndef H5
  96. uni.navigateBack({
  97. delta: parseInt(url),
  98. })
  99. // #endif
  100. // #ifdef H5
  101. history.back();
  102. // #endif
  103. }, endtime);
  104. break;
  105. case 4:
  106. //关闭当前所有页面跳转至非table页面
  107. setTimeout(function() {
  108. uni.reLaunch({
  109. url: url,
  110. })
  111. }, endtime);
  112. break;
  113. case 5:
  114. //关闭当前页面跳转至非table页面
  115. setTimeout(function() {
  116. uni.redirectTo({
  117. url: url,
  118. })
  119. }, endtime);
  120. break;
  121. }
  122. } else if (typeof to_url == 'function') {
  123. setTimeout(function() {
  124. to_url && to_url();
  125. }, endtime);
  126. } else {
  127. //没有提示时跳转不延迟
  128. setTimeout(function() {
  129. uni.navigateTo({
  130. url: to_url,
  131. })
  132. }, title ? endtime : 0);
  133. }
  134. }
  135. },
  136. /**
  137. * 移除数组中的某个数组并组成新的数组返回
  138. * @param array array 需要移除的数组
  139. * @param int index 需要移除的数组的键值
  140. * @param string | int 值
  141. * @return array
  142. *
  143. */
  144. ArrayRemove: function(array, index, value) {
  145. const valueArray = [];
  146. if (array instanceof Array) {
  147. for (let i = 0; i < array.length; i++) {
  148. if (typeof index == 'number' && array[index] != i) {
  149. valueArray.push(array[i]);
  150. } else if (typeof index == 'string' && array[i][index] != value) {
  151. valueArray.push(array[i]);
  152. }
  153. }
  154. }
  155. return valueArray;
  156. },
  157. /**
  158. * 获取视频分享海报
  159. * @param array arr2 海报素材
  160. * @param string store_name 素材文字
  161. * @param string price 价格
  162. * @param function successFn 回调函数
  163. *
  164. *
  165. */
  166. videoPosterCanvas: function(arr2, content, nickname, successFn, errFun) {
  167. let that = this;
  168. const ctx = uni.createCanvasContext('myCanvas');
  169. ctx.clearRect(0, 0, 0, 0);
  170. /**
  171. * 只能获取合法域名下的图片信息,本地调试无法获取
  172. *
  173. */
  174. uni.getImageInfo({
  175. src: arr2[0],
  176. success: function(res) {
  177. const WIDTH = res.width;
  178. const HEIGHT = res.height;
  179. let r = 90;
  180. let d = r * 2;
  181. let cx = 40;
  182. let cy = 760;
  183. let ux = 50;
  184. let uy = 700;
  185. ctx.drawImage(arr2[0], 0, 0, WIDTH, HEIGHT);
  186. ctx.drawImage(arr2[1], 32, 32, WIDTH - 64, WIDTH - 64);
  187. ctx.strokeStyle = "#ffffff";
  188. ctx.save();
  189. ctx.arc(cx + r, cy + r, r, 0, 2 * Math.PI);
  190. ctx.drawImage(arr2[2], 530, 760, d, d);
  191. that.handleBorderRect(ctx, ux, uy, r, r, 45);
  192. ctx.clip();
  193. ctx.stockStyle = "#ffffff";
  194. ctx.drawImage(arr2[3], ux, uy, r, r);
  195. ctx.restore();
  196. ctx.setTextAlign('left')
  197. ctx.setFontSize(28);
  198. ctx.setFillStyle('#282828');
  199. ctx.fillText(nickname, r + 60, 760);
  200. ctx.setTextAlign('left')
  201. ctx.setFontSize(28);
  202. ctx.setFillStyle('#282828');
  203. const CONTENT_ROW_LENGTH = 25;
  204. let [contentLeng, contentArray, contentRows] = that.textByteLength(content,
  205. CONTENT_ROW_LENGTH);
  206. if (contentRows > 2) {
  207. contentRows = 2;
  208. let textArray = contentArray.slice(0, 2);
  209. textArray[textArray.length - 1] += '……';
  210. contentArray = textArray;
  211. }
  212. ctx.setTextAlign('left');
  213. ctx.font = 'bold 32px Arial';
  214. let contentHh = 32 * 1.3;
  215. for (let m = 0; m < contentArray.length; m++) {
  216. ctx.fillText(contentArray[m], 55, 850 + contentHh * m);
  217. }
  218. ctx.draw(true, function() {
  219. uni.canvasToTempFilePath({
  220. canvasId: 'myCanvas',
  221. fileType: 'png',
  222. destWidth: WIDTH,
  223. destHeight: HEIGHT,
  224. success: function(res) {
  225. uni.hideLoading();
  226. successFn && successFn(res.tempFilePath);
  227. },
  228. fail: function(err) {
  229. uni.hideLoading();
  230. errFun && errFun(err);
  231. }
  232. })
  233. });
  234. },
  235. fail: function(err) {
  236. uni.hideLoading();
  237. that.Tips({
  238. title: '无法获取图片信息'
  239. });
  240. errFun && errFun(err);
  241. }
  242. })
  243. },
  244. /**
  245. * 生成海报获取文字
  246. * @param string text 为传入的文本
  247. * @param int num 为单行显示的字节长度
  248. * @return array
  249. */
  250. textByteLength: function(text, num) {
  251. let strLength = 0;
  252. let rows = 1;
  253. let str = 0;
  254. let arr = [];
  255. for (let j = 0; j < text.length; j++) {
  256. if (text.charCodeAt(j) > 255) {
  257. strLength += 2;
  258. if (strLength > rows * num) {
  259. strLength++;
  260. arr.push(text.slice(str, j));
  261. str = j;
  262. rows++;
  263. }
  264. } else {
  265. strLength++;
  266. if (strLength > rows * num) {
  267. arr.push(text.slice(str, j));
  268. str = j;
  269. rows++;
  270. }
  271. }
  272. }
  273. arr.push(text.slice(str, text.length));
  274. return [strLength, arr, rows] // [处理文字的总字节长度,每行显示内容的数组,行数]
  275. },
  276. /**
  277. * 获取分享海报
  278. * @param array arr2 海报素材
  279. * @param string store_name 素材文字
  280. * @param string price 价格
  281. * @param string ot_price 原始价格
  282. * @param function successFn 回调函数
  283. *
  284. *
  285. */
  286. PosterCanvas: function(arr2, store_name, price, ot_price, successFn) {
  287. let that = this;
  288. const ctx = uni.createCanvasContext('firstCanvas');
  289. ctx.clearRect(0, 0, 0, 0);
  290. /**
  291. * 只能获取合法域名下的图片信息,本地调试无法获取
  292. *
  293. */
  294. ctx.fillStyle = '#fff';
  295. ctx.fillRect(0, 0, 750, 1150);
  296. uni.getImageInfo({
  297. src: arr2[0],
  298. success: function(res) {
  299. const WIDTH = res.width;
  300. const HEIGHT = res.height;
  301. // ctx.drawImage(arr2[0], 0, 0, WIDTH, 1050);
  302. ctx.drawImage(arr2[1], 0, 0, WIDTH, WIDTH);
  303. ctx.save();
  304. let r = 110;
  305. let d = r * 2;
  306. let cx = 480;
  307. let cy = 790;
  308. ctx.arc(cx + r, cy + r, r, 0, 2 * Math.PI);
  309. // ctx.clip();
  310. ctx.drawImage(arr2[2], cx, cy, d, d);
  311. ctx.restore();
  312. const CONTENT_ROW_LENGTH = 18;
  313. let [contentLeng, contentArray, contentRows] = that.textByteLength(store_name,
  314. CONTENT_ROW_LENGTH);
  315. if (contentRows > 2) {
  316. contentRows = 2;
  317. let textArray = contentArray.slice(0, 2);
  318. textArray[textArray.length - 1] += '……';
  319. contentArray = textArray;
  320. }
  321. ctx.setTextAlign('left');
  322. ctx.setFontSize(36);
  323. ctx.setFillStyle('#000');
  324. // let contentHh = 36 * 1.5;
  325. let contentHh = 36;
  326. for (let m = 0; m < contentArray.length; m++) {
  327. // ctx.fillText(contentArray[m], 50, 1000 + contentHh * m,750);
  328. if (m) {
  329. ctx.fillText(contentArray[m], 50, 1000 + contentHh * m + 18, 1100);
  330. } else {
  331. ctx.fillText(contentArray[m], 50, 1000 + contentHh * m, 1100);
  332. }
  333. }
  334. ctx.setTextAlign('left')
  335. ctx.setFontSize(72);
  336. ctx.setFillStyle('#DA4F2A');
  337. ctx.fillText('¥' + price, 40, 820 + contentHh);
  338. ctx.setTextAlign('left')
  339. ctx.setFontSize(36);
  340. ctx.setFillStyle('#999');
  341. ctx.fillText('¥' + ot_price, 50, 876 + contentHh);
  342. var underline = function(ctx, text, x, y, size, color, thickness, offset) {
  343. var width = ctx.measureText(text).width;
  344. switch (ctx.textAlign) {
  345. case "center":
  346. x -= (width / 2);
  347. break;
  348. case "right":
  349. x -= width;
  350. break;
  351. }
  352. y += size + offset;
  353. ctx.beginPath();
  354. ctx.strokeStyle = color;
  355. ctx.lineWidth = thickness;
  356. ctx.moveTo(x, y);
  357. ctx.lineTo(x + width, y);
  358. ctx.stroke();
  359. }
  360. underline(ctx, '¥' + ot_price, 55, 865, 36, '#999', 2, 0)
  361. ctx.setTextAlign('left')
  362. ctx.setFontSize(28);
  363. ctx.setFillStyle('#999');
  364. ctx.fillText('长按或扫描查看', 490, 1030 + contentHh);
  365. ctx.draw(true, function() {
  366. uni.canvasToTempFilePath({
  367. canvasId: 'firstCanvas',
  368. fileType: 'png',
  369. destWidth: WIDTH,
  370. destHeight: HEIGHT,
  371. success: function(res) {
  372. // uni.hideLoading();
  373. successFn && successFn(res.tempFilePath);
  374. }
  375. })
  376. });
  377. },
  378. fail: function(err) {
  379. console.log('失败', err)
  380. uni.hideLoading();
  381. that.Tips({
  382. title: '无法获取图片信息'
  383. });
  384. }
  385. })
  386. },
  387. /**
  388. * 拼团邀请海报
  389. * @param array arr2 海报素材
  390. * @param string store_name 素材文字
  391. * @param string price 价格
  392. * @param string ot_price 拼团人数
  393. * @param function successFn 回调函数
  394. *
  395. *
  396. */
  397. circleImg(ctx, img, x, y, r) {
  398. ctx.save();
  399. ctx.beginPath()
  400. var d =2 * r;
  401. var cx = x + r;
  402. var cy = y + r;
  403. ctx.arc(cx, cy, r, 0, 2 * Math.PI);
  404. ctx.clip();
  405. ctx.drawImage(img, x, y, d, d);
  406. ctx.restore();
  407. },
  408. groupCanvas: function(arr2, store_name, price, ot_price,groupLeaderNickname, successFn) {
  409. let that = this;
  410. const ctx = uni.createCanvasContext('firstCanvas');
  411. ctx.clearRect(0, 0, 0, 0);
  412. /**
  413. * 只能获取合法域名下的图片信息,本地调试无法获取
  414. *
  415. */
  416. ctx.fillStyle = '#fff';
  417. ctx.fillRect(0, 30, 750, 1100);
  418. uni.getImageInfo({
  419. src: arr2[0],
  420. success: function(res) {
  421. const WIDTH = res.width;
  422. const HEIGHT = res.height;
  423. ctx.drawImage(arr2[0], 0, 0, 750, 1180);
  424. ctx.drawImage(arr2[3], 30, 80, 700, 1020);
  425. ctx.drawImage(arr2[1], 88, 300, WIDTH+90, WIDTH+120);
  426. ctx.save();
  427. let r = 70;
  428. let d = r * 2;
  429. let cx = 470;
  430. let cy = 870;
  431. ctx.arc(cx + r, cy + r, r, 0, 2 * Math.PI);
  432. // ctx.clip();
  433. ctx.drawImage(arr2[2], cx+45, cy+70, d, d);
  434. ctx.restore();
  435. that.circleImg(ctx, arr2[5], 70, 30, 30);
  436. const CONTENT_ROW_LENGTH = 20;
  437. let [contentLeng, contentArray, contentRows] = that.textByteLength(store_name,
  438. CONTENT_ROW_LENGTH);
  439. if (contentRows > 2) {
  440. contentRows = 2;
  441. let textArray = contentArray.slice(0, 2);
  442. textArray[textArray.length - 1] += '……';
  443. contentArray = textArray;
  444. }
  445. ctx.setTextAlign('left');
  446. ctx.setFontSize(36);
  447. ctx.setFillStyle('#000');
  448. // let contentHh = 36 * 1.5;
  449. let contentHh = 36;
  450. for (let m = 0; m < contentArray.length; m++) {
  451. // ctx.fillText(contentArray[m], 50, 1000 + contentHh * m,750);
  452. if (m) {
  453. ctx.fillText(contentArray[m], 90, 200 + contentHh * m + 18, 1400);
  454. } else {
  455. ctx.fillText(contentArray[m], 90, 200 + contentHh * m, 1400);
  456. }
  457. }
  458. ctx.setTextAlign('left')
  459. ctx.setFontSize(34);
  460. ctx.setFillStyle('#fff');
  461. ctx.fillText(groupLeaderNickname+'邀请你拼团', 135, 73 );
  462. ctx.setTextAlign('left')
  463. ctx.setFontSize(40);
  464. ctx.setFillStyle('#DA4F2A');
  465. ctx.fillText('¥' + price, 95, 950 + contentHh);
  466. let priceNumWidth = ctx.measureText('¥' + price).width
  467. ctx.drawImage(arr2[4], 110+priceNumWidth, 948, 100, 50);
  468. ctx.setTextAlign('left')
  469. ctx.setFontSize(28);
  470. ctx.setFillStyle('#666');
  471. ctx.fillText(`还差`, 100, 1020 + contentHh);
  472. ctx.setTextAlign('left')
  473. ctx.setFontSize(28);
  474. ctx.setFillStyle('#DA4F2A');
  475. ctx.fillText(`${ot_price}人`, 160, 1020 + contentHh);
  476. let numWidth = ctx.measureText(`${ot_price}人`).width
  477. ctx.setTextAlign('left')
  478. ctx.setFontSize(28);
  479. ctx.setFillStyle('#999');
  480. ctx.fillText(`即可拼团成功`, 160+numWidth, 1020 + contentHh);
  481. ctx.draw(true, function() {
  482. uni.canvasToTempFilePath({
  483. canvasId: 'firstCanvas',
  484. fileType: 'png',
  485. destWidth: WIDTH,
  486. destHeight: HEIGHT,
  487. success: function(res) {
  488. // uni.hideLoading();
  489. successFn && successFn(res.tempFilePath);
  490. }
  491. })
  492. });
  493. },
  494. fail: function(err) {
  495. console.log('失败', err)
  496. uni.hideLoading();
  497. that.Tips({
  498. title: '无法获取图片信息'
  499. });
  500. }
  501. })
  502. },
  503. /**
  504. * 绘制文字自动换行
  505. * @param array arr2 海报素材
  506. * @param Number x , y 绘制的坐标
  507. * @param Number maxWigth 绘制文字的宽度
  508. * @param Number lineHeight 行高
  509. * @param Number maxRowNum 最大行数
  510. */
  511. canvasWraptitleText(canvas, text, x, y, maxWidth, lineHeight, maxRowNum) {
  512. if (typeof text != 'string' || typeof x != 'number' || typeof y != 'number') {
  513. return;
  514. }
  515. // canvas.font = '20px Bold PingFang SC'; //绘制文字的字号和大小
  516. // 字符分隔为数组
  517. var arrText = text.split('');
  518. var line = '';
  519. var rowNum = 1
  520. for (var n = 0; n < arrText.length; n++) {
  521. var testLine = line + arrText[n];
  522. var metrics = canvas.measureText(testLine);
  523. var testWidth = metrics.width;
  524. if (testWidth > maxWidth && n > 0) {
  525. if (rowNum >= maxRowNum) {
  526. var arrLine = testLine.split('')
  527. arrLine.splice(-9)
  528. var newTestLine = arrLine.join("")
  529. newTestLine += "..."
  530. canvas.fillText(newTestLine, x, y);
  531. //如果需要在省略号后面添加其他的东西,就在这个位置写(列如添加扫码查看详情字样)
  532. //canvas.fillStyle = '#2259CA';
  533. //canvas.fillText('扫码查看详情',x + maxWidth-90, y);
  534. return
  535. }
  536. canvas.fillText(line, x, y);
  537. line = arrText[n];
  538. y += lineHeight;
  539. rowNum += 1
  540. } else {
  541. line = testLine;
  542. }
  543. }
  544. canvas.fillText(line, x, y);
  545. },
  546. /**
  547. * 获取活动分享海报
  548. * @param array arr2 海报素材
  549. * @param string storeName 素材文字
  550. * @param string price 价格
  551. * @param string people 人数
  552. * @param string count 剩余人数
  553. * @param function successFn 回调函数
  554. */
  555. activityCanvas: function(arrImages, storeName, price, people, count, num, successFn) {
  556. let that = this;
  557. let rain = 2;
  558. const context = uni.createCanvasContext('activityCanvas');
  559. context.clearRect(0, 0, 0, 0);
  560. /**
  561. * 只能获取合法域名下的图片信息,本地调试无法获取
  562. *
  563. */
  564. context.fillStyle = '#fff';
  565. context.fillRect(0, 0, 594, 850);
  566. uni.getImageInfo({
  567. src: arrImages[0],
  568. success: function(res) {
  569. context.drawImage(arrImages[0], 0, 0, 594, 850);
  570. context.setFontSize(14 * rain);
  571. context.setFillStyle('#333333');
  572. that.canvasWraptitleText(context, storeName, 110 * rain, 110 * rain, 230 * rain, 30 *
  573. rain, 1)
  574. context.drawImage(arrImages[2], 68 * rain, 194 * rain, 160 * rain, 160 * rain);
  575. context.save();
  576. context.setFontSize(14 * rain);
  577. context.setFillStyle('#fc4141');
  578. context.fillText('¥', 157 * rain, 145 * rain);
  579. context.setFontSize(24 * rain);
  580. context.setFillStyle('#fc4141');
  581. context.fillText(price, 170 * rain, 145 * rain);
  582. context.setFontSize(10 * rain);
  583. context.setFillStyle('#fff');
  584. context.fillText(people, 118 * rain, 143 * rain);
  585. context.setFontSize(12 * rain);
  586. context.setFillStyle('#666666');
  587. context.setTextAlign('center');
  588. context.fillText(count, (167 - num) * rain, 166 * rain);
  589. that.handleBorderRect(context, 27 * rain, 94 * rain, 75 * rain, 75 * rain, 6 * rain);
  590. context.clip();
  591. context.drawImage(arrImages[1], 27 * rain, 94 * rain, 75 * rain, 75 * rain);
  592. context.draw(true, function() {
  593. uni.canvasToTempFilePath({
  594. canvasId: 'activityCanvas',
  595. fileType: 'png',
  596. destWidth: 594,
  597. destHeight: 850,
  598. success: function(res) {
  599. // uni.hideLoading();
  600. successFn && successFn(res.tempFilePath);
  601. }
  602. })
  603. });
  604. },
  605. fail: function(err) {
  606. console.log('失败', err)
  607. uni.hideLoading();
  608. that.Tips({
  609. title: '无法获取图片信息'
  610. });
  611. }
  612. })
  613. },
  614. /**
  615. * 图片圆角设置
  616. * @param string x x轴位置
  617. * @param string y y轴位置
  618. * @param string w 图片宽
  619. * @param string y 图片高
  620. * @param string r 圆角值
  621. */
  622. handleBorderRect(ctx, x, y, w, h, r) {
  623. ctx.beginPath();
  624. // 左上角
  625. ctx.arc(x + r, y + r, r, Math.PI, 1.5 * Math.PI);
  626. ctx.moveTo(x + r, y);
  627. ctx.lineTo(x + w - r, y);
  628. ctx.lineTo(x + w, y + r);
  629. // 右上角
  630. ctx.arc(x + w - r, y + r, r, 1.5 * Math.PI, 2 * Math.PI);
  631. ctx.lineTo(x + w, y + h - r);
  632. ctx.lineTo(x + w - r, y + h);
  633. // 右下角
  634. ctx.arc(x + w - r, y + h - r, r, 0, 0.5 * Math.PI);
  635. ctx.lineTo(x + r, y + h);
  636. ctx.lineTo(x, y + h - r);
  637. // 左下角
  638. ctx.arc(x + r, y + h - r, r, 0.5 * Math.PI, Math.PI);
  639. ctx.lineTo(x, y + r);
  640. ctx.lineTo(x + r, y);
  641. ctx.fill();
  642. ctx.closePath();
  643. },
  644. /*
  645. * 视频上传
  646. * @param object opt
  647. * @param callable successCallback 成功执行方法 data
  648. * @param callable errorCallback 失败执行方法
  649. */
  650. uploadVideo: function(opt, successCallback, errorCallback) {
  651. let that = this;
  652. if (typeof opt === 'string') {
  653. let url = opt;
  654. opt = {};
  655. opt.url = url;
  656. }
  657. let count = opt.count || 1,
  658. sizeType = opt.sizeType || ['compressed'],
  659. sourceType = opt.sourceType || ['album', 'camera'],
  660. is_load = opt.is_load || true,
  661. uploadUrl = opt.url || '',
  662. inputName = opt.name || 'file',
  663. pid = opt.pid,
  664. fils = '',
  665. uploadMaxSize = 30,
  666. urlPath = HTTP_REQUEST_URL + '/api/front/upload/file' + "?model=" + opt.model +
  667. "&pid=" + opt.pid,
  668. model = opt.model;
  669. uni.chooseVideo({
  670. sourceType: sourceType,
  671. success: async (res) => {
  672. if (Math.ceil(res.size / 1024) < uploadMaxSize * 1024) {
  673. fils = await that.uploadFile(urlPath, res.tempFilePath, opt, '视频上传中');
  674. //获取视频第一帧为封面图,只兼容h5
  675. // #ifdef H5
  676. let dataURL = '';
  677. //uni.createVideoContext('1', that).play()
  678. let video = document.createElement("video");
  679. video.setAttribute('crossOrigin', 'anonymous'); //处理跨域
  680. video.setAttribute('src', fils);
  681. video.setAttribute('width', 400);
  682. video.setAttribute('height', 240);
  683. video.setAttribute('preload', 'auto');
  684. video.addEventListener('loadeddata', async function() {
  685. uni.showLoading({
  686. title: '加载中...',
  687. });
  688. let canvas = document.createElement("canvas"),
  689. width = video.width, //canvas的尺寸和图片一样
  690. height = video.height;
  691. canvas.width = width;
  692. canvas.height = height;
  693. canvas.getContext("2d").drawImage(video, 0, 0, width,
  694. height); //绘制canvas
  695. dataURL = canvas.toDataURL('image/png'); //转换为base64
  696. let file = await that.base64ToFile(dataURL); //base64转文件流
  697. let urlPaths = HTTP_REQUEST_URL + '/api/front/upload/image' +
  698. "?model=product&pid=1"; //图片上传地址
  699. let coverURL = await that.uploadFile(urlPaths, file, opt) //封面图
  700. successCallback && successCallback({
  701. fils: fils,
  702. coverURL: coverURL
  703. })
  704. });
  705. // #endif
  706. // #ifndef H5
  707. successCallback && successCallback({
  708. fils: fils,
  709. coverURL: ''
  710. })
  711. // #endif
  712. } else {
  713. // #ifdef APP-PLUS
  714. plus.nativeUI.alert(`您选择的视频超出${uploadMaxSize}MB,已过滤`);
  715. // #endif
  716. // #ifndef APP-PLUS
  717. uni.showModal({
  718. content: `您选择的视频超出${uploadMaxSize}MB,已过滤`,
  719. showCancel: false
  720. });
  721. // #endif
  722. }
  723. }
  724. })
  725. },
  726. /*
  727. * 单图上传
  728. * @param object opt
  729. * @param callable successCallback 成功执行方法 data
  730. * @param callable errorCallback 失败执行方法
  731. */
  732. uploadImageOne: function(opt, successCallback, errorCallback) {
  733. let that = this;
  734. if (typeof opt === 'string') {
  735. let url = opt;
  736. opt = {};
  737. opt.url = url;
  738. }
  739. let count = opt.count || 1,
  740. sizeType = opt.sizeType || ['compressed'],
  741. sourceType = opt.sourceType || ['album', 'camera'],
  742. is_load = opt.is_load || true,
  743. uploadUrl = opt.url || '',
  744. inputName = opt.name || 'pics',
  745. pid = opt.pid,
  746. model = opt.model;
  747. uni.chooseImage({
  748. count: count, //最多可以选择的图片总数
  749. sizeType: sizeType, // 可以指定是原图还是压缩图,默认二者都有
  750. sourceType: sourceType, // 可以指定来源是相册还是相机,默认二者都有
  751. mediaType:['image'],
  752. success: async (res) => {
  753. let image = [];
  754. let filesLen = res.tempFiles.length;
  755. let exceeded_list = [];
  756. let uploadMaxSize = 10;
  757. let imageList = [];
  758. let urlPath = HTTP_REQUEST_URL + '/api/front/upload/image' + "?model=" + opt.model +
  759. "&pid=" + opt.pid
  760. if (count === 1) {
  761. successCallback && successCallback(await that.uploadFile(urlPath, res.tempFilePaths[
  762. 0], opt, '图片上传中'))
  763. } else {
  764. for (let i = 0; i < res.tempFiles.length; i++) {
  765. if (Math.ceil(res.tempFiles[i].size / 1024) < uploadMaxSize * 1024) {
  766. image.push(res.tempFiles[i].path);
  767. } else {
  768. exceeded_list.push(i + 1);
  769. filesLen = filesLen - 1;
  770. // #ifdef APP-PLUS
  771. plus.nativeUI.alert(
  772. `第${[...new Set(exceeded_list)].join(',')}张图片超出限制${uploadMaxSize}MB,已过滤`
  773. );
  774. // #endif
  775. // #ifndef APP-PLUS
  776. uni.showModal({
  777. content: `第${[...new Set(exceeded_list)].join(',')}张图片超出限制${uploadMaxSize}MB,已过滤`
  778. });
  779. // #endif
  780. continue;
  781. }
  782. }
  783. for (const key in image) {
  784. imageList.push(await that.uploadFile(urlPath, image[key], opt, '图片上传中'))
  785. }
  786. successCallback && successCallback(imageList)
  787. }
  788. }
  789. })
  790. },
  791. uploadFile(urlPath, localPath, opt, message) {
  792. let that = this;
  793. return new Promise(async (resolve) => {
  794. //启动上传等待中...
  795. if (message) uni.showLoading({
  796. title: message,
  797. });
  798. uni.uploadFile({
  799. url: urlPath,
  800. filePath: localPath,
  801. name: opt.name || 'pics',
  802. header: {
  803. // #ifdef MP
  804. "Content-Type": "multipart/form-data",
  805. // #endif
  806. [TOKENNAME]: store.state.app.token
  807. },
  808. success: function(res) {
  809. uni.hideLoading();
  810. if (res.statusCode == 403) {
  811. that.Tips({
  812. title: res.data
  813. });
  814. } else {
  815. let data = res.data ? JSON.parse(res.data) : {};
  816. if (data.code == 200) {
  817. resolve(data.data.url);
  818. } else {
  819. that.Tips({
  820. title: data.message
  821. });
  822. }
  823. }
  824. },
  825. fail: function(res) {
  826. uni.hideLoading();
  827. that.Tips({
  828. title: res
  829. });
  830. }
  831. })
  832. })
  833. },
  834. /**
  835. * 小程序头像获取上传
  836. * @param uploadUrl 上传接口地址
  837. * @param filePath 上传文件路径
  838. * @param successCallback success回调
  839. * @param errorCallback err回调
  840. */
  841. uploadImgs(filePath, opt, successCallback, errorCallback) {
  842. let that = this;
  843. if (typeof opt === 'string') {
  844. let url = opt;
  845. opt = {};
  846. opt.url = url;
  847. }
  848. let count = opt.count || 1,
  849. sizeType = opt.sizeType || ['compressed'],
  850. sourceType = opt.sourceType || ['album', 'camera'],
  851. is_load = opt.is_load || true,
  852. uploadUrl = opt.url || '',
  853. inputName = opt.name || 'pics',
  854. pid = opt.pid,
  855. model = opt.model;
  856. let urlPath = HTTP_REQUEST_URL + '/api/front/upload/image' + "?model=" + model +
  857. "&pid=" + pid
  858. uni.uploadFile({
  859. url: urlPath,
  860. filePath: filePath,
  861. name: inputName,
  862. formData: {
  863. 'filename': inputName
  864. },
  865. header: {
  866. // #ifdef MP
  867. "Content-Type": "multipart/form-data",
  868. // #endif
  869. [TOKENNAME]: store.state.app.token
  870. },
  871. success: function(res) {
  872. uni.hideLoading();
  873. if (res.statusCode == 403) {
  874. that.Tips({
  875. title: res.data
  876. });
  877. } else {
  878. let data = res.data ? JSON.parse(res.data) : {};
  879. if (data.code == 200) {
  880. successCallback && successCallback(data)
  881. } else {
  882. errorCallback && errorCallback(data);
  883. that.Tips({
  884. title: data.message
  885. });
  886. }
  887. }
  888. },
  889. fail: function(res) {
  890. uni.hideLoading();
  891. that.Tips({
  892. title: res
  893. });
  894. }
  895. })
  896. },
  897. base64ToImg(urlData, filename) {
  898. // 64转file
  899. var arr = urlData.split(",");
  900. var type = arr[0].match(/:(.*?);/)[1];
  901. var fileExt = type.split("/")[1];
  902. var bstr = atob(arr[1]);
  903. var n = bstr.length;
  904. var u8arr = new Uint8Array(n);
  905. while (n--) {
  906. u8arr[n] = bstr.charCodeAt(n);
  907. }
  908. return new File([u8arr], `${filename}.` + fileExt, {
  909. type: type,
  910. });
  911. },
  912. /**
  913. * 处理服务器扫码带进来的参数
  914. * @param string param 扫码携带参数
  915. * @param string k 整体分割符 默认为:&
  916. * @param string p 单个分隔符 默认为:=
  917. * @return object
  918. *
  919. */
  920. // #ifdef MP
  921. getUrlParams: function(param, k, p) {
  922. if (typeof param != 'string') return {};
  923. k = k ? k : '&'; //整体参数分隔符
  924. p = p ? p : '='; //单个参数分隔符
  925. var value = {};
  926. if (param.indexOf(k) !== -1) {
  927. param = param.split(k);
  928. for (var val in param) {
  929. if (param[val].indexOf(p) !== -1) {
  930. var item = param[val].split(p);
  931. value[item[0]] = item[1];
  932. }
  933. }
  934. } else if (param.indexOf(p) !== -1) {
  935. var item = param.split(p);
  936. value[item[0]] = item[1];
  937. } else {
  938. return param;
  939. }
  940. return value;
  941. },
  942. /**根据格式组装公共参数
  943. * @param {Object} value
  944. */
  945. formatMpQrCodeData(value) {
  946. let values = value.split(',');
  947. let result = {};
  948. if (values.length === 2) {
  949. let v1 = values[0].split(":");
  950. if (v1[0] === 'pid') {
  951. result.spread = v1[1];
  952. } else {
  953. result.id = v1[1];
  954. }
  955. let v2 = values[1].split(":");
  956. if (v2[0] === 'pid') {
  957. result.spread = v2[1];
  958. } else {
  959. result.id = v2[1];
  960. }
  961. } else {
  962. result.spread = values[0].split(":")[1];
  963. }
  964. return result;
  965. },
  966. // #endif
  967. /*
  968. * 合并数组
  969. */
  970. SplitArray(list, sp) {
  971. if (typeof list != 'object') return [];
  972. if (sp === undefined) sp = [];
  973. for (var i = 0; i < list.length; i++) {
  974. sp.push(list[i]);
  975. }
  976. return sp;
  977. },
  978. trim(str) {
  979. return String.prototype.trim.call(str);
  980. },
  981. $h: {
  982. //除法函数,用来得到精确的除法结果
  983. //说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
  984. //调用:$h.Div(arg1,arg2)
  985. //返回值:arg1除以arg2的精确结果
  986. Div: function(arg1, arg2) {
  987. arg1 = parseFloat(arg1);
  988. arg2 = parseFloat(arg2);
  989. var t1 = 0,
  990. t2 = 0,
  991. r1, r2;
  992. try {
  993. t1 = arg1.toString().split(".")[1].length;
  994. } catch (e) {}
  995. try {
  996. t2 = arg2.toString().split(".")[1].length;
  997. } catch (e) {}
  998. r1 = Number(arg1.toString().replace(".", ""));
  999. r2 = Number(arg2.toString().replace(".", ""));
  1000. return this.Mul(r1 / r2, Math.pow(10, t2 - t1));
  1001. },
  1002. //加法函数,用来得到精确的加法结果
  1003. //说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
  1004. //调用:$h.Add(arg1,arg2)
  1005. //返回值:arg1加上arg2的精确结果
  1006. Add: function(arg1, arg2) {
  1007. arg2 = parseFloat(arg2);
  1008. var r1, r2, m;
  1009. try {
  1010. r1 = arg1.toString().split(".")[1].length
  1011. } catch (e) {
  1012. r1 = 0
  1013. }
  1014. try {
  1015. r2 = arg2.toString().split(".")[1].length
  1016. } catch (e) {
  1017. r2 = 0
  1018. }
  1019. m = Math.pow(100, Math.max(r1, r2));
  1020. return (this.Mul(arg1, m) + this.Mul(arg2, m)) / m;
  1021. },
  1022. //减法函数,用来得到精确的减法结果
  1023. //说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的减法结果。
  1024. //调用:$h.Sub(arg1,arg2)
  1025. //返回值:arg1减去arg2的精确结果
  1026. Sub: function(arg1, arg2) {
  1027. arg1 = parseFloat(arg1);
  1028. arg2 = parseFloat(arg2);
  1029. var r1, r2, m, n;
  1030. try {
  1031. r1 = arg1.toString().split(".")[1].length
  1032. } catch (e) {
  1033. r1 = 0
  1034. }
  1035. try {
  1036. r2 = arg2.toString().split(".")[1].length
  1037. } catch (e) {
  1038. r2 = 0
  1039. }
  1040. m = Math.pow(10, Math.max(r1, r2));
  1041. //动态控制精度长度
  1042. n = (r1 >= r2) ? r1 : r2;
  1043. return ((this.Mul(arg1, m) - this.Mul(arg2, m)) / m).toFixed(n);
  1044. },
  1045. //乘法函数,用来得到精确的乘法结果
  1046. //说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
  1047. //调用:$h.Mul(arg1,arg2)
  1048. //返回值:arg1乘以arg2的精确结果
  1049. Mul: function(arg1, arg2) {
  1050. arg1 = parseFloat(arg1);
  1051. arg2 = parseFloat(arg2);
  1052. var m = 0,
  1053. s1 = arg1.toString(),
  1054. s2 = arg2.toString();
  1055. try {
  1056. m += s1.split(".")[1].length
  1057. } catch (e) {}
  1058. try {
  1059. m += s2.split(".")[1].length
  1060. } catch (e) {}
  1061. return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
  1062. },
  1063. },
  1064. // 获取地理位置;
  1065. $L: {
  1066. getLocation() {
  1067. console.log('Location')
  1068. return new Promise(async (resolve, reject) => {
  1069. // #ifdef APP-PLUS
  1070. let status = await this.checkPermission();
  1071. if (status !== 1) {
  1072. uni.removeStorageSync('user_latitude');
  1073. uni.removeStorageSync('user_longitude');
  1074. resolve(status);
  1075. return;
  1076. }
  1077. // #endif
  1078. // #ifdef MP
  1079. let status = await this.getSetting();
  1080. if (status === 2) {
  1081. uni.removeStorageSync('user_latitude');
  1082. uni.removeStorageSync('user_longitude');
  1083. this.Tips({
  1084. title: '获取当前定位遇到困难,如需定位请开启权限'
  1085. });
  1086. //this.openSetting();
  1087. resolve(status);
  1088. return;
  1089. }
  1090. // #endif
  1091. let Location = await this.doGetLocation();
  1092. resolve(Location);
  1093. });
  1094. },
  1095. doGetLocation() {
  1096. return new Promise((resolve, reject) => {
  1097. uni.getLocation({
  1098. //type: 'wgs84',
  1099. type: 'gcj02',
  1100. isHighAccuracy: true,
  1101. success: (res) => {
  1102. uni.setStorageSync('user_latitude', res.latitude);
  1103. uni.setStorageSync('user_longitude', res.longitude);
  1104. resolve(res);
  1105. },
  1106. complete: (res) => {
  1107. uni.setStorageSync('user_latitude', res.latitude);
  1108. uni.setStorageSync('user_longitude', res.longitude);
  1109. resolve(res);
  1110. },
  1111. fail: (err) => {
  1112. uni.removeStorageSync('user_latitude');
  1113. uni.removeStorageSync('user_longitude');
  1114. reject(err);
  1115. // #ifdef MP-BAIDU
  1116. if (err.errCode === 202 || err.errCode ===
  1117. 10003) { // 202模拟器 10003真机 user deny
  1118. this.openSetting();
  1119. }
  1120. // #endif
  1121. // #ifndef MP-BAIDU
  1122. if (err.errMsg.indexOf("auth deny") >= 0) {
  1123. uni.showToast({
  1124. title: '访问位置被拒绝',
  1125. icon: 'none',
  1126. duration: 2000
  1127. });
  1128. } else {
  1129. uni.showToast({
  1130. title: err.errMsg,
  1131. icon: 'none',
  1132. duration: 2000
  1133. });
  1134. }
  1135. // #endif
  1136. }
  1137. })
  1138. });
  1139. },
  1140. getSetting: function() {
  1141. return new Promise((resolve, reject) => {
  1142. uni.getSetting({
  1143. success: (res) => {
  1144. if (res.authSetting['scope.userLocation'] === undefined) {
  1145. resolve(0);
  1146. return;
  1147. }
  1148. if (res.authSetting['scope.userLocation']) {
  1149. resolve(1);
  1150. } else {
  1151. resolve(2);
  1152. }
  1153. }
  1154. });
  1155. });
  1156. },
  1157. /**
  1158. * 开启权限提示
  1159. */
  1160. openSetting: function() {
  1161. uni.openSetting({
  1162. success: (res) => {
  1163. if (res.authSetting && res.authSetting['scope.userLocation']) {
  1164. this.doGetLocation();
  1165. }
  1166. },
  1167. fail: (err) => {}
  1168. })
  1169. },
  1170. async checkPermission() {
  1171. let status = permision.isIOS ? await permision.requestIOS('location') :
  1172. await permision.requestAndroid('android.permission.ACCESS_FINE_LOCATION');
  1173. let pages = getCurrentPages();
  1174. let prePage = pages[pages.length - 1].route;
  1175. if (status === null || status === 1) {
  1176. status = 1;
  1177. } else if (status === 2) {
  1178. if (prePage === 'pages/users/user_address/index')
  1179. uni.showModal({
  1180. content: "系统定位已关闭",
  1181. confirmText: "确定",
  1182. showCancel: false,
  1183. success: function(res) {}
  1184. })
  1185. } else if (status.code) {
  1186. if (prePage === 'pages/users/user_address/index')
  1187. uni.showModal({
  1188. content: status.message
  1189. })
  1190. } else {
  1191. if (prePage === 'pages/users/user_address/index')
  1192. uni.showModal({
  1193. content: "需要定位权限",
  1194. confirmText: "设置",
  1195. success: function(res) {
  1196. if (res.confirm) {
  1197. permision.gotoAppSetting();
  1198. }
  1199. }
  1200. })
  1201. }
  1202. return status;
  1203. },
  1204. },
  1205. toStringValue: function(obj) {
  1206. if (obj instanceof Array) {
  1207. var arr = [];
  1208. for (var i = 0; i < obj.length; i++) {
  1209. arr[i] = toStringValue(obj[i]);
  1210. }
  1211. return arr;
  1212. } else if (typeof obj == 'object') {
  1213. for (var p in obj) {
  1214. obj[p] = toStringValue(obj[p]);
  1215. }
  1216. } else if (typeof obj == 'number') {
  1217. obj = obj + '';
  1218. }
  1219. return obj;
  1220. },
  1221. /*
  1222. * 替换域名
  1223. */
  1224. setDomain: function(url) {
  1225. url = url ? url.toString() : '';
  1226. return url
  1227. // if (url.indexOf("https://") > -1) return url;
  1228. // else return url.replace('http://', 'https://');
  1229. },
  1230. /**
  1231. * 姓名除了姓显示其他
  1232. */
  1233. formatName: function(str) {
  1234. return str.substr(0, 1) + new Array(str.length).join('*');
  1235. },
  1236. /**
  1237. * 微信地址导入
  1238. * @param uploadUrl 上传接口地址
  1239. * @param filePath 上传文件路径
  1240. * @param successCallback success回调
  1241. * @param errorCallback err回调
  1242. */
  1243. addressWxImport() {
  1244. let that = this;
  1245. uni.showLoading({
  1246. title: '加载中...'
  1247. });
  1248. return new Promise((resolve, reject) => {
  1249. uni.authorize({
  1250. scope: 'scope.address',
  1251. success: function(res) {
  1252. uni.hideLoading();
  1253. uni.chooseAddress({
  1254. success(resd) {
  1255. resolve(resd);
  1256. },
  1257. fail: function(err) {
  1258. if (err.errMsg == 'chooseAddress:cancel') return that.Tips({
  1259. title: '取消选择'
  1260. });
  1261. },
  1262. })
  1263. },
  1264. fail: function(err) {
  1265. uni.hideLoading();
  1266. uni.showModal({
  1267. title: '您已拒绝导入微信地址权限',
  1268. content: '是否进入权限管理,调整授权?',
  1269. success(err) {
  1270. if (err.confirm) {
  1271. uni.openSetting({
  1272. success: function(err) {
  1273. console.log(err.authSetting)
  1274. }
  1275. });
  1276. } else if (err.cancel) {
  1277. return that.Tips({
  1278. title: '已取消!'
  1279. });
  1280. }
  1281. }
  1282. })
  1283. }
  1284. })
  1285. });
  1286. },
  1287. /**
  1288. * 回退并且刷新页面
  1289. */
  1290. backPageRefresh() {
  1291. let pages = getCurrentPages(); // 当前页面
  1292. let beforePage = pages[pages.length - 2]; // 上一页
  1293. uni.navigateBack({
  1294. success: function() {
  1295. beforePage.$vm.reFresh();
  1296. }
  1297. })
  1298. },
  1299. /**
  1300. * 将时间转化为几小时
  1301. * @param {Object} data data必须是日期格式,不能是时间戳
  1302. */
  1303. getDateDiff(data) {
  1304. let datas = data;
  1305. // 传进来的data必须是日期格式,不能是时间戳
  1306. //var str = data;
  1307. //将字符串转换成时间格式
  1308. var timePublish = new Date(data);
  1309. var timeNow = new Date();
  1310. var minute = 1000 * 60;
  1311. var hour = minute * 60;
  1312. var day = hour * 24;
  1313. var month = day * 30;
  1314. var result = "";
  1315. var diffValue = timeNow - timePublish;
  1316. var diffMonth = diffValue / month;
  1317. var diffWeek = diffValue / (7 * day);
  1318. var diffDay = diffValue / day;
  1319. var diffHour = diffValue / hour;
  1320. var diffMinute = diffValue / minute;
  1321. if (diffValue < 0) {} else if (diffMonth > 3) {
  1322. result = timePublish.getFullYear() + "-";
  1323. result += timePublish.getMonth() + "-";
  1324. result += timePublish.getDate();
  1325. } else if (diffMonth > 1) {
  1326. result = parseInt(diffMonth) + "月前";
  1327. } else if (diffWeek > 1) {
  1328. result = parseInt(diffWeek) + "周前";
  1329. } else if (diffDay > 1) {
  1330. result = parseInt(diffDay) + "天前";
  1331. } else if (diffHour > 1) {
  1332. result = parseInt(diffHour) + "小时前";
  1333. } else if (diffMinute > 1) {
  1334. result = parseInt(diffMinute) + "分钟前";
  1335. } else {
  1336. result = "刚刚";
  1337. }
  1338. return result;
  1339. },
  1340. /**
  1341. * 链接地址跳转
  1342. * @param {Object} url 链接地址
  1343. */
  1344. navigateTo(url) {
  1345. if (url.indexOf("http") !== -1) {
  1346. // #ifdef H5
  1347. location.href = url
  1348. // #endif
  1349. // #ifdef APP-PLUS || MP
  1350. uni.navigateTo({
  1351. url: '/pages/users/web_page/index?webUel=' + encodeURIComponent(url)
  1352. })
  1353. // #endif
  1354. } else {
  1355. if (['/pages/goods_cate/index', '/pages/order_addcart/order_addcart', '/pages/user/index',
  1356. '/pages/discover_index/index', '/pages/index/index'
  1357. ].indexOf(url) == -1) {
  1358. uni.navigateTo({
  1359. animationType: animationType.type,
  1360. animationDuration: animationType.duration,
  1361. url: url
  1362. })
  1363. } else {
  1364. uni.switchTab({
  1365. animationType: animationType.type,
  1366. animationDuration: animationType.duration,
  1367. url: url
  1368. })
  1369. }
  1370. }
  1371. },
  1372. /**
  1373. * base64格式转为文件流
  1374. * @param base64 base64地址
  1375. * @returns {File}
  1376. */
  1377. base64ToFile(base64) {
  1378. return new Promise(function(resolve, reject) {
  1379. if (typeof window === 'object' && 'document' in window) {
  1380. base64 = base64.split(',')
  1381. var type = base64[0].match(/:(.*?);/)[1]
  1382. var str = atob(base64[1])
  1383. var n = str.length
  1384. var array = new Uint8Array(n)
  1385. while (n--) {
  1386. array[n] = str.charCodeAt(n)
  1387. }
  1388. return resolve((window.URL || window.webkitURL).createObjectURL(new Blob([array], {
  1389. type: type
  1390. })))
  1391. }
  1392. var extName = base64.match(/data\:\S+\/(\S+);/)
  1393. if (extName) {
  1394. extName = extName[1]
  1395. } else {
  1396. reject(new Error('base64 error'))
  1397. }
  1398. var fileName = Date.now() + '.' + extName
  1399. if (typeof plus === 'object') {
  1400. var bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
  1401. bitmap.loadBase64Data(base64, function() {
  1402. var filePath = '_doc/uniapp_temp/' + fileName
  1403. bitmap.save(filePath, {}, function() {
  1404. bitmap.clear()
  1405. resolve(filePath)
  1406. }, function(error) {
  1407. bitmap.clear()
  1408. reject(error)
  1409. })
  1410. }, function(error) {
  1411. bitmap.clear()
  1412. reject(error)
  1413. })
  1414. return
  1415. }
  1416. if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
  1417. var filePath = wx.env.USER_DATA_PATH + '/' + fileName
  1418. wx.getFileSystemManager().writeFile({
  1419. filePath: filePath,
  1420. data: base64.replace(/^data:\S+\/\S+;base64,/, ''),
  1421. encoding: 'base64',
  1422. success: function() {
  1423. resolve(filePath)
  1424. },
  1425. fail: function(error) {
  1426. reject(error)
  1427. }
  1428. })
  1429. return
  1430. }
  1431. reject(new Error('not support'))
  1432. })
  1433. },
  1434. // 计算头部自定义导航高度;
  1435. getWXStatusHeight() {
  1436. // 获取距上
  1437. const barTop = uni.getSystemInfoSync().statusBarHeight;
  1438. // #ifdef MP
  1439. // 获取胶囊按钮位置信息
  1440. const menuButtonInfo = wx.getMenuButtonBoundingClientRect() || 0
  1441. // 获取导航栏高度
  1442. const barHeight = menuButtonInfo.height + (menuButtonInfo.top - barTop) * 2
  1443. let barWidth = menuButtonInfo.width
  1444. // #endif
  1445. // #ifndef MP
  1446. // 获取导航栏高度
  1447. const barHeight = parseInt(barTop) + 10;
  1448. let barWidth = '100%'
  1449. // #endif
  1450. return {
  1451. barHeight,
  1452. barTop,
  1453. barWidth
  1454. }
  1455. },
  1456. /**
  1457. * 对象转数组
  1458. * @param data 对象
  1459. * @returns {*[]}
  1460. */
  1461. objToArr(data) {
  1462. let obj = Object.keys(data).sort();
  1463. let m = obj.map(key => data[key]);
  1464. return m;
  1465. },
  1466. }