util.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. import CONSTANT from "@/constant";
  2. import { mobileReg } from "@/utils/tools/validate";
  3. import { getMiniAppUrl, isWxBrowser } from "@/utils/common";
  4. import permision from "@/utils/wa-permission_1.1/permission.js";
  5. // 是否为空
  6. const isEmpty = val => {
  7. if (val instanceof Array) {
  8. if (val.length === 0){
  9. return true
  10. }
  11. } else if (val instanceof Object) {
  12. if (Object.keys(val).length == 0){
  13. return true
  14. }
  15. } else {
  16. if ( val === "null" || val === null || val === "undefined" || val === undefined || val === "" || JSON.stringify(val) == "[]"){
  17. return true
  18. }
  19. return false;
  20. }
  21. return false;
  22. };
  23. /**
  24. * 深拷贝对象
  25. * @param {要拷贝对象} obj
  26. */
  27. export const copyObject = obj => {
  28. let str,
  29. newobj = Array.isArray(obj) === true ? [] : {};
  30. if (typeof obj !== "object") {
  31. return;
  32. } else if (JSON) {
  33. (str = JSON.stringify(obj)), //系列化对象
  34. (newobj = JSON.parse(str)); //还原
  35. } else {
  36. for (let i in obj) {
  37. newobj[i] = typeof obj[i] === "object" ? copyObject(obj[i]) : obj[i];
  38. }
  39. }
  40. return newobj;
  41. };
  42. const numberFormat = (number, type) => {
  43. if(number > 100000000){
  44. let num = (number / 100000000 + "").split(".");
  45. return `${num[0]}.${("" + num[1]).slice(0, 1)} 亿`;
  46. }else if (number > 10000) {
  47. let num = (number / 10000 + "").split(".");
  48. return `${num[0]}.${("" + num[1]).slice(0, 1)} 万`;
  49. } else {
  50. return parseFloat(Number(number))
  51. }
  52. };
  53. // 截取图片上传字符串
  54. const imgSubstr = val => {
  55. if (isEmpty(val)) return [];
  56. if (isArray(val)) {
  57. return val.map(e => {
  58. let index = e.indexOf("/uploads/");
  59. e = e.substring(index);
  60. return e;
  61. });
  62. } else {
  63. let index = val.indexOf("/uploads/");
  64. return val.substring(index);
  65. }
  66. };
  67. // 是否为数组
  68. const isArray = arr => {
  69. return typeof arr == "object" && arr.constructor == Array;
  70. };
  71. // 是否为字符串
  72. const isString = str => {
  73. return typeof str == "string" && str.constructor == String;
  74. };
  75. // 是否为对象
  76. const isObject = obj => {
  77. return typeof obj == "object" && obj.constructor == Object;
  78. };
  79. // 是否为数字
  80. const isNumber = num => {
  81. return typeof num == "number" && num.constructor == Number;
  82. };
  83. //是否金额
  84. const isMoney = money =>{
  85. return /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/.test(money)
  86. }
  87. // 是否为日期类型
  88. const isDate = date => {
  89. return typeof date == "object" && date.constructor == Date;
  90. };
  91. // 是否为函数
  92. const isFunction = obj => {
  93. return typeof obj == "object" && obj.constructor == Function;
  94. };
  95. const checkMobile = num => {
  96. return mobileReg.test(num);
  97. };
  98. const checkName = str => {
  99. return /^[\u4E00-\u9FA5A-Za-z\s]+(·[\u4E00-\u9FA5A-Za-z]+)*$/.test(str);
  100. };
  101. /** *
  102. * 检查登录
  103. * @parmas query 拼接得参数对象
  104. * @parmas isFrist 为true时开头为&
  105. */
  106. export async function getCheckLogin() {
  107. let status = false;
  108. let token = uni.getStorageSync("token");
  109. if (token) {
  110. status = true;
  111. } else {
  112. // #ifdef H5
  113. if (isWxBrowser()) {
  114. let option = JSON.parse(uni.getStorageSync("currentQuery")) || {};
  115. location.href = `${CONSTANT.hostUrl}/auth/prepare?url=${encodeURIComponent(
  116. getMiniAppUrl(option, true)
  117. )}`;
  118. }
  119. // #endif
  120. // #ifndef H5
  121. // #endif
  122. }
  123. return status;
  124. }
  125. export const floatFormat = (f, n) => {
  126. let m = Math.pow(10, n);
  127. return parseInt(f * m, 10) / m;
  128. };
  129. /** *
  130. * 对象参数转为url参数
  131. * @parmas query 拼接得参数对象
  132. * @parmas isFrist 为true时开头为&
  133. */
  134. export const parse = (query, isFrist = false) => {
  135. let str = Object.keys(query)
  136. .filter(key => !isEmpty(query[key]))
  137. .reduce((result, key) => {
  138. const value = query[key];
  139. // in查询特殊处理
  140. if (Array.isArray(value) && !isEmpty(value)) {
  141. return `${result}&${value.reduce(
  142. (val, cVal) => `${val ? `${val}&` : val}${key}=${cVal}`,
  143. ""
  144. )}`;
  145. }
  146. // between查询做特殊处理
  147. if (typeof value === "object" && !isEmpty(value)) {
  148. const [start, end] = value;
  149. return `${result}&${key}[]=${start}&${key}[]=${end}`;
  150. }
  151. return `${result}&${key}=${value}`;
  152. }, "");
  153. return isFrist ? str : str.replace(/^&/, "?");
  154. };
  155. /** *
  156. * 全局时间转换
  157. * @parmas num 时间戳默认为11位时间戳
  158. * @parmas fmt 默认转换的时间格式
  159. * @parmas all 为true时time为13位时间戳
  160. */
  161. export const $formatDate = (num, fmt = "YYYY-MM-DD HH:mm", all) => {
  162. num = all ? num : num * 1000;
  163. let date = new Date();
  164. date.setTime(num);
  165. let o = {
  166. "M+": date.getMonth() + 1,
  167. "D+": date.getDate(),
  168. "h+": date.getHours() % 12 === 0 ? 12 : date.getHours() % 12,
  169. "H+": date.getHours(),
  170. "m+": date.getMinutes(),
  171. "s+": date.getSeconds(),
  172. "q+": Math.floor((date.getMonth() + 3) / 3),
  173. S: date.getMilliseconds()
  174. };
  175. let week = {
  176. "0": "\u65e5",
  177. "1": "\u4e00",
  178. "2": "\u4e8c",
  179. "3": "\u4e09",
  180. "4": "\u56db",
  181. "5": "\u4e94",
  182. "6": "\u516d"
  183. };
  184. if (/(Y+)/.test(fmt)) {
  185. fmt = fmt.replace(
  186. RegExp.$1,
  187. (date.getFullYear() + "").substr(4 - RegExp.$1.length)
  188. );
  189. }
  190. if (/(E+)/.test(fmt)) {
  191. fmt = fmt.replace(
  192. RegExp.$1,
  193. (RegExp.$1.length > 1
  194. ? RegExp.$1.length > 2
  195. ? "\u661f\u671f"
  196. : "\u5468"
  197. : "") + week[date.getDay() + ""]
  198. );
  199. }
  200. for (let k in o) {
  201. if (new RegExp("(" + k + ")").test(fmt)) {
  202. fmt = fmt.replace(
  203. RegExp.$1,
  204. RegExp.$1.length === 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)
  205. );
  206. }
  207. }
  208. return fmt;
  209. };
  210. /** *
  211. * 全局公共按钮跳转
  212. * @parmas item.funtion 为可执行函数
  213. * @parmas item.url 为跳转的路径
  214. * @parmas item.query 为跳转携带的参数
  215. * @parmas item.type 为跳转调用的函数 1为navigateTo, 2为redirectTo 关闭当前页面,跳转到应用内的某个页面 3为reLaunch 关闭所有页面,打开到应用内的某个页面 4为switchTab
  216. */
  217. export const pageTo = item => {
  218. if (isNumber(item)) {
  219. uni.navigateBack({
  220. delta: item
  221. });
  222. }
  223. if (isString(item)) {
  224. uni.navigateTo({
  225. url: item
  226. });
  227. return false;
  228. }
  229. if (item.funtion) {
  230. item.funtion();
  231. }
  232. if (item.url) {
  233. let query = item.query ? parse(item.query) : "";
  234. let allUrl = `${item.url}${query}`;
  235. if (item.type == 2) {
  236. uni.redirectTo({
  237. url: allUrl,
  238. success(res) {
  239. },
  240. fail(err) {
  241. console.log(err);
  242. }
  243. });
  244. } else if (item.type == 3) {
  245. uni.reLaunch({
  246. url: allUrl,
  247. success(res) {
  248. },
  249. fail(err) {
  250. console.log(err);
  251. }
  252. });
  253. } else if (item.type == 4) {
  254. uni.setStorageSync("switchTabQuery", item.query);
  255. uni.switchTab({
  256. url: item.url,
  257. success(res) {
  258. },
  259. fail(err) {
  260. console.log(err);
  261. }
  262. });
  263. } else {
  264. uni.navigateTo({
  265. url: allUrl,
  266. success(res) {
  267. },
  268. fail(err) {
  269. console.log(err);
  270. }
  271. });
  272. }
  273. }
  274. };
  275. /** *
  276. * 是否登录
  277. */
  278. export const isLogin = () => {
  279. let token = uni.getStorageSync("token");
  280. if (token) {
  281. return true;
  282. }
  283. return false;
  284. };
  285. export async function callUp(mobile){
  286. //#ifdef MP-WEIXIN
  287. uni.makePhoneCall({phoneNumber: mobile})
  288. //#endif
  289. //#ifdef APP-PLUS
  290. let env = uni.getSystemInfoSync().platform
  291. if(env == 'android'){
  292. //Android是动态权限,请求权限状态时会触发弹框询问是否赋权(如果已经同意或永久禁止则不会询问),所以必须使用异步方式来处理
  293. var result = await permision.requestAndroidPermission('android.permission.CALL_PHONE')
  294. if(Number(result) == -1){
  295. confirmModal({content:'请在权限管理中开启【拨打电话】','okText':'去开启'},() => {
  296. permision.gotoAppPermissionSetting()
  297. })
  298. return
  299. }
  300. }
  301. uni.makePhoneCall({phoneNumber: mobile})
  302. //#endif
  303. }
  304. //没有库存时的语音播放 shish
  305. export const noStockRemind = () =>{
  306. try{
  307. if(uni.getSystemInfoSync().platform != 'windows'){
  308. const innerAudioContext = uni.createInnerAudioContext()
  309. innerAudioContext.autoplay = true
  310. innerAudioContext.src = "/static/noStock.mp3"
  311. innerAudioContext.volume = 1
  312. innerAudioContext.onPlay()
  313. innerAudioContext.onError()
  314. innerAudioContext.onPause(function() {
  315. innerAudioContext.destroy()
  316. })
  317. }
  318. } catch (e) {
  319. // 开发环境兼容处理
  320. console.warn('开发环境音频播放异常(可忽略):', e);
  321. }
  322. }
  323. //点击声效 shish
  324. export const hitRemind = () =>{
  325. try{
  326. if(uni.getSystemInfoSync().platform != 'windows'){
  327. const innerAudioContext = uni.createInnerAudioContext()
  328. innerAudioContext.autoplay = true
  329. innerAudioContext.src = '/static/hit.mp3'
  330. innerAudioContext.onPlay()
  331. innerAudioContext.onError()
  332. innerAudioContext.onPause(function() {
  333. innerAudioContext.destroy()
  334. })
  335. }
  336. } catch (e) {
  337. // 开发环境兼容处理
  338. console.warn('开发环境音频播放异常(可忽略):', e);
  339. }
  340. }
  341. //去重 姜枫 2021.05.05
  342. export const unique = (arr) => {
  343. for(var i=0; i<arr.length; i++){
  344. for(var j=i+1; j<arr.length; j++){
  345. if(arr[i].classId==arr[j].classId){ //第一个等同于第二个,splice方法删除第二个
  346. arr.splice(j,1);
  347. j--;
  348. }
  349. }
  350. }
  351. return arr;
  352. };
  353. //#ifdef APP-PLUS
  354. const CLDialog=uni.requireNativePlugin("CL-Dialog")
  355. //#endif
  356. export const confirmModal = (item,okCallback=null,cancelCallback=null) => {
  357. let title = item.title || '提示'
  358. let content = item.content || '确认操作?'
  359. let okText = item.okText || '确认'
  360. let cancelText = item.cancelText || '取消'
  361. let cacelTextColor = '#999999'
  362. let okTextColor = '#38ADFF'
  363. let singer = item.singer || false
  364. //#ifdef APP-PLUS
  365. let platform=uni.getSystemInfoSync().platform
  366. if(platform=='ios'){
  367. uni.showModal({
  368. title: title,
  369. content: content,
  370. showCancel: true,
  371. cancelText: cancelText,
  372. cancelColor: cacelTextColor,
  373. confirmText: okText,
  374. confirmColor: okTextColor,
  375. success: function (res) {
  376. if (res.confirm) {
  377. if(okCallback!=null){
  378. okCallback()
  379. }
  380. } else if (res.cancel) {
  381. if(cancelCallback!=null){
  382. cancelCallback()
  383. }
  384. }
  385. }
  386. })
  387. }else if(platform=='android'){
  388. let options={
  389. title:title,//内容(可选)但是标题和内容至少选择一个
  390. con:content,
  391. okTitle:okText,//确认按钮文字(可选)
  392. cancleTitle:cancelText,//取消按钮文字(可选)
  393. okTextColor:"#38ADFF",//确认按钮颜色(可选)
  394. cancleTextColor:"#999999",//取消按钮颜色(可选)
  395. singer:singer,//是否只显示确认按钮,默认false(可选)
  396. textAlign:"center",//对齐方式 //left居左,center居中,right 居右 默认居中
  397. conColor:"",
  398. bgColor:"#FFFFFF",//自定义弹框颜色
  399. titleColor:"#3d3d3d"//自定义title颜色
  400. }
  401. CLDialog.show(options,()=>{
  402. if(okCallback!=null){
  403. okCallback()
  404. }
  405. },()=>{
  406. if(cancelCallback!=null){
  407. cancelCallback()
  408. }
  409. })
  410. }
  411. //#endif
  412. // #ifdef MP-WEIXIN
  413. uni.showModal({
  414. title: title,
  415. content: content,
  416. showCancel: true,
  417. cancelText: cancelText,
  418. cancelColor: cacelTextColor,
  419. confirmText: okText,
  420. confirmColor: okTextColor,
  421. success: function (res) {
  422. if (res.confirm) {
  423. if(okCallback!=null){
  424. okCallback()
  425. }
  426. } else if (res.cancel) {
  427. if(cancelCallback!=null){
  428. cancelCallback()
  429. }
  430. }
  431. }
  432. })
  433. //#endif
  434. }
  435. //判断是否有扫码的条件
  436. export const isScanEnv = () =>{
  437. let isScanEnv = false
  438. //#ifdef APP-PLUS
  439. if(plus.device.vendor == 'Newland'){
  440. isScanEnv = true
  441. }
  442. //#endif
  443. return isScanEnv
  444. }
  445. export default {
  446. isEmpty,
  447. copyObject,
  448. imgSubstr,
  449. isArray,
  450. parse,
  451. checkMobile,
  452. checkName,
  453. $formatDate,
  454. floatFormat,
  455. pageTo,
  456. isLogin,
  457. getCheckLogin,
  458. numberFormat,
  459. isString,
  460. unique,
  461. isMoney,
  462. isNumber,
  463. noStockRemind,
  464. callUp,
  465. hitRemind,
  466. confirmModal,
  467. isScanEnv
  468. };