tools.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. let carmera = uni.requireNativePlugin('uniplugin_camerascan')
  2. let cameraModule = uni.requireNativePlugin("SMUniPlugin-CameraModule")
  3. export function objToUrl(obj) {
  4. let uri = '';
  5. let keys = Object.keys(obj);
  6. keys.forEach(item => {
  7. uri += '&' + item + '=' + obj[item];
  8. });
  9. uri = uri.substr(1);
  10. return uri;
  11. }
  12. // 节流函数
  13. export function throttle(fn, gaptime) {
  14. if (gaptime == null || gaptime == undefined) {
  15. gaptime = 200
  16. }
  17. let _lastTime = null
  18. return function() {
  19. let _nowTime = +new Date()
  20. if (_nowTime - _lastTime > gaptime || !_lastTime) {
  21. fn.apply(this, arguments)
  22. _lastTime = _nowTime
  23. }
  24. }
  25. }
  26. // 图片转Base64,pad 平台
  27. export const imgToBase64 = function (path,callback){
  28. // plus.nativeUI.previewImage([path]);
  29. // return
  30. plus.io.resolveLocalFileSystemURL(path, function (entry) {
  31. // 可通过entry对象操作文件
  32. entry.file(function (file){
  33. var fileReader = new plus.io.FileReader()
  34. fileReader.readAsDataURL(file, 'utf-8')
  35. fileReader.onloadend = function (evt) {
  36. let result = evt.target.result
  37. callback(1,result.split(',')[1])
  38. // remove this file
  39. entry.remove( function ( entry ) {
  40. console.log( "Remove succeeded" );
  41. }, function ( e ) {
  42. console.log( e.message );
  43. });
  44. }
  45. fileReader.onerror = function (e){
  46. callback(0,'文件读取失败')
  47. }
  48. })
  49. }, function (e) {
  50. console.log(JSON.stringify(e))
  51. uni.showToast({icon: 'none',title: 'Resolve file URL failed: ' + e.message})
  52. })
  53. }
  54. // 打开摄像头
  55. export const openCamera = function (type,callback){
  56. let carNumberOptions = {
  57. widthRatio: 0.8,
  58. heightRatio: 0.3,
  59. showText: '请将车牌号码对准框中'
  60. }
  61. let carVinNumberOptions = {
  62. widthRatio: 1,
  63. heightRatio: 0.15,
  64. showText: '请将车辆VIN码对准框中'
  65. }
  66. let option = (type == 'searchCar' || type == 'carNumber') ? carNumberOptions : carVinNumberOptions
  67. // 竖屏 false,横屏 true
  68. let isLandscape = (type == 'searchCar' || type == 'carNumber') ? false : true
  69. //安卓摄像头
  70. if(uni.getSystemInfoSync().platform === 'android'){
  71. carmera.show(option,function(result){
  72. callback(result)
  73. })
  74. }
  75. // ios 摄像头
  76. if(uni.getSystemInfoSync().platform == 'ios'){
  77. let screenWidth = uni.getSystemInfoSync().screenWidth
  78. let screenHeight = uni.getSystemInfoSync().screenHeight
  79. let [w,h,x,y] = [0,0,0,0]
  80. // 横屏
  81. if(isLandscape){
  82. h = screenWidth*option.widthRatio*1.2
  83. w = screenHeight*option.heightRatio
  84. x = (screenWidth - w)/2
  85. y = (screenHeight - h)/2
  86. }else{
  87. // 竖屏
  88. w = screenWidth*option.widthRatio*0.9
  89. h = screenHeight*option.heightRatio
  90. x = (screenWidth - w)/2
  91. y = (screenHeight - h)/2 - 50
  92. }
  93. cameraModule.showCamera({
  94. 'showTitle': option.showText,
  95. 'size': [w, h],
  96. 'orign': [x, y],
  97. 'isLandscape': isLandscape
  98. },
  99. (result) => {
  100. callback({path:'file://'+result})
  101. })
  102. }
  103. }
  104. /**
  105. * @param {*} obj1 对象
  106. * @param {*} obj2 对象
  107. * @description 遍历赋值
  108. */
  109. export const objExtend = (obj1, obj2) => {
  110. for (let a in obj1){
  111. obj2[a] = obj1[a]
  112. }
  113. return obj2
  114. }
  115. // 正则验证车牌,验证通过返回true,不通过返回false
  116. export const isLicensePlate = function (str) {
  117. return /^(([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z](([0-9]{5}[DF])|([DF]([A-HJ-NP-Z0-9])[0-9]{4})))|([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳使领]))$/.test(str)
  118. }
  119. /**
  120. * 校验身份证号合法性
  121. */
  122. export const checkIdNumberValid = (tex) => {
  123. // var tip = '输入的身份证号有误,请检查后重新输入!'
  124. let num = tex
  125. num = num.toUpperCase()
  126. let len = num.length
  127. let re
  128. if (len == 0) return true
  129. // 身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X。
  130. if (!(/(^\d{15}$)|(^\d{17}([0-9]|X)$)/.test(num))){
  131. return false
  132. }
  133. // 验证前两位地区是否有效
  134. let aCity = {11: '北京',12: '天津',13: '河北',14: '山西',15: '内蒙古',21: '辽宁',22: '吉林',23: '黑龙江',31: '上海',32: '江苏',33: '浙江',
  135. 34: '安徽',35: '福建',36: '江西',37: '山东',41: '河南',42: '湖北',43: '湖南',44: '广东',45: '广西',46: '海南',50: '重庆',51: '四川',
  136. 52: '贵州',53: '云南',54: '西藏',61: '陕西',62: '甘肃',63: '青海',64: '宁夏',65: '新疆',71: '台湾',81: '香港',82: '澳门',91: '国外'}
  137. if (aCity[parseInt(num.substr(0, 2))] == null){
  138. return false
  139. }
  140. // 当身份证为15位时的验证出生日期。
  141. if (len == 15){
  142. re = new RegExp(/^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/)
  143. let arrSplit = num.match(re)
  144. // 检查生日日期是否正确
  145. let dtmBirth = new Date('19' + arrSplit[2] + '/' + arrSplit[3] + '/' + arrSplit[4])
  146. let bGoodDay = (dtmBirth.getYear() == Number(arrSplit[2])) && ((dtmBirth.getMonth() + 1) == Number(arrSplit[3])) && (dtmBirth.getDate() == Number(arrSplit[4]))
  147. if (!bGoodDay){
  148. return false
  149. }
  150. }
  151. // 当身份证号为18位时,校验出生日期和校验位。
  152. if (len == 18){
  153. re = new RegExp(/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/)
  154. let arrSplit = num.match(re)
  155. // 检查生日日期是否正确
  156. let dtmBirth = new Date(arrSplit[2] + '/' + arrSplit[3] + '/' + arrSplit[4])
  157. let bGoodDay = (dtmBirth.getFullYear() == Number(arrSplit[2])) && ((dtmBirth.getMonth() + 1) == Number(arrSplit[3])) && (dtmBirth.getDate() == Number(arrSplit[4]))
  158. if (!bGoodDay){
  159. return false
  160. } else {
  161. // 检验18位身份证的校验码是否正确。
  162. // 校验位按照ISO 7064:1983.MOD 11-2的规定生成,X可以认为是数字10。
  163. let valnum
  164. let arrInt = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
  165. let arrCh = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']
  166. let nTemp = 0
  167. let i
  168. for (i = 0; i < 17; i++){
  169. nTemp += num.substr(i, 1) * arrInt[i]
  170. }
  171. valnum = arrCh[nTemp % 11]
  172. if (valnum != num.substr(17, 1)){
  173. return false
  174. }
  175. }
  176. }
  177. return true
  178. }
  179. // 正则有效手机号码
  180. export const isvalidPhone = function (str) {
  181. const reg = /^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/
  182. return reg.test(str)
  183. }
  184. // 日期格式化
  185. export const formatSubmitDate = (val, type) => {
  186. if (val == null || val == '' || val == undefined) {
  187. return ''
  188. } else {
  189. let _date = new Date(val)
  190. let _year = _date.getFullYear()
  191. let _montn = (_date.getMonth() + 1) < 10 ? '0' + (_date.getMonth() + 1) : (_date.getMonth() + 1)
  192. let _day = _date.getDate() < 10 ? '0' + _date.getDate() : _date.getDate()
  193. let _hour = _date.getHours() < 10 ? '0' + _date.getHours() : _date.getHours()
  194. let _minutes = _date.getMinutes() < 10 ? '0' + _date.getMinutes() : _date.getMinutes()
  195. let _seconds = _date.getSeconds() < 10 ? '0' + _date.getSeconds() : _date.getSeconds()
  196. if (type == 'minutes') return _year + '-' + _montn + '-' + _day + ' ' + _hour + ':' + _minutes
  197. else if (type == 'seconds') return _year + '-' + _montn + '-' + _day + ' ' + _hour + ':' + _minutes + ':' + _seconds
  198. else return _year + '-' + _montn + '-' + _day
  199. }
  200. }
  201. /**
  202. * //设置应用版本号对应的缓存信息
  203. * @param {Object} currTimeStamp 当前获取的时间戳
  204. */
  205. export const setStorageForAppVersion = function(currTimeStamp){
  206. uni.setStorage({
  207. key: 'tip_version_update_time',
  208. data: currTimeStamp,
  209. success: function () {
  210. console.log('setStorage-success');
  211. }
  212. });
  213. }
  214. /**
  215. * 进行版本型号的比对 以及下载更新请求
  216. * @param {Object} server_version 服务器最新 应用版本号
  217. * @param {Object} curr_version 当前应用版本号
  218. * isQzgx 是否强制更新
  219. * market 打开应用市场
  220. */
  221. export const checkVersionToLoadUpdate = function(newVersion,type,market){
  222. console.log(newVersion)
  223. const curVer = getApp().globalData.version
  224. const server_version = newVersion.version
  225. const curr_version = curVer.versionCode
  226. const isQzgx = newVersion.forceUpgrade != 1
  227. let isWifi = plus.networkinfo.getCurrentType()!=3 ? '有新的版本发布,检测到您目前非Wifi连接,' : '有新的版本发布,'
  228. let msg = isWifi + (!isQzgx ? '请立即更新?' : '是否立即更新版本?')
  229. // 下载app并安装
  230. let downloadApp = function(downloadApkUrl){
  231. uni.showLoading({
  232. title: '正在更新中...',
  233. mask: true,
  234. });
  235. var dtask = plus.downloader.createDownload( downloadApkUrl, {}, function ( d, status ) {
  236. // 下载完成
  237. if ( status == 200 ) {
  238. plus.runtime.install(plus.io.convertLocalFileSystemURL(d.filename),{},{},function(error){
  239. uni.showToast({
  240. icon: 'none',
  241. title: '安装失败',
  242. duration: 1500
  243. });
  244. })
  245. uni.hideLoading()
  246. } else {
  247. uni.showToast({
  248. icon: 'none',
  249. title: '更新失败',
  250. duration: 1500
  251. });
  252. }
  253. });
  254. dtask.start();
  255. }
  256. // 打开ios 应用市场
  257. let openIosAppSotre = function(downloadUrl){
  258. //在App Store Connect中的App Store下的app信息,可找到appleId
  259. // let appleId= 111111111
  260. plus.runtime.launchApplication({
  261. // action: `itms-apps://itunes.apple.com/cn/app/id${appleId}?mt=8`
  262. action: downloadUrl
  263. }, function(e) {
  264. console.log('Open system default browser failed: ' + e.message);
  265. })
  266. }
  267. // 打开应用市场
  268. // const marketOpen = function(){
  269. // market.open({
  270. // ios:'',
  271. // android:'com.zyucgj.car'
  272. // });
  273. // }
  274. if(Number(server_version) > Number(curr_version)){
  275. // #ifndef APP-PLUS
  276. uni.showModal({
  277. title: msg,
  278. content: '更新内容:'+newVersion.upgradeContent,
  279. showCancel: isQzgx,
  280. confirmText:'立即更新',
  281. cancelText:'稍后进行',
  282. success: function (res) {
  283. if (res.confirm) {
  284. if(curVer.platform == 'android'){
  285. //设置 最新版本apk的下载链接
  286. downloadApp(newVersion.attachment);
  287. }else{
  288. openIosAppSotre(newVersion.downloadUrl)
  289. }
  290. // marketOpen()
  291. } else if (res.cancel) {
  292. console.log('稍后更新');
  293. }
  294. }
  295. });
  296. // #endif
  297. // #ifdef APP-PLUS
  298. plus.nativeUI.confirm('更新内容:'+newVersion.upgradeContent, function(e){
  299. if(e.index == 0){ // 确认
  300. if(curVer.platform == 'android'){
  301. //设置最新版本apk的下载链接
  302. downloadApp(newVersion.attachment);
  303. }else{
  304. openIosAppSotre(newVersion.downloadUrl)
  305. }
  306. // marketOpen()
  307. }
  308. },{"title":msg,"buttons": !isQzgx ? ["立即更新"] : ["立即更新","稍后进行"]})
  309. // #endif
  310. }else{
  311. if(type){
  312. uni.showToast({
  313. icon: 'none',
  314. title: '已是最新版本',
  315. duration: 1500
  316. });
  317. }
  318. }
  319. }
  320. // 确认弹框
  321. export const clzConfirm = function(opts){
  322. // #ifndef APP-PLUS
  323. uni.showModal({
  324. title: opts.title,
  325. content: opts.content,
  326. showCancel: opts.showCancel,
  327. confirmText: opts.confirmText || '确定',
  328. cancelText: opts.cancelText || '取消',
  329. success: opts.success,
  330. })
  331. // #endif
  332. // #ifdef APP-PLUS
  333. if(opts.showCancel==false){
  334. if(!opts.buttons){
  335. opts.buttons = ["确定"]
  336. }
  337. }
  338. plus.nativeUI.confirm(
  339. opts.content,
  340. opts.success,
  341. {"title":opts.title,"buttons": opts.buttons || ["确定","取消"]},
  342. )
  343. // #endif
  344. }
  345. // 小数点后两位
  346. export const numberToFixed = function (val, num, max) {
  347. let maxNums = max || 100000000
  348. let _value = val + ''
  349. _value = _value.replace(/[^\d.]/g, '')// 清楚数字和.以外的字数
  350. _value = _value.replace(/^\./g, '')
  351. _value = _value.replace(/\.{2,}/g, '')// 保留第一个,清楚多余的
  352. if (num == 1)_value = _value.replace(/^(\-)*(\d+)\.(\d).*$/, '$1$2.$3')
  353. else if (num == 3)_value = _value.replace(/^(\-)*(\d+)\.(\d\d\d).*$/, '$1$2.$3')
  354. else if (num == 4)_value = _value.replace(/^(\-)*(\d+)\.(\d\d\d\d).*$/, '$1$2.$3')
  355. else if (num == 5)_value = _value.replace(/^(\-)*(\d+)\.(\d\d\d\d\d).*$/, '$1$2.$3')
  356. else if (num == 0)_value = _value.indexOf('.') >= 0 ? _value.split('.')[0] : _value
  357. else _value = _value.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3')
  358. return _value > maxNums ? maxNums : _value
  359. }