You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

885 lines
23 KiB

  1. import moment from 'moment'
  2. import get from 'lodash/get'
  3. import mapValues from 'lodash/mapValues'
  4. import defaultConfig from './config.default.js'
  5. import globalConfig from '@/config.js'
  6. import md5 from '@/common/md5.js'
  7. /**
  8. * 通用工具方法、全局数据
  9. * 以下定义的所有方法、计算属性,均会被挂载到所有 .vue 页面的 this 上
  10. *
  11. * 注意:小程序端,计算属性会以数据对象的形式挂载到所有页面的 Page 对象中
  12. * 因此,数据量较大的情况下,为优化性能请使用调用方法动态获取的形式,避免占用太多内存
  13. * (例如,GLOBAL 全局对象现在已经移除,改为使用 GET_GLOBAL(key) 来获取全局对象)
  14. */
  15. export default {
  16. // 【App 平台】点击返回键后移除 loading,防止某个页面出错按返回键后还有 loading
  17. // #ifdef APP-VUE
  18. onBackPress() {
  19. uni.hideLoading()
  20. },
  21. // #endif
  22. methods: {
  23. // 暂存一个跨页面变量 (与 this.GET_PARAM 成对使用)
  24. SET_PARAM(val) {
  25. this.SET_GLOBAL('pageParam', val)
  26. },
  27. // 获取之前暂存的跨页面变量 (与 this.SET_PARAM 成对使用)
  28. GET_PARAM() {
  29. return this.GET_GLOBAL('pageParam')
  30. },
  31. // 进入某个页面
  32. NAV_TO(url, param, usePageParam) {
  33. uni.navigateTo({
  34. url: this.handleNav(url, param, usePageParam)
  35. })
  36. },
  37. // 返回上个页面
  38. // delta 参数为返回的次数
  39. NAV_BACK(delta = 1) {
  40. uni.navigateBack({
  41. delta
  42. })
  43. },
  44. // 跳转到某个页面,跳转后无法返回
  45. JUMP_TO(url, param, usePageParam) {
  46. uni.redirectTo({
  47. url: this.handleNav(url, param, usePageParam)
  48. })
  49. },
  50. // 转到某个 Tab 页
  51. TAB_TO(url, param) {
  52. uni.switchTab({
  53. url: this.handleNav(url, param, true)
  54. })
  55. },
  56. // 重启应用,跳转到指定页面
  57. RELAUNCH_TO(url) {
  58. uni.reLaunch({
  59. url
  60. })
  61. },
  62. // 获取一个全局变量
  63. // key 为键名
  64. GET_GLOBAL(key) {
  65. return this.$store.state[key]
  66. },
  67. // 设置一个全局变量
  68. // key 为键名
  69. // val 为值
  70. SET_GLOBAL(key, val) {
  71. this.$store.commit(key, val)
  72. },
  73. // 清空全局变量
  74. CLEAR_GLOBAL() {
  75. this.$store.commit('clear')
  76. uni.removeStorageSync('token')
  77. },
  78. // 将数据写入本地缓存
  79. SET_STORAGE(key, data) {
  80. if (data === null) {
  81. uni.removeStorageSync(key)
  82. } else {
  83. uni.setStorageSync(key, data)
  84. }
  85. },
  86. // 获取之前写入本地缓存的数据
  87. GET_STORAGE(key) {
  88. return uni.getStorageSync(key)
  89. },
  90. // 清空本地缓存
  91. CLEAR_STORAGE() {
  92. uni.clearStorageSync()
  93. },
  94. // 展示提示框
  95. // title 为提示文字
  96. // mask 为是否禁止点击
  97. // icon 为显示图标,可以改为 'success'
  98. TOAST(title, icon = 'none', mask = false) {
  99. uni.showToast({
  100. title,
  101. icon,
  102. mask
  103. })
  104. },
  105. // 停止展示 toast 提示框
  106. HIDE_TOAST() {
  107. uni.hideToast()
  108. },
  109. // 显示 loading 提示框
  110. // title 为提示文字
  111. // mask 为是否禁止点击
  112. LOADING(title, mask = true) {
  113. uni.showLoading({
  114. title,
  115. mask
  116. })
  117. },
  118. // 停止展示 loading 提示框
  119. HIDE_LOADING() {
  120. uni.hideLoading()
  121. },
  122. // 展示确认提示框
  123. // title 为标题
  124. // content 为提示框文字内容
  125. // showCancel 为是否显示取消按钮
  126. // 返回一个结果,true 或 false,表示用户是否确认
  127. async CONFIRM(title, content, showCancel = false) {
  128. return new Promise(res => {
  129. uni.showModal({
  130. title,
  131. content,
  132. showCancel,
  133. success: ({
  134. confirm
  135. }) => {
  136. res(confirm)
  137. },
  138. fail: () => {
  139. res(false)
  140. }
  141. })
  142. })
  143. },
  144. // 设置页面标题
  145. SET_TITLE(title) {
  146. uni.setNavigationBarTitle({
  147. title
  148. })
  149. },
  150. // 从 /config.js 中获取某条配置项
  151. // 如果在 /config.js 中获取不到,则前往 /common/config.default.js 中获取默认值
  152. // path 为配置项的访问路径
  153. // 举例:
  154. // 以下语句获取是否全局开启圆形头像
  155. // this.CONFIG('pageConfig.roundAvatar')
  156. CONFIG(path) {
  157. return get(globalConfig, path, get(defaultConfig, path))
  158. },
  159. // 监听一个全局事件
  160. ON(name, func) {
  161. uni.$on(name, func)
  162. },
  163. // 仅单次监听一个全局事件
  164. ONCE(name, func) {
  165. uni.$once(name, func)
  166. },
  167. // 触发一个全局事件
  168. EMIT(name, data) {
  169. uni.$emit(name, data)
  170. },
  171. // 移除全局事件监听器
  172. OFF(name, func) {
  173. uni.$off(name, func)
  174. },
  175. // sortArr(array,num=0){
  176. // let arr = JSON.parse(JSON.stringify(array))
  177. // for(let i = 0;i<arr.length-1-num;i++){
  178. // if(Number(arr[i].classno) < Number(arr[i+1].classno)){
  179. // let item = JSON.parse(JSON.stringify(arr[i]))
  180. // let item1 = JSON.parse(JSON.stringify(arr[i+1]))
  181. // arr[i] = item1
  182. // arr[i+1] = item
  183. // }
  184. // }
  185. // if(num < arr.length-1){
  186. // return this.sortArr(arr,num+1)
  187. // }else{
  188. // return arr
  189. // }
  190. // },
  191. // 拉取指定 code 值的数据源数据
  192. async FETCH_DATASOURCE(code) {
  193. if (!code) {
  194. return []
  195. }
  196. let res = await this.HTTP_GET('learun/adms/datasource/map', {code,ver: ''})
  197. // if(res.data&&res.data.length){
  198. // if(code == "bjsj"){
  199. // console.log({data:this.sortArr(res.data),ver:res.ver})
  200. // return {data:this.sortArr(res.data),ver:res.ver}
  201. // }
  202. // }
  203. return res
  204. },
  205. // 拉取指定规则编号的表单编码数据
  206. async FETCH_ENCODE(rulecode) {
  207. if (!rulecode) {
  208. return ''
  209. }
  210. return await this.HTTP_GET('learun/adms/coderule/code', rulecode)
  211. },
  212. // 拉取指定 id 的文件信息
  213. async FETCH_FILEINFO(fileId) {
  214. if (!fileId) {
  215. return null
  216. }
  217. return await this.HTTP_GET('learun/adms/annexes/wxfileinfo', fileId)
  218. },
  219. //删除指定id的文件信息
  220. async DELETE_FILE(fileId) {
  221. if (!fileId) {
  222. return null
  223. }
  224. return await this.HTTP_POST('learun/adms/annexes/wxdelete', fileId);
  225. },
  226. //获取文件夹下文件列表
  227. async FETCH_FILEList(folderId) {
  228. if (!folderId) {
  229. return null
  230. }
  231. return await this.HTTP_GET('learun/adms/annexes/wxlist', folderId)
  232. },
  233. // 根据文件夹id获取图片列表用于上传组件
  234. async getFileListById(folderId){
  235. if(!folderId){
  236. return []
  237. }
  238. let wxlist = await this.FETCH_FILEList(folderId),fileList = []
  239. for (const wxfile of wxlist) {
  240. const fileInfo = await this.FETCH_FILEINFO(wxfile.F_Id)
  241. if (!fileInfo) {
  242. continue
  243. }
  244. const fileType = fileInfo.F_FileType
  245. const fileSize = fileInfo.F_FileSize
  246. const fileName = fileInfo.F_FileName
  247. const path = this.API + '/learun/adms/annexes/wxdown?' + this.URL_QUERY(wxfile.F_Id, true)
  248. fileList.push({
  249. path,
  250. type: fileType,
  251. uid:wxfile.F_Id,
  252. folderId:wxfile.F_FolderId,
  253. size: fileSize,
  254. name:fileName
  255. })
  256. }
  257. return fileList
  258. },
  259. // 封装的 GET 请求,集成了验证信息
  260. // 返回请求结果或 null
  261. // 对网络错误、返回错误码、登录状态失效等情况做了相应处理
  262. // url 为请求地址
  263. // data 为请求附带的提交数据
  264. async HTTP_GET(url, data, showTips) {
  265. const [err, res] = await this.requestBase(url, data, null, 'GET')
  266. return this.handleResult(err, res, showTips)
  267. },
  268. // 封装的 POST 请求,集成了验证信息
  269. // 返回请求结果或 null
  270. // 对网络错误、返回错误码、登录状态失效等情况做了相应处理
  271. // url 为请求地址
  272. // data 为请求附带的提交数据
  273. async HTTP_POST(url, data, showTips) {
  274. const [err, res] = await this.requestBase(url, data, null, 'POST')
  275. return this.handleResult(err, res, showTips)
  276. },
  277. // 封装的文件上传,集成了验证信息
  278. // 返回接口返回值或 null
  279. // 对网络错误、返回错误码、登录状态失效等情况做了相应处理
  280. // url 为请求地址
  281. // filePath 为临时文件的路径
  282. // formData 为请求附带的提交数据
  283. async HTTP_UPLOAD(filePath, formData,guid) {
  284. const [err, res] = await this.UPLOAD('/learun/adms/annexes/wxupload', filePath, formData,guid)
  285. return this.handleResult(err, res)
  286. },
  287. async HTTP_UPLOAD2(url,filePath, formData) {
  288. const [err, res] = await this.UPLOAD(url, filePath, formData)
  289. return this.handleResult(err, res)
  290. },
  291. // 封装的文件下载,集成了验证信息
  292. // 返回临时文件路径或 null
  293. // 对网络错误、返回错误码、登录状态失效等情况做了相应处理
  294. // url 为请求地址
  295. // formData 为请求附带的提交数据
  296. async HTTP_DOWNLOAD(formData) {
  297. const [err, res] = await this.DOWNLOAD('/learun/adms/annexes/wxdown', formData)
  298. return this.handleResult(err, res)
  299. },
  300. // 发起一个 GET 请求,封装了身份验证
  301. // url 为请求地址
  302. // data 为请求附带的提交数据
  303. // 返回结果是一个数组: [error, result]
  304. // error 表示错误,一般是网络错误,请求很可能根本没有发出
  305. // result 包含 { statusCode, headers, data } 分别表示状态码、响应头、数据
  306. async GET(url, data, header) {
  307. return await this.requestBase(url, data, header, 'GET')
  308. },
  309. // 发起一个 POST 请求,封装了身份验证
  310. // url 为请求地址
  311. // data 为请求附带的提交数据
  312. // 返回结果是一个数组: [error, result]
  313. // error 表示错误,一般是网络错误,请求很可能根本没有发出
  314. // result 包含 { statusCode, headers, data } 分别表示状态码、响应头、数据
  315. async POST(url, data, header) {
  316. return await this.requestBase(url, data, header, 'POST')
  317. },
  318. // 上传一个文件 (本地临时文件),封装了身份验证
  319. // url 为提交地址
  320. // filePath 为本地临时文件路径
  321. // formData 为上传时附带的参数
  322. // 返回结果是一个数组: [error, result]
  323. // error 表示错误,一般是网络错误,请求很可能根本没有发出
  324. // result 包含 { statusCode, data } 分别表示状态码、接口返回的数据
  325. async UPLOAD(url, filePath, formData,guid) {
  326. const uploadUrl = this.handleUrl(url)
  327. const query = {
  328. loginMark: this.getLoginMark(),
  329. token: this.GET_GLOBAL('token'),
  330. folderId:guid
  331. }
  332. if (formData && typeof formData === 'object') {
  333. Object.assign(query, formData)
  334. } else if (typeof formData === 'string') {
  335. Object.assign(query, {
  336. data: formData
  337. })
  338. }
  339. // #ifdef MP-DINGTALK
  340. // return new Promise((res, rej) => {
  341. // dd.uploadFile({
  342. // url: uploadUrl,
  343. // filePath,
  344. // fileName: 'file',
  345. // fileType: 'image',
  346. // formData: query,
  347. // success: dt => {
  348. // dt.data = JSON.parse(dt.data)
  349. // res([null, dt])
  350. // },
  351. // fail: rs => {
  352. // rej([rs, null])
  353. // }
  354. // })
  355. // })
  356. // #endif
  357. // #ifndef MP-DINGTALK
  358. return uni.uploadFile({
  359. url: uploadUrl,
  360. filePath:filePath,
  361. name: 'file',
  362. fileType: 'image',
  363. formData: query
  364. }).then(([err, result]) => {
  365. if (!err) {
  366. result.data = JSON.parse(result.data)
  367. return [null, result]
  368. } else {
  369. return [err, null]
  370. }
  371. })
  372. // #endif
  373. },
  374. // 下载一个文件(下载后为临时文件),封装了身份验证
  375. // url 为请求的地址
  376. // formData 为请求时附带的参数
  377. // 返回结果是一个数组: [error, result]
  378. // error 表示错误,一般是网络错误,请求很可能根本没有发出
  379. // result 包含 { statusCode, tempFilePath } 分别表示状态码、下载后的临时文件路径
  380. async DOWNLOAD(url, formData) {
  381. let downloadUrl = this.handleUrl(url)
  382. const query = {}
  383. if (formData && typeof formData === 'object') {
  384. Object.assign(query, formData)
  385. } else if (typeof formData === 'string') {
  386. Object.assign(query, {
  387. data: formData
  388. })
  389. }
  390. downloadUrl = downloadUrl + '?' + this.URL_QUERY(query, true)
  391. return uni.downloadFile({
  392. url: downloadUrl
  393. }).then(([err, result]) => {
  394. if (!err) {
  395. result.data = {
  396. data: result.tempFilePath
  397. }
  398. result.statusCode = 200
  399. }
  400. return [err, result]
  401. })
  402. },
  403. // 拉取客户端全局数据,直接写入全局变量
  404. // 目前包括了:公司、部门、人员、数据字典
  405. async FETCH_CLIENTDATA() {
  406. await Promise.all([
  407. this.HTTP_GET('learun/adms/company/map').then(res => this.SET_GLOBAL('company', res.data || {})),
  408. this.HTTP_GET('learun/adms/department/map').then(res => this.SET_GLOBAL('department', res.data || {})),
  409. this.HTTP_GET('learun/adms/user/map').then(res => this.SET_GLOBAL('user', res.data || {})),
  410. this.HTTP_GET('learun/adms/dataitem/map').then(res => this.SET_GLOBAL('dataDictionary', res.data || {}))
  411. ])
  412. },
  413. // 使用 JSON 序列化的方式克隆一个对象或数组
  414. COPY(val) {
  415. return JSON.parse(JSON.stringify(val))
  416. },
  417. // 生成一个32位 GUID 随机字符串
  418. // joinChar 为分割符,默认为下划线
  419. GUID(joinChar = '_') {
  420. return `xxxxxxxx${joinChar}xxxx${joinChar}4xxx${joinChar}yxxx${joinChar}xxxxxxxxxxxx`.replace(/[xy]/g, c => {
  421. const r = Math.random() * 16 | 0;
  422. const v = c === 'x' ? r : (r & 0x3 | 0x8);
  423. return v.toString(16);
  424. })
  425. },
  426. // 获取指定字符串的 MD5 码
  427. MD5(val = '') {
  428. return md5(val)
  429. },
  430. // 将时间日期转化为特定格式 (一般用于 <l-list-item>)
  431. // datetimeString 为要格式化的日期时间字符串
  432. // 返回值是一个数组,它也可以当做字符串直接使用
  433. // 举例:
  434. // 如果日期是当天,则返回 ['今天 17:32'] 或者 '今天 17:32'
  435. // 如果日期是今年,则返回 ['6月8日', '17:32'] 或者 '6月8日 17:32'
  436. // 如果日期不是今年,返回 ['2018-06-08'] 或者 '2018-06-08'
  437. TABLEITEM_DATEFORMAT(datetimeString) {
  438. const dt = moment(datetimeString)
  439. let result = []
  440. if (!dt.isValid()) {
  441. result.toString = () => ''
  442. return result
  443. }
  444. const now = moment()
  445. if (dt.isSame(now, 'day')) {
  446. result = [`今天 ${dt.format('HH:mm')}`]
  447. result.toString = () => `今天 ${dt.format('HH:mm')}`
  448. } else if (dt.isSame(now, 'year')) {
  449. result = [dt.format('M月D日'), dt.format('HH:mm')]
  450. result.toString = () => dt.format('M月D日') + ' ' + dt.format('HH:mm')
  451. } else {
  452. result = [dt.format('YYYY-MM-DD')]
  453. result.toString = () => dt.format('YYYY-MM-DD')
  454. }
  455. return result
  456. },
  457. // 将一个对象编码并转化为 url 查询字符串
  458. // obj 为要转换的对象,值为空则会被忽略,值为对象会被转为 JSON 字符串
  459. // auth 为是否编入身份验证信息
  460. URL_QUERY(obj, auth = false) {
  461. let queryObject = obj || {}
  462. if (typeof obj === 'string') {
  463. queryObject = {
  464. data: obj
  465. }
  466. }
  467. if (auth) {
  468. Object.assign(queryObject, {
  469. loginMark: this.getLoginMark(),
  470. token: this.GET_GLOBAL('token')
  471. })
  472. }
  473. return Object.entries(queryObject)
  474. .filter(([k, v]) => k && v)
  475. .map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(typeof v === 'object' ? JSON.stringify(v) : v))
  476. .join('&')
  477. },
  478. // 将字符串转化为 HTML 格式 (处理表单页面的 HTML)
  479. CONVERT_HTML(str) {
  480. if (!str) {
  481. return ''
  482. }
  483. return str
  484. .replace(/{@zuojian@}|{@youjian@}|{@and@}/g, tag => ({
  485. '{@zuojian@}': '<',
  486. '{@youjian@}': '>',
  487. '{@and@}': '&'
  488. })[tag] || tag)
  489. .replace(/&amp;|&lt;|&gt;|&#39;|&quot;/g, tag => ({
  490. '&amp;': '&',
  491. '&lt;': '<',
  492. '&gt;': '>',
  493. '&#39;': "'",
  494. '&quot;': '"'
  495. })[tag] || tag)
  496. },
  497. // 用于编码小程序分享消息的 url 查询字符串 (开发环境下还会打印出来)
  498. // pageParam 为点击分享消息跳转时携带的 pageParam
  499. // query 为点击分享消息跳转时携带的 query
  500. // pagePath 点击分享消息跳转到小程序的页面 (默认为当前页)
  501. // 返回编码好的查询字符串
  502. MP_SHARE_ENCODE(pageParam, query, pagePath) {
  503. const shareObj = {
  504. fromUser: this.GET_GLOBAL('loginUser').userId,
  505. fromPlatform: this.PLATFORM,
  506. timestamp: new Date().valueOf(),
  507. pagePath: pagePath || this.pagePath,
  508. query: query,
  509. pageParam,
  510. learun: this.APP_VERSION
  511. }
  512. const result = this.URL_QUERY(shareObj)
  513. if (this.DEV) {
  514. console.log('【您正在分享力软小程序页面】')
  515. console.log('====分享对象:====')
  516. console.log(shareObj)
  517. console.log('====启动路径:====')
  518. console.log('/pages/home')
  519. console.log('====启动参数:====')
  520. console.log(result)
  521. console.log('====(以上消息仅开发模式可见)====')
  522. }
  523. return result
  524. },
  525. // 解析小程序分享字符串 (会自动适配微信小程序的 url 编码)
  526. MP_SHARE_DECODE(info) {
  527. // 微信小程序中获取的分享信息是被 uri 编码过的,需要解码
  528. // 支付宝/钉钉小程序不需要解码
  529. // #ifdef MP-WEIXIN
  530. const shareInfo = mapValues(info, decodeURIComponent)
  531. // #endif
  532. shareInfo.pageParam = shareInfo.pageParam ? JSON.parse(shareInfo.pageParam) : undefined
  533. shareInfo.query = shareInfo.query ? this.URL_QUERY(JSON.parse(shareInfo.query)) : undefined
  534. if (this.DEV) {
  535. console.log('【您通过小程序消息分享启动了力软小程序】')
  536. console.log('====小程序分享对象:====')
  537. console.log(shareInfo)
  538. console.log('====即将转入页面:====')
  539. console.log(shareInfo.pagePath)
  540. console.log('====设置的 url query:====')
  541. console.log(shareInfo.query)
  542. console.log('====设置的 pageParam:====')
  543. console.log(shareInfo.pageParam)
  544. console.log('====(以上消息仅开发模式可见)====')
  545. }
  546. this.SET_GLOBAL('pageParam', shareInfo.pageParam)
  547. uni.navigateTo({
  548. url: `${shareInfo.pagePath}?${this.URL_QUERY(shareInfo.query)}`
  549. })
  550. },
  551. // 【内部方法】处理页面跳转 url 和参数
  552. handleNav(url, param, usePageParam) {
  553. let query = ''
  554. if (param && usePageParam) {
  555. this.SET_PARAM(param)
  556. } else if (param && !usePageParam) {
  557. query += '?' + Object.entries(param).filter(([k, v]) => k && v).map(([k, v]) => k + '=' + v).join('&')
  558. }
  559. return url + query
  560. },
  561. // 【内部方法】从全局变量和缓存中获取 loginMark 设备标识,获取不到则会重新生成一个
  562. getLoginMark() {
  563. if (this.GET_GLOBAL('loginMark')) {
  564. return this.GET_GLOBAL('loginMark')
  565. }
  566. const storageData = uni.getStorageSync('loginMark')
  567. if (storageData && storageData !== 'null' && storageData !== 'undefined') {
  568. this.SET_GLOBAL('loginMark', storageData)
  569. return storageData
  570. }
  571. const newLoginMark = this.GUID()
  572. this.SET_GLOBAL('loginMark', newLoginMark)
  573. uni.setStorageSync('loginMark', newLoginMark)
  574. return newLoginMark
  575. },
  576. // 【内部方法】处理 url,判断是否需要添加后台地址前缀
  577. handleUrl(url) {
  578. let result = url
  579. if (result.startsWith('http://') || result.startsWith('https://')) {
  580. return result
  581. }
  582. if (!result.startsWith(this.API)) {
  583. result = this.API + result
  584. }
  585. return result
  586. },
  587. // 【内部方法】HTTP 请求基础方法
  588. async requestBase(url, data, header, method = 'GET') {
  589. const requestUrl = this.handleUrl(url)
  590. const requestHeader = header || {}
  591. let requestData = {
  592. loginMark: this.getLoginMark(),
  593. token: this.GET_GLOBAL('token') || ''
  594. }
  595. if (data && typeof data === 'object') {
  596. requestData.data = JSON.stringify(data)
  597. } else if (data) {
  598. Object.assign(requestData, {
  599. data
  600. })
  601. }
  602. return uni.request({
  603. url: requestUrl,
  604. method,
  605. header: {
  606. 'content-type': 'application/x-www-form-urlencoded',
  607. ...requestHeader
  608. },
  609. data: requestData
  610. })
  611. },
  612. // 【内部方法】处理网络请求方法的返回结果
  613. handleResult(err, result, tips) {
  614. // 出现错误,一般是网络连接错误
  615. if (err || !result) {
  616. uni.hideLoading()
  617. uni.showToast({
  618. title: '网络请求失败,请检查您的网络连接',
  619. icon: 'none'
  620. })
  621. return null
  622. }
  623. // 状态码为 410,登录状态失效
  624. if (result.statusCode === 410 || (result.data && result.data.code === 410)) {
  625. uni.hideLoading()
  626. uni.showToast({
  627. title: '登录状态无效,正在跳转到登录页…',
  628. icon: 'none'
  629. })
  630. return null
  631. this.CLEAR_GLOBAL()
  632. uni.reLaunch({
  633. url: '/pages/login'
  634. })
  635. return null
  636. uni.hideLoading()
  637. if (tips) {
  638. const errInfo = (result.data && result.data.info) || '(未知原因)'
  639. const errTips = typeof tips === 'string' ? tips : '请求数据时发生错误'
  640. uni.showToast({
  641. title: `${errTips}: ${errInfo}`,
  642. icon: 'none'
  643. })
  644. }
  645. return null
  646. }
  647. if(result.data.code != 200){
  648. uni.hideLoading()
  649. uni.showToast({
  650. title: result.data.info,
  651. icon: 'none'
  652. })
  653. return null
  654. }
  655. return result.data.data
  656. },
  657. // 【即将废弃】请使用 this.CONFIG() 来替代
  658. config(path) {
  659. return get(globalConfig, path, get(defaultConfig, path))
  660. },
  661. // 【即将废弃】请使用 this.SET_PARAM() 来代替
  662. setPageParam(val) {
  663. this.$store.commit('pageParam', val)
  664. },
  665. // 【即将废弃】请使用 this.GET_PARAM() 来代替
  666. getPageParam() {
  667. return this.$store.state.pageParam
  668. }
  669. },
  670. computed: {
  671. // 请求后台接口的地址
  672. API() {
  673. return this.$store.state.apiRoot ||
  674. this.CONFIG('apiHost')[this.DEV ? this.CONFIG('devApiHostIndex') : this.CONFIG('prodApiHostIndex')]
  675. },
  676. // 当前页面的路径
  677. // 举例:登录页为 '/pages/login'
  678. PATH() {
  679. if (!getCurrentPages) {
  680. return ''
  681. }
  682. const pages = getCurrentPages()
  683. return pages ? '/' + pages.slice(-1)[0].route : ''
  684. },
  685. // 当前是否为开发环境
  686. DEV() {
  687. return process.env.NODE_ENV === 'development'
  688. },
  689. // 【仅开发模式】获取当前全局变量
  690. // 生产环境、正式发行时无效,因为小程序端全局变量会挂载到每个页面,影响性能
  691. DEV_ONLY_GLOBAL() {
  692. return process.env.NODE_ENV === 'development' && this.$store.state
  693. },
  694. // 获取当前移动端版本号 (定义在 config.js)
  695. APP_VERSION() {
  696. return this.CONFIG('appVersion')
  697. },
  698. // 当前运行平台
  699. // 取值 'alipay'/'weixin'/'dingtalk'/'h5'/'app'/'unknow'
  700. PLATFORM() {
  701. let result = 'unknow'
  702. // #ifdef MP-ALIPAY
  703. // #ifndef MP-DINGTALK
  704. result = 'alipay'
  705. // #endif
  706. // #ifdef MP-DINGTALK
  707. result = 'dingtalk'
  708. // #endif
  709. // #endif
  710. // #ifdef MP-WEIXIN
  711. result = 'weixin'
  712. // #endif
  713. // #ifdef H5
  714. result = 'h5'
  715. // #endif
  716. // #ifdef APP-VUE
  717. result = 'app'
  718. // #endif
  719. return result
  720. },
  721. // 获取当前运行平台的中文全称
  722. // 取值 '支付宝小程序'/'微信小程序'/'钉钉小程序'/'移动 H5 '/'手机 App '/'(未知)'
  723. PLATFORM_TEXT() {
  724. let result = '(未知)'
  725. // #ifdef MP-ALIPAY
  726. // #ifndef MP-DINGTALK
  727. result = '支付宝小程序'
  728. // #endif
  729. // #ifdef MP-DINGTALK
  730. result = '钉钉小程序'
  731. // #endif
  732. // #endif
  733. // #ifdef MP-WEIXIN
  734. result = '微信小程序'
  735. // #endif
  736. // #ifdef H5
  737. result = '移动 H5 '
  738. // #endif
  739. // #ifdef APP-VUE
  740. result = '手机 App '
  741. // #endif
  742. return result
  743. },
  744. // 【即将废弃】请使用 this.PATH 来代替
  745. pagePath() {
  746. if (!getCurrentPages) {
  747. return ''
  748. }
  749. const pages = getCurrentPages()
  750. return pages ? '/' + pages.slice(-1)[0].route : ''
  751. },
  752. // 【即将废弃】请使用 this.API 来代替
  753. apiRoot() {
  754. return this.$store.state.apiRoot ||
  755. this.CONFIG('apiHost')[this.DEV ? this.CONFIG('devApiHostIndex') : this.CONFIG('prodApiHostIndex')]
  756. },
  757. }
  758. }