mock.js

/**
 * 模拟数据Mockjs处理模块
 * @module $ui/utils/mock
 * @author 陈华春
 */

import Mock from 'mockjs'
import pathToRegex from 'path-to-regexp'
import {parse, getParams} from './url'
import {log, tip} from './log'
import config from '$ui/config'


// 模拟请求延时时间
Mock.setup(config.mock || {})

/**
 * 字符串转换成对象
 * @private
 * @param {string} str
 * @returns {Object} json
 *
 *
 * @example
 * // json 格式字符串
 *  "{name:'kenny', password:'123'}"
 *
 *  // 结果
 *  {name:'kenny', password:'123'}
 */
function toObject(str) {
  if (typeof str === 'object') {
    return str
  }
  const regex = /^\{[\W\w]*\}$/
  return regex.test(str) ? JSON.parse(str) : null
}


/**
 * 请求数据 body 转换成 JSON,发送内容有两种形式,json格式或表单模式
 * @private
 * @param {String} body 数据内容文本
 * @returns {Object} json
 *
 * @example
 * // json 格式
 *  "{name:'kenny', password:'123'}"
 *
 *  //表单模式
 *  name=kenny&passwrod=123
 *
 *  // 结果
 *  {name:'kenny', password:'123'}
 */
function getBody(body) {
  if (!body) return null

  const regex = /^\{[\W\w]*\}$/
  return regex.test(body) ? JSON.parse(body) : parse(body)
}


/**
 * 根据mock配置规则,设置拦截请求返回模拟数据
 * @param {Object} item mock规则对象
 * @param {String} item.title 规则描述文字
 * @param {String} item.url 请求url地址
 * @param {String} item.method 请求方法类型,如:get post head put patch delete options
 * @param {Object} [item.params] 请求url查询参数对象
 * @param {Object|Function} item.template 模拟数据模板
 *
 * @example
 *
 * import mock from '@/utils/mock'
 * mock({
 *  title: 'GET_USERS',
 *  url: GET_USERS,
 *  method: 'get',
 *  params: {},
 *  template: {
 *    code: 0,
 *    msg: '获取成功',
 *    data: {
 *      'id': '@guid',
 *      'name': '@cname'
 *    }
 *   }
 * })
 */
export default function (item = {}) {
  if (!item.url) return

  // 匹配的请求url
  const oRegex = pathToRegex(item.url)
  // 只匹配path,忽略参数
  const regex = new RegExp(
    oRegex.source
      .replace('(?:\\/)?$', '($|\\?)')
      .replace(/\[\^\d\\\/\]/, '[^\\/]'),
    'i')
  // 设置拦截请求ur

  Mock.mock(regex, item.method, function (options) {
    let result
    const body = getBody(options.body) || {}
    // 把GET、POST请求的参数对象与默认的参数进行合并组成新的对象
    const query = Object.assign({},
      item.params || {},
      getParams(item.url, options.url),
      parse(options.url || ' '),
      body,
      toObject(body.data) || {}
    )
    if (typeof item.template === 'function') {
      result = item.template(Mock, options.url, query, options)
    } else {
      // 把模拟数据模板字转换成字符串,因为需要对模板插入自定义参数
      let templateString = JSON.stringify(item.template)

      // 替换在模板中的参数标识
      for (const key in query) {
        templateString = templateString.replace(new RegExp('{{' + key + '}}', 'g'), query[key])
      }

      // 返回模拟数据
      result = Mock.mock(JSON.parse(templateString))
    }
    // 打印模拟请求日志
    tip('Mock', item.title)
    log(options, result)
    log('-------------------------------------------')
    return result
  })
}