util.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935
  1. import {
  2. TOKENNAME,
  3. HTTP_REQUEST_URL,
  4. UPLOAD_URL
  5. } from '../config/app.js';
  6. import store from '../store';
  7. import i18n from './lang.js';
  8. import {
  9. pathToBase64
  10. } from '@/plugin/image-tools/index.js';
  11. // #ifdef APP-PLUS
  12. import permision from "./permission.js"
  13. // #endif
  14. export default {
  15. /**
  16. * opt object | string
  17. * to_url object | string
  18. * 例:
  19. * this.Tips('/pages/test/test'); 跳转不提示
  20. * this.Tips({title:'提示'},'/pages/test/test'); 提示并跳转
  21. * this.Tips({title:'提示'},{tab:1,url:'/pages/index/index'}); 提示并跳转值table上
  22. * tab=1 一定时间后跳转至 table上
  23. * tab=2 一定时间后跳转至非 table上
  24. * tab=3 一定时间后返回上页面
  25. * tab=4 关闭所有页面,打开到应用内的某个页面
  26. * tab=5 关闭当前页面,跳转到应用内的某个页面
  27. */
  28. Tips: function(opt, to_url) {
  29. console.log(opt,to_url)
  30. if (typeof opt == 'string') {
  31. to_url = opt;
  32. opt = {};
  33. }
  34. let title = opt.title || '',
  35. icon = opt.icon || 'none',
  36. endtime = opt.endtime || 2000,
  37. success = opt.success;
  38. if (title) uni.showToast({
  39. title: title,
  40. icon: icon,
  41. duration: endtime,
  42. success
  43. })
  44. if (to_url != undefined) {
  45. if (typeof to_url == 'object') {
  46. let tab = to_url.tab || 1,
  47. url = to_url.url || '';
  48. console.log(url);
  49. switch (tab) {
  50. case 1:
  51. //一定时间后跳转至 table
  52. setTimeout(function() {
  53. uni.navigateTo({
  54. url: url
  55. })
  56. }, endtime);
  57. break;
  58. case 2:
  59. //跳转至非table页面
  60. setTimeout(function() {
  61. uni.navigateTo({
  62. url: url,
  63. })
  64. }, endtime);
  65. break;
  66. case 3:
  67. //返回上页面
  68. setTimeout(function() {
  69. // #ifndef H5
  70. uni.navigateBack({
  71. delta: parseInt(url),
  72. })
  73. // #endif
  74. // #ifdef H5
  75. history.back();
  76. // #endif
  77. }, endtime);
  78. break;
  79. case 4:
  80. //关闭所有页面,打开到应用内的某个页面
  81. setTimeout(function() {
  82. uni.reLaunch({
  83. url: url,
  84. })
  85. }, endtime);
  86. break;
  87. case 5:
  88. //关闭当前页面,跳转到应用内的某个页面
  89. setTimeout(function() {
  90. uni.redirectTo({
  91. url: url,
  92. })
  93. }, endtime);
  94. break;
  95. }
  96. } else if (typeof to_url == 'function') {
  97. setTimeout(function() {
  98. to_url && to_url();
  99. }, endtime);
  100. } else {
  101. //没有提示时跳转不延迟
  102. setTimeout(function() {
  103. uni.navigateTo({
  104. url: to_url,
  105. })
  106. }, title ? endtime : 0);
  107. }
  108. }
  109. },
  110. /**
  111. * 移除数组中的某个数组并组成新的数组返回
  112. * @param array array 需要移除的数组
  113. * @param int index 需要移除的数组的键值
  114. * @param string | int 值
  115. * @return array
  116. *
  117. */
  118. ArrayRemove: function(array, index, value) {
  119. const valueArray = [];
  120. if (array instanceof Array) {
  121. for (let i = 0; i < array.length; i++) {
  122. if (typeof index == 'number' && array[index] != i) {
  123. valueArray.push(array[i]);
  124. } else if (typeof index == 'string' && array[i][index] != value) {
  125. valueArray.push(array[i]);
  126. }
  127. }
  128. }
  129. return valueArray;
  130. },
  131. /**
  132. * 生成海报获取文字
  133. * @param string text 为传入的文本
  134. * @param int num 为单行显示的字节长度
  135. * @return array
  136. */
  137. textByteLength: function(text, num) {
  138. let strLength = 0;
  139. let rows = 1;
  140. let str = 0;
  141. let arr = [];
  142. for (let j = 0; j < text.length; j++) {
  143. if (text.charCodeAt(j) > 255) {
  144. strLength += 2;
  145. if (strLength > rows * num) {
  146. strLength++;
  147. arr.push(text.slice(str, j));
  148. str = j;
  149. rows++;
  150. }
  151. } else {
  152. strLength++;
  153. if (strLength > rows * num) {
  154. arr.push(text.slice(str, j));
  155. str = j;
  156. rows++;
  157. }
  158. }
  159. }
  160. arr.push(text.slice(str, text.length));
  161. return [strLength, arr, rows] // [处理文字的总字节长度,每行显示内容的数组,行数]
  162. },
  163. /**
  164. * 获取分享海报
  165. * @param array arr2 海报素材
  166. * @param string store_name 素材文字
  167. * @param string price 价格
  168. * @param string ot_price 原始价格
  169. * @param function successFn 回调函数
  170. *
  171. *
  172. */
  173. PosterCanvas: function(arr2, store_name, price, ot_price, successFn) {
  174. let that = this;
  175. uni.showLoading({
  176. title: i18n.t(`海报生成中`),
  177. mask: true
  178. });
  179. const ctx = uni.createCanvasContext('myCanvas');
  180. ctx.clearRect(0, 0, 0, 0);
  181. /**
  182. * 只能获取合法域名下的图片信息,本地调试无法获取
  183. *
  184. */
  185. ctx.fillStyle = '#fff';
  186. ctx.fillRect(0, 0, 750, 1150);
  187. uni.getImageInfo({
  188. src: arr2[0],
  189. success: function(res) {
  190. const WIDTH = res.width;
  191. const HEIGHT = res.height;
  192. // ctx.drawImage(arr2[0], 0, 0, WIDTH, 1050);
  193. ctx.drawImage(arr2[1], 0, 0, WIDTH, WIDTH);
  194. ctx.save();
  195. let r = 110;
  196. let d = r * 2;
  197. let cx = 480;
  198. let cy = 790;
  199. ctx.arc(cx + r, cy + r, r, 0, 2 * Math.PI);
  200. // ctx.clip();
  201. ctx.drawImage(arr2[2], cx, cy, d, d);
  202. ctx.restore();
  203. const CONTENT_ROW_LENGTH = 20;
  204. let [contentLeng, contentArray, contentRows] = that.textByteLength(store_name,
  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.setFontSize(36);
  214. ctx.setFillStyle('#000');
  215. // let contentHh = 36 * 1.5;
  216. let contentHh = 36;
  217. for (let m = 0; m < contentArray.length; m++) {
  218. if (m) {
  219. ctx.fillText(contentArray[m], 50, 1000 + contentHh * m + 18, 1100);
  220. } else {
  221. ctx.fillText(contentArray[m], 50, 1000 + contentHh * m, 1100);
  222. }
  223. }
  224. ctx.setTextAlign('left')
  225. ctx.setFontSize(72);
  226. ctx.setFillStyle('#DA4F2A');
  227. ctx.fillText(i18n.t(`¥`) + price, 40, 820 + contentHh);
  228. ctx.setTextAlign('left')
  229. ctx.setFontSize(36);
  230. ctx.setFillStyle('#999');
  231. if(ot_price){
  232. ctx.fillText(i18n.t(`推荐码 `) + ot_price, 50, 876 + contentHh);
  233. // var underline = function(ctx, text, x, y, size, color, thickness, offset) {
  234. // var width = ctx.measureText(text).width;
  235. // switch (ctx.textAlign) {
  236. // case "center":
  237. // x -= (width / 2);
  238. // break;
  239. // case "right":
  240. // x -= width;
  241. // break;
  242. // }
  243. // y += size + offset;
  244. // ctx.beginPath();
  245. // ctx.strokeStyle = color;
  246. // ctx.lineWidth = thickness;
  247. // ctx.moveTo(x, y);
  248. // ctx.lineTo(x + width, y);
  249. // ctx.stroke();
  250. // }
  251. // underline(ctx, i18n.t(`¥`) + ot_price, 55, 865, 36, '#999', 2, 0)
  252. }
  253. ctx.setTextAlign('left')
  254. ctx.setFontSize(28);
  255. ctx.setFillStyle('#999');
  256. ctx.fillText(i18n.t(`长按或扫描查看`), 490, 1030 + contentHh);
  257. ctx.draw(true, function() {
  258. uni.canvasToTempFilePath({
  259. canvasId: 'myCanvas',
  260. fileType: 'png',
  261. destWidth: WIDTH,
  262. destHeight: HEIGHT,
  263. success: function(res) {
  264. uni.hideLoading();
  265. successFn && successFn(res.tempFilePath);
  266. }
  267. })
  268. });
  269. },
  270. fail: function(err) {
  271. uni.hideLoading();
  272. that.Tips({
  273. title: i18n.t(`无法获取图片信息`)
  274. });
  275. }
  276. })
  277. },
  278. /**
  279. * 获取砍价/拼团海报
  280. * @param array arr2 海报素材 背景图
  281. * @param string store_name 素材文字
  282. * @param string price 价格
  283. * @param string ot_price 原始价格
  284. * @param function successFn 回调函数
  285. *
  286. *
  287. */
  288. bargainPosterCanvas: function(arr2, title, label, msg, price, wd, hg, successFn) {
  289. let that = this;
  290. const ctx = uni.createCanvasContext('myCanvas');
  291. ctx.clearRect(0, 0, 0, 0);
  292. /**
  293. * 只能获取合法域名下的图片信息,本地调试无法获取
  294. *
  295. */
  296. ctx.fillStyle = '#fff';
  297. ctx.fillRect(0, 0, wd * 2, hg * 2);
  298. uni.getImageInfo({
  299. src: arr2[0],
  300. success: function(res) {
  301. const WIDTH = res.width;
  302. const HEIGHT = res.height;
  303. ctx.drawImage(arr2[0], 0, 0, wd, hg);
  304. // 保证在不同机型对应坐标准确
  305. let labelx = 0.6500 //标签x
  306. let labely = 0.166 //标签y
  307. let pricex = 0.1857 //价格x
  308. let pricey = 0.180 //价格x
  309. let codex = 0.385 //二维码
  310. let codey = 0.77
  311. let picturex = 0.1571 //商品图左上点
  312. let picturey = 0.2916
  313. let picturebx = 0.6857 //商品图右下点
  314. let pictureby = 0.4316
  315. let msgx = 0.1036 //msg
  316. let msgy = 0.2306
  317. let codew = 0.25
  318. ctx.drawImage(arr2[1], wd * picturex, hg * picturey, wd * picturebx, hg * pictureby);
  319. ctx.drawImage(arr2[2], wd * codex, hg * codey, wd * codew, wd * codew);
  320. ctx.save();
  321. //标题
  322. const CONTENT_ROW_LENGTH = 30;
  323. let [contentLeng, contentArray, contentRows] = that.textByteLength(title,
  324. CONTENT_ROW_LENGTH);
  325. if (contentRows > 2) {
  326. contentRows = 2;
  327. let textArray = contentArray.slice(0, 2);
  328. textArray[textArray.length - 1] += '…';
  329. contentArray = textArray;
  330. }
  331. ctx.setTextAlign('left');
  332. ctx.setFillStyle('#000');
  333. if (contentArray.length < 2) {
  334. ctx.setFontSize(22);
  335. } else {
  336. ctx.setFontSize(20);
  337. }
  338. let contentHh = 8;
  339. for (let m = 0; m < contentArray.length; m++) {
  340. if (m) {
  341. ctx.fillText(contentArray[m], 20, 35 + contentHh * m + 18, 1100);
  342. } else {
  343. ctx.fillText(contentArray[m], 20, 35, 1100);
  344. }
  345. }
  346. // 标签内容
  347. ctx.setTextAlign('left')
  348. ctx.setFontSize(16);
  349. ctx.setFillStyle('#FFF');
  350. ctx.fillText(label, wd * labelx, hg * labely);
  351. ctx.save();
  352. // 价格
  353. ctx.setFillStyle('red');
  354. ctx.setFontSize(26);
  355. ctx.fillText(price, wd * pricex, hg * pricey);
  356. ctx.save();
  357. // msg
  358. ctx.setFillStyle('#333');
  359. ctx.setFontSize(16);
  360. ctx.fillText(msg, wd * msgx, hg * msgy);
  361. ctx.save();
  362. ctx.draw(true, () => {
  363. uni.canvasToTempFilePath({
  364. canvasId: 'myCanvas',
  365. fileType: 'png',
  366. quality: 1,
  367. success: (res) => {
  368. successFn && successFn(res.tempFilePath);
  369. uni.hideLoading();
  370. }
  371. })
  372. });
  373. },
  374. fail: function(err) {
  375. uni.hideLoading();
  376. that.Tips({
  377. title: i18n.t(`无法获取图片信息`)
  378. });
  379. }
  380. })
  381. },
  382. /**
  383. * 用户信息分享海报
  384. * @param array arr2 海报素材 1背景 0二维码
  385. * @param string nickname 昵称
  386. * @param string sitename 价格
  387. * @param function successFn 回调函数
  388. *
  389. *
  390. */
  391. userPosterCanvas: function(arr2, nickname, sitename, index, w, h, successFn) {
  392. let that = this;
  393. const ctx = uni.createCanvasContext('myCanvas' + index);
  394. ctx.clearRect(0, 0, 0, 0);
  395. /**
  396. * 只能获取合法域名下的图片信息,本地调试无法获取
  397. *
  398. */
  399. uni.getImageInfo({
  400. src: arr2[1],
  401. success: function(res) {
  402. const WIDTH = res.width;
  403. const HEIGHT = res.height;
  404. ctx.fillStyle = '#fff';
  405. ctx.fillRect(0, 0, w, h);
  406. ctx.drawImage(arr2[1], 0, 0, w, h);
  407. ctx.setTextAlign('left')
  408. ctx.setFontSize(12);
  409. ctx.setFillStyle('#333');
  410. // x:240 y:426
  411. let codex = 0.1906
  412. let codey = 0.7746
  413. let codeSize = 0.21666
  414. let namex = 0.4283
  415. let namey = 0.8215
  416. let markx = 0.4283
  417. let marky = 0.8685
  418. ctx.drawImage(arr2[0], w * codex, h * codey, w * codeSize, w * codeSize);
  419. if (w < 270) {
  420. ctx.setFontSize(8);
  421. } else {
  422. ctx.setFontSize(10);
  423. }
  424. ctx.fillText(nickname, w * namex, h * namey);
  425. if (w < 270) {
  426. ctx.setFontSize(8);
  427. } else {
  428. ctx.setFontSize(10);
  429. }
  430. ctx.fillText(i18n.t(`邀请您加入`) + sitename, w * markx, h * marky);
  431. ctx.save();
  432. ctx.draw(true, function() {
  433. uni.canvasToTempFilePath({
  434. canvasId: 'myCanvas' + index,
  435. fileType: 'png',
  436. quality: 1,
  437. success: function(res) {
  438. successFn && successFn(res.tempFilePath);
  439. }
  440. })
  441. });
  442. },
  443. fail: function(err) {
  444. uni.hideLoading();
  445. that.Tips({
  446. title: i18n.t(`无法获取图片信息`)
  447. });
  448. }
  449. })
  450. },
  451. /*
  452. * 单图上传
  453. * @param object opt
  454. * @param callable successCallback 成功执行方法 data
  455. * @param callable errorCallback 失败执行方法
  456. */
  457. uploadImageOne: function(opt, successCallback, errorCallback) {
  458. let that = this;
  459. if (typeof opt === 'string') {
  460. let url = opt;
  461. opt = {};
  462. opt.url = url;
  463. }
  464. let count = opt.count || 1,
  465. sizeType = opt.sizeType || ['compressed'],
  466. sourceType = opt.sourceType || ['album', 'camera'],
  467. is_load = opt.is_load || true,
  468. uploadUrl = opt.url || '',
  469. inputName = opt.name || 'pics',
  470. fileType = opt.fileType || 'image';
  471. uni.chooseImage({
  472. count: count, //最多可以选择的图片总数
  473. sizeType: sizeType, // 可以指定是原图还是压缩图,默认二者都有
  474. sourceType: sourceType, // 可以指定来源是相册还是相机,默认二者都有
  475. success: function(res) {
  476. //启动上传等待中...
  477. uni.showLoading({
  478. title: i18n.t(`图片上传中`),
  479. });
  480. uni.uploadFile({
  481. url: HTTP_REQUEST_URL + UPLOAD_URL,
  482. filePath: res.tempFilePaths[0],
  483. fileType: fileType,
  484. name: inputName,
  485. formData: {
  486. 'filename': inputName
  487. },
  488. header: {
  489. // #ifdef MP
  490. "Content-Type": "multipart/form-data",
  491. // #endif
  492. [TOKENNAME]: 'Bearer ' + store.state.app.token
  493. },
  494. success: function(res) {
  495. uni.hideLoading();
  496. if (res.statusCode === 403) {
  497. that.Tips({
  498. title: res.data
  499. });
  500. } else {
  501. let data = res.data ? JSON.parse(res.data) : {};
  502. if (data.code === 200) {
  503. successCallback && successCallback(data)
  504. } else {
  505. errorCallback && errorCallback(data);
  506. that.Tips({
  507. title: data.msg
  508. });
  509. }
  510. }
  511. },
  512. fail: function(res) {
  513. uni.hideLoading();
  514. that.Tips({
  515. title: i18n.t(`上传图片失败`)
  516. });
  517. }
  518. })
  519. }
  520. })
  521. },
  522. /**
  523. * 头像上传
  524. */
  525. weixinAvatarUpload:function(url,successCallback, errorCallback){
  526. uni.uploadFile({
  527. url: HTTP_REQUEST_URL + UPLOAD_URL,
  528. filePath: url,
  529. fileType: 'image',
  530. name: 'file',
  531. header: {
  532. // #ifdef MP
  533. "Content-Type": "multipart/form-data",
  534. // #endif
  535. [TOKENNAME]: 'Bearer ' + store.state.app.token
  536. },
  537. success: function(res) {
  538. uni.hideLoading();
  539. if (res.statusCode === 403) {
  540. that.Tips({
  541. title: res.data
  542. });
  543. } else {
  544. let data = res.data ? JSON.parse(res.data) : {};
  545. if (data.code === 200) {
  546. successCallback && successCallback(data)
  547. } else {
  548. errorCallback && errorCallback(data);
  549. that.Tips({
  550. title: data.msg
  551. });
  552. }
  553. }
  554. },
  555. fail: function(res) {
  556. uni.hideLoading();
  557. that.Tips({
  558. title: i18n.t(`上传图片失败`)
  559. });
  560. }
  561. })
  562. },
  563. /*
  564. * 单图上传压缩版
  565. * @param object opt
  566. * @param callable successCallback 成功执行方法 data
  567. * @param callable errorCallback 失败执行方法
  568. */
  569. uploadImageChange: function(opt, successCallback, errorCallback, sizeCallback) {
  570. let that = this;
  571. if (typeof opt === 'string') {
  572. let url = opt;
  573. opt = {};
  574. opt.url = url;
  575. }
  576. let count = opt.count || 1,
  577. sizeType = opt.sizeType || ['compressed'],
  578. sourceType = opt.sourceType || ['album', 'camera'],
  579. is_load = opt.is_load || true,
  580. uploadUrl = opt.url || '',
  581. inputName = opt.name || 'pics',
  582. fileType = opt.fileType || 'image';
  583. uni.chooseImage({
  584. count: count, //最多可以选择的图片总数
  585. sizeType: sizeType, // 可以指定是原图还是压缩图,默认二者都有
  586. sourceType: sourceType, // 可以指定来源是相册还是相机,默认二者都有
  587. success: function(res) {
  588. //启动上传等待中...
  589. let imgSrc
  590. uni.getImageInfo({
  591. src: res.tempFilePaths[0],
  592. success(ress) {
  593. uni.showLoading({
  594. title: i18n.t(`图片上传中`),
  595. });
  596. if (res.tempFiles[0].size <= 2097152) {
  597. uploadImg(ress.path)
  598. return
  599. }
  600. // uploadImg(canvasPath.tempFilePath)
  601. let canvasWidth, canvasHeight, xs, maxWidth = 750
  602. xs = ress.width / ress.height // 宽高比例
  603. if (ress.width > maxWidth) {
  604. canvasWidth = maxWidth // 这里是最大限制宽度
  605. canvasHeight = maxWidth / xs
  606. } else {
  607. canvasWidth = ress.width
  608. canvasHeight = ress.height
  609. }
  610. sizeCallback && sizeCallback({
  611. w: canvasWidth,
  612. h: canvasHeight
  613. })
  614. let canvas = uni.createCanvasContext('canvas');
  615. canvas.width = canvasWidth
  616. canvas.height = canvasHeight
  617. canvas.clearRect(0, 0, canvasWidth, canvasHeight);
  618. canvas.drawImage(ress.path, 0, 0, canvasWidth, canvasHeight)
  619. canvas.save();
  620. // 这里的画布drawImage是一种异步属性 可能存在未绘制全就执行了draw的问题 so添加延迟
  621. setTimeout(e => {
  622. canvas.draw(true, () => {
  623. uni.canvasToTempFilePath({
  624. canvasId: 'canvas',
  625. fileType: 'JPEG',
  626. destWidth: canvasWidth,
  627. destHeight: canvasHeight,
  628. quality: 0.7,
  629. success: function(canvasPath) {
  630. uploadImg(canvasPath
  631. .tempFilePath)
  632. }
  633. })
  634. });
  635. }, 200)
  636. }
  637. })
  638. }
  639. })
  640. function uploadImg(filePath) {
  641. uni.uploadFile({
  642. url: HTTP_REQUEST_URL + '/api/' + uploadUrl,
  643. filePath,
  644. fileType: fileType,
  645. name: inputName,
  646. formData: {
  647. 'filename': inputName
  648. },
  649. header: {
  650. // #ifdef MP
  651. "Content-Type": "multipart/form-data",
  652. // #endif
  653. [TOKENNAME]: 'Bearer ' + store.state.app.token
  654. },
  655. success: function(res) {
  656. uni.hideLoading();
  657. if (res.statusCode == 403) {
  658. that.Tips({
  659. title: res.data
  660. });
  661. } else {
  662. let data = res.data ? JSON.parse(res.data) : {};
  663. if (data.status == 200) {
  664. successCallback && successCallback(data)
  665. } else {
  666. errorCallback && errorCallback(data);
  667. that.Tips({
  668. title: data.msg
  669. });
  670. }
  671. }
  672. },
  673. fail: function(res) {
  674. uni.hideLoading();
  675. that.Tips({
  676. title: i18n.t(`上传图片失败`)
  677. });
  678. }
  679. })
  680. }
  681. },
  682. /**
  683. * 处理服务器扫码带进来的参数
  684. * @param string param 扫码携带参数
  685. * @param string k 整体分割符 默认为:&
  686. * @param string p 单个分隔符 默认为:=
  687. * @return object
  688. *
  689. */
  690. // #ifdef MP
  691. getUrlParams: function(param, k, p) {
  692. if (typeof param != 'string') return {};
  693. k = k ? k : '&'; //整体参数分隔符
  694. p = p ? p : '='; //单个参数分隔符
  695. var value = {};
  696. if (param.indexOf(k) !== -1) {
  697. param = param.split(k);
  698. for (var val in param) {
  699. if (param[val].indexOf(p) !== -1) {
  700. var item = param[val].split(p);
  701. value[item[0]] = item[1];
  702. }
  703. }
  704. } else if (param.indexOf(p) !== -1) {
  705. var item = param.split(p);
  706. value[item[0]] = item[1];
  707. } else {
  708. return param;
  709. }
  710. return value;
  711. },
  712. // #endif
  713. /*
  714. * 合并数组
  715. */
  716. SplitArray(list, sp) {
  717. if (typeof list != 'object') return [];
  718. if (sp === undefined) sp = [];
  719. for (var i = 0; i < list.length; i++) {
  720. sp.push(list[i]);
  721. }
  722. return sp;
  723. },
  724. trim(backUrlCRshlcICwGdGY) {
  725. return String.prototype.trim.call(backUrlCRshlcICwGdGY);
  726. },
  727. $h: {
  728. //除法函数,用来得到精确的除法结果
  729. //说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
  730. //调用:$h.Div(arg1,arg2)
  731. //返回值:arg1除以arg2的精确结果
  732. Div: function(arg1, arg2) {
  733. arg1 = parseFloat(arg1);
  734. arg2 = parseFloat(arg2);
  735. var t1 = 0,
  736. t2 = 0,
  737. r1, r2;
  738. try {
  739. t1 = arg1.toString().split(".")[1].length;
  740. } catch (e) {}
  741. try {
  742. t2 = arg2.toString().split(".")[1].length;
  743. } catch (e) {}
  744. r1 = Number(arg1.toString().replace(".", ""));
  745. r2 = Number(arg2.toString().replace(".", ""));
  746. return this.Mul(r1 / r2, Math.pow(10, t2 - t1));
  747. },
  748. //加法函数,用来得到精确的加法结果
  749. //说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
  750. //调用:$h.Add(arg1,arg2)
  751. //返回值:arg1加上arg2的精确结果
  752. Add: function(arg1, arg2) {
  753. arg2 = parseFloat(arg2);
  754. var r1, r2, m;
  755. try {
  756. r1 = arg1.toString().split(".")[1].length
  757. } catch (e) {
  758. r1 = 0
  759. }
  760. try {
  761. r2 = arg2.toString().split(".")[1].length
  762. } catch (e) {
  763. r2 = 0
  764. }
  765. m = Math.pow(100, Math.max(r1, r2));
  766. return (this.Mul(arg1, m) + this.Mul(arg2, m)) / m;
  767. },
  768. //减法函数,用来得到精确的减法结果
  769. //说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的减法结果。
  770. //调用:$h.Sub(arg1,arg2)
  771. //返回值:arg1减去arg2的精确结果
  772. Sub: function(arg1, arg2) {
  773. arg1 = parseFloat(arg1);
  774. arg2 = parseFloat(arg2);
  775. var r1, r2, m, n;
  776. try {
  777. r1 = arg1.toString().split(".")[1].length
  778. } catch (e) {
  779. r1 = 0
  780. }
  781. try {
  782. r2 = arg2.toString().split(".")[1].length
  783. } catch (e) {
  784. r2 = 0
  785. }
  786. m = Math.pow(10, Math.max(r1, r2));
  787. //动态控制精度长度
  788. n = (r1 >= r2) ? r1 : r2;
  789. return ((this.Mul(arg1, m) - this.Mul(arg2, m)) / m).toFixed(n);
  790. },
  791. //乘法函数,用来得到精确的乘法结果
  792. //说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
  793. //调用:$h.Mul(arg1,arg2)
  794. //返回值:arg1乘以arg2的精确结果
  795. Mul: function(arg1, arg2) {
  796. arg1 = parseFloat(arg1);
  797. arg2 = parseFloat(arg2);
  798. var m = 0,
  799. s1 = arg1.toString(),
  800. s2 = arg2.toString();
  801. try {
  802. m += s1.split(".")[1].length
  803. } catch (e) {}
  804. try {
  805. m += s2.split(".")[1].length
  806. } catch (e) {}
  807. return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
  808. },
  809. },
  810. // 获取地理位置;
  811. $L: {
  812. async getLocation() {
  813. // #ifdef APP-PLUS
  814. let status = await this.checkPermission();
  815. if (status !== 1) {
  816. return;
  817. }
  818. // #endif
  819. // #ifdef MP-WEIXIN || MP-TOUTIAO || MP-QQ
  820. let status = await this.getSetting();
  821. if (status === 2) {
  822. this.openSetting();
  823. return;
  824. }
  825. // #endif
  826. this.doGetLocation();
  827. },
  828. doGetLocation() {
  829. uni.getLocation({
  830. success: (res) => {
  831. uni.removeStorageSync('CACHE_LONGITUDE');
  832. uni.removeStorageSync('CACHE_LATITUDE');
  833. uni.setStorageSync('CACHE_LONGITUDE', res.longitude);
  834. uni.setStorageSync('CACHE_LATITUDE', res.latitude);
  835. },
  836. fail: (err) => {
  837. // #ifdef MP-BAIDU
  838. if (err.errCode === 202 || err.errCode === 10003) { // 202模拟器 10003真机 user deny
  839. this.openSetting();
  840. }
  841. // #endif
  842. // #ifndef MP-BAIDU
  843. if (err.errMsg.indexOf("auth deny") >= 0) {
  844. uni.showToast({
  845. title: i18n.t(`访问位置被拒绝`)
  846. })
  847. } else {
  848. uni.showToast({
  849. title: err.errMsg
  850. })
  851. }
  852. // #endif
  853. }
  854. })
  855. },
  856. getSetting: function() {
  857. return new Promise((resolve, reject) => {
  858. uni.getSetting({
  859. success: (res) => {
  860. if (res.authSetting['scope.userLocation'] === undefined) {
  861. resolve(0);
  862. return;
  863. }
  864. if (res.authSetting['scope.userLocation']) {
  865. resolve(1);
  866. } else {
  867. resolve(2);
  868. }
  869. }
  870. });
  871. });
  872. },
  873. openSetting: function() {
  874. uni.openSetting({
  875. success: (res) => {
  876. if (res.authSetting && res.authSetting['scope.userLocation']) {
  877. this.doGetLocation();
  878. }
  879. },
  880. fail: (err) => {}
  881. })
  882. },
  883. async checkPermission() {
  884. let status = permision.isIOS ? await permision.requestIOS('location') :
  885. await permision.requestAndroid('android.permission.ACCESS_FINE_LOCATION');
  886. if (status === null || status === 1) {
  887. status = 1;
  888. } else if (status === 2) {
  889. uni.showModal({
  890. content: i18n.t(`系统定位已关闭`),
  891. confirmText: i18n.t(`确定`),
  892. showCancel: false,
  893. success: function(res) {}
  894. })
  895. } else if (status.code) {
  896. uni.showModal({
  897. content: status.message
  898. })
  899. } else {
  900. uni.showModal({
  901. content: i18n.t(`需要定位权限`),
  902. confirmText: i18n.t(`确定`),
  903. success: function(res) {
  904. if (res.confirm) {
  905. permision.gotoAppSetting();
  906. }
  907. }
  908. })
  909. }
  910. return status;
  911. },
  912. }
  913. }