utils.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. import { Linking, Platform } from "react-native";
  2. import { showLocation } from 'react-native-map-link'
  3. import { host } from '../api/http';
  4. import apiUser from "../api/apiUser";
  5. import { getStorageSync, setStorage } from "./storage";
  6. import { PERMISSIONS } from "react-native-permissions";
  7. import app from '../../app.json';
  8. import { PageList } from "../pages/Router";
  9. import analytics from '@react-native-firebase/analytics';
  10. import crashlytics from '@react-native-firebase/crashlytics';
  11. /**
  12. * 工具集
  13. * @邠心vbe on 2021/04/20
  14. */
  15. const formatNumber = (n) => {
  16. n = n.toString()
  17. return n[1] ? n : '0' + n
  18. }
  19. export default {
  20. getDistance(dis) {
  21. if (dis) {
  22. if (dis > 1000) {
  23. return Number((dis / 1000).toFixed(1)) + 'km';
  24. } else {
  25. return dis + 'm';
  26. }
  27. } else {
  28. return 'NA';
  29. }
  30. },
  31. directMaps(lat, lng, address) {
  32. if (isIOS) {
  33. showLocation({
  34. latitude: lat,
  35. longitude: lng,
  36. title: address,
  37. dialogMessage: "",
  38. googleForceLatLon: true
  39. }).catch(erros => {
  40. console.warn("directMaps", erros);
  41. });
  42. } else {
  43. var uri = "geo:" + lat + "," + lng + "?q=" + lat + "," + lng + "(" + address + ")";
  44. Linking.openURL(uri).catch(erros => {
  45. console.warn("directMaps", erros);
  46. });
  47. }
  48. },
  49. getSiteInfo(obj) {
  50. if (obj) {
  51. const acRates = [], dcRates = [];
  52. obj?.rates.forEach((item) => {
  53. if (item.type?.indexOf('AC') >= 0) {
  54. acRates.push(item)
  55. } else {
  56. dcRates.push(item)
  57. }
  58. })
  59. return {
  60. id: obj.sitePk,
  61. name: obj.siteName,
  62. address: obj.siteAddress,
  63. latitude: obj.locationLatitude,
  64. longitude: obj.locationLongitude,
  65. acConnector: obj.acConnector,
  66. allConnector: obj.allConnector,
  67. dcConnector: obj.dcConnector,
  68. distance: this.getDistance(obj.distance),
  69. favorite: obj.favorite,
  70. acRates: acRates,
  71. dcRates: dcRates,
  72. idleFee: obj.idleDetail,
  73. labels: obj.siteLabels,
  74. upcoming: obj.upcoming,
  75. rateList: obj.rates,
  76. siteType: obj.siteType,
  77. parkingFee: obj.parkingFee,
  78. hasDiscount: obj.hasDiscount,
  79. parkingFeeFree: obj.free,
  80. operatingHours: obj.operatingHours,
  81. additionalNotes: obj.additionalNotes,
  82. endlessService: obj.endlessService,
  83. serviceProvider: obj.serviceProvider,
  84. enableReservation: obj.enableReservation,
  85. payPerUseAmount: obj.payPerUseAmount
  86. }
  87. } else {
  88. return {id: 0}
  89. }
  90. },
  91. getNowHHmm() {
  92. const now = new Date();
  93. var month = now.getHours();
  94. var minute = now.getMinutes();
  95. return [month, minute].map(formatNumber).join(':');
  96. },
  97. getYYMMdd(date) {
  98. var year = date.getFullYear()
  99. var month = date.getMonth() + 1
  100. var day = date.getDate()
  101. //var hour = date.getHours()
  102. //var minute = date.getMinutes()
  103. //var second = date.getSeconds()
  104. return [year, month, day].map(formatNumber).join('/')
  105. },
  106. formatYYMM(date) {
  107. var year = date.getFullYear()
  108. var month = date.getMonth() + 1
  109. return [year, month].map(formatNumber).join('-')
  110. },
  111. hour2HHmm(hour) {
  112. if (hour) {
  113. if (hour > 0) {
  114. const h = parseInt(hour);
  115. const m = (hour - h) * 60;
  116. return h + ' hr ' + parseInt(m) + 'min';
  117. } else {
  118. const m = hour * 60;
  119. return parseInt(m) + 'min';
  120. }
  121. } else {
  122. return '0 min';
  123. }
  124. },
  125. minutes2HHmm(minutes) {
  126. if (minutes) {
  127. const m = Number(minutes);
  128. if (m > 60) {
  129. const h = m / 60;
  130. const mm = m % 60;
  131. return parseInt(h) + ' hr ' + parseInt(mm) + ' min';
  132. } else {
  133. return parseInt(minutes) + ' min';
  134. }
  135. } else {
  136. return '0 min';
  137. }
  138. },
  139. minutes2HHMM(minutes) {
  140. if (minutes) {
  141. const m = Number(minutes);
  142. if (m > 60) {
  143. const h = m / 60;
  144. const mm = m % 60;
  145. if (h >= 24) {
  146. const hh = h % 24;
  147. const d = h / 24;
  148. return parseInt(d) + "d " + formatNumber(parseInt(hh)) + ':' + formatNumber(parseInt(mm));
  149. } else {
  150. return formatNumber(parseInt(h)) + ':' + formatNumber(parseInt(mm));
  151. }
  152. } else {
  153. return '00:' + formatNumber(parseInt(minutes));
  154. }
  155. } else {
  156. return '00:00';
  157. }
  158. },
  159. /**
  160. * 判断指定对象是否为空
  161. * @param {*} str 判定对象(字符串、数字、JSON)
  162. * @param {Boolean} encNo 是否判定数字(为true则数字0判定为空)
  163. */
  164. isEmpty(str, encNo=false) {
  165. if (typeof str == 'number') {
  166. if (encNo) {
  167. return str === 0;
  168. } else {
  169. return false;
  170. }
  171. } else if (str) {
  172. if (typeof str == 'object') {
  173. return Object.keys(str).length == 0;
  174. } else if (Array.isArray(str)) {
  175. return str.length == 0;
  176. } else {
  177. if (str == undefined || str == null || str == "")
  178. return true;
  179. return false;
  180. }
  181. } else {
  182. return true;
  183. }
  184. },
  185. isNotEmpty(str, encNo) {
  186. return !this.isEmpty(str, encNo);
  187. },
  188. getParamsFromUrl(url) {
  189. var params = {}
  190. const list = url.split('&');
  191. for (let item of list) {
  192. if (item.indexOf('=') > 0) {
  193. const param = item.split('=');
  194. if (param.length == 2)
  195. params[param[0]] = param[1];
  196. }
  197. }
  198. return params;
  199. },
  200. /**
  201. * 将数组以指定分隔符组装为字符串
  202. * @param {Array} arrays 源数组
  203. * @param {String} spect 分隔符
  204. */
  205. join(arrays=[], spect="") {
  206. let str = ''
  207. if (arrays) {
  208. arrays.forEach((item, index) => {
  209. if (index == 0) {
  210. str += item;
  211. } else {
  212. str += spect + item;
  213. }
  214. });
  215. }
  216. return str;
  217. },
  218. /**
  219. * 将给定数字保留任意位小数
  220. * @param {number} text 源数字
  221. * @param {number} scape 小数位
  222. * @returns 小数
  223. */
  224. toFixed(text, scape) {
  225. if (text) {
  226. return Number(Number(text).toFixed(scape));
  227. } else {
  228. return text;
  229. }
  230. },
  231. /**
  232. * 16进制颜色转为RGB
  233. * @param {*} value 16进制颜色
  234. * @returns {Array} RGB数据
  235. */
  236. hexColorToRgb(value) {
  237. let sColor = value.toLowerCase()
  238. if (sColor && sColor.indexOf("#") >= 0) {
  239. if (sColor.length === 4) {
  240. let sColorNew = '#'
  241. for (let i = 1; i < 4; i += 1) {
  242. sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
  243. }
  244. sColor = sColorNew
  245. }
  246. // 处理1+6位的颜色值
  247. let sColorChange = []
  248. for (let i = 1; i < 7; i += 2) {
  249. sColorChange.push(parseInt('0x' + sColor.slice(i, i + 2)))
  250. }
  251. return sColorChange;//'rgb(' + sColorChange.join(',') + ')'
  252. } else if (sColor && sColor.indexOf("0x") >= 0) {
  253. if (sColor.length === 4) {
  254. let sColorNew = '0x'
  255. for (let i = 1; i < 4; i += 1) {
  256. sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
  257. }
  258. sColor = sColorNew
  259. }
  260. // 处理2+6位的颜色值
  261. let sColorChange = []
  262. for (let i = 2; i < 8; i += 2) {
  263. sColorChange.push(parseInt('0x' + sColor.slice(i, i + 2)))
  264. }
  265. return sColorChange;//'rgb(' + sColorChange.join(',') + ')'
  266. }
  267. return sColor
  268. },
  269. /**
  270. * 给颜色值添加透明度
  271. * @param {Array} colors 10进制颜色
  272. * @param {Number} alpha 透明度(0-1)
  273. */
  274. getRgbaColor(colors, alpha=1) {
  275. if (colors.length == 3) {
  276. return "rgba(" + this.join(colors, ",") + "," +alpha + ")";
  277. }
  278. },
  279. /**
  280. * 注册FCM通知token
  281. * @param {String} token 原始保存的Firebase令牌
  282. * @param {Function} back 执行结果(boolean)
  283. */
  284. async registerFirebaseToken(token, back) {
  285. const thisDate = this.formatYYMM(new Date()) + "-" + getUserId();
  286. const lastDate = await getStorageSync('RegisterTokenDate');
  287. console.log('>>>RegisterToken<<<', thisDate, lastDate + "●");
  288. if (thisDate != lastDate || token != notifyToken.token) {
  289. const params = {
  290. os: isIOS ? "ios": "android",
  291. googleToken: notifyToken.token
  292. }
  293. apiUser.setNotifyToken(params).then(res => {
  294. console.log('>>>RegisterToken-Suc<<<', res);
  295. setStorage('RegisterTokenDate', thisDate);
  296. if (back) back(true);
  297. }).catch(err => {
  298. console.log('>>>RegisterToken-Err<<<', err);
  299. if (back) back(false);
  300. });
  301. } else {
  302. if (back) back(false);
  303. }
  304. },
  305. setBackClick(routeNames, func) {
  306. global.pageBackFallback = {
  307. names: routeNames,
  308. callback: func
  309. }
  310. },
  311. getImageUrl(path) {
  312. if (path && path.indexOf("http") >= 0) {
  313. return path;
  314. } else {
  315. return host + path;
  316. }
  317. },
  318. getFilePermissionString() {
  319. if (Platform.Version >= 33) {
  320. return PERMISSIONS.ANDROID.READ_MEDIA_IMAGES;
  321. } else {
  322. return PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE;
  323. }
  324. },
  325. toChargeDetailPage(sitePk, action, form) {
  326. if (app.charge.version == 1) {
  327. startPage(PageList.chargeDetail, { stationInfo: {id: sitePk}, action: action, from: form});
  328. } else {
  329. startPage(PageList.chargeDetailPage, {stationInfo: {id: sitePk}, action: action, from: form});
  330. }
  331. },
  332. toChargingPage(connectorInfo) {
  333. startPage(app.charge.version == 4 ? PageList.chargingPageV4 : PageList.chargingPage, connectorInfo);
  334. },
  335. /**
  336. * 校验邮箱是否合法
  337. * @param {String} email 邮箱地址
  338. * @returns {Boolean}
  339. */
  340. isValidEmail(email) {
  341. const pattern = /^[a-zA-Z0-9]+[\S]*@[a-zA-Z0-9_-]+[\.][\Sa-zA-Z]+$/
  342. return pattern.test(email)
  343. },
  344. logEventTracking(event, message="") {
  345. if (app.debug && event && message) {
  346. console.log("已记录事件跟踪", event, message);
  347. if (!app.product) {
  348. analytics().logEvent("event_" + event, {
  349. message: message
  350. });
  351. }
  352. if (message) {
  353. crashlytics().log(event + ": " + message);
  354. } else {
  355. crashlytics().log(event);
  356. }
  357. }
  358. }
  359. }