欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

微信小程序通用后台请求生成器

程序员文章站 2024-01-27 08:37:04
...

目的:统一数据请求,模拟数据

1.serviceCreator.js

/*
 * ServiceCreater.js
 */

//ramda.js 工具库
import R from "../lib/ramda/ramda.js"

//Mock.js 用于数据模拟
import Mock from "../lib/mock/mock.js"

//只使用了类型判断函数 isFunction/isArray/isPlainObject
import Util from "./util.js"

//全局请求统一入口
function ajax(option) {
    return new Promise(function(resolve, reject) {
      option.header = option.header || {};
      option.data = option.data || {};
      option.method = option.method || "post";

      let sessionId = wx.getStorageSync("sessionid");
      sessionId && (option.header.Cookie = sessionId);
      let wxtoken = wx.getStorageSync("wxtoken")
      option.url += (option.url.indexOf('?') != -1?"&":"?")+"wxtoken=" + wxtoken;

      wx.request(R.mergeDeepRight(option, {
        success: function(res) {
          if (res['statusCode'] == 200) {
            resolve(res.data) //异步成功之后执行的函数
          } else {
            if (res.data.errCode == -1) {
              wx.showModal({
                title: '温馨提示',
                content: res.data.errMsg,
                showCancel: false,
                success: function(res) {
                  //存储用户名
                  wx.redirectTo({
                    url: '/pages/login/login'
                  })
                }
              })
            } else {
              wx.showToast({
                title: res.data.errMsg || res.statusCode,
                icon: 'none',
                duration: 2000,
                mask: true
              })
            }
            reject(new Error("请求异常"));
          }
        },
        complete: function() {
          wx.hideLoading()
          setTimeout(function() {
            if (reject) {
              return;
            }
            reject("超时");
          }, 10000)
        },
        fail: function (res) {
          wx.showToast({
            title: '您的网络开小差啦~~~',
            icon: 'none',
            duration: 2000,
            mask: true
          })
          reject('网络出错');
        }
      }));
    });
}


/*
 * 创建接口对象(单个接口)
 */
function createService(setting, context) {
  var _this = this;

  //获取上下文
  var getContext = () => Promise.resolve(Util.isFunction(context) ? context() : context);

  //若配置为 函数、字符串,则将其设置为 url,一遍后续处理
  (Util.isFunction(setting) || typeof setting == "string") && (setting = {
    url: setting
  });

  //返回一个函数,用于直接调用
  return function() {
    //记录调用时传入参数
    var allarg = arguments;

    return getContext().then(function(con) {
      return new Promise(function (resolve, reject) {
        //根据参数配置 props 属性,处理实参

        //props 若为函数
        if (Util.isFunction(setting.props)) {
          //若props为函数,将实参列表传入props,在props函数中this指向services,this.context指向当前配置,
          return Promise.resolve(setting.props.apply(con, allarg))
            .then(resolve)["catch"](reject);
        }
        //props 若为数组
        if (Util.isArray(setting.props)) {
          //若props为string[],将实参列表传入props
          var rev = {};
          setting.props.forEach(function(iprop, index) {
            rev[iprop] = allarg[index] || null;
          })
          return resolve(rev);
        }

        //不再 关心 props 配置,直接将实参列表传出
        return resolve([].slice.call(allarg, 0));
      }).then(function(args) {
        //合并附加参数props_exit,并调用
        var rev = null;
        if (setting.usemock && setting.mock){
          //使用模拟数据
          if (Util.isFunction(setting.mock)) {
            //使用自定义函数模拟
            rev = Promise.resolve(setting.mock.apply(con, allarg));
          } else if (Util.isPlainObject(setting.mock)) {
            //使用自定义mock对象生成
            rev = Promise.resolve(Mock.mock(setting.mock));
          }else{
            //直接返回模拟数据
            rev = Promise.resolve(setting.mock);
          }
        } else {
          //url 为字符串,则认为是接口地址
          if (typeof setting.url == "string") {
            var opt = {
              url: setting.url,
              method: setting.type || "post"
            }
            if (Util.isArray(args) && args.length > 0) {
              //若传入参数处理仍为数组,则认为
              opt.data = args[0]
            }
            rev = ajax(R.mergeDeepRight(setting.ajax, opt));
          } else if (Util.isFunction(setting.url)) {
            //url 为函数,则直接调用此函数
            rev = Promise.resolve(setting.url.apply(con, args));
          } else {
            rev = Promise.resolve(rev);
          }
        }
        rev = setting.then ? rev.then(setting.then) : rev;
        rev = rev.catch(function (err) {
          throw err;
        })
        rev = setting["catch"] ? rev["catch"](setting["catch"]) : rev;
        return rev;
      })
    });
  }
}


/*
 * 创建接口集合
 */
function createServices(setting, option) {
  var _service = R.map(function(item) {
    return createService(item, function() {
      return R.mergeDeepRight(_service, {
        context: item
      });
    });
  }, setting);

  return _service;
}

module.exports = {
  createServices,
  createService,
  ajax,
  mockAjax
}

2.service.test.js

/*
 * service.test.js
 */

import serviceCreater from "serviceCreater.js"

module.exports = serviceCreater.createServices({
  //直接配置为url
  getData1: url,

  //配置为函数
  getData2: function() {return 111},

  //配置参数转换器
  getData3: {
    url: url,
    props:(p1)=>({p:p1,t:"222"})
  },

  //配置返回值转换器
  getData4: {
    url: url,
    ajax:{},
    then: (list) => list.map((item) => item.zhuti)
  },

  //使用模拟数据
  getData5: {
    url: url,
    usemock: true,//将次配置改为false使用url请求
    mock: {
      "id": "@id()",
      "xxx": "xxx"
    }
  },

  //定义服务端接收数据编码类型字符串参数
  getData6: {
    url: url,
    ajax:{
      header: {
        /*
          服务端接收数据编码类型(Mime- Type),配合服务端设置,常用以下几种
          text:'text/plain'
          json:'application/json'
          form:'application/x-www-form-urlencoded'
        */
        'Content-Type':"text/plain"
      }
    }
  },

  //模板
  getDataTemplate:{
        //可选配置,string/function
        url:"https://xxx.xx.com/xxx.action",

        //可选配置,调用时将实参列表按次配置合并成一个object对象并上传
        props:["gid"],

        //可选配置,使用模拟数据
        usemock:true,

        //可选配置,usemock:true时使用,可谓mock表达式/json数据/函数
        mock:{
            "list|1-10":{
                {id:}
            }
        },

        //可选配置,调用ajax原始配置
        ajax:{
            
        },

        //可选配置,转换原始数据
        then:function(data){
            return data;
        }
    }
})

//接口使用示例

testService.getData1().then(data=>this.setData(data))