天天看點

athena之___封裝vue-resource資料請求方式

src/assets/scripts/base/dataService.js :

/**
 * vue 中的ajax 資料服務:vue-resource
 */
import Vue from 'vue'
import store from 'store'
import vueResource from 'vue-resource'
import MockData from 'assets/mock/index'
import moment from 'moment'
import {dataServiceConfig, loginUserKey, backendMenuId, submitToken, routeKey} from 'src/config/index.js'
import {dotData, alert, replaceNullDeep} from './functions.js' //
import login from './login'
Vue.use(vueResource)
Vue.http.options.emulateHTTP = true
Vue.http.options.timeout = 0

let devMode = process.env.NODE_ENV !== 'production'

// 更新token
Vue.http.interceptors.push((request, next) => {
  const token = dotData(store.get(loginUserKey), 'token')
  if (devMode) {
    if (MockData.has(request.url.replace('/api', ''))) {
      request.url = '/mock' + MockData.get(request.url.replace('/api', ''))
    }
  }
  // 通路token
  if (token) {
    Vue.http.headers.common['token'] = token
  } else {
    Vue.http.headers.common['token'] = ''
  }
  // 菜單編号
  const menuId = store.get(backendMenuId)
  if (menuId) {
    Vue.http.headers.common['menu-id'] = String(menuId)
  }
  const startTime = moment().valueOf()
  // continue to next interceptor
  next((response) => {
    if (process.env.NODE_ENV === 'testing' && token) {
      const endTime = moment().valueOf()
      const menuUtil = require('assets/scripts/business/menu')
      // 這些接口要跳過統計 因為通路這些接口都是沒有授權的時候
      const breakPathUrl = [
        '/api/ms-user-info/user/userLogin', // 沒有授權
        '/api/ms-user-info/user/userMobile', // 沒有授權
        '/api/ms-user-info/user/backPws', // 沒有授權
        '/api/ms-user-info/user/menu-user-id', // 不能統計, 這裡會産生遞歸
        '/api/ms-access-log/CallOnInterface/log-record', // 統計的統計接口,不用統計
        '/api/token/resubmit-token' // 擷取token不統計
      ]
      let url = request.url
      const urlIndexOf = String(request.url).indexOf('?')
      if (urlIndexOf >= 0) {
        url = url.substring(0, urlIndexOf)
      }
      if (breakPathUrl.indexOf(url) < 0 && response.status === 200) {
        menuUtil.getMenuDataPathMap().then(map => {
          const lableName = dotData(store.get(routeKey), 'name')
          const matchPath = dotData(store.get(routeKey), 'path')
          const menuName = dotData(map.get(matchPath), 'text')
          const util = require('assets/scripts/base/util')
          util.httpSuccessGet('/ms-access-log/CallOnInterface/log-record', {
            menuName, lableName, menuUrl: matchPath, afterPort: url, visitStarttime: startTime, visitEndtime: endTime
          })
        })
      }
    }
    const tokenNew = response.headers.get('token-new')
    let data = store.get(loginUserKey)
    if (tokenNew && data) {
      data.token = tokenNew
      store.set(loginUserKey, data)
    }
  })
})
let statusMap = new Map()
export default {
  createUrl (url) {
    if (/^http:\/\//.test(url)) {
      return url
    }
    if (/^prefix:/.test(url)) {
      return url.replace('prefix:', '')
    }
    if (url.charAt(0) !== '/') {
      url = '/' + url
    }
    return dataServiceConfig.urlPrefix + url
  },
  get (url, options = {}) {
    url = this.createUrl(url)
    options.params = window.$.extend(true, {t: new Date().getTime()}, options.params)
    return Vue.http.get(url, options)
  },
  getWithParams (url, params, options = {}) {
    options.params = window.$.extend(true, params, options.params)
    return this.get(url, options)
  },
  head (url, options = {}) {
    url = this.createUrl(url)
    return Vue.http.head(url, options)
  },
  delete (url, options = {}) {
    url = this.createUrl(url)
    return Vue.http.delete(url, options)
  },
  jsonp (url, options = {}) {
    url = this.createUrl(url)
    return Vue.http.jsonp(url, options)
  },
  post (url, body = {}, options = {}) {
    url = this.createUrl(url)
    options.params = window.$.extend(true, {t: new Date().getTime()}, options.params)
    return Vue.http.post(url, body, options)
  },
  put (url, body = {}, options = {}) {
    url = this.createUrl(url)
    return Vue.http.put(url, body, options)
  },
  patch (url, body = {}, options = {}) {
    url = this.createUrl(url)
    return Vue.http.patch(url, body, options)
  },
  resource (url, params = {}, actions = {}, options = {}) {
    url = this.createUrl(url)
    return Vue.resource(url, params, actions, options)
  },
  handleError (response) {
    if (response.status === 200) {
      response.json().then(responseJson => {
        alert(responseJson.message || '系統報錯')
      })
    } else if (response.status === 401) {
      login.logout(true)
    } else if (response.status === 402) {
      const newToken = response.headers.get('resubmit-token')
      if (newToken) {
        store.set(submitToken, newToken)
      }
      alert('請勿重複送出')
    } else if (response.status === 503) {
      window.location.reload()
    } else if (response.status === 0) {
      if (window.navigator.onLine) {
        alert('網絡連接配接異常')
      } else {
        alert('通路失敗:請檢查網絡')
      }
    } else {
      // 此處處理一下 同一個狀态碼在4秒内隻包一次錯誤
      if (!statusMap.has(response.status)) {
        alert('系統報錯 status:' + response.status)
        statusMap.set(response.status, true)
        setTimeout(_ => {
          statusMap.delete(response.status)
        }, 4000)
      }
      throw response
    }
  },
  // 過濾一下json
  handleJson (json) {
    return replaceNullDeep(json)
  }
}
           

資料請求方式集合:src/assets/scripts/base/util.js

httpSuccessGet、httpSuccessGetArr、httpGetTable、httpGetDetail、httpSuccessPost

import dataService from './dataService'

import {unixTimestampFilter, filterDataBaseDictionary} from './filters'

import store from 'store'

舉例:

// 擷取詳情資料
export const httpGetDetail = (url, that, params = {}, dictionary = [], key = 'detailData', dataFunc = (responseJson) => {
  return responseJson
}) => {
  return httpSuccessGet(url, params).then(detailData => {
    let data = dataFunc(detailData)
    dictionary.forEach(v => {
      setDotData(data, v + '@Text', filterDataBaseDictionary(dotData(data, v)))
    })
    that[key] = dataService.handleJson(data)
    return that[key]
  })
}

// 成功post資料
export const httpSuccessPost = (url, body, options = {}, failMessage = '') => {
  let resubmitUrl = lodash.indexOf(interfaceArr, '/api' + url)
  // 嵌入 token 後端防止重複送出
  const resubmitToken = store.get(submitToken)
  if (resubmitToken && resubmitUrl >= 0) {
    options.headers = merge(options.headers || {}, {'resubmit-token': resubmitToken})
  }
  return dataService.post(url, body, options).then(response => {
    const status = response.status
    const newToken = response.headers.get('resubmit-token')
    if (newToken && resubmitUrl >= 0) {
      store.set(submitToken, newToken)
    }
    return response.json().then(responseJson => {
      if (responseJson.success === true) {
        return {success: true, data: dataService.handleJson(responseJson.data)}
      } else {
        if (status === 200) {
          alert(failMessage || responseJson.error_message || '系統傳回 success: false')
        }
      }
      return {success: false, error: responseJson.error_message}
    })
  }).catch(response => {
    dataService.handleError(response)
  })
}

// 成功Get資料
export const httpSuccessGet = (url, params = {}, options = {}, failMessage = '') => {
  return dataService.getWithParams(url, params, options).then(response => {
    const status = response.status
    return response.json().then(responseJson => {
      if (responseJson.success === true) {
        return dataService.handleJson(responseJson.data)
      } else {
        if (status === 200) {
          alert(failMessage || responseJson.error_message || '系統傳回 success: false')
        }
      }
      return false
    })
  }).catch(response => {
    dataService.handleError(response)
  })
}

// 成功Get資料
export const httpGetResponse = (url, params = {}, options = {}, failMessage = '') => {
  return dataService.getWithParams(url, params, options).then(response => {
    const status = response.status
    return response.json().then(responseJson => {
      if (responseJson.success === true) {
        return dataService.handleJson(responseJson)
      } else {
        if (status === 200) {
          alert(failMessage || responseJson.error_message || '系統傳回 success: false')
        }
      }
      return responseJson
    })
  }).catch(response => {
    dataService.handleError(response)
  })
}
           

繼續閱讀