tools.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. //#ifdef APP-PLUS
  2. let carmera = uni.requireNativePlugin('ziteng-maskcamera')
  3. let cameraModule = uni.requireNativePlugin("SMUniPlugin-CameraModule")
  4. //#endif
  5. // 处理数字千位分隔符 num 数值,decimal要保留的小数位数
  6. export const toThousands = (num, decimal) => {
  7. if (decimal) {
  8. num = formatDecimal(num, decimal)
  9. }
  10. return num.toString().replace(/\d+/, function (n) { // 先提取整数部分
  11. return n.replace(/(\d)(?=(\d{3})+$)/g, function ($1) {
  12. return $1 + ','
  13. })
  14. })
  15. }
  16. // 保留decimal位小数(不四舍五入) num 数值,decimal要保留的小数位数
  17. export const formatDecimal = function (num, decimal) {
  18. num = num.toString()
  19. const index = num.indexOf('.')
  20. if (index !== -1) {
  21. num = num.substring(0, decimal + index + 1)
  22. } else {
  23. num = num.substring(0)
  24. }
  25. return parseFloat(num).toFixed(decimal)
  26. }
  27. export function objToUrl(obj) {
  28. let uri = '';
  29. let keys = Object.keys(obj);
  30. keys.forEach(item => {
  31. uri += '&' + item + '=' + obj[item];
  32. });
  33. uri = uri.substr(1);
  34. return uri;
  35. }
  36. // 获取地址栏参数
  37. export function getQueryString(url, name) {
  38. var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)")
  39. var r = url.substr(1).match(reg)
  40. if(r!=null) return unescape(r[2])
  41. return null
  42. }
  43. // 节流函数
  44. export function throttle(fn, gaptime) {
  45. if (gaptime == null || gaptime == undefined) {
  46. gaptime = 200
  47. }
  48. let _lastTime = null
  49. return function() {
  50. let _nowTime = +new Date()
  51. if (_nowTime - _lastTime > gaptime || !_lastTime) {
  52. fn.apply(this, arguments)
  53. _lastTime = _nowTime
  54. }
  55. }
  56. }
  57. //延迟函数
  58. export function delayDel(fn) {
  59. setTimeout(()=>{
  60. fn();
  61. },80)
  62. }
  63. // 图片转Base64,pad 平台
  64. export const imgToBase64 = function (path,callback){
  65. // plus.nativeUI.previewImage([path]);
  66. // return
  67. plus.io.resolveLocalFileSystemURL(path, function (entry) {
  68. // 可通过entry对象操作文件
  69. entry.file(function (file){
  70. var fileReader = new plus.io.FileReader()
  71. fileReader.readAsDataURL(file, 'utf-8')
  72. fileReader.onloadend = function (evt) {
  73. let result = evt.target.result
  74. callback(1,result.split(',')[1])
  75. // remove this file
  76. entry.remove( function ( entry ) {
  77. console.log( "Remove succeeded" );
  78. }, function ( e ) {
  79. console.log( e.message );
  80. });
  81. }
  82. fileReader.onerror = function (e){
  83. callback(0,'文件读取失败')
  84. }
  85. })
  86. }, function (e) {
  87. console.log(JSON.stringify(e))
  88. uni.showToast({icon: 'none',title: 'Resolve file URL failed: ' + e.message})
  89. })
  90. }
  91. // 打开摄像头
  92. export const openCamera = function (type,callback){
  93. let carNumberOptions = {
  94. widthRatio: 0.8,
  95. heightRatio: 0.2,
  96. showText: '请将车牌号码对准框中'
  97. }
  98. let carVinNumberOptions = {
  99. widthRatio: 0.9,
  100. heightRatio: 0.1,
  101. showText: '请将车辆VIN码对准框中'
  102. }
  103. let option = (type == 'searchCar' || type == 'carNumber') ? carNumberOptions : carVinNumberOptions
  104. // 竖屏 false,横屏 true
  105. let isLandscape = false
  106. //安卓摄像头
  107. if(uni.getSystemInfoSync().platform === 'android'){
  108. option.isLandscape = isLandscape
  109. carmera.show(option,function(result){
  110. console.log(result)
  111. if(result.msg != 'backCancel'){
  112. callback(result.data)
  113. }
  114. })
  115. }
  116. // ios 摄像头
  117. if(uni.getSystemInfoSync().platform == 'ios'){
  118. let screenWidth = uni.getSystemInfoSync().screenWidth
  119. let screenHeight = uni.getSystemInfoSync().screenHeight
  120. let [w,h,x,y] = [0,0,0,0]
  121. // 横屏
  122. if(isLandscape){
  123. h = screenWidth*option.widthRatio*1.2
  124. w = screenHeight*option.heightRatio
  125. x = (screenWidth - w)/2
  126. y = (screenHeight - h)/2
  127. }else{
  128. // 竖屏
  129. w = screenWidth*option.widthRatio
  130. h = screenHeight*option.heightRatio
  131. x = (screenWidth - w)/2
  132. y = (screenHeight - h)/2 - 50
  133. }
  134. cameraModule.showCamera({
  135. 'showTitle': option.showText,
  136. 'size': [w, h],
  137. 'orign': [x, y],
  138. 'isLandscape': isLandscape
  139. },
  140. (result) => {
  141. callback('file://'+result)
  142. })
  143. }
  144. }
  145. /**
  146. * @param {*} obj1 对象
  147. * @param {*} obj2 对象
  148. * @description 遍历赋值
  149. */
  150. export const objExtend = (obj1, obj2) => {
  151. for (let a in obj1){
  152. obj2[a] = obj1[a]
  153. }
  154. return obj2
  155. }
  156. // 正则验证车牌,验证通过返回true,不通过返回false
  157. export const isLicensePlate = function (str) {
  158. 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)
  159. }
  160. /**
  161. * 校验身份证号合法性
  162. */
  163. export const checkIdNumberValid = (tex) => {
  164. // var tip = '输入的身份证号有误,请检查后重新输入!'
  165. let num = tex
  166. num = num.toUpperCase()
  167. let len = num.length
  168. let re
  169. if (len == 0) return true
  170. // 身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X。
  171. if (!(/(^\d{15}$)|(^\d{17}([0-9]|X)$)/.test(num))){
  172. return false
  173. }
  174. // 验证前两位地区是否有效
  175. let aCity = {11: '北京',12: '天津',13: '河北',14: '山西',15: '内蒙古',21: '辽宁',22: '吉林',23: '黑龙江',31: '上海',32: '江苏',33: '浙江',
  176. 34: '安徽',35: '福建',36: '江西',37: '山东',41: '河南',42: '湖北',43: '湖南',44: '广东',45: '广西',46: '海南',50: '重庆',51: '四川',
  177. 52: '贵州',53: '云南',54: '西藏',61: '陕西',62: '甘肃',63: '青海',64: '宁夏',65: '新疆',71: '台湾',81: '香港',82: '澳门',91: '国外'}
  178. if (aCity[parseInt(num.substr(0, 2))] == null){
  179. return false
  180. }
  181. // 当身份证为15位时的验证出生日期。
  182. if (len == 15){
  183. re = new RegExp(/^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/)
  184. let arrSplit = num.match(re)
  185. // 检查生日日期是否正确
  186. let dtmBirth = new Date('19' + arrSplit[2] + '/' + arrSplit[3] + '/' + arrSplit[4])
  187. let bGoodDay = (dtmBirth.getYear() == Number(arrSplit[2])) && ((dtmBirth.getMonth() + 1) == Number(arrSplit[3])) && (dtmBirth.getDate() == Number(arrSplit[4]))
  188. if (!bGoodDay){
  189. return false
  190. }
  191. }
  192. // 当身份证号为18位时,校验出生日期和校验位。
  193. if (len == 18){
  194. re = new RegExp(/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/)
  195. let arrSplit = num.match(re)
  196. // 检查生日日期是否正确
  197. let dtmBirth = new Date(arrSplit[2] + '/' + arrSplit[3] + '/' + arrSplit[4])
  198. let bGoodDay = (dtmBirth.getFullYear() == Number(arrSplit[2])) && ((dtmBirth.getMonth() + 1) == Number(arrSplit[3])) && (dtmBirth.getDate() == Number(arrSplit[4]))
  199. if (!bGoodDay){
  200. return false
  201. } else {
  202. // 检验18位身份证的校验码是否正确。
  203. // 校验位按照ISO 7064:1983.MOD 11-2的规定生成,X可以认为是数字10。
  204. let valnum
  205. let arrInt = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
  206. let arrCh = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']
  207. let nTemp = 0
  208. let i
  209. for (i = 0; i < 17; i++){
  210. nTemp += num.substr(i, 1) * arrInt[i]
  211. }
  212. valnum = arrCh[nTemp % 11]
  213. if (valnum != num.substr(17, 1)){
  214. return false
  215. }
  216. }
  217. }
  218. return true
  219. }
  220. // 正则有效手机号码
  221. export const isvalidPhone = function (str) {
  222. const reg = /^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/
  223. return reg.test(str)
  224. }
  225. // 日期格式化
  226. export const formatSubmitDate = (val, type) => {
  227. if (val == null || val == '' || val == undefined) {
  228. return ''
  229. } else {
  230. let _date = new Date(val)
  231. let _year = _date.getFullYear()
  232. let _montn = (_date.getMonth() + 1) < 10 ? '0' + (_date.getMonth() + 1) : (_date.getMonth() + 1)
  233. let _day = _date.getDate() < 10 ? '0' + _date.getDate() : _date.getDate()
  234. let _hour = _date.getHours() < 10 ? '0' + _date.getHours() : _date.getHours()
  235. let _minutes = _date.getMinutes() < 10 ? '0' + _date.getMinutes() : _date.getMinutes()
  236. let _seconds = _date.getSeconds() < 10 ? '0' + _date.getSeconds() : _date.getSeconds()
  237. if (type == 'minutes') return _year + '-' + _montn + '-' + _day + ' ' + _hour + ':' + _minutes
  238. else if (type == 'seconds') return _year + '-' + _montn + '-' + _day + ' ' + _hour + ':' + _minutes + ':' + _seconds
  239. else return _year + '-' + _montn + '-' + _day
  240. }
  241. }
  242. /**
  243. * //设置应用版本号对应的缓存信息
  244. * @param {Object} currTimeStamp 当前获取的时间戳
  245. */
  246. export const setStorageForAppVersion = function(currTimeStamp){
  247. uni.setStorage({
  248. key: 'tip_version_update_time',
  249. data: currTimeStamp,
  250. success: function () {
  251. console.log('setStorage-success');
  252. }
  253. });
  254. }
  255. /**
  256. * 进行版本型号的比对 以及下载更新请求
  257. * @param {Object} server_version 服务器最新 应用版本号
  258. * @param {Object} curr_version 当前应用版本号
  259. * isQzgx 是否强制更新
  260. * callback 登录
  261. */
  262. export const checkVersionToLoadUpdate = function(newVersion,type,callback){
  263. if(newVersion.version == '2001'||newVersion.version == '2002'){
  264. newVersion.version = 201
  265. }
  266. const curVer = getApp({ allowDefault: true }).globalData.version // 当前版本信息
  267. console.log(newVersion,curVer,callback)
  268. if(!newVersion || !curVer){
  269. callback()
  270. return
  271. }
  272. const curr_version = curVer && curVer.version ? curVer.version.replace(/\./g,'') : ''
  273. const server_version = newVersion && newVersion.version ? newVersion.version : '' // 最新版本信息
  274. const isQzgx = newVersion && newVersion.forceUpgrade != 1
  275. let isWifi = plus.networkinfo.getCurrentType()!=3 ? '有新的版本发布,检测到您目前非Wifi连接,' : '有新的版本发布,'
  276. let msg = isWifi + (!isQzgx ? '请立即更新?' : '是否立即更新版本?')
  277. // 下载app并安装
  278. let downloadApp = function(downloadApkUrl){
  279. uni.showLoading({
  280. title: '正在更新中...',
  281. mask: true,
  282. });
  283. var dtask = plus.downloader.createDownload( downloadApkUrl, {}, function ( d, status ) {
  284. // 下载完成
  285. if ( status == 200 ) {
  286. plus.runtime.install(plus.io.convertLocalFileSystemURL(d.filename),{},{},function(error){
  287. uni.showToast({
  288. icon: 'none',
  289. title: '安装失败',
  290. duration: 1500
  291. });
  292. })
  293. uni.hideLoading()
  294. } else {
  295. uni.showToast({
  296. icon: 'none',
  297. title: '更新失败',
  298. duration: 1500
  299. });
  300. }
  301. });
  302. dtask.start();
  303. }
  304. // 打开ios 应用市场
  305. let openIosAppSotre = function(downloadUrl){
  306. //在App Store Connect中的App Store下的app信息,可找到appleId
  307. plus.runtime.launchApplication({
  308. action: downloadUrl
  309. }, function(e) {
  310. console.log('Open system default browser failed: ' + e.message);
  311. })
  312. }
  313. console.log(server_version,curr_version)
  314. if(Number(server_version) > Number(curr_version)){
  315. uni.showModal({
  316. title: msg,
  317. content: '更新内容:'+newVersion.upgradeContent,
  318. showCancel: isQzgx,
  319. confirmText:'立即更新',
  320. cancelText:'稍后进行',
  321. success: function (res) {
  322. if (res.confirm) {
  323. // 清空缓存token
  324. let tmp = uni.getStorageSync('lifeData');
  325. tmp = tmp ? tmp : {};
  326. tmp['vuex_token'] = '';
  327. uni.setStorageSync('lifeData', tmp);
  328. if(curVer.platform == 'android'){
  329. //设置 最新版本apk的下载链接
  330. downloadApp(newVersion.attachment);
  331. }else{
  332. openIosAppSotre(newVersion.downloadUrl)
  333. }
  334. } else if (res.cancel) {
  335. console.log('稍后更新');
  336. callback()
  337. }
  338. }
  339. });
  340. uni.hideLoading();
  341. }else{
  342. if(type){
  343. uni.showToast({
  344. icon: 'none',
  345. title: '已是最新版本',
  346. duration: 1500
  347. });
  348. }else{
  349. callback()
  350. }
  351. }
  352. }
  353. // 确认弹框
  354. export const clzConfirm = function(opts){
  355. // #ifndef APP-PLUS
  356. uni.showModal({
  357. title: opts.title,
  358. content: opts.content,
  359. showCancel: opts.showCancel,
  360. confirmText: opts.confirmText || '确定',
  361. cancelText: opts.cancelText || '取消',
  362. success: opts.success,
  363. })
  364. // #endif
  365. // #ifdef APP-PLUS
  366. if(opts.showCancel==false){
  367. if(!opts.buttons){
  368. opts.buttons = ["确定"]
  369. }
  370. }
  371. plus.nativeUI.confirm(
  372. opts.content,
  373. opts.success,
  374. {"title":opts.title,"buttons": opts.buttons || ["确定","取消"]},
  375. )
  376. // #endif
  377. }
  378. // 小数点后两位
  379. export const numberToFixed = function (val, num, max) {
  380. let maxNums = max || 100000000
  381. let _value = val + ''
  382. _value = _value.replace(/[^\d.]/g, '')// 清楚数字和.以外的字数
  383. _value = _value.replace(/^\./g, '')
  384. _value = _value.replace(/\.{2,}/g, '')// 保留第一个,清楚多余的
  385. if (num == 1)_value = _value.replace(/^(\-)*(\d+)\.(\d).*$/, '$1$2.$3')
  386. else if (num == 3)_value = _value.replace(/^(\-)*(\d+)\.(\d\d\d).*$/, '$1$2.$3')
  387. else if (num == 4)_value = _value.replace(/^(\-)*(\d+)\.(\d\d\d\d).*$/, '$1$2.$3')
  388. else if (num == 5)_value = _value.replace(/^(\-)*(\d+)\.(\d\d\d\d\d).*$/, '$1$2.$3')
  389. else if (num == 0)_value = _value.indexOf('.') >= 0 ? _value.split('.')[0] : _value
  390. else _value = _value.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3')
  391. // console.log(_value,maxNums,Number(_value)>Number(maxNums),'_value')
  392. return Number(_value)>Number(maxNums) ? maxNums : _value
  393. }
  394. // 保存图片到阿里云
  395. export const saveImgToAliOss = function(src,callback){
  396. const App = getApp({ allowDefault: true })
  397. console.log(src,App.globalData.baseUrl,'getApp({ allowDefault: true }).globalData.baseUrl')
  398. const authorization = App.globalData.token
  399. uni.uploadFile({
  400. url: App.globalData.baseUrl + 'upload/', //自行修改各自的对应的接口
  401. filePath: src,
  402. name: 'file',
  403. header: {'X-AUTH-TOKEN':authorization},
  404. success: (uploadFileRes) => {
  405. if (uploadFileRes) {
  406. let res = JSON.parse(uploadFileRes.data);
  407. callback(res)
  408. }
  409. uni.showToast({
  410. icon: 'none',
  411. title: uploadFileRes ? '保存图片成功' : '保存图片失败'
  412. })
  413. },
  414. fail:(error) => {
  415. console.log(error)
  416. }
  417. });
  418. }
  419. // 点击消息打开对应的页面
  420. export const openMessagePage = function(data){
  421. // 急送订单
  422. if (data.extras.bizType == 'TEMP_ORDER') {
  423. uni.navigateTo({ url: '/pages/sales/edit?pageType=detail&data='+JSON.stringify({ salesBillSn: data.extras.bizSn }) })
  424. }
  425. // 补货订单
  426. if (data.extras.bizType == 'SHELF_REPLENISH') {
  427. // uni.navigateTo({ url: '/pages/replenishmentManage/replenishmentList?billState=ALL' })
  428. uni.navigateTo({url: '/pages/soldOut/shelfList'})
  429. }
  430. // 货架订单
  431. if (data.extras.bizType == 'SHELF_ORDER') {
  432. uni.navigateTo({ url: '/pages/shelfOrder/orderDetail?pageType=detail&orderBillSn='+data.extras.bizSn })
  433. }
  434. // 货架异常
  435. if (data.extras.bizType == 'SHELF_WARN') {
  436. const shelfName = data.content.split('已经超过')[0]
  437. uni.navigateTo({ url: '/pages/shelfOrder/shelfOrder?bizType=SHELF_WARN&shelfSn='+data.extras.bizSn+'&shelfName='+shelfName })
  438. }
  439. }